forked from snxraven/LinkUp-P2P-Chat
Up to date fork #1
135
app.js
135
app.js
@ -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] || [];
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user