diff --git a/frontend/src/chat/chat.css b/frontend/src/chat/chat.css
index 993c029..b308418 100644
--- a/frontend/src/chat/chat.css
+++ b/frontend/src/chat/chat.css
@@ -230,6 +230,33 @@ div-private {
right-12
}
+
+.popUpMessage {
+ @apply
+ bg-white
+ p-6 rounded-xl
+ shadow-xl
+ w-[800px]
+ h-[100px]
+ p-[10px]
+ border-1
+ border-black
+
+}
+
+.gamePopup {
+ @apply
+ fixed
+ inset-0
+ bg-black/50
+ flex
+ justify-center
+ items-center;
+}
+
+
+
+
.hidden{
display: none;
}
\ No newline at end of file
diff --git a/frontend/src/pages/chat/chat.html b/frontend/src/pages/chat/chat.html
index bf06259..87b57be 100644
--- a/frontend/src/pages/chat/chat.html
+++ b/frontend/src/pages/chat/chat.html
@@ -1,6 +1,7 @@
+
ChatterBox
@@ -26,9 +27,6 @@
Ping Buddies
+
diff --git a/frontend/src/pages/chat/chat.ts b/frontend/src/pages/chat/chat.ts
index ea68dfd..fb18ecb 100644
--- a/frontend/src/pages/chat/chat.ts
+++ b/frontend/src/pages/chat/chat.ts
@@ -87,10 +87,12 @@ function addMessage(text: string) {
return ;
};
-function clearText() {
+function clear(senderSocket: Socket) {
const chatWindow = document.getElementById("t-chatbox") as HTMLDivElement;
if (!chatWindow) return;
chatWindow.innerHTML = "";
+ // senderSocket.emit('nextGame');
+
}
function isLoggedIn() {
@@ -106,11 +108,11 @@ function inviteToPlayPong(profil: ClientProfil, senderSocket: Socket) {
-function actionBtnPopUpClear(profil: ClientProfil) {
+function actionBtnPopUpClear(profil: ClientProfil, senderSocket: Socket) {
setTimeout(() => {
const clearTextBtn = document.querySelector("#popup-b-clear");
clearTextBtn?.addEventListener("click", () => {
- clearText();
+ clear(senderSocket);
});
}, 0)
};
@@ -240,8 +242,9 @@ async function listBuddies(socket: Socket, buddies: HTMLDivElement, listBuddies:
});
buddiesElement.addEventListener("dblclick", () => {
- console.log("Open profile:", listBuddies);
+ console.log("Open profile:", listBuddies);
getProfil(socket, listBuddies);
+ sendtextbox.value = "";
});
buddies.appendChild(buddiesElement);
@@ -387,12 +390,32 @@ async function openProfilePopup(profil: ClientProfil) {
About: '${profil.text}'
`;
- const profilList = document.getElementById("profile-modal") ?? null;
+ const profilList = document.getElementById("profile-modal") ?? null;
if (profilList)
profilList.classList.remove("hidden");
// The popup now exists → attach the event
}
+async function openMessagePopup(message: string) {
+
+
+ const modalmessage = document.getElementById("modal-message") ?? null;
+ if(!message) return
+ const obj:any = JSON.parse(message);
+ if (modalmessage)
+ modalmessage.innerHTML = `
+
+
+
Next Game Message: ${obj.link}
+
`;
+ const gameMessage = document.getElementById("game-modal") ?? null;
+ if (gameMessage)
+ gameMessage.classList.remove("hidden");
+ // The popup now exists → attach the event
+}
+
+
+
function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn {
@@ -470,7 +493,7 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
socket.on('profilMessage', (profil: ClientProfil) => {
openProfilePopup(profil);
- actionBtnPopUpClear(profil);
+ actionBtnPopUpClear(profil, socket);
actionBtnPopUpInvite(profil, socket);
});
@@ -489,37 +512,39 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
addMessage(message);
})
- type Providers = {
- name: string,
- display_name: string,
- icon_url?: string,
- color?: { default: string, hover: string },
- };
+ //receives broadcast of the next GAME
+ socket.on('nextGame', (message) => {
+ openMessagePopup(message);
+ // addMessage(message);
+ })
let toggle = false
- window.addEventListener("focus", () => {
+ window.addEventListener("focus", async () => {
//nst bwhoami = document.getElementById('b-whoami') as HTMLButtonElement;
- if (window.location.pathname === '/app/chat') {
+
+ setTimeout(() => {
connected(socket);
- console.log("%cWindow is focused on /chat:" + socket.id, color.green);
+ }, 0);
+ if (window.location.pathname === '/app/chat') {
+ console.log('%cWindow is focused on /chat:' + socket.id, color.green);
if (socket.id) {
- windowStateVisable();
+ await windowStateVisable();
}
toggle = true;
}
});
window.addEventListener("blur", () => {
- console.log("%cWindow is not focused on /chat", color.red);
+ console.log('%cWindow is not focused on /chat', color.red);
if (socket.id)
windowStateHidden();
toggle = false;
});
-
// setInterval(async () => {
// //connected(socket);
- // },10000); // every 10 seco
+ // },10000); // every 10 sec
+
socket.on('listBud', async (myBuddies: string) => {
const buddies = document.getElementById('div-buddies') as HTMLDivElement;
console.log('List buddies connected ', myBuddies);
@@ -552,6 +577,7 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
const buddies = document.getElementById('div-buddies') as HTMLDivElement;
const bquit = document.getElementById('b-quit') as HTMLDivElement;
const systemWindow = document.getElementById('system-box') as HTMLDivElement;
+ const bnextGame = document.getElementById('b-nextGame') as HTMLDivElement;
chatWindow.textContent = '';
chatWindow.innerHTML = '';
@@ -578,6 +604,18 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
if (profilList) profilList.classList.add("hidden");
});
+
+
+
+ const buttonMessage = document.getElementById("close-modal-message") ?? null;
+
+ if (buttonMessage)
+ buttonMessage.addEventListener("click", () => {
+ const gameMessage = document.getElementById("game-modal") ?? null;
+ if (gameMessage) gameMessage.classList.add("hidden");
+ });
+
+
// Send button
sendButton?.addEventListener("click", () => {
if (sendtextbox && sendtextbox.value.trim()) {
@@ -631,6 +669,14 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
if (chatWindow) {
chatWindow.innerHTML = '';
}
+ clear(socket); //DEV testing broadcastGames
+ });
+
+ // Dev Game message button
+ bnextGame?.addEventListener("click", () => {
+ if (chatWindow) {
+ socket.emit('nextGame');
+ }
});
bquit?.addEventListener('click', () => {
@@ -652,5 +698,4 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
}
}
};
-addRoute('/chat', handleChat, { bypass_auth: true });
-
+addRoute('/chat', handleChat, { bypass_auth: true });
\ No newline at end of file
diff --git a/src/@shared/src/utils/index.ts b/src/@shared/src/utils/index.ts
index a79cbe9..96d02ad 100644
--- a/src/@shared/src/utils/index.ts
+++ b/src/@shared/src/utils/index.ts
@@ -142,3 +142,11 @@ export function typeResponse(
export function isNullish(v: T | undefined | null): v is null | undefined {
return v === null || v === undefined;
}
+
+/**
+/* EXPERIMENTAL: how to send a starting game link to chat
+**/
+export async function sendGameLinkToChatService(link: string) :Promise {
+ const payload = { link };
+ return JSON.stringify(payload);
+}
\ No newline at end of file
diff --git a/src/chat/src/app.ts b/src/chat/src/app.ts
index 14258e2..e904b15 100644
--- a/src/chat/src/app.ts
+++ b/src/chat/src/app.ts
@@ -7,6 +7,7 @@ import * as swagger from '@shared/swagger';
import * as utils from '@shared/utils';
import { Server, Socket } from 'socket.io';
import type { User } from '@shared/database/mixin/user';
+import { sendGameLinkToChatService } from '../../@shared/src/utils/index';
// colors for console.log
export const color = {
@@ -46,7 +47,7 @@ export type ClientProfil = {
command: string,
destination: string,
type: string,
- user: string,
+ user: string,
loginName: string,
userID: string,
text: string,
@@ -55,21 +56,28 @@ export type ClientProfil = {
SenderName: string,
innerHtml?: string,
-};
+};
+/**
+/* TODO find the description info for profil / or profil game link and return
+**/
+function createNextGame() {
+ return 'The next Game is Starting click here to watch';
+};
-// export type inviteGame = {
-// command?: string,
-// destination?: string,
-// type?: string,
-// user?: string,
-// loginName?: string,
-// userID?: string,
-// innerHtml?: string,
-// timestamp?: number,
-// SenderWindowID?:string,
-// SenderName: string
-// };
+function setAboutPlayer(about: string): string {
+ if (!about) {
+ about = 'Player is good Shape - This is a default description';
+ }
+ return about;
+};
+
+function setGameLink(link: string): string {
+ if (!link) {
+ link = 'Click me';
+ }
+ return link;
+};
const clientChat = new Map();
@@ -118,6 +126,7 @@ declare module 'fastify' {
profilMessage: (data: ClientProfil) => void;
inviteGame: (data: ClientProfil) => void;
privMessageCopy: (msg: string) => void;
+ nextGame: (msg: string) => void;
message: (msg: string) => void;
listBud: (msg: string) => void;
testend: (sock_id_client: string) => void;
@@ -189,6 +198,28 @@ async function onReady(fastify: FastifyInstance) {
});
}
+
+ async function broadcastNextGame(gameLink?: Promise) {
+
+ const link = gameLink ? await gameLink : undefined;
+ const sockets = await fastify.io.fetchSockets();
+ // fastify.io.fetchSockets().then((sockets) => {
+ for (const socket of sockets) {
+ // Skip sender's own socket
+ const clientInfo = clientChat.get(socket.id);
+ if (!clientInfo?.user) {
+ console.log(color.yellow, `Skipping socket ${socket.id} (no user found)`);
+ continue;
+ }
+ // Emit structured JSON object
+ if (link) {
+ socket.emit('nextGame', link);
+ }
+ // Debug logs
+ // console.log(color.green, `'DEBUG LOG: Broadcast to:', ${data.command} message: ${data.text}`);
+ }
+ };
+
// function formatTimestamp(ms: number) {
// const d = new Date(ms);
// return d.toLocaleString('fr-FR', { timeZone: 'Europe/Paris' });
@@ -198,21 +229,9 @@ async function onReady(fastify: FastifyInstance) {
return users.find(user => user.name === name) || null;
}
- ///TODO find the description info for profil / or profil game link and return
- function getAboutPlayer( ): string{
- const description = 'Player is good Shape this needs to be replaced by a bd.function()';
- return description;
- }
-
- function getGameLink(): string{
- const link = `Click me`;
- return link;
- }
-
-
// this function returns html the profil pop up in CHAT of a user 'nickname unique' TODO ....
async function getProfil(user: string, socket: Socket): Promise {
-
+
let clientProfil!: ClientProfil;
const users: User[] = fastify.db.getAllUsers() ?? [];
const allUsers: User | null = getUserByName(users, user);
@@ -220,20 +239,20 @@ async function onReady(fastify: FastifyInstance) {
if (user === allUsers?.name) {
console.log(color.yellow, `'login Name: '${allUsers.login}' user: '${user}'`);
- clientProfil =
+ clientProfil =
{
command: 'getProfil',
destination: 'profilMsg',
type: 'chat' as const,
- user: `${allUsers.name}`,
+ user: `${allUsers.name}`,
loginName: `${allUsers?.login ?? 'Guest'}`,
userID: `${allUsers?.id ?? ''}`,
- text: getAboutPlayer(),
+ text: setAboutPlayer(''),
timestamp: Date.now(),
SenderWindowID: socket.id,
SenderName: '',
innerHtml: '',
- };
+ };
}
return clientProfil;
};
@@ -250,10 +269,10 @@ async function onReady(fastify: FastifyInstance) {
function sendInvite(innerHtml: string, data: ClientProfil) {
fastify.io.fetchSockets().then((sockets) => {
-
+
let targetSocket;
for (const socket of sockets) {
- let clientInfo: string = clientChat.get(socket.id)?.user || '';
+ const clientInfo: string = clientChat.get(socket.id)?.user || '';
if (clientInfo === data.user) {
console.log(color.yellow, 'FOUND:', data.user);
targetSocket = socket || '';
@@ -261,7 +280,7 @@ async function onReady(fastify: FastifyInstance) {
}
}
data.innerHtml = innerHtml ?? '';
- if (targetSocket) {
+ if (targetSocket) {
targetSocket.emit('inviteGame', data);
}
});
@@ -333,6 +352,13 @@ async function onReady(fastify: FastifyInstance) {
console.log('testend received from client socket id:', sock_id_cl);
});
+
+ socket.on('nextGame', () => {
+ const link = createNextGame();
+ const game: Promise = sendGameLinkToChatService(link);
+ broadcastNextGame(game);
+ });
+
socket.on('list', (object) => {
const userFromFrontend = object || null;
@@ -496,8 +522,8 @@ async function onReady(fastify: FastifyInstance) {
const clientName: string = clientChat.get(socket.id)?.user || '';
const profilInvite: ClientProfil = JSON.parse(data) || '';
// const users: User[] = fastify.db.getAllUsers() ?? [];
-
- const inviteHtml: string = `invites you to a game ` + getGameLink();
+
+ const inviteHtml: string = 'invites you to a game ' + setGameLink('');
if (clientName !== null) {
// const testuser: User | null = getUserByName(users, profilInvite.user ?? '');
// console.log(color.yellow, 'user:', testuser?.name ?? 'Guest');