chat general broadcast done with now notifications system separated in different space on the chat windo
This commit is contained in:
parent
26c9bd6421
commit
8a151cfb5e
6 changed files with 81 additions and 78 deletions
2
frontend/src/@types/dom.d.ts
vendored
2
frontend/src/@types/dom.d.ts
vendored
|
|
@ -9,4 +9,6 @@ declare global {
|
|||
dispatchEvent<K extends keyof CustomEventMap>(ev: CustomEventMap[K]): void;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export { }; //keep that for TS compiler.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -7,9 +7,10 @@
|
|||
<button id="b-clear" class="btn-style absolute top-4 right-6">Clear Text</button>
|
||||
<button id="b-quit" class="btn-style absolute top-14 right-6">Quit Chat</button>
|
||||
<button id="b-help" class="btn-style absolute top-14 left-6">Connected</button>
|
||||
|
||||
<!-- Center wrapper for chat + vertical box -->
|
||||
<!-- Horizontal Message Box -->
|
||||
<div id="system-box" class="system-info">System: connecting ... </div>
|
||||
<div class="flex justify-center mt-2">
|
||||
<!-- Center wrapper for chat + vertical box -->
|
||||
<!-- Groupe Chat + vertical box container -->
|
||||
<div id = "g-boxes" class="flex gap-2">
|
||||
<!-- Text Chat box panel + send -->
|
||||
|
|
@ -20,7 +21,6 @@
|
|||
<button id="b-send" class="send-btn-style">Send</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Vertical Ping Buddies box panel-->
|
||||
<div id="ping-box" class="ping-box">
|
||||
<p id="ping-title" class="ping-title">Ping Buddies</p>
|
||||
|
|
@ -34,7 +34,9 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="text-gray-400 mt-2">From this Chat Box you can send messages to other players</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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: '',
|
||||
|
|
|
|||
|
|
@ -32,6 +32,13 @@ interface ClientInfo {
|
|||
lastSeen: number;
|
||||
}
|
||||
|
||||
export type ClientMessage = {
|
||||
destination: string;
|
||||
user: string;
|
||||
text: string;
|
||||
SenderWindowID: string;
|
||||
};
|
||||
|
||||
const clientChat = new Map<string, ClientInfo>();
|
||||
|
||||
// @ts-expect-error: import.meta.glob is a vite thing. Typescript doesn't know this...
|
||||
|
|
@ -69,11 +76,6 @@ 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' {
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -34,54 +34,6 @@ export const ChatRes = {
|
|||
export type ChatResType = MakeStaticResponse<typeof ChatRes>;
|
||||
|
||||
|
||||
function connectedUser(io: Server | undefined, targetSocketId?: string): number {
|
||||
let count = 0;
|
||||
|
||||
// Track unique usernames (avoid duplicates)
|
||||
const seenUsers = new Set<string>();
|
||||
|
||||
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<void> => {
|
||||
fastify.get(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue