From f408548ab02b456afea67ec55a4006a542eacdd4 Mon Sep 17 00:00:00 2001 From: Baipyrus Date: Mon, 6 Feb 2023 09:25:14 +0100 Subject: [PATCH] group chat bugfixes --- index.js | 180 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 133 insertions(+), 47 deletions(-) diff --git a/index.js b/index.js index 9c47f20..7edd168 100644 --- a/index.js +++ b/index.js @@ -38,6 +38,8 @@ function generatePartialID() { function userInactivity(name, id) { for (let i = 0; i < users.length; i++) if (users[i].name === name && users[i].id === id && new Date() - users[i].seen > 86400000) { + // User with ID 'name#id' was inactive for longer than a day. + if (consoleLogging) console.log(`Deleting user with ID '${name}#${id}' because of inactivity.`); @@ -51,12 +53,16 @@ function userInactivity(name, id) { const users = [], chats = []; // Incoming user connection app.post('/connect', (req, res) => { - // Generate id, save user + // Retrieve username const { name } = req.body; + + // Generate id in unique pattern 'name#id' let id = generatePartialID(); const name_id = users.map(u => `${u.name}#${u.id}`); while (!isStringUnique(name_id, `${name}#${id}`)) id = generatePartialID(); + + // Save user data users.push({ deletion: setInterval( ()=>userInactivity(name, id), @@ -66,24 +72,34 @@ app.post('/connect', (req, res) => { name, id }); - // Log connection, send back id + + // Log connection if (consoleLogging) console.log(`User with ID '${name}#${id}' connected.`); + + // Respond with id res.status(200).json({ id }); }); // User has disconnected app.post('/disconnect', (req, res) => { + // Retrieve user data const { name, id } = req.body; + + // Search for user in data for (let i = 0; i < users.length; i++) + // If user was found, delete all of their data if (users[i].name === name && users[i].id === id) { - // If id is valid, delete all user data + // Log disconnect if (consoleLogging) console.log(`User with ID '${name}#${id}' disconnected.`); + + // Delete user users.splice(i, 1); break; } - // Confirm disconnect + + // Respond with id as confirmation res.status(200).send(); }); @@ -94,33 +110,39 @@ app.get('/ping', (req, res) => { // User wants to change name app.post('/nickname', (req, res) => { + // Retrieve user data and old name const { oldName, name, id } = req.body; - // Check if name is taken, if not, append id until unique + // Check if unique pattern 'name#id' is valid, generate new one const name_id = users.map(u => `${u.name}#${u.id}`); let currentID = id; while (!isStringUnique(name_id, `${name}#${currentID}`)) currentID = generatePartialID(); - // Change username + // Find specified user for (const u of users) if (u.name === oldName && u.id === id) { + // Log renaming if (consoleLogging) console.log(`(Re-)named user with ID '${oldName}#${id}'.`); + + // Save new name u.name = name; u.id = currentID; u.seen = new Date(); break; } - // Confirm renaming + // Respond with confirmation res.status(200).json({ id: currentID }); }); // User is pulling messages app.post('/getChat', (req, res) => { + // Retrieve user data and where to retrieve data from const { name, from, id } = req.body; + // Save user activity for (const u of users) if (u.name === name && u.id === id) { u.seen = new Date(); @@ -128,17 +150,31 @@ app.post('/getChat', (req, res) => { } // Go through users' chats, retrieve messages, save by username - let chats = {}; + let received = {}; const fullName = `${name}#${id}`; for (const u of users) if (fullName in u.chats) { + // User might have new message from another user const len = u.chats[fullName].length; if (len > 0 && from.includes(`${u.name}#${u.id}`)) - chats[`${u.name}#${u.id}`] = u.chats[fullName].splice(0, len); + received[`${u.name}#${u.id}`] = u.chats[fullName].splice(0, len); + } + + // Go through chats (Array of Objects) + for (const c of chats) + if (from.includes(c.name)) { + const cusers = c.users[fullName]; + // Look through user data (Object with usernames as keys) + for (const u in cusers) { + // Retrieve messages from data (Array) + const len = cusers[u].length; + if (len > 0) received[u] = cusers[u].splice(0, len); + } } // No chat messages were found - if (Object.keys(chats).length === 0) { + if (Object.keys(received).length === 0) { + // Respond with no content res.status(204).send(); return; } @@ -147,27 +183,31 @@ app.post('/getChat', (req, res) => { if (consoleLogging) console.log(`Delivered messages to user with ID '${fullName}' from '${from}'.`); - // Send back data - res.status(200).json(chats); + // Respond with data + res.status(200).json(received); }); // User sent new message app.post('/message', (req, res) => { + // Retrieve user data, their message and where to deliver it to const { name, id, to, message } = req.body; - // Search for senders' name, save message + // Search for sender for (const u of users) if (u.name === name && u.id === id) { + // Go through every recipient for (const recipient of to) { + // Save message for recipient if (!u.chats[recipient]) u.chats[recipient] = []; u.chats[recipient].push(message); } + // Save user activity u.seen = new Date(); break; } - // Log message for debugging + // Log users' message if (consoleLogging) console.log(`User with ID '${name}#${id}' sent message '${message}' to '${to}'.`); @@ -177,9 +217,11 @@ app.post('/message', (req, res) => { // User requesting all names app.get('/getNames', (req, res) => { + // Log request if (consoleLogging) console.log('Some user requested all usernames + IDs.'); + // Respond with unique patterns 'name#id' res.status(200).json(users.map(u => { return { name: u.name, @@ -190,82 +232,126 @@ app.get('/getNames', (req, res) => { // User sends activity notification app.post('/activity', (req, res) => { + // Retrieve user data const { name, id } = req.body; + // Log activity if (consoleLogging) console.log(`User with ID '${name}#${id}' is online.`); + // Save activity for (const u of users) if (u.name === name && u.id === id) { u.seen = new Date(); break; } + // Confirm process res.status(200).send(); }); +// User asks if their data exists app.post('/login', (req, res) => { + // Retrieve user data const { name, id } = req.body; + // Log login if (consoleLogging) console.log(`Some user requested existence of '${name}#${id}'.`); + // Go through users, success if user exists let success = false; for (const u of users) if (u.name === name && u.id === id) { success = true; + // Save activity u.seen = new Date(); break; } + // Respond with status res.status(200).json({success}); }); +// User wants to join chat app.post('/chatInit', (req, res) => { + // Retrieve user data and chat name const { name, id, chat } = req.body; - const fullName = `${name}#${id}`; - - let chatExists = false; - for (const c of chats) - if (c.name === chat) { - chatExists = true; - if (!c.users[fullName]) - c.users[fullName] = []; - break; - } - - if (!chatExists) - chats.push({ - users: {}, - name: chat - }); - - // Log message for debugging - if (consoleLogging) - console.log(`User with ID '${name}#${id}' joined chat '${chat}'.`); - - res.status(200).send(); -}); - -app.post('/sendGroup', (req, res) => { - const { name, id, message, chat } = req.body; - - for (const c of chats) - if (c.name === chat) { - c.users[`${name}#${id}`].push(message); - break; - } + // Save user activity for (const u of users) if (u.name === name && u.id === id) { u.seen = new Date(); break; } - // Log message for debugging + // Check if chats already exist + const fullName = `${name}#${id}`; + let existance = chat.map(e => [e, false]); + // Go through chats + for (const c of chats) + // Go through provided names + for (const n of existance) { + // If name is this chat + if (n[0] === c.name) { + // Chat exists, add user to it + n[1] = true; + if (!c.users[fullName]) + c.users[fullName] = {}; + break; + } + } + + // Go through provided names + for (const n of existance) { + // Chat didn't exist + if (!n[1]) + // Create it and save user in it + chats.push({ + users: {[fullName]: {}}, + name: n[0] + }); + } + + // Log chat initialization + if (consoleLogging) + console.log(`User with ID '${name}#${id}' joined chat '${chat}'.`); + + // Confirm process + res.status(200).send(); +}); + +// User sends a message in chat +app.post('/sendGroup', (req, res) => { + // Retrieve user data and chat name and message + const { name, id, message, chat } = req.body; + + // Save user activity + for (const u of users) + if (u.name === name && u.id === id) { + u.seen = new Date(); + break; + } + + // Find provided chat + const fullName = `${name}#${id}`; + for (const c of chats) + if (chat.includes(c.name)) { + // Go through users in chat + for (const u in c.users) + if (u !== fullName) { + // Save message for recipient + if (!c.users[u][fullName]) + c.users[u][fullName] = []; + c.users[u][fullName].push(message); + } + } + + // Log users' message if (consoleLogging) console.log(`User with ID '${name}#${id}' sent message '${message}' in '${chat}'.`); + // Confirm process res.status(200).send(); });