diff --git a/frontend/src/chat/chat.css b/frontend/src/chat/chat.css index d02bc50..91901a4 100644 --- a/frontend/src/chat/chat.css +++ b/frontend/src/chat/chat.css @@ -80,20 +80,17 @@ .mainboxDisplay button { @apply - cursor-pointer; + cursor-pointer } p { @apply text-black - - - } -.div-test { +div-test { @apply - italic - + text-red-800 + text-right } \ No newline at end of file diff --git a/frontend/src/pages/chat/chat.ts b/frontend/src/pages/chat/chat.ts index 1e0d53f..9399b0c 100644 --- a/frontend/src/pages/chat/chat.ts +++ b/frontend/src/pages/chat/chat.ts @@ -14,6 +14,28 @@ document.addEventListener('ft:pageChange', () => { }) +function getSocket(): Socket { + if (__socket === undefined) + __socket = io("wss://localhost:8888", { + path: "/api/chat/socket.io/", + secure: false, + transports: ["websocket"], + }); + return __socket; +} + + +async function isLoggedIn() { + return getUser() || null; +} + + + +function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn { + let socket = getSocket(); + + + document.addEventListener("visibilitychange", async () => { const socketId = __socket || undefined; @@ -40,44 +62,6 @@ document.addEventListener("visibilitychange", async () => { -async function getUserName(): Promise { - try { - const res = await client.guestLogin(); - - if (res.kind !== "success") { - console.error("Login failed:", res.msg); - return null; - } - - const user = await updateUser(); - if (!user) return null; - - return user.name; // <-- return the username - } catch (err) { - console.error("getUserName error:", err); - return null; - } -} - -function getSocket(): Socket { - if (__socket === undefined) - __socket = io("wss://localhost:8888", { - path: "/api/chat/socket.io/", - secure: false, - transports: ["websocket"], - }); - return __socket; -} - - -async function isLoggedIn() { - return getUser() || null; -} - - - -function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn { - let socket = getSocket(); // Listen for the 'connect' event socket.on("connect", () => { console.log("I AM Connected to the server:", socket.id); @@ -154,7 +138,7 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn const addMessage = (text: string) => { if (!chatWindow) return; - const messageElement = document.createElement("div"); + const messageElement = document.createElement("div-test"); messageElement.textContent = text; chatWindow.appendChild(messageElement); chatWindow.scrollTop = chatWindow.scrollHeight; @@ -200,14 +184,20 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn bconnected?.addEventListener("click", async () => { const loggedIn = await isLoggedIn(); - + let oldUser = localStorage.getItem("oldName") || undefined; if (loggedIn?.name === undefined) return ; + oldUser = loggedIn.name || "undefined"; const res = await client.guestLogin(); let user = await updateUser(); + localStorage.setItem("oldName", oldUser); + console.log('USER ', user?.name); if (chatWindow) { addMessage('@list - lists all connected users in the chat'); - socket.emit('list'); + socket.emit('list', { + oldUser: oldUser, + user: user?.name + }); } }); socket.on('listObj', (list: string) => { @@ -229,10 +219,22 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn // Whoami button to display user name bwhoami?.addEventListener('click', async () => { try { + const loggedIn = await isLoggedIn(); + let oldUser = localStorage.getItem("oldName") || undefined; + oldUser = loggedIn?.name || "undefined"; + localStorage.setItem("oldName", oldUser); + const res = await client.guestLogin(); switch (res.kind) { case 'success': { let user = await updateUser(); + console.log('USER ', user?.name); + if (chatWindow) { + socket.emit('updateClientName', { + oldUser: oldUser, + user: user?.name + }); + } if (user === null) return showError('Failed to get user: no user ?'); setTitle(`Welcome ${user.guest ? '[GUEST] ' : ''}${user.name}`); diff --git a/src/chat/src/app.ts b/src/chat/src/app.ts index abc7a53..7a92dc5 100644 --- a/src/chat/src/app.ts +++ b/src/chat/src/app.ts @@ -74,6 +74,9 @@ declare module 'fastify' { MsgObjectServer: (data: { message: ClientMessage }) => void; message: (msg: string) => void; testend: (sock_id_client: string) => void; + client_entered: (userName: string, user: string) => void; + list: (oldUser: string, user: string) => void; + updateClientName: (oldUser: string, user: string) => void; }>; } } @@ -84,7 +87,7 @@ async function onReady(fastify: FastifyInstance) { const seen = new Set(); // <- only log/count unique usernames - for (const [socketId, username,] of clientChat) { + for (const [socketId, username] of clientChat) { // Basic sanity checks if (typeof socketId !== 'string' || socketId.length === 0) { clientChat.delete(socketId); @@ -163,10 +166,9 @@ async function onReady(fastify: FastifyInstance) { } }); } - - + fastify.io.on('connection', (socket: Socket) => { - + socket.on('message', (message: string) => { console.info( color.blue, @@ -180,19 +182,19 @@ async function onReady(fastify: FastifyInstance) { color.reset, message, ); - + const obj: ClientMessage = JSON.parse(message) as ClientMessage; clientChat.set(socket.id, { user: obj.user, lastSeen: Date.now() }); console.log( color.green, 'Message from client', color.reset, - `Sender: login name: "${obj.user}" - windowID "${obj.SenderWindowID}" - text message: "${obj.text}"`, + `Sender: login name: ${obj.user} - windowID ${obj.SenderWindowID} - text message: ${obj.text}`, ); socket.emit('welcome', { - msg: `Welcome to the chat! `, + msg: 'Welcome to the chat!', }); - + // Send object directly — DO NOT wrap it in a string broadcast(obj, obj.SenderWindowID); console.log( @@ -202,32 +204,57 @@ async function onReady(fastify: FastifyInstance) { color.reset, ); }); - + socket.on('testend', (sock_id_cl: string) => { console.log('testend received from client socket id:', sock_id_cl); }); - - socket.on('wakeup', (message: string) => { - const obj: ClientMessage = JSON.parse(message) as ClientMessage; - clientChat.set(socket.id, { user: obj.user, lastSeen: Date.now() }); - connectedUser(fastify.io), - console.log('Wakeup: ', message); - }); - socket.on('list', () => { - console.log(color.red, 'list activated', color.reset, socket.id); + socket.on('list', (object) => { + + const userFromFrontend = object || null; + const client = clientChat.get(socket.id) || null; + + console.log(color.red, 'list activated', userFromFrontend, color.reset, socket.id); + + if (userFromFrontend.oldUser !== userFromFrontend.user) { + console.log(color.red, 'list activated', userFromFrontend.oldUser, color.reset); + if (client === null) { + console.log('ERROR: clientName is NULL'); + return; + }; + if (client) { + client.user = userFromFrontend.user; + } + } connectedUser(fastify.io, socket.id); }); - + + socket.on('updateClientName', (object) => { + const userFromFrontend = object || null; + const client = clientChat.get(socket.id) || null; + console.log(color.red, 'whoAMi activated', userFromFrontend, color.reset, socket.id); + if (userFromFrontend.oldUser !== userFromFrontend.user) { + console.log(color.red, 'whoAMi activated', userFromFrontend.oldUser, color.reset); + if (client === null) { + console.log('ERROR: clientName is NULL'); + return; + }; + if (client) { + client.user = userFromFrontend.user; + } + } + }); + + socket.on('disconnecting', (reason) => { - const clientName = clientChat.get(socket.id)?.user|| null; + const clientName = clientChat.get(socket.id)?.user || null; console.log( color.green, `Client disconnecting: ${clientName} (${socket.id}) reason:`, reason, ); if (reason === 'transport error') return; - + if (clientName !== null) { const obj = { type: 'chat', @@ -237,21 +264,20 @@ async function onReady(fastify: FastifyInstance) { timestamp: Date.now(), SenderWindowID: socket.id, }; - + broadcast(obj, obj.SenderWindowID); - // clientChat.delete(obj.user); } }); socket.on('client_left', (reason) => { - const clientName = clientChat.get(socket.id)?.user|| null; + const clientName = clientChat.get(socket.id)?.user || null; console.log( color.green, `Client left the Chat: ${clientName} (${socket.id}) reason:`, reason, ); if (reason === 'transport error') return; - + if (clientName !== null) { const obj = { type: 'chat', @@ -261,13 +287,12 @@ async function onReady(fastify: FastifyInstance) { timestamp: Date.now(), SenderWindowID: socket.id, }; - console.log(obj.SenderWindowID); + console.log(obj.SenderWindowID); broadcast(obj, obj.SenderWindowID); // clientChat.delete(obj.user); } }); - socket.on('client_entered', (data) => { // data may be undefined (when frontend calls emit with no payload) @@ -276,29 +301,33 @@ async function onReady(fastify: FastifyInstance) { let clientName = clientChat.get(socket.id)?.user || null; const client = clientChat.get(socket.id) || null; let text = 'is back in the chat'; - - // connectedUser(fastify.io, socket.id); - if(clientName === null) {console.log('ERROR: clientName is NULL'); return;}; - if(client === null) {console.log('ERROR: client is NULL'); return;}; - + + if (clientName === null) { + console.log('ERROR: clientName is NULL'); return; + }; + if (client === null) { + console.log('ERROR: client is NULL'); return; + }; if (userNameFromFrontend !== userFromFrontend) { text = `'is back in the chat, I used to be called '${userNameFromFrontend}`; clientName = userFromFrontend; - if(clientName === null) {console.log('ERROR: clientName is NULL'); return;}; + if (clientName === null) { + console.log('ERROR: clientName is NULL'); return; + }; if (client) { - client.user = clientName; - } + client.user = clientName; + } } console.log( color.green, - `Client entered the Chat: ${clientName} (${socket.id})` + `Client entered the Chat: ${clientName} (${socket.id})`, ); if (clientName !== null) { const obj = { type: 'chat', - user: clientName, // server-side stored name - frontendUserName: userNameFromFrontend, // from frontend - frontendUser: userFromFrontend, // from frontend + user: clientName, + frontendUserName: userNameFromFrontend, + frontendUser: userFromFrontend, token: '', text: text, timestamp: Date.now(),