diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/LinkUp-P2P-Chat.iml b/.idea/LinkUp-P2P-Chat.iml
new file mode 100644
index 0000000..24643cc
--- /dev/null
+++ b/.idea/LinkUp-P2P-Chat.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..3668dc8
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..8ab2f2f
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app.js b/app.js
index 6c3dbf7..fa93d67 100644
--- a/app.js
+++ b/app.js
@@ -16,7 +16,7 @@ await drive.ready();
let swarm;
let registeredUsers = JSON.parse(localStorage.getItem('registeredUsers')) || {};
let peerCount = 0;
-let currentRoom = null;
+let activeRooms = [];
const eventEmitter = new EventEmitter();
// Define servePort at the top level
@@ -29,7 +29,10 @@ let config = {
rooms: []
};
-// Function to get a random port between 1337 and 2223
+// Store messages for each room
+let messagesStore = {};
+
+// Function to get a random port between 49152 and 65535
function getRandomPort() {
return Math.floor(Math.random() * (65535 - 49152 + 1)) + 49152;
}
@@ -73,40 +76,38 @@ async function initialize() {
toggleSetupBtn.addEventListener('click', toggleSetupView);
}
if (removeRoomBtn) {
- removeRoomBtn.addEventListener('click', leaveRoom);
+ removeRoomBtn.addEventListener('click', () => {
+ const topic = document.querySelector('#chat-room-topic').innerText;
+ leaveRoom(topic);
+ });
}
if (attachFileButton) {
attachFileButton.addEventListener('click', () => fileInput.click());
}
if (fileInput) {
- fileInput.addEventListener('change', async (event) => {
- const file = event.target.files[0];
- if (file) {
- const reader = new FileReader();
- reader.onload = async (event) => {
- const buffer = new Uint8Array(event.target.result);
- const filePath = `/files/${file.name}`;
- await drive.put(filePath, buffer);
- const fileUrl = `http://localhost:${servePort}${filePath}`;
- sendFileMessage(config.userName, fileUrl, file.type, config.userAvatar);
- };
- reader.readAsArrayBuffer(file);
- }
- });
+ fileInput.addEventListener('change', handleFileInput);
}
const configExists = fs.existsSync("./config.json");
if (configExists) {
config = JSON.parse(fs.readFileSync("./config.json", 'utf8'));
- console.log("Read config from file:", config)
+ console.log("Read config from file:", config);
// Update port in URLs
config.userAvatar = updatePortInUrl(config.userAvatar);
config.rooms.forEach(room => {
- addRoomToListWithoutWritingToConfig(room);
+ room.alias = room.alias || truncateHash(room.topic);
});
for (let user in registeredUsers) {
registeredUsers[user] = updatePortInUrl(registeredUsers[user]);
}
+
+ renderRoomList(); // Render the room list with aliases
+
+ // Connect to all rooms on startup
+ for (const room of config.rooms) {
+ const topicBuffer = b4a.from(room.topic, 'hex');
+ await joinSwarm(topicBuffer);
+ }
}
const registerDiv = document.querySelector('#register');
@@ -115,15 +116,30 @@ async function initialize() {
}
eventEmitter.on('onMessage', async (messageObj) => {
+ console.log('Received message:', messageObj); // Debugging log
+
if (messageObj.type === 'icon') {
const username = messageObj.username;
- const avatarBuffer = Buffer.from(messageObj.avatar, 'base64');
- await drive.put(`/icons/${username}.png`, avatarBuffer);
- updateIcon(username, avatarBuffer);
+ if (messageObj.avatar) {
+ const avatarBuffer = b4a.from(messageObj.avatar, 'base64');
+ await drive.put(`/icons/${username}.png`, avatarBuffer);
+ updateIcon(username, avatarBuffer);
+ } else {
+ console.error('Received icon message with missing avatar data:', messageObj);
+ }
} else if (messageObj.type === 'file') {
- addFileMessage(messageObj.name, messageObj.fileName, messageObj.fileUrl, messageObj.fileType, messageObj.avatar);
+ if (messageObj.file && messageObj.fileName) {
+ const fileBuffer = b4a.from(messageObj.file, 'base64');
+ await drive.put(`/files/${messageObj.fileName}`, fileBuffer);
+ const fileUrl = `http://localhost:${servePort}/files/${messageObj.fileName}`;
+ addFileMessage(messageObj.name, messageObj.fileName, updatePortInUrl(fileUrl), messageObj.fileType, updatePortInUrl(messageObj.avatar), messageObj.topic);
+ } else {
+ console.error('Received file message with missing file data or fileName:', messageObj);
+ }
+ } else if (messageObj.type === 'message') {
+ onMessageAdded(messageObj.name, messageObj.message, messageObj.avatar, messageObj.topic);
} else {
- onMessageAdded(messageObj.name, messageObj.message, messageObj.avatar);
+ console.error('Received unknown message type:', messageObj);
}
});
@@ -138,7 +154,7 @@ async function initialize() {
const iconMessage = JSON.stringify({
type: 'icon',
username: config.userName,
- avatar: iconBuffer.toString('base64'),
+ avatar: b4a.toString(iconBuffer, 'base64'),
});
connection.write(iconMessage);
}
@@ -162,6 +178,11 @@ async function initialize() {
swarm.on('close', () => {
console.log('Swarm closed');
});
+
+ // Initialize highlight.js once the DOM is fully loaded
+ document.addEventListener("DOMContentLoaded", (event) => {
+ hljs.highlightAll();
+ });
}
function registerUser(e) {
@@ -214,7 +235,7 @@ async function createChatRoom() {
const topicBuffer = crypto.randomBytes(32);
const topic = b4a.toString(topicBuffer, 'hex');
addRoomToList(topic);
- joinSwarm(topicBuffer);
+ await joinSwarm(topicBuffer);
}
async function joinChatRoom(e) {
@@ -222,27 +243,21 @@ async function joinChatRoom(e) {
const topicStr = document.querySelector('#join-chat-room-topic').value;
const topicBuffer = b4a.from(topicStr, 'hex');
addRoomToList(topicStr);
- joinSwarm(topicBuffer);
+ await joinSwarm(topicBuffer);
}
async function joinSwarm(topicBuffer) {
- if (currentRoom) {
- currentRoom.destroy();
- }
-
- document.querySelector('#setup').classList.add('hidden');
- document.querySelector('#loading').classList.remove('hidden');
-
- const discovery = swarm.join(topicBuffer, { client: true, server: true });
- await discovery.flushed();
-
const topic = b4a.toString(topicBuffer, 'hex');
- document.querySelector('#chat-room-topic').innerText = topic; // Set full topic here
- document.querySelector('#loading').classList.add('hidden');
- document.querySelector('#chat').classList.remove('hidden');
+ if (!activeRooms.some(room => room.topic === topic)) {
+ const discovery = swarm.join(topicBuffer, { client: true, server: true });
+ await discovery.flushed();
- currentRoom = discovery;
- clearMessages();
+ activeRooms.push({ topic, discovery });
+
+ console.log('Joined room:', topic); // Debugging log
+
+ renderMessagesForRoom(topic);
+ }
}
function addRoomToList(topic) {
@@ -250,43 +265,118 @@ function addRoomToList(topic) {
const roomItem = document.createElement('li');
roomItem.textContent = truncateHash(topic);
roomItem.dataset.topic = topic;
+
+ roomItem.addEventListener('dblclick', () => enterEditMode(roomItem));
roomItem.addEventListener('click', () => switchRoom(topic));
roomList.appendChild(roomItem);
- config.rooms.push(topic);
+ config.rooms.push({ topic, alias: truncateHash(topic) });
writeConfigToFile("./config.json");
}
-function addRoomToListWithoutWritingToConfig(topic) {
- const roomList = document.querySelector('#room-list');
- const roomItem = document.createElement('li');
- roomItem.textContent = truncateHash(topic);
- roomItem.dataset.topic = topic;
- roomItem.addEventListener('click', () => switchRoom(topic));
- roomList.appendChild(roomItem);
+function enterEditMode(roomItem) {
+ const originalText = roomItem.textContent;
+ const topic = roomItem.dataset.topic;
+ roomItem.innerHTML = '';
+
+ const input = document.createElement('input');
+ input.type = 'text';
+ input.value = originalText;
+ input.style.maxWidth = '100%'; // Add this line to set the max width
+ input.style.boxSizing = 'border-box'; // Add this line to ensure padding and border are included in the width
+
+ roomItem.appendChild(input);
+
+ input.focus();
+
+ input.addEventListener('blur', () => {
+ exitEditMode(roomItem, input, topic);
+ });
+
+ input.addEventListener('keydown', (e) => {
+ if (e.key === 'Enter') {
+ exitEditMode(roomItem, input, topic);
+ } else if (e.key === 'Escape') {
+ roomItem.textContent = originalText;
+ }
+ });
+}
+
+function exitEditMode(roomItem, input, topic) {
+ const newAlias = input.value.trim();
+ if (newAlias) {
+ roomItem.textContent = newAlias;
+
+ // Update the config with the new alias
+ const roomConfig = config.rooms.find(room => room.topic === topic);
+ if (roomConfig) {
+ roomConfig.alias = newAlias;
+ writeConfigToFile("./config.json");
+ }
+
+ // Check if the edited room is the current room in view
+ const currentTopic = document.querySelector('#chat-room-topic').innerText;
+ if (currentTopic === topic) {
+ const chatRoomName = document.querySelector('#chat-room-name');
+ if (chatRoomName) {
+ chatRoomName.innerText = newAlias;
+ }
+ }
+ } else {
+ roomItem.textContent = truncateHash(topic);
+ }
}
function switchRoom(topic) {
- const topicBuffer = b4a.from(topic, 'hex');
- joinSwarm(topicBuffer);
+ console.log('Switching to room:', topic); // Debugging log
+ const chatRoomTopic = document.querySelector('#chat-room-topic');
+ const chatRoomName = document.querySelector('#chat-room-name');
+
+ if (chatRoomTopic) {
+ chatRoomTopic.innerText = topic; // Set full topic here
+ } else {
+ console.error('Element #chat-room-topic not found');
+ }
+
+ if (chatRoomName) {
+ // Update the room name in the header
+ const room = config.rooms.find(r => r.topic === topic);
+ const roomName = room ? room.alias : truncateHash(topic);
+ chatRoomName.innerText = roomName;
+ } else {
+ console.error('Element #chat-room-name not found');
+ }
+
+ clearMessages();
+ renderMessagesForRoom(topic);
+
+ // Show chat UI elements
+ document.querySelector('#chat').classList.remove('hidden');
+ document.querySelector('#setup').classList.add('hidden');
}
-function leaveRoom() {
- if (currentRoom) {
- const topic = b4a.toString(currentRoom.topic, 'hex');
- const roomItem = document.querySelector(`li[data-topic="${topic}"]`);
- if (roomItem) {
- roomItem.remove();
- }
-
- config.rooms = config.rooms.filter(e => e !== topic);
- writeConfigToFile("./config.json");
-
- currentRoom.destroy();
- currentRoom = null;
+function leaveRoom(topic) {
+ const roomIndex = activeRooms.findIndex(room => room.topic === topic);
+ if (roomIndex !== -1) {
+ const room = activeRooms[roomIndex];
+ room.discovery.destroy();
+ activeRooms.splice(roomIndex, 1);
+ }
+
+ const roomItem = document.querySelector(`li[data-topic="${topic}"]`);
+ if (roomItem) {
+ roomItem.remove();
+ }
+
+ config.rooms = config.rooms.filter(e => e.topic !== topic);
+ writeConfigToFile("./config.json");
+
+ if (activeRooms.length > 0) {
+ switchRoom(activeRooms[0].topic);
+ } else {
+ document.querySelector('#chat').classList.add('hidden');
+ document.querySelector('#setup').classList.remove('hidden');
}
- document.querySelector('#chat').classList.add('hidden');
- document.querySelector('#setup').classList.remove('hidden');
}
function sendMessage(e) {
@@ -294,7 +384,11 @@ function sendMessage(e) {
const message = document.querySelector('#message').value;
document.querySelector('#message').value = '';
- onMessageAdded(config.userName, message, config.userAvatar);
+ const topic = document.querySelector('#chat-room-topic').innerText;
+
+ console.log('Sending message:', message); // Debugging log
+
+ onMessageAdded(config.userName, message, config.userAvatar, topic);
let peersPublicKeys = [];
peersPublicKeys.push([...swarm.connections].map(peer => peer.remotePublicKey.toString('hex')));
@@ -306,7 +400,7 @@ function sendMessage(e) {
name: config.userName,
message,
avatar: config.userAvatar,
- topic: b4a.toString(currentRoom.topic, 'hex'),
+ topic: topic,
peers: peersPublicKeys, // Deprecated. To be deleted in future updates
timestamp: Date.now(),
readableTimestamp: new Date().toLocaleString(), // Added human-readable timestamp
@@ -318,6 +412,41 @@ function sendMessage(e) {
}
}
+async function handleFileInput(event) {
+ const file = event.target.files[0];
+ if (file) {
+ const reader = new FileReader();
+ reader.onload = async (event) => {
+ const buffer = new Uint8Array(event.target.result);
+ const filePath = `/files/${file.name}`;
+ await drive.put(filePath, buffer);
+ const fileUrl = `http://localhost:${servePort}${filePath}`;
+
+ const topic = document.querySelector('#chat-room-topic').innerText;
+
+ const fileMessage = {
+ type: 'file',
+ name: config.userName,
+ fileName: file.name,
+ file: b4a.toString(buffer, 'base64'),
+ fileType: file.type,
+ avatar: updatePortInUrl(config.userAvatar),
+ topic: topic
+ };
+
+ console.log('Sending file message:', fileMessage); // Debugging log
+
+ const peers = [...swarm.connections];
+ for (const peer of peers) {
+ peer.write(JSON.stringify(fileMessage));
+ }
+
+ addFileMessage(config.userName, file.name, fileUrl, file.type, config.userAvatar, topic);
+ };
+ reader.readAsArrayBuffer(file);
+ }
+}
+
function sendFileMessage(name, fileUrl, fileType, avatar) {
const fileName = fileUrl.split('/').pop();
const messageObj = JSON.stringify({
@@ -327,7 +456,7 @@ function sendFileMessage(name, fileUrl, fileType, avatar) {
fileUrl,
fileType,
avatar,
- topic: b4a.toString(currentRoom.topic, 'hex'),
+ topic: document.querySelector('#chat-room-topic').innerText,
timestamp: Date.now(),
});
@@ -336,10 +465,11 @@ function sendFileMessage(name, fileUrl, fileType, avatar) {
peer.write(messageObj);
}
- addFileMessage(name, fileName, fileUrl, fileType, avatar);
+ addFileMessage(name, fileName, fileUrl, fileType, avatar, document.querySelector('#chat-room-topic').innerText);
}
-function addFileMessage(from, fileName, fileUrl, fileType, avatar) {
+function addFileMessage(from, fileName, fileUrl, fileType, avatar, topic) {
+ console.log('Adding file message:', { from, fileName, fileUrl, fileType, avatar, topic }); // Debugging log
const $div = document.createElement('div');
$div.classList.add('message');
@@ -363,16 +493,27 @@ function addFileMessage(from, fileName, fileUrl, fileType, avatar) {
$image.classList.add('attached-image');
$content.appendChild($image);
} else {
- const $fileLink = document.createElement('a');
- $fileLink.href = fileUrl;
- $fileLink.textContent = `File: ${fileName}`;
- $fileLink.download = fileName;
- $content.appendChild($fileLink);
+ const $fileButton = document.createElement('button');
+ $fileButton.textContent = `Download File: ${fileName}`;
+ $fileButton.onclick = function() {
+ const $fileLink = document.createElement('a');
+ $fileLink.href = fileUrl;
+ $fileLink.download = fileName;
+ $fileLink.click();
+ };
+ $content.appendChild($fileButton);
}
$div.appendChild($content);
- document.querySelector('#messages').appendChild($div);
- scrollToBottom();
+
+ // Only render the message if it's for the current room
+ const currentTopic = document.querySelector('#chat-room-topic').innerText;
+ if (currentTopic === topic) {
+ document.querySelector('#messages').appendChild($div);
+ scrollToBottom();
+ } else {
+ console.log(`Message for topic ${topic} not rendered because current topic is ${currentTopic}`); // Debugging log
+ }
}
function updatePeerCount() {
@@ -387,37 +528,61 @@ function scrollToBottom() {
container.scrollTop = container.scrollHeight;
}
-function onMessageAdded(from, message, avatar) {
- const $div = document.createElement('div');
- $div.classList.add('message');
-
- const $img = document.createElement('img');
+function onMessageAdded(from, message, avatar, topic) {
+ console.log('Adding message:', { from, message, avatar, topic }); // Debugging log
+ const messageObj = {
+ from,
+ message,
+ avatar
+ };
- $img.src = updatePortInUrl(avatar) || 'https://via.placeholder.com/40'; // Default to a placeholder image if avatar URL is not provided
- console.log(updatePortInUrl(avatar))
- $img.classList.add('avatar');
- $div.appendChild($img);
+ // Add the message to the store
+ addMessageToStore(topic, messageObj);
- const $content = document.createElement('div');
- $content.classList.add('message-content');
+ // Only render messages for the current room
+ const currentTopic = document.querySelector('#chat-room-topic').innerText;
+ if (currentTopic === topic) {
+ const $div = document.createElement('div');
+ $div.classList.add('message');
- const $header = document.createElement('div');
- $header.classList.add('message-header');
- $header.textContent = from;
+ const $img = document.createElement('img');
+ $img.src = updatePortInUrl(avatar) || 'https://via.placeholder.com/40'; // Default to a placeholder image if avatar URL is not provided
+ $img.classList.add('avatar');
+ $div.appendChild($img);
- const $text = document.createElement('div');
- $text.classList.add('message-text');
+ const $content = document.createElement('div');
+ $content.classList.add('message-content');
- const md = window.markdownit();
- const markdownContent = md.render(message);
- $text.innerHTML = markdownContent;
+ const $header = document.createElement('div');
+ $header.classList.add('message-header');
+ $header.textContent = from;
- $content.appendChild($header);
- $content.appendChild($text);
- $div.appendChild($content);
+ const $text = document.createElement('div');
+ $text.classList.add('message-text');
- document.querySelector('#messages').appendChild($div);
- scrollToBottom();
+ const md = window.markdownit({
+ highlight: function (str, lang) {
+ if (lang && hljs.getLanguage(lang)) {
+ try {
+ return hljs.highlight(str, { language: lang }).value;
+ } catch (__) {}
+ }
+ return ''; // use external default escaping
+ }
+ });
+
+ const markdownContent = md.render(message);
+ $text.innerHTML = markdownContent;
+
+ $content.appendChild($header);
+ $content.appendChild($text);
+ $div.appendChild($content);
+
+ document.querySelector('#messages').appendChild($div);
+ scrollToBottom();
+ } else {
+ console.log(`Message for topic ${topic} not rendered because current topic is ${currentTopic}`); // Debugging log
+ }
}
function truncateHash(hash) {
@@ -429,7 +594,7 @@ async function updateIcon(username, avatarBuffer) {
if (userIcon) {
const avatarBlob = new Blob([avatarBuffer], { type: 'image/png' });
const avatarUrl = URL.createObjectURL(avatarBlob);
- userIcon.src = avatarUrl;
+ userIcon.src = updatePortInUrl(avatarUrl);
config.userAvatar = avatarUrl;
writeConfigToFile("./config.json");
@@ -462,4 +627,45 @@ function updatePortInUrl(url) {
return urlObject.toString();
}
-initialize();
\ No newline at end of file
+function renderRoomList() {
+ const roomList = document.querySelector('#room-list');
+ roomList.innerHTML = '';
+
+ config.rooms.forEach(room => {
+ const roomItem = document.createElement('li');
+ roomItem.textContent = room.alias || truncateHash(room.topic);
+ roomItem.dataset.topic = room.topic;
+
+ roomItem.addEventListener('dblclick', () => enterEditMode(roomItem));
+ roomItem.addEventListener('click', () => switchRoom(room.topic));
+ roomList.appendChild(roomItem);
+ });
+}
+
+function renderMessagesForRoom(topic) {
+ console.log('Rendering messages for room:', topic); // Debugging log
+ // Clear the message area
+ clearMessages();
+
+ // Fetch and render messages for the selected room
+ const messages = getMessagesForRoom(topic);
+ messages.forEach(message => {
+ onMessageAdded(message.from, message.message, message.avatar, topic);
+ });
+}
+
+function getMessagesForRoom(topic) {
+ return messagesStore[topic] || [];
+}
+
+function addMessageToStore(topic, messageObj) {
+ if (!messagesStore[topic]) {
+ messagesStore[topic] = [];
+ }
+ messagesStore[topic].push(messageObj);
+}
+
+// Call this function when loading the rooms initially
+renderRoomList();
+
+initialize();
diff --git a/chatBot/includes/Client.js b/chatBot/includes/Client.js
index 78d364f..f249b23 100644
--- a/chatBot/includes/Client.js
+++ b/chatBot/includes/Client.js
@@ -1,5 +1,5 @@
import Hyperswarm from 'hyperswarm';
-import EventEmitter from 'node:events'
+import EventEmitter from 'node:events';
import b4a from "b4a";
class Client extends EventEmitter {
@@ -8,15 +8,21 @@ class Client extends EventEmitter {
if(!botName) return console.error("Bot Name is not defined!");
this.botName = botName;
this.swarm = new Hyperswarm();
+ this.joinedRooms = new Set(); // Track the rooms the bot has joined
+ this.currentTopic = null; // Track the current topic
this.setupSwarm();
}
setupSwarm() {
this.swarm.on('connection', (peer) => {
peer.on('data', message => {
- if(message.type === "message") this.emit('onMessage', peer, JSON.parse(message.toString()));
- if(message.type === "icon") this.emit('onIcon', peer, JSON.parse(message.toString()));
- if(message.type === "file") this.emit('onFile', peer, JSON.parse(message.toString()));
+ const messageObj = JSON.parse(message.toString());
+ if (this.joinedRooms.has(messageObj.topic)) { // Process message only if it is from a joined room
+ this.currentTopic = messageObj.topic; // Set the current topic from the incoming message
+ if (messageObj.type === "message") this.emit('onMessage', peer, messageObj);
+ if (messageObj.type === "icon") this.emit('onIcon', peer, messageObj);
+ if (messageObj.type === "file") this.emit('onFile', peer, messageObj);
+ }
});
peer.on('error', e => {
@@ -27,20 +33,13 @@ class Client extends EventEmitter {
this.swarm.on('update', () => {
console.log(`Connections count: ${this.swarm.connections.size} / Peers count: ${this.swarm.peers.size}`);
-
- this.swarm.peers.forEach((peerInfo, peerId) => {
- // Please do not try to understand what is going on here. I have no idea anyway. But it surprisingly works
-
- const peer = [peerId];
- const peerTopics = [peerInfo.topics]
- .filter(topics => topics)
- .map(topics => topics.map(topic => b4a.toString(topic, 'hex')));
- });
});
}
joinChatRoom(chatRoomID) {
- this.discovery = this.swarm.join(Buffer.from(chatRoomID, 'hex'), {client: true, server: true});
+ this.joinedRooms.add(chatRoomID); // Add the room to the list of joined rooms
+ this.currentTopic = chatRoomID; // Store the current topic
+ this.discovery = this.swarm.join(Buffer.from(chatRoomID, 'hex'), { client: true, server: true });
this.discovery.flushed().then(() => {
console.log(`Bot ${this.botName} joined the chat room.`);
this.emit('onBotJoinRoom');
@@ -49,17 +48,31 @@ class Client extends EventEmitter {
sendMessage(roomPeers, message) {
console.log('Bot name:', this.botName);
- const timestamp = Date.now(); // Generate timestamp
- const peers = [...this.swarm.connections].filter(peer => roomPeers.includes(peer.remotePublicKey.toString('hex'))); // We remove all the peers that arent included in a room
- const data = JSON.stringify({name: this.botName, message, timestamp}); // Include timestamp
+ const timestamp = Date.now();
+ const messageObj = {
+ type: 'message',
+ name: this.botName,
+ message,
+ timestamp,
+ topic: this.currentTopic // Include the current topic
+ };
+ const data = JSON.stringify(messageObj);
+ const peers = [...this.swarm.connections].filter(peer => roomPeers.includes(peer.remotePublicKey.toString('hex')));
for (const peer of peers) peer.write(data);
}
sendMessageToAll(message) {
console.log('Bot name:', this.botName);
- const timestamp = Date.now(); // Generate timestamp
- const peers = [...this.swarm.connections]
- const data = JSON.stringify({name: this.botName, message, timestamp}); // Include timestamp
+ const timestamp = Date.now();
+ const messageObj = {
+ type: 'message',
+ name: this.botName,
+ message,
+ timestamp,
+ topic: this.currentTopic // Include the current topic
+ };
+ const data = JSON.stringify(messageObj);
+ const peers = [...this.swarm.connections];
for (const peer of peers) peer.write(data);
}
diff --git a/index.html b/index.html
index ffe7718..0f31c1b 100644
--- a/index.html
+++ b/index.html
@@ -7,11 +7,13 @@
+
+
- LinkUp
+ LinkUp | Peers: 0