Merge branch 'main' of git.ssh.surf:snxraven/LinkUp-P2P-Chat

This commit is contained in:
Raven Scott 2024-06-13 20:05:21 -04:00
commit 0dbd441cd5

135
app.js
View File

@ -14,6 +14,7 @@ const drive = new Hyperdrive(store);
await drive.ready(); await drive.ready();
let swarm; let swarm;
let peerCount = 0;
let activeRooms = []; let activeRooms = [];
const eventEmitter = new EventEmitter(); const eventEmitter = new EventEmitter();
@ -31,12 +32,6 @@ let config = {
// Store messages for each room // Store messages for each room
let messagesStore = {}; let messagesStore = {};
// Store peer counts for each room
let peerCounts = {};
// Map to store discovery instances and their associated topics
const discoveryTopicsMap = new Map();
// Function to get a random port between 49152 and 65535 // Function to get a random port between 49152 and 65535
function getRandomPort() { function getRandomPort() {
return Math.floor(Math.random() * (65535 - 49152 + 1)) + 49152; return Math.floor(Math.random() * (65535 - 49152 + 1)) + 49152;
@ -130,7 +125,6 @@ async function initialize() {
if (messageObj.type === 'icon') { if (messageObj.type === 'icon') {
const username = messageObj.username; const username = messageObj.username;
const topic = messageObj.topic;
if (messageObj.avatar) { if (messageObj.avatar) {
const avatarBuffer = b4a.from(messageObj.avatar, 'base64'); const avatarBuffer = b4a.from(messageObj.avatar, 'base64');
await drive.put(`/icons/${username}.png`, avatarBuffer); await drive.put(`/icons/${username}.png`, avatarBuffer);
@ -138,7 +132,6 @@ async function initialize() {
} else { } else {
console.error('Received icon message with missing avatar data:', messageObj); console.error('Received icon message with missing avatar data:', messageObj);
} }
// updatePeerCount(topic);
} else if (messageObj.type === 'file') { } else if (messageObj.type === 'file') {
if (messageObj.file && messageObj.fileName) { if (messageObj.file && messageObj.fileName) {
const fileBuffer = b4a.from(messageObj.file, 'base64'); const fileBuffer = b4a.from(messageObj.file, 'base64');
@ -162,61 +155,31 @@ async function initialize() {
}); });
swarm.on('connection', async (connection, info) => { swarm.on('connection', async (connection, info) => {
try { peerCount++;
connection.on('data', (data) => { updatePeerCount();
const messageObj = JSON.parse(data.toString()); console.log('Peer connected, current peer count:', peerCount);
if (messageObj.type === 'icon' && messageObj.topic) {
connection.topic = messageObj.topic; // Send the current user's icon to the new peer
if (!peerCounts[messageObj.topic]) { const iconBuffer = await drive.get(`/icons/${config.userName}.png`);
peerCounts[messageObj.topic] = 0; if (iconBuffer) {
} const iconMessage = JSON.stringify({
peerCounts[messageObj.topic]++; type: 'icon',
updateHeaderPeerCount(messageObj.topic); username: config.userName,
} avatar: b4a.toString(iconBuffer, 'base64'),
eventEmitter.emit('onMessage', messageObj);
}); });
connection.write(iconMessage);
connection.on('close', () => {
const topic = connection.topic;
if (topic && peerCounts[topic]) {
peerCounts[topic]--;
updateHeaderPeerCount(topic);
console.log('Peer disconnected, current peer count:', peerCounts[topic]);
}
});
// Sending current user's topic to the new peer
const currentTopic = document.querySelector('#chat-room-topic').innerText;
connection.topic = currentTopic;
if (!peerCounts[currentTopic]) {
peerCounts[currentTopic] = 0;
}
peerCounts[currentTopic]++;
updateHeaderPeerCount(currentTopic);
console.log('Peer connected, current peer count:', peerCounts[currentTopic]);
// Send the current user's icon to the new peer
const iconBuffer = await drive.get(`/icons/${config.userName}.png`);
if (iconBuffer) {
const iconMessage = JSON.stringify({
type: 'icon',
username: config.userName,
avatar: b4a.toString(iconBuffer, 'base64'),
topic: currentTopic
});
connection.write(iconMessage);
} else {
const iconMessage = JSON.stringify({
type: 'icon',
username: config.userName,
topic: currentTopic
});
connection.write(iconMessage);
}
} catch (error) {
console.error('Error handling connection:', error);
} }
connection.on('data', (data) => {
const messageObj = JSON.parse(data.toString());
eventEmitter.emit('onMessage', messageObj);
});
connection.on('close', () => {
peerCount--;
updatePeerCount();
console.log('Peer disconnected, current peer count:', peerCount);
});
}); });
swarm.on('error', (err) => { swarm.on('error', (err) => {
@ -367,10 +330,6 @@ async function joinSwarm(topicBuffer) {
await discovery.flushed(); await discovery.flushed();
activeRooms.push({ topic, discovery }); activeRooms.push({ topic, discovery });
peerCounts[topic] = 0; // Initialize peer count for the new room
// Store the topic in the map
discoveryTopicsMap.set(discovery, topic);
console.log('Joined room:', topic); // Debugging log console.log('Joined room:', topic); // Debugging log
@ -384,13 +343,9 @@ async function joinSwarm(topicBuffer) {
function addRoomToList(topic) { function addRoomToList(topic) {
const roomList = document.querySelector('#room-list'); const roomList = document.querySelector('#room-list');
const roomItem = document.createElement('li'); const roomItem = document.createElement('li');
roomItem.textContent = truncateHash(topic);
roomItem.dataset.topic = topic; roomItem.dataset.topic = topic;
const roomName = document.createElement('span');
roomName.textContent = truncateHash(topic);
roomItem.appendChild(roomName);
roomItem.addEventListener('dblclick', () => enterEditMode(roomItem)); roomItem.addEventListener('dblclick', () => enterEditMode(roomItem));
roomItem.addEventListener('click', () => switchRoom(topic)); roomItem.addEventListener('click', () => switchRoom(topic));
roomList.appendChild(roomItem); roomList.appendChild(roomItem);
@ -478,9 +433,6 @@ function switchRoom(topic) {
// Show chat UI elements // Show chat UI elements
document.querySelector('#chat').classList.remove('hidden'); document.querySelector('#chat').classList.remove('hidden');
document.querySelector('#setup').classList.add('hidden'); document.querySelector('#setup').classList.add('hidden');
// Update the peer count in the header
updateHeaderPeerCount(topic);
} }
function leaveRoom(topic) { function leaveRoom(topic) {
@ -489,7 +441,6 @@ function leaveRoom(topic) {
const room = activeRooms[roomIndex]; const room = activeRooms[roomIndex];
room.discovery.destroy(); room.discovery.destroy();
activeRooms.splice(roomIndex, 1); activeRooms.splice(roomIndex, 1);
discoveryTopicsMap.delete(room.discovery);
} }
const roomItem = document.querySelector(`li[data-topic="${topic}"]`); const roomItem = document.querySelector(`li[data-topic="${topic}"]`);
@ -617,11 +568,10 @@ function addFileMessage(from, fileName, fileUrl, fileType, avatar, topic) {
} }
} }
function updateHeaderPeerCount(topic) { function updatePeerCount() {
const peerCountElement = document.querySelector('#peers-count'); const peerCountElement = document.querySelector('#peers-count');
if (peerCountElement) { if (peerCountElement) {
const peerCount = peerCounts[topic] || 0; peerCountElement.textContent = peerCount; // Display the actual peer count
peerCountElement.textContent = peerCount;
} }
} }
@ -632,13 +582,12 @@ function scrollToBottom() {
function onMessageAdded(from, message, avatar, topic) { function onMessageAdded(from, message, avatar, topic) {
console.log('Adding message:', { from, message, avatar, topic }); // Debugging log console.log('Adding message:', { from, message, avatar, topic }); // Debugging log
const messageObj = { const messageObj = {
from, from,
message, message,
avatar avatar
}; };
// Add the message to the store // Add the message to the store
addMessageToStore(topic, messageObj); addMessageToStore(topic, messageObj);
@ -663,24 +612,19 @@ function onMessageAdded(from, message, avatar, topic) {
const $text = document.createElement('div'); const $text = document.createElement('div');
$text.classList.add('message-text'); $text.classList.add('message-text');
if (typeof message === 'string') { const md = window.markdownit({
const md = window.markdownit({ highlight: function (str, lang) {
highlight: function (str, lang) { if (lang && hljs.getLanguage(lang)) {
if (lang && hljs.getLanguage(lang)) { try {
try { return hljs.highlight(str, { language: lang }).value;
return hljs.highlight(str, { language: lang }).value; } catch (__) {}
} catch (__) {}
}
return ''; // use external default escaping
} }
}); return ''; // use external default escaping
}
});
const markdownContent = md.render(message); const markdownContent = md.render(message);
$text.innerHTML = markdownContent; $text.innerHTML = markdownContent;
} else {
console.error('Message content is not a string:', message);
$text.textContent = 'Invalid message content.';
}
$content.appendChild($header); $content.appendChild($header);
$content.appendChild($text); $content.appendChild($text);
@ -800,6 +744,7 @@ function renderMessagesForRoom(topic) {
onMessageAdded(message.from, message.message, message.avatar, topic); onMessageAdded(message.from, message.message, message.avatar, topic);
}); });
} }
function getMessagesForRoom(topic) { function getMessagesForRoom(topic) {
return messagesStore[topic] || []; return messagesStore[topic] || [];
} }