From 5bd107a3aea99693a3872fc1b6a468aefc5ad825 Mon Sep 17 00:00:00 2001 From: Kislay Date: Thu, 20 Jun 2024 15:00:33 +0530 Subject: [PATCH] channel: Add utility function for triggering events from the frontend. --- backend/src/controllers/gameControllers.ts | 2 ++ frontend/src/channel.ts | 39 +++++++++++++++++++--- frontend/src/contexts/AuthContext.tsx | 6 ++-- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/backend/src/controllers/gameControllers.ts b/backend/src/controllers/gameControllers.ts index c5018f9..e7e2d70 100644 --- a/backend/src/controllers/gameControllers.ts +++ b/backend/src/controllers/gameControllers.ts @@ -18,6 +18,7 @@ export async function handleGameEvent(req: AuthRequest, res: Response) { res.status(404).send({ message: 'Game not found' }); return; } + console.log('handling event ', event); //todo: When game data is retrieved from database, it is not an instance of GameEngine // so we would need to convert it to an instance of GameEngine const result = game.dispatchEvent(event); @@ -46,6 +47,7 @@ export async function handleGameJoin(req: AuthRequest, res: Response) { } //note: when retrieving game from database, it is not an instance of GameEngine // we'd need to add these functions to the mongodb game schema + // this should be sent once the joining player receives the game state game.dispatchEvent({ type: 'JOIN_GAME', playerId: req.user.id }); propagateChanges(game); req.user.activeGameId = gameCode; diff --git a/frontend/src/channel.ts b/frontend/src/channel.ts index c55b9df..9e77a3e 100644 --- a/frontend/src/channel.ts +++ b/frontend/src/channel.ts @@ -12,7 +12,7 @@ const GAME_EVENTS = { STATE_SYNC: 'STATE_SYNC', }; -let jwt: string = ''; +let authCreds: { jwt: string; playerId: string } | null = null; let polling = false; let gameEventsDispatcher: (event: types.AppEvent) => void = () => {}; @@ -24,6 +24,9 @@ export function setGameEventsDispatcher( } let abortController: AbortController | null = null; async function poll() { + if (!authCreds) { + throw new Error('Auth credentials not set'); + } if (abortController) { abortController.abort(); } @@ -35,7 +38,7 @@ async function poll() { method: 'GET', headers: { 'Content-Type': 'application/json', - Authorization: jwt, + Authorization: authCreds.jwt, }, signal: abortController.signal, } @@ -73,8 +76,14 @@ function pollLoop() { }); } -export function startPolling(_jwt: string) { - jwt = _jwt; +export function setAuthCreds(jwt: string, playerId: string) { + authCreds = { jwt, playerId }; +} + +export function startPolling() { + if (!authCreds) { + throw new Error('Auth credentials not set'); + } polling = true; pollLoop(); } @@ -85,3 +94,25 @@ export function stopPolling() { abortController.abort(); } } + +export function triggerEvent(type: types.GameEventType, data?: unknown) { + if (!authCreds) { + throw new Error('Auth credentials not set'); + } + fetch(`${process.env.REACT_APP_BACKEND_URL}/game/events`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: authCreds.jwt, + }, + body: JSON.stringify({ + event: { + type, + playerId: authCreds.playerId, + data, + }, + }), + }).catch((e) => { + console.error('Error triggering event:', e); + }); +} diff --git a/frontend/src/contexts/AuthContext.tsx b/frontend/src/contexts/AuthContext.tsx index 40a33ea..009cfb2 100644 --- a/frontend/src/contexts/AuthContext.tsx +++ b/frontend/src/contexts/AuthContext.tsx @@ -67,7 +67,8 @@ export function AuthProvider({ children }: { children: ReactElement }) { name: data.user.username, }); setJwt(localToken!); - channel.startPolling(localToken!); + channel.setAuthCreds(data.token, data.user.id); + channel.startPolling(); } } catch (e) { console.info('deleting existing jwt'); @@ -105,7 +106,8 @@ export function AuthProvider({ children }: { children: ReactElement }) { }); setJwt(data.token); localStorage.setItem('jwt', data.token); - channel.startPolling(data.token); + channel.setAuthCreds(data.token, data.user.id); + channel.startPolling(); }, [setUser, toast] );