This commit is contained in:
Raven Scott 2024-06-03 20:01:09 -04:00
parent 50026db476
commit 2fbc3f3bf0
2 changed files with 71 additions and 40 deletions

109
app.js
View File

@ -3,21 +3,20 @@ import crypto from 'hypercore-crypto';
import b4a from 'b4a'; import b4a from 'b4a';
import ServeDrive from 'serve-drive'; import ServeDrive from 'serve-drive';
import Localdrive from 'localdrive'; import Localdrive from 'localdrive';
import fs from 'fs';
const drive = new Localdrive('./storage'); const sharedDrive = new Localdrive('./shared-storage');
let swarm; let swarm;
let userName = 'Anonymous'; let userName = 'Anonymous';
let userAvatar = ''; let userAvatar = '';
let registeredUsers = JSON.parse(localStorage.getItem('registeredUsers')) || {};
let peerCount = 0; let peerCount = 0;
async function initialize() { async function initialize() {
swarm = new Hyperswarm(); swarm = new Hyperswarm();
await drive.ready(); await sharedDrive.ready();
const servePort = 1337; const servePort = 1337;
const serve = new ServeDrive({ port: servePort, get: ({ key, filename, version }) => drive }); const serve = new ServeDrive({ port: servePort, get: ({ key, filename, version }) => sharedDrive });
await serve.ready(); await serve.ready();
console.log('Listening on http://localhost:' + serve.address().port); console.log('Listening on http://localhost:' + serve.address().port);
@ -45,6 +44,38 @@ async function initialize() {
messageForm.addEventListener('submit', sendMessage); messageForm.addEventListener('submit', sendMessage);
} }
swarm.on('connection', (connection, info) => {
peerCount++;
updatePeerCount();
connection.on('data', async (data) => {
const messageObj = JSON.parse(data.toString());
if (messageObj.type === 'avatarRequest') {
const avatarBuffer = await getAvatar(messageObj.username);
if (avatarBuffer) {
connection.write(avatarBuffer);
}
} else if (messageObj.type === 'fileUpdate') {
await processFileUpdate(messageObj);
} else {
onMessageAdded(messageObj.name, messageObj.message, messageObj.avatar);
}
});
connection.on('close', () => {
peerCount--;
updatePeerCount();
});
});
swarm.on('error', (err) => {
console.error('Swarm error:', err);
});
swarm.on('close', () => {
console.log('Swarm closed.');
});
const savedUser = localStorage.getItem('currentUser'); const savedUser = localStorage.getItem('currentUser');
if (savedUser) { if (savedUser) {
const user = JSON.parse(savedUser); const user = JSON.parse(savedUser);
@ -61,33 +92,8 @@ async function initialize() {
} }
} }
swarm.on('connection', (connection, info) => { const randomTopic = crypto.randomBytes(32);
peerCount++; document.querySelector('#chat-room-topic').innerText = b4a.toString(randomTopic, 'hex');
updatePeerCount();
connection.on('data', async (data) => {
const messageObj = JSON.parse(data.toString());
if (messageObj.type === 'icon') {
// Save icon to local directory
const username = messageObj.username;
const avatarBuffer = Buffer.from(messageObj.avatar, 'base64');
await drive.put(`/icons/${username}.png`, avatarBuffer);
} else {
onMessageAdded(messageObj.name, messageObj.message, messageObj.avatar);
}
});
connection.on('close', () => {
peerCount--;
updatePeerCount();
});
});
swarm.on('error', (err) => {
console.error('Swarm error:', err);
});
swarm.on('close', () => {
console.log('Swarm closed.');
});
} }
function updatePeerCount() { function updatePeerCount() {
@ -97,6 +103,17 @@ function updatePeerCount() {
} }
} }
async function getAvatar(username) {
try {
const avatarPath = `./shared-storage/icons/${username}.png`;
const avatarBuffer = await sharedDrive.get(avatarPath);
return avatarBuffer;
} catch (error) {
console.error('Error getting avatar:', error);
return null;
}
}
async function registerUser(e) { async function registerUser(e) {
e.preventDefault(); e.preventDefault();
@ -125,9 +142,8 @@ async function registerUser(e) {
const reader = new FileReader(); const reader = new FileReader();
reader.onload = async () => { reader.onload = async () => {
const fileBuffer = Buffer.from(reader.result); const fileBuffer = Buffer.from(reader.result);
await drive.put(`/icons/${regUsername}.png`, fileBuffer); await sharedDrive.put(`/icons/${regUsername}-${file.name}`, fileBuffer);
userAvatar = `http://localhost:1337/icons/${regUsername}.png`; userAvatar = `http://localhost:1337/icons/${regUsername}-${file.name}`;
// Save avatar URL to localStorage
localStorage.setItem('avatarURL', userAvatar); localStorage.setItem('avatarURL', userAvatar);
}; };
reader.readAsArrayBuffer(file); reader.readAsArrayBuffer(file);
@ -157,7 +173,6 @@ async function continueRegistration(regUsername) {
} }
async function createChatRoom() { async function createChatRoom() {
// Generate a new random topic (32 byte string)
const topicBuffer = crypto.randomBytes(32); const topicBuffer = crypto.randomBytes(32);
joinSwarm(topicBuffer); joinSwarm(topicBuffer);
} }
@ -173,7 +188,6 @@ async function joinSwarm(topicBuffer) {
document.querySelector('#setup').classList.add('hidden'); document.querySelector('#setup').classList.add('hidden');
document.querySelector('#loading').classList.remove('hidden'); document.querySelector('#loading').classList.remove('hidden');
// Join the swarm with the topic. Setting both client/server to true means that this app can act as both.
const discovery = swarm.join(topicBuffer, { client: true, server: true }); const discovery = swarm.join(topicBuffer, { client: true, server: true });
await discovery.flushed(); await discovery.flushed();
@ -190,7 +204,8 @@ function sendMessage(e) {
onMessageAdded(userName, message, userAvatar); onMessageAdded(userName, message, userAvatar);
// Send the message to all peers (that you are connected to) onMessageAdded(userName, message, userAvatar);
const messageObj = JSON.stringify({ const messageObj = JSON.stringify({
type: 'message', type: 'message',
name: userName, name: userName,
@ -205,7 +220,23 @@ function sendMessage(e) {
} }
} }
// appends element to #messages element with content set to sender and message async function processFileUpdate(messageObj) {
try {
const filePath = messageObj.filePath;
const fileBuffer = await downloadFileFromPeer(messageObj.peerId, filePath);
await sharedDrive.put(filePath, fileBuffer);
console.log(`File ${filePath} updated successfully.`);
} catch (error) {
console.error('Error processing file update:', error);
}
}
async function downloadFileFromPeer(peerId, filePath) {
// Implement logic to download file from peer using Hyperswarm or other P2P mechanisms
}
function onMessageAdded(from, message, avatar) { function onMessageAdded(from, message, avatar) {
const $div = document.createElement('div'); const $div = document.createElement('div');
$div.classList.add('message'); $div.classList.add('message');

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB