diff --git a/back-end/api/src/controllers/SocketClients.ts b/back-end/api/src/controllers/SocketClients.ts index fda7f310..030248d5 100644 --- a/back-end/api/src/controllers/SocketClients.ts +++ b/back-end/api/src/controllers/SocketClients.ts @@ -49,6 +49,25 @@ router.post( } ); +// Client Disconnected +router.post( + '/update/:persistantClientId', + async (req: Request, res: Response, next: NextFunction) => { + const { persistantClientId } = req.params; + try { + const db = await getDB('global'); + await db.updateWhere( + 'socket_clients', + req.body, + `persistantClientId = "${persistantClientId}"` + ); + res.json({ success: true }); + } catch (e) { + next(e); + } + } +); + // Client Deleted router.post( '/disconnect/:lastSocketId', diff --git a/front-end/src/api/ApiProvider.ts b/front-end/src/api/ApiProvider.ts index 681c6b02..1a3c6143 100644 --- a/front-end/src/api/ApiProvider.ts +++ b/front-end/src/api/ApiProvider.ts @@ -250,6 +250,9 @@ export const postFrcFmsSettings = (settings: FMSSettings): Promise => export const deleteSocketClient = (uuid: string): Promise => clientFetcher(`socketClients/remove/${uuid}`, 'DELETE'); +export const updateSocketClient = (uuid: string, data: any): Promise => + clientFetcher(`socketClients/update/${uuid}`, 'POST', data); + // Results Syncing export const resultsSyncMatches = ( eventKey: string, diff --git a/front-end/src/api/SocketProvider.tsx b/front-end/src/api/SocketProvider.tsx index 7295a2d2..566443c6 100644 --- a/front-end/src/api/SocketProvider.tsx +++ b/front-end/src/api/SocketProvider.tsx @@ -73,7 +73,8 @@ export const useSocket = (): [ .map((d: any) => ({ field: parseInt(d), name: `Field ${d}` })) ); set(followerModeEnabledAtom, data.followerMode === 1); - set(leaderApiHostAtom, data.followerApiHost); + // TODO: Setter for this may be broken, investigate this later + // set(leaderApiHostAtom, data.followerApiHost); set(displayChromaKeyAtom, data.audienceDisplayChroma); localStorage.setItem('persistantClientId', data.persistantClientId); }); diff --git a/front-end/src/apps/Settings/tabs/audience.tsx b/front-end/src/apps/Settings/tabs/audience.tsx index 66a73d8d..70558b86 100644 --- a/front-end/src/apps/Settings/tabs/audience.tsx +++ b/front-end/src/apps/Settings/tabs/audience.tsx @@ -3,16 +3,30 @@ import Box from '@mui/material/Box'; import { useRecoilState } from 'recoil'; import { displayChromaKeyAtom } from 'src/stores/NewRecoil'; import TextSetting from '../components/TextSetting'; +import { updateSocketClient } from 'src/api/ApiProvider'; const AudienceDisplaySettingsTab: FC = () => { const [chromaKey, setChromaKey] = useRecoilState(displayChromaKeyAtom); + let timeout: any = null; + + const update = (key: string | number) => { + setChromaKey(key); + + // Don't hammer the server with requests + if (timeout) clearTimeout(timeout); + timeout = setTimeout(() => { + updateSocketClient(localStorage.getItem('persistantClientId') ?? '', { + audienceDisplayChroma: key + }); + }, 1000); + }; return ( diff --git a/front-end/src/apps/Settings/tabs/main.tsx b/front-end/src/apps/Settings/tabs/main.tsx index 08ba7f0b..1839f6d7 100644 --- a/front-end/src/apps/Settings/tabs/main.tsx +++ b/front-end/src/apps/Settings/tabs/main.tsx @@ -15,6 +15,7 @@ import { TeamKeys } from '@toa-lib/models'; import { MultiSelectSetting } from '../components/MultiSelectSetting'; import TextSetting from '../components/TextSetting'; import { APIOptions } from '@toa-lib/client'; +import { updateSocketClient } from 'src/api/ApiProvider'; const MainSettingsTab: FC = () => { const [darkMode, setDarkMode] = useRecoilState(darkModeAtom); @@ -47,6 +48,49 @@ const MainSettingsTab: FC = () => { APIOptions.host = value.toString(); }; + let followTimeout: any = null; + const updateFollowerMode = (value: boolean) => { + handleFollowerModeChange(value); + + // Don't hammer the server with requests + if (followTimeout !== null) clearTimeout(followTimeout); + followTimeout = setTimeout(() => { + updateSocketClient(localStorage.getItem('persistantClientId') ?? '', { + followerMode: value ? 1 : 0 + }); + }, 1000); + }; + + let leaderApiHostTimeout: any = null; + const updateFollowerApiHost = (value: string | number) => { + handleLeaderAddressChange(value); + + // Don't hammer the server with requests + if (leaderApiHostTimeout !== null) clearTimeout(leaderApiHostTimeout); + leaderApiHostTimeout = setTimeout(() => { + updateSocketClient(localStorage.getItem('persistantClientId') ?? '', { + followerApiHost: value + }); + }, 1000); + }; + + let fieldIdTimeout: any = null; + const updateFieldControl = (value: any[]) => { + handleFieldChange(value); + + // Don't hammer the server with requests + const fields = allFields + .filter((f) => value.includes(f.name)) + .map((f) => f.field) + .join(','); + if (fieldIdTimeout !== null) clearTimeout(fieldIdTimeout); + fieldIdTimeout = setTimeout(() => { + updateSocketClient(localStorage.getItem('persistantClientId') ?? '', { + fieldNumbers: fields + }); + }, 1000); + }; + return ( { name='Field Control' value={fieldControl.map((f) => f.name)} options={allFields.map((f) => f.name)} - onChange={handleFieldChange} + onChange={updateFieldControl} inline />