From f61ca0d0a1e80ac6f7985f4e5e83f04a77f4e34b Mon Sep 17 00:00:00 2001 From: Gavin McDonald Date: Tue, 1 Jul 2025 14:35:32 -0400 Subject: [PATCH] keep tilts synced --- app/AppContext.tsx | 4 ++++ components/TiltCard.tsx | 12 +++++------- lib/GameStore.ts | 31 +++++++++++++++++++------------ server.ts | 3 +-- 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/app/AppContext.tsx b/app/AppContext.tsx index 3205f5c..7261041 100644 --- a/app/AppContext.tsx +++ b/app/AppContext.tsx @@ -45,6 +45,10 @@ export function AppProvider({ children }: { children: ReactNode }) { if (tilt[cardIndex]) { emitTilt(cardIndex, tilt[cardIndex]); + } else { + // cardIndex does not matter + // all tilts for this user will be cleared + emitTilt(0, { rotateX: 0, rotateY: 0 }); } }, [tilt]); diff --git a/components/TiltCard.tsx b/components/TiltCard.tsx index bdc51e6..413eb5b 100644 --- a/components/TiltCard.tsx +++ b/components/TiltCard.tsx @@ -23,15 +23,13 @@ export default function TiltCard({ if (!card) return; if (tilt) { - const tilt = gameData.tilts[cardIndex]; - if (!tilt) { + const tilts = gameData.tilts[cardIndex]; + if (!tilts.length) { card.style.transform = `rotateX(0deg) rotateY(0deg)`; return; } - const tilted = tilt.filter(({ rotateX, rotateY }) => rotateX || rotateY); - - const { totalX, totalY } = tilted.reduce( + const { totalX, totalY } = tilts.reduce( ({ totalX, totalY }, { rotateX, rotateY }) => ({ totalX: totalX + rotateX, totalY: totalY + rotateY, @@ -39,8 +37,8 @@ export default function TiltCard({ { totalX: 0, totalY: 0 }, ); - const rotateX = totalX / tilted.length; - const rotateY = totalY / tilted.length; + const rotateX = totalX / tilts.length; + const rotateY = totalY / tilts.length; if (rotateX || rotateY) { card.style.transform = `rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; diff --git a/lib/GameStore.ts b/lib/GameStore.ts index 64d7fe6..5ff278d 100644 --- a/lib/GameStore.ts +++ b/lib/GameStore.ts @@ -107,11 +107,15 @@ export default class GameStore { return this.gameUpdate(game); } - leaveGame(game: GameState, playerID: string): GameState { + leaveGame(playerID: string): GameUpdate { + const game = this.getGameByPlayerID(playerID); + + this.players.delete(playerID); game.players.delete(playerID); + this._clearTilts(game, playerID); game.lastUpdated = Date.now(); - return game; + return this.gameUpdate(game); } flipCard(gameID: string, cardIndex: number): GameUpdate { @@ -159,15 +163,21 @@ export default class GameStore { if (!cardTilts) throw new Error(`Card tilts ${cardIndex} not found`); - game.tilts[cardIndex] = [ - ...cardTilts.filter((tilt) => tilt.playerID !== playerID), - { playerID, rotateX, rotateY }, - ]; - game.lastUpdated = Date.now(); + this._clearTilts(game, playerID); + + if (rotateX && rotateY) { + game.tilts[cardIndex] = [...game.tilts[cardIndex], { playerID, rotateX, rotateY }]; + game.lastUpdated = Date.now(); + } return this.gameUpdate(game); } + _clearTilts(game: GameState, playerID: string) { + game.tilts = game.tilts.map((card) => card.filter((tilt) => tilt.playerID !== playerID)); + game.lastUpdated = Date.now(); + } + updateSettings(gameID: string, settings: Settings) { const game = this.getGame(gameID); @@ -198,16 +208,13 @@ export default class GameStore { return { dmID, spectatorID, cards, settings, tilts }; } - playerExit(playerID: string): GameState | null { + playerExit(playerID: string): GameUpdate | null { if (this.startUps.has(playerID)) { this.startUps.delete(playerID); return null; } else { - const game = this.getGameByPlayerID(playerID); - - this.players.delete(playerID); - return this.leaveGame(game, playerID); + return this.leaveGame(playerID); } } diff --git a/server.ts b/server.ts index 8678e74..cc887ef 100644 --- a/server.ts +++ b/server.ts @@ -21,7 +21,6 @@ const timedReleases = {}; app.prepare().then(() => { const httpServer = createServer(handler); - const io = new SocketIOServer(httpServer); const broadcast = (event: string, gameUpdate: GameUpdate) => { @@ -32,9 +31,9 @@ app.prepare().then(() => { const timedRelease = (event: string, gameUpdate: GameUpdate, threshold: number) => { const now = Date.now(); const lastEvent = timedReleases[event]; + clearTimeout(lastEvent?.to); if (lastEvent?.embargo >= now) { - clearTimeout(lastEvent.to); const embargo = lastEvent.embargo - now; const to = setTimeout(() => {