Compare commits
12 Commits
6cfbb36d35
...
guilds
Author | SHA1 | Date | |
---|---|---|---|
7eddd45f79 | |||
70bc69ddea | |||
aa70e42fdc | |||
c530a8d69c | |||
084cb02a11 | |||
a0c7eb1561 | |||
43e9890235 | |||
ed4625275d | |||
55875f468c | |||
e0ad9c7067 | |||
d423031cfb | |||
181d011b8d |
108
app.js
108
app.js
@ -141,6 +141,7 @@ async function initialize() {
|
|||||||
loadConfigFromFile();
|
loadConfigFromFile();
|
||||||
renderGuildList();
|
renderGuildList();
|
||||||
await connectToAllRooms();
|
await connectToAllRooms();
|
||||||
|
await joinAllGuilds(); // Ensure the app joins all guilds on startup
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!configExists) {
|
if (!configExists) {
|
||||||
@ -179,11 +180,22 @@ async function initialize() {
|
|||||||
console.log('Event switchRoom with roomTopic:', roomTopic);
|
console.log('Event switchRoom with roomTopic:', roomTopic);
|
||||||
switchRoom(guildTopic, roomTopic);
|
switchRoom(guildTopic, roomTopic);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.addEventListener('joinGuildRequest', (event) => {
|
||||||
|
const { guildTopic } = event.detail;
|
||||||
|
joinGuildRequest(guildTopic);
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error during initialization:', error);
|
console.error('Error during initialization:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function joinAllGuilds() {
|
||||||
|
for (const guildTopic in config.guilds) {
|
||||||
|
await joinGuildRequest(guildTopic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function setupEventListeners() {
|
function setupEventListeners() {
|
||||||
const registerForm = document.querySelector('#register-form');
|
const registerForm = document.querySelector('#register-form');
|
||||||
const selectAvatarButton = document.querySelector('#select-avatar');
|
const selectAvatarButton = document.querySelector('#select-avatar');
|
||||||
@ -195,6 +207,7 @@ function setupEventListeners() {
|
|||||||
const attachFileButton = document.getElementById('attach-file');
|
const attachFileButton = document.getElementById('attach-file');
|
||||||
const fileInput = document.getElementById('file-input');
|
const fileInput = document.getElementById('file-input');
|
||||||
const talkButton = document.getElementById('talk-btn');
|
const talkButton = document.getElementById('talk-btn');
|
||||||
|
const joinGuildBtn = document.getElementById('join-guild');
|
||||||
|
|
||||||
if (registerForm) {
|
if (registerForm) {
|
||||||
registerForm.addEventListener('submit', registerUser);
|
registerForm.addEventListener('submit', registerUser);
|
||||||
@ -234,6 +247,14 @@ function setupEventListeners() {
|
|||||||
if (talkButton) {
|
if (talkButton) {
|
||||||
setupTalkButton();
|
setupTalkButton();
|
||||||
}
|
}
|
||||||
|
if (joinGuildBtn) {
|
||||||
|
joinGuildBtn.addEventListener('click', () => {
|
||||||
|
const guildTopic = document.getElementById('join-guild-topic').value.trim();
|
||||||
|
if (guildTopic) {
|
||||||
|
joinGuildRequest(guildTopic);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Add event listeners only for room items
|
// Add event listeners only for room items
|
||||||
document.querySelectorAll('.room-item').forEach(item => {
|
document.querySelectorAll('.room-item').forEach(item => {
|
||||||
@ -249,7 +270,7 @@ function setupEventListeners() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleIncomingMessage(messageObj) {
|
function handleIncomingMessage(messageObj, connection) {
|
||||||
console.log('Received message:', messageObj); // Debugging log
|
console.log('Received message:', messageObj); // Debugging log
|
||||||
|
|
||||||
if (messageObj.type === 'icon') {
|
if (messageObj.type === 'icon') {
|
||||||
@ -347,7 +368,25 @@ function handleIncomingMessage(messageObj) {
|
|||||||
renderGuildList();
|
renderGuildList();
|
||||||
joinGuild(guildTopic);
|
joinGuild(guildTopic);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (messageObj.type === 'guildRequest') {
|
||||||
|
const guildTopic = messageObj.guildTopic;
|
||||||
|
const guild = config.guilds[guildTopic];
|
||||||
|
if (guild) {
|
||||||
|
const guildResponseMessage = JSON.stringify({
|
||||||
|
type: 'guildResponse',
|
||||||
|
guildData: JSON.stringify({
|
||||||
|
guildTopic,
|
||||||
|
guildAlias: guild.alias,
|
||||||
|
rooms: guild.rooms,
|
||||||
|
owner: guild.owner
|
||||||
|
})
|
||||||
|
});
|
||||||
|
connection.write(guildResponseMessage);
|
||||||
|
}
|
||||||
|
} else if (messageObj.type === 'guildResponse') {
|
||||||
|
const guildData = messageObj.guildData;
|
||||||
|
processGuild(guildData);
|
||||||
|
} else {
|
||||||
console.error('Received unknown message type:', messageObj);
|
console.error('Received unknown message type:', messageObj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -360,7 +399,7 @@ async function handleConnection(connection, info) {
|
|||||||
if (iconBuffer) {
|
if (iconBuffer) {
|
||||||
const iconMessage = JSON.stringify({
|
const iconMessage = JSON.stringify({
|
||||||
type: 'icon',
|
type: 'icon',
|
||||||
username: config.userName,
|
name: config.userName,
|
||||||
avatar: b4a.toString(iconBuffer, 'base64'),
|
avatar: b4a.toString(iconBuffer, 'base64'),
|
||||||
timestamp: Date.now()
|
timestamp: Date.now()
|
||||||
});
|
});
|
||||||
@ -399,7 +438,7 @@ async function handleConnection(connection, info) {
|
|||||||
connection.write(guildJoinMessage);
|
connection.write(guildJoinMessage);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
eventEmitter.emit('onMessage', messageObj);
|
eventEmitter.emit('onMessage', messageObj, connection);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1008,7 +1047,6 @@ function addFileMessage(name, fileName, fileUrl, fileType, avatar, topic) {
|
|||||||
container.scrollTop = container.scrollHeight;
|
container.scrollTop = container.scrollHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addAudioMessage(name, audioUrl, avatar, topic) {
|
function addAudioMessage(name, audioUrl, avatar, topic) {
|
||||||
const container = document.querySelector('#messages');
|
const container = document.querySelector('#messages');
|
||||||
if (!container) {
|
if (!container) {
|
||||||
@ -1037,6 +1075,10 @@ function addAudioMessage(name, audioUrl, avatar, topic) {
|
|||||||
const audioElement = document.createElement('audio');
|
const audioElement = document.createElement('audio');
|
||||||
audioElement.src = audioUrl;
|
audioElement.src = audioUrl;
|
||||||
audioElement.controls = true;
|
audioElement.controls = true;
|
||||||
|
// Autoplay only if the message is from a peer
|
||||||
|
if (name !== config.userName) {
|
||||||
|
audioElement.autoplay = true;
|
||||||
|
}
|
||||||
audioElement.classList.add('message-audio');
|
audioElement.classList.add('message-audio');
|
||||||
|
|
||||||
messageContent.appendChild(senderName);
|
messageContent.appendChild(senderName);
|
||||||
@ -1050,6 +1092,7 @@ function addAudioMessage(name, audioUrl, avatar, topic) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function addMessage(name, message, avatar, topic) {
|
function addMessage(name, message, avatar, topic) {
|
||||||
const container = document.querySelector('#messages');
|
const container = document.querySelector('#messages');
|
||||||
if (!container) {
|
if (!container) {
|
||||||
@ -1077,6 +1120,7 @@ function addMessage(name, message, avatar, topic) {
|
|||||||
|
|
||||||
const messageText = document.createElement('div');
|
const messageText = document.createElement('div');
|
||||||
messageText.classList.add('message-text');
|
messageText.classList.add('message-text');
|
||||||
|
|
||||||
messageText.innerHTML = message;
|
messageText.innerHTML = message;
|
||||||
|
|
||||||
messageContent.appendChild(senderName);
|
messageContent.appendChild(senderName);
|
||||||
@ -1090,6 +1134,19 @@ function addMessage(name, message, avatar, topic) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updateIcon(username, avatarBuffer) {
|
||||||
|
const userIcon = document.querySelector(`img[src*="${username}.png"]`);
|
||||||
|
if (userIcon) {
|
||||||
|
const avatarBlob = new Blob([avatarBuffer], { type: 'image/png' });
|
||||||
|
const avatarUrl = URL.createObjectURL(avatarBlob);
|
||||||
|
userIcon.src = updatePortInUrl(avatarUrl);
|
||||||
|
|
||||||
|
config.userAvatar = avatarUrl;
|
||||||
|
writeConfigToFile("./config.json");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function clearMessages() {
|
function clearMessages() {
|
||||||
const messagesContainer = document.querySelector('#messages');
|
const messagesContainer = document.querySelector('#messages');
|
||||||
while (messagesContainer.firstChild) {
|
while (messagesContainer.firstChild) {
|
||||||
@ -1110,8 +1167,7 @@ async function sendMessage(e) {
|
|||||||
const timestamp = Date.now();
|
const timestamp = Date.now();
|
||||||
|
|
||||||
console.log("Sending message to current topic:", topic); // Add logging
|
console.log("Sending message to current topic:", topic); // Add logging
|
||||||
|
if (message.startsWith('>')) {
|
||||||
if (message.startsWith('~')) {
|
|
||||||
await handleCommand(message, {
|
await handleCommand(message, {
|
||||||
eventEmitter,
|
eventEmitter,
|
||||||
currentTopic: topic, // Pass the current topic as a string
|
currentTopic: topic, // Pass the current topic as a string
|
||||||
@ -1121,7 +1177,8 @@ async function sendMessage(e) {
|
|||||||
leaveRoom,
|
leaveRoom,
|
||||||
createRoom,
|
createRoom,
|
||||||
listFiles,
|
listFiles,
|
||||||
deleteFile
|
deleteFile,
|
||||||
|
servePort
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1133,7 +1190,7 @@ async function sendMessage(e) {
|
|||||||
const messageObj = JSON.stringify({
|
const messageObj = JSON.stringify({
|
||||||
type: 'message',
|
type: 'message',
|
||||||
name: config.userName,
|
name: config.userName,
|
||||||
avatar: config.userAvatar,
|
avatar: updatePortInUrl(config.userAvatar),
|
||||||
topic: topic,
|
topic: topic,
|
||||||
timestamp: timestamp,
|
timestamp: timestamp,
|
||||||
message
|
message
|
||||||
@ -1207,4 +1264,35 @@ function handleFileInput(event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize();
|
async function joinGuildRequest(guildTopic) {
|
||||||
|
const guildTopicBuffer = b4a.from(guildTopic, 'hex');
|
||||||
|
if (!activeRooms.some(room => room.topic === guildTopic)) {
|
||||||
|
try {
|
||||||
|
const swarm = new Hyperswarm();
|
||||||
|
const discovery = swarm.join(guildTopicBuffer, { client: true, server: true });
|
||||||
|
await discovery.flushed();
|
||||||
|
|
||||||
|
swarm.on('connection', (connection, info) => {
|
||||||
|
handleConnection(connection, info);
|
||||||
|
// Request guild information from peers
|
||||||
|
const guildRequestMessage = JSON.stringify({
|
||||||
|
type: 'guildRequest',
|
||||||
|
guildTopic
|
||||||
|
});
|
||||||
|
connection.write(guildRequestMessage);
|
||||||
|
});
|
||||||
|
|
||||||
|
activeRooms.push({ topic: guildTopic, swarm, discovery });
|
||||||
|
|
||||||
|
console.log('Joined guild topic:', guildTopic); // Debugging log
|
||||||
|
|
||||||
|
updatePeerCount();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error joining swarm for guild topic:', guildTopic, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.joinGuildRequest = joinGuildRequest;
|
||||||
|
|
||||||
|
initialize();
|
||||||
|
65
commands.js
65
commands.js
@ -11,7 +11,7 @@ if (fs.existsSync(agentAvatarPath)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default async function handleCommand(command, context) {
|
export default async function handleCommand(command, context) {
|
||||||
const { eventEmitter, currentTopic, clearMessages, addMessage, joinRoom, leaveRoom, createRoom, listFiles } = context;
|
const { eventEmitter, currentTopic, clearMessages, addMessage, joinRoom, leaveRoom, createRoom, listFiles, deleteFile, servePort } = context;
|
||||||
|
|
||||||
console.log("Context received in handleCommand:", context); // Add logging
|
console.log("Context received in handleCommand:", context); // Add logging
|
||||||
|
|
||||||
@ -23,39 +23,82 @@ export default async function handleCommand(command, context) {
|
|||||||
console.log("Current topic:", currentTopic); // Add logging to check the current topic
|
console.log("Current topic:", currentTopic); // Add logging to check the current topic
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case '~clear':
|
case '>clear':
|
||||||
clearMessages(currentTopic);
|
clearMessages(currentTopic);
|
||||||
break;
|
break;
|
||||||
case '~ping':
|
case '>ping':
|
||||||
addMessage('LinkUp', 'pong', agentAvatar, currentTopic);
|
addMessage('LinkUp', 'pong', agentAvatar, currentTopic);
|
||||||
break;
|
break;
|
||||||
case '~help':
|
case '>help':
|
||||||
addMessage('LinkUp', 'Available commands:\n- ~clear\n- ~ping\n- ~help\n- ~join [topic]\n- ~leave\n- ~create [alias]\n- ~list-files', agentAvatar, currentTopic);
|
addMessage('LinkUp', 'Available commands:\n- >clear\n- >ping\n- >help\n- >join [topic]\n- >leave\n- >create [alias]\n- >list-files', agentAvatar, currentTopic);
|
||||||
break;
|
break;
|
||||||
case '~join':
|
case '>join':
|
||||||
if (restArgs) {
|
if (restArgs) {
|
||||||
await joinRoom(currentTopic, restArgs);
|
await joinRoom(currentTopic, restArgs);
|
||||||
} else {
|
} else {
|
||||||
addMessage('LinkUp', 'Usage: ~join [topic]', agentAvatar, currentTopic);
|
addMessage('LinkUp', 'Usage: >join [topic]', agentAvatar, currentTopic);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '~leave':
|
case '>leave':
|
||||||
leaveRoom(currentTopic);
|
leaveRoom(currentTopic);
|
||||||
break;
|
break;
|
||||||
case '~create':
|
case '>create':
|
||||||
if (restArgs) {
|
if (restArgs) {
|
||||||
await createRoom(currentTopic, restArgs);
|
await createRoom(currentTopic, restArgs);
|
||||||
} else {
|
} else {
|
||||||
addMessage('LinkUp', 'Usage: ~create [alias]', agentAvatar, currentTopic);
|
addMessage('LinkUp', 'Usage: >create [alias]', agentAvatar, currentTopic);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '~list-files':
|
case '>list-files':
|
||||||
const files = await listFiles();
|
const files = await listFiles();
|
||||||
const fileList = files.length > 0 ? files.map(file => `- ${file}`).join('\n') : 'No files available';
|
const fileList = files.length > 0 ? files.map(file => `- ${file}`).join('\n') : 'No files available';
|
||||||
addMessage('LinkUp', `Available files:\n${fileList}`, agentAvatar, currentTopic);
|
addMessage('LinkUp', `Available files:\n${fileList}`, agentAvatar, currentTopic);
|
||||||
|
|
||||||
|
// Render the file list with delete buttons
|
||||||
|
renderFileList(files, deleteFile, servePort);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
addMessage('LinkUp', `Unknown command: ${cmd}`, agentAvatar, currentTopic);
|
addMessage('LinkUp', `Unknown command: ${cmd}`, agentAvatar, currentTopic);
|
||||||
console.log('Unknown command:', command);
|
console.log('Unknown command:', command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderFileList(files, deleteFile, servePort) {
|
||||||
|
const container = document.querySelector('#messages');
|
||||||
|
if (!container) {
|
||||||
|
console.error('Element #messages not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileList = document.createElement('ul');
|
||||||
|
|
||||||
|
files.forEach(file => {
|
||||||
|
const listItem = document.createElement('li');
|
||||||
|
const fileButton = document.createElement('button');
|
||||||
|
fileButton.textContent = file.trim();
|
||||||
|
fileButton.onclick = () => downloadFile(file.trim(), servePort);
|
||||||
|
|
||||||
|
const deleteButton = document.createElement('button');
|
||||||
|
deleteButton.textContent = 'Delete';
|
||||||
|
deleteButton.onclick = async () => {
|
||||||
|
await deleteFile(file);
|
||||||
|
listItem.remove();
|
||||||
|
};
|
||||||
|
|
||||||
|
listItem.appendChild(fileButton);
|
||||||
|
listItem.appendChild(deleteButton);
|
||||||
|
fileList.appendChild(listItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
container.appendChild(fileList);
|
||||||
|
}
|
||||||
|
|
||||||
|
function downloadFile(filename, servePort) {
|
||||||
|
const url = `http://localhost:${servePort}/files/${filename}`;
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = url;
|
||||||
|
link.download = filename;
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
}
|
||||||
|
@ -185,7 +185,7 @@
|
|||||||
joinGuildBtn.addEventListener('click', async (event) => {
|
joinGuildBtn.addEventListener('click', async (event) => {
|
||||||
const guildTopic = document.getElementById('join-guild-topic').value.trim();
|
const guildTopic = document.getElementById('join-guild-topic').value.trim();
|
||||||
if (guildTopic) {
|
if (guildTopic) {
|
||||||
await processGuild(guildTopic);
|
await joinGuildRequest(guildTopic);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -254,4 +254,4 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Reference in New Issue
Block a user