From 8a151cfb5e9cbbd80e8842d0adb777a2116d5720 Mon Sep 17 00:00:00 2001 From: NigeParis Date: Tue, 2 Dec 2025 16:52:41 +0100 Subject: [PATCH] chat general broadcast done with now notifications system separated in different space on the chat windo --- frontend/src/@types/dom.d.ts | 2 ++ frontend/src/chat/chat.css | 28 ++++++++++++++-- frontend/src/pages/chat/chat.html | 10 +++--- frontend/src/pages/chat/chat.ts | 53 ++++++++++++++++++++----------- src/chat/src/app.ts | 18 +++++++---- src/chat/src/routes/nginx-chat.ts | 48 ---------------------------- 6 files changed, 81 insertions(+), 78 deletions(-) diff --git a/frontend/src/@types/dom.d.ts b/frontend/src/@types/dom.d.ts index 5cbf23c..1c35dd9 100644 --- a/frontend/src/@types/dom.d.ts +++ b/frontend/src/@types/dom.d.ts @@ -9,4 +9,6 @@ declare global { dispatchEvent(ev: CustomEventMap[K]): void; } } + + export { }; //keep that for TS compiler. diff --git a/frontend/src/chat/chat.css b/frontend/src/chat/chat.css index 95c2bb5..eb43dce 100644 --- a/frontend/src/chat/chat.css +++ b/frontend/src/chat/chat.css @@ -40,7 +40,6 @@ active:shadow-[0_2px_0_0_black];; } - .chatbox-style { @apply w-[650px] @@ -60,12 +59,37 @@ mx-auto; } +.system-info { + @apply + h-[40px] + bg-gray-200 + text-gray-700 + p-3 + rounded-3xl + mb-2 border + border-gray-200 + text-center + shadow + overflow-y-auto + justify-end /* 👈 forces text to bottom */ + relative; /* needed for overlay */ +} + + +.text-info { + @apply + text-blue-800 + +} + + .chat-window-style { @apply w-[400px] h-[50px] p-[10px] - border-1 border-black + border-1 + border-black shadow-sm flex-1 rounded-3xl diff --git a/frontend/src/pages/chat/chat.html b/frontend/src/pages/chat/chat.html index e6d9e92..2882ae5 100644 --- a/frontend/src/pages/chat/chat.html +++ b/frontend/src/pages/chat/chat.html @@ -7,9 +7,10 @@ - - + +
System: connecting ...
+
@@ -20,7 +21,6 @@
-

Ping Buddies

@@ -34,7 +34,9 @@
-

From this Chat Box you can send messages to other players

+ + + diff --git a/frontend/src/pages/chat/chat.ts b/frontend/src/pages/chat/chat.ts index cff6c80..26dd177 100644 --- a/frontend/src/pages/chat/chat.ts +++ b/frontend/src/pages/chat/chat.ts @@ -4,17 +4,22 @@ import authHtml from './chat.html?raw'; import client from '@app/api' import { getUser, updateUser } from "@app/auth"; import io, { Socket } from 'socket.io-client'; +// import type { ClientMessage } from "@app/@types/dom"; const color = { - red: 'color: red; font-weight: bold;', - green: 'color: green; font-weight: bold;', - yellow: 'color: orange; font-weight: bold;', - blue: 'color: blue; font-weight: bold;', + red: 'color: red;', + green: 'color: green;', + yellow: 'color: orange;', + blue: 'color: blue;', reset: '', }; - - +export type ClientMessage = { + destination: string; + user: string; + text: string; + SenderWindowID: string; +}; // get the name of the machine used to connect @@ -143,26 +148,39 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn }); // Listen for messages from the server "MsgObjectServer" - socket.on("MsgObjectServer", (data: any) => { - console.log("Message Obj Recieved:", data.message); - console.log("Recieved data.message.text: ", data.message.text); - console.log("Recieved data.message.user: ", data.message.user); - console.log("Recieved data.message.type: ", data.message.type); - console.log("Recieved data.message.token: ", data.message.token); - console.log("Recieved data.message.timestamp: ", data.message.timestamp); + socket.on("MsgObjectServer", (data: { message: ClientMessage}) => { + console.log("Message Obj Recieved:", data); + console.log("%cRecieved data.message.text: ", color.blue, data.message.text); + console.log("%cRecieved data.message.user: ", color.blue, data.message.user); // Display the message in the chat window + const systemWindow = document.getElementById('system-box') as HTMLDivElement; const chatWindow = document.getElementById("t-chatbox") as HTMLDivElement; const bconnected = document.getElementById('b-help') as HTMLButtonElement; if (bconnected) { bconnected.click(); } - if (chatWindow) { + if (chatWindow && data.message.destination === "") { const messageElement = document.createElement("div"); messageElement.textContent = `${data.message.user}: ${data.message.text}`; chatWindow.appendChild(messageElement); chatWindow.scrollTop = chatWindow.scrollHeight; } + const MAX_SYSTEM_MESSAGES = 10; + + if (systemWindow && data.message.destination === "system-info") { + const messageElement = document.createElement("div"); + messageElement.textContent = `${data.message.user}: ${data.message.text}`; + systemWindow.appendChild(messageElement); + + // keep only last 10 + while (systemWindow.children.length > MAX_SYSTEM_MESSAGES) { + systemWindow.removeChild(systemWindow.firstChild!); + } + + systemWindow.scrollTop = systemWindow.scrollHeight; + } + console.log("Getuser():", getUser()); }); @@ -261,6 +279,7 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn const user = getUser(); if (user && socket?.connected) { const message = { + destination: "", type: "chat", user: user.name, token: document.cookie, @@ -298,7 +317,7 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn setInterval(async () => { - bconnected.click(); + //bconnected.click(); }, 10000); // every 10 second // Help Text button @@ -312,7 +331,7 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn oldUser = loggedIn.name || "undefined"; const res = await client.guestLogin(); let user = await updateUser(); - console.log('%User?name:',color.yellow, user?.name); + console.log('%cUser?name:',color.yellow, user?.name); localStorage.setItem("oldName", oldUser); buddies.textContent = ""; // if (chatWindow) { @@ -347,8 +366,6 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn switch (res.kind) { case 'success': { let user = await updateUser(); - console.log('%cUSER_NAME ',color.yellow, user?.name); - console.log('%cGET_user ',color.yellow, getUser()?.name || null); if (chatWindow) { socket.emit('updateClientName', { oldUser: '', diff --git a/src/chat/src/app.ts b/src/chat/src/app.ts index f5082b4..933048b 100644 --- a/src/chat/src/app.ts +++ b/src/chat/src/app.ts @@ -32,6 +32,13 @@ interface ClientInfo { lastSeen: number; } +export type ClientMessage = { + destination: string; + user: string; + text: string; + SenderWindowID: string; +}; + const clientChat = new Map(); // @ts-expect-error: import.meta.glob is a vite thing. Typescript doesn't know this... @@ -69,18 +76,13 @@ export default app; export { app }; -type ClientMessage = { - user: string; - text: string; - SenderWindowID: string; -}; // When using .decorate you have to specify added properties for Typescript declare module 'fastify' { interface FastifyInstance { io: Server<{ hello: (message: string) => string; - MsgObjectServer: (data: { message: ClientMessage }) => void; + MsgObjectServer: (data: { message: ClientMessage } ) => void; message: (msg: string) => void; listBud: (msg: string) => void; testend: (sock_id_client: string) => void; @@ -273,6 +275,7 @@ function broadcast(data: ClientMessage, sender?: string) { if (!clientName) return; console.log(color.green, `Client logging out: ${clientName} (${socket.id})`); const obj = { + destination: "system-info", type: "chat" as const, user: clientName, token: "", @@ -300,6 +303,7 @@ function broadcast(data: ClientMessage, sender?: string) { if (clientName !== null) { const obj = { + destination: "system-info", type: 'chat', user: clientName, token: '', @@ -323,6 +327,7 @@ function broadcast(data: ClientMessage, sender?: string) { if (clientName !== null) { const obj = { + destination: "system-info", type: 'chat', user: clientName, token: '', @@ -367,6 +372,7 @@ function broadcast(data: ClientMessage, sender?: string) { ); if (clientName !== null) { const obj = { + destination: "system-info", type: 'chat', user: clientName, frontendUserName: userNameFromFrontend, diff --git a/src/chat/src/routes/nginx-chat.ts b/src/chat/src/routes/nginx-chat.ts index e6dd4df..99dc7a6 100644 --- a/src/chat/src/routes/nginx-chat.ts +++ b/src/chat/src/routes/nginx-chat.ts @@ -34,54 +34,6 @@ export const ChatRes = { export type ChatResType = MakeStaticResponse; -function connectedUser(io: Server | undefined, targetSocketId?: string): number { - let count = 0; - - // Track unique usernames (avoid duplicates) - const seenUsers = new Set(); - - for (const [socketId, info] of clientChat) { - - // Validate entry - if (!info || typeof info.user !== "string" || info.user.trim() === "") { - clientChat.delete(socketId); - continue; - } - - const username = info.user; - - // Validate socket exists if io is passed - if (io) { - const socket = io.sockets.sockets.get(socketId); - - // Remove disconnected sockets - if (!socket || socket.disconnected) { - clientChat.delete(socketId); - continue; - } - } - - // Skip duplicates - if (seenUsers.has(username)) - continue; - - seenUsers.add(username); - count++; - - // Send to target only - if (io && targetSocketId) { - io.to(targetSocketId).emit("listBud", username); - } - - console.log(color.yellow, "Client:", color.reset, username); - console.log(color.yellow, "Socket ID:", color.reset, socketId); - } - - return count; -} - - - const route: FastifyPluginAsync = async (fastify): Promise => { fastify.get(