Compare commits

..

No commits in common. "cd5edfc9aa2013506ebb975642e5ab0f9e81392e" and "dae080a833f3e48f6a8f22cde73ea5be1b9f467b" have entirely different histories.

4 changed files with 71 additions and 41 deletions

1
.gitignore vendored
View File

@ -1,4 +1,3 @@
node_modules
package-lock.json
shared-storage
storage

111
app.js
View File

@ -3,21 +3,20 @@ import crypto from 'hypercore-crypto';
import b4a from 'b4a';
import ServeDrive from 'serve-drive';
import Localdrive from 'localdrive';
import fs from 'fs';
const drive = new Localdrive('./storage');
const sharedDrive = new Localdrive('./shared-storage');
let swarm;
let userName = 'Anonymous';
let userAvatar = '';
let registeredUsers = JSON.parse(localStorage.getItem('registeredUsers')) || {};
let peerCount = 0;
async function initialize() {
swarm = new Hyperswarm();
await drive.ready();
await sharedDrive.ready();
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();
console.log('Listening on http://localhost:' + serve.address().port);
@ -45,6 +44,38 @@ async function initialize() {
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');
if (savedUser) {
const user = JSON.parse(savedUser);
@ -61,33 +92,8 @@ async function initialize() {
}
}
swarm.on('connection', (connection, info) => {
peerCount++;
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.');
});
const randomTopic = crypto.randomBytes(32);
document.querySelector('#chat-room-topic').innerText = b4a.toString(randomTopic, 'hex');
}
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) {
e.preventDefault();
@ -125,9 +142,8 @@ async function registerUser(e) {
const reader = new FileReader();
reader.onload = async () => {
const fileBuffer = Buffer.from(reader.result);
await drive.put(`/icons/${regUsername}.png`, fileBuffer);
userAvatar = `http://localhost:1337/icons/${regUsername}.png`;
// Save avatar URL to localStorage
await sharedDrive.put(`/icons/${regUsername}-${file.name}`, fileBuffer);
userAvatar = `http://localhost:1337/icons/${regUsername}-${file.name}`;
localStorage.setItem('avatarURL', userAvatar);
};
reader.readAsArrayBuffer(file);
@ -157,7 +173,6 @@ async function continueRegistration(regUsername) {
}
async function createChatRoom() {
// Generate a new random topic (32 byte string)
const topicBuffer = crypto.randomBytes(32);
joinSwarm(topicBuffer);
}
@ -173,7 +188,6 @@ async function joinSwarm(topicBuffer) {
document.querySelector('#setup').classList.add('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 });
await discovery.flushed();
@ -190,7 +204,8 @@ function sendMessage(e) {
onMessageAdded(userName, message, userAvatar);
// Send the message to all peers (that you are connected to)
onMessageAdded(userName, message, userAvatar);
const messageObj = JSON.stringify({
type: 'message',
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) {
const $div = document.createElement('div');
$div.classList.add('message');
@ -231,4 +262,4 @@ function onMessageAdded(from, message, avatar) {
document.querySelector('#messages').appendChild($div);
}
initialize();
initialize();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 554 KiB