Feature/chess game time - #6
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThe change centralizes chess state in client hooks, adds online and computer-game timers, and synchronizes timing through shared server events. It extracts game-over evaluation into shared utilities, adds authentication and game-session hooks, and reorganizes client hook imports. Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR introduces chess clock support by adding shared TimeInfo types, server-side time state propagation, and client-side timer rendering/logic. It also refactors client pages to use new game/auth hooks and consolidates “game over” detection into a shared utility.
Changes:
- Add
TimeInfoto shared types and propagate it through server socket events (game:game-started,game:move-made,game:sync). - Add shared
getGameOverInfohelper and update the serverGamelogic to use it. - Refactor client game pages into reusable hooks (
useChessGame,useComputerGame, new timers) and update auth hook import paths.
Reviewed changes
Copilot reviewed 25 out of 29 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Adds chess.js / @types/chess.js for shared utilities and bumps @types/react-dom. |
| packages/shared/package.json | Exposes new shared modules and adds chess dependencies. |
| packages/shared/src/types.ts | Introduces TimeInfo and threads it through game events/sync. |
| packages/shared/src/utils.ts | Adds shared getGameOverInfo helper for chess.js end-state detection. |
| apps/server/src/game/game.ts | Adds time state accessor and reuses shared game-over logic. |
| apps/server/src/sockets/socket.ts | Sends timeInfo in socket events; emits game:game-started with payload. |
| apps/client/src/pages/signupPage.tsx | Updates auth hook import path. |
| apps/client/src/pages/loginPage.tsx | Updates auth hook import path. |
| apps/client/src/pages/homePage.tsx | Switches create/join game logic to new game hooks. |
| apps/client/src/pages/playerGame.tsx | Refactors multiplayer game UI to useChessGame and renders timers. |
| apps/client/src/pages/computerGame.tsx | Refactors vs-computer game UI to useComputerGame, renders timer and sidebar. |
| apps/client/src/layouts/SocketProvider.tsx | Updates auth hook import path. |
| apps/client/src/layouts/RequireAuth.tsx | Updates auth hook import path. |
| apps/client/src/layouts/NotLoggedIn.tsx | Updates auth hook import path. |
| apps/client/src/hooks/useTimer.ts | Removes old timer hook (replaced by game-scoped timer hooks). |
| apps/client/src/hooks/useFetchUser.ts | Updates auth hook import path. |
| apps/client/src/hooks/useApi.ts | Updates auth hook import path. |
| apps/client/src/hooks/game/useTimer.ts | New multiplayer timer hook driven by server timeInfo. |
| apps/client/src/hooks/game/useStockfish.ts | Adds isGameOver gating to stop engine moves after game end. |
| apps/client/src/hooks/game/useJoinGame.ts | New join-game hook with navigation + error handling. |
| apps/client/src/hooks/game/useCreateGame.ts | New create-game hook with navigation + error handling. |
| apps/client/src/hooks/game/useComputerGame.ts | New vs-computer game hook (stockfish + timer + game-over handling). |
| apps/client/src/hooks/game/useCompTimer.ts | New vs-computer timer hook. |
| apps/client/src/hooks/game/useChessGame.ts | New multiplayer game hook (socket sync + board options + timers). |
| apps/client/src/hooks/auth/useAuthForm.ts | Updates API hook import path. |
| apps/client/src/hooks/auth/useAuth.ts | Adds auth context accessor hook. |
| apps/client/src/components/Timer.tsx | Updates Timer API to accept a single optional displayTime. |
| apps/client/src/components/profile/logoutBtn.tsx | Updates auth hook import path. |
| apps/client/src/components/profile/deleteAccountBtn.tsx | Updates auth hook import path. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Suppressed comments (1)
apps/server/src/sockets/socket.ts:179
game:game-overpayload shape is inconsistent: this handler emits a rawGameStateEvent, but other handlers in this file emit{ GameStateEvent: ... }. The client subscribes expectingGameStateEventdirectly, so timeout/abandonment events can break at runtime. Standardize the event payload across allgame:game-overemits.
if (game.isGameOver()) {
io.to(gameId).emit("game:game-over", game.getGameStateEvent());
}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Actionable comments posted: 17
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/client/src/hooks/game/useStockfish.ts (1)
44-55: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick winStockfish is reset on every render. The shared root cause is an unstable
onMovecallback identity wired into an effect dependency array.useComputerGamepasses a new arrow function on every render, anduseStockfishlists it as a dependency of the effect that initializes the engine. The cleanup posts"stop"and the setup posts"ucinewgame", so each render aborts the in-flight search and resets engine state. The second effect does not re-run, becauseturn,chessGame,stockfishSide, andisGameOverare unchanged, so the search is never restarted.useCompTimerre-renders the tree every 250 ms, which is shorter than ago depth 15search, so Stockfish stops producing moves. Fix both sites together.
apps/client/src/hooks/game/useStockfish.ts#L44-L55: storeonMovein a ref, callonMoveRef.current()in thebestmovehandler, and removeonMovefrom the dependency array on Line 48.apps/client/src/hooks/game/useComputerGame.ts#L36-L41: wrap theonMovebody inuseCallbackwith[chessGame]as the dependency list and pass the memoized callback.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/client/src/hooks/game/useStockfish.ts` around lines 44 - 55, Stabilize the Stockfish callback across renders: in apps/client/src/hooks/game/useStockfish.ts:44-55, store onMove in a ref, invoke onMoveRef.current() from the bestmove handler, and remove onMove from the initialization effect dependencies; in apps/client/src/hooks/game/useComputerGame.ts:36-41, wrap the onMove body in useCallback with [chessGame] and pass the memoized callback.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/client/src/components/Timer.tsx`:
- Around line 5-10: Update the TimerType interface properties displayTime and
playerName to optional props, preserving their existing number/string types and
the Timer component’s playerName default value.
In `@apps/client/src/hooks/auth/useAuth.ts`:
- Around line 4-9: Remove the local useAuth implementations from useAuthForm and
SocketProvider, and import and use the shared default useAuth hook defined here.
Preserve each consumer’s existing authentication behavior while ensuring both
rely on the shared hook contract.
In `@apps/client/src/hooks/game/useChessGame.ts`:
- Line 20: Update the chessGame state initialization to use a lazy useState
initializer, matching the existing lazy pattern on the next line, so new Chess
instances are created only during initial state setup.
- Line 87: Remove the dead !color condition from the move guard in the chess
game hook, since color is always a valid PlayerColor. If pre-sync move blocking
is required, replace it with an explicit check for the sync state rather than
relying on color.
- Around line 61-76: Remove the debug console.log(res) from the game:sync
acknowledgement callback to avoid logging user identifiers. In the surrounding
effect, add a cancellation flag and have the callback return before any state
updates when cleanup has run; set that flag during the effect cleanup alongside
socket.off. Preserve the existing error handling and successful sync updates
while the effect remains active.
- Around line 116-135: Update the game:move socket emission in the move-handling
flow to use socket.timeout(ms).emit with the acknowledgement callback signature
(error, data). Treat a timeout or missing/failed acknowledgement like a rejected
move by restoring previousFen, chessPosition, and turn; retain the existing
successful acknowledgement updates for valid data.ok responses.
In `@apps/client/src/hooks/game/useCompTimer.ts`:
- Around line 11-25: Update useCompTimer to track each active turn’s deadline
with Date.now() rather than decrementing timeMs by fixed intervals. Use a ref to
preserve the deadline across effect re-runs, derive and clamp remaining time to
zero, and ensure turn changes do not discard elapsed partial time or introduce
drift while retaining the existing isGameOver cleanup behavior.
In `@apps/client/src/hooks/game/useComputerGame.ts`:
- Line 10: Update the chessPosition state initializer to read the starting FEN
from the existing chessGame instance instead of creating another Chess instance,
preserving custom initial positions. In the timeout winner logic near the
useCompTimer call, derive the winner from side rather than turn so it identifies
the human player's expired clock.
In `@apps/client/src/hooks/game/useCreateGame.ts`:
- Around line 14-27: Update the request handling in
apps/client/src/hooks/game/useCreateGame.ts (lines 14-27) and
apps/client/src/hooks/game/useJoinGame.ts (lines 18-29) to use one per-request
finalizer that clears the timeout, removes the connect_error listener, and marks
the request as finalized. Invoke it from the timeout handler, onError, and the
game:create/game:join acknowledgement callbacks; ignore any later
acknowledgements, and ensure cancelled requests do not update errorMessage.
In `@apps/client/src/hooks/game/useJoinGame.ts`:
- Around line 13-27: Update the validation in the join-game hook to trim gameId
before checking whether it is empty, so whitespace-only input is rejected. Reuse
that trimmed value for the game:join socket emission and subsequent navigation
instead of the untrimmed input.
In `@apps/client/src/hooks/game/useTimer.ts`:
- Line 18: Update the guard in the useTimer hook to check gameOverInfo?.gameOver
rather than gameOverInfo object presence, while retaining the existing !timeInfo
early return. This must allow timer updates when a GameStateEvent exists with
gameOver: false, matching the gating behavior in useChessGame.
- Around line 20-29: The useTimer interval must not derive elapsed time from
server lastMoveTime and client Date.now(). Capture a client receipt timestamp
when getTimeInfo() data arrives, use that timestamp as the local timer anchor,
and update the server response so whiteTimeMs/blackTimeMs are already
decremented through the emission time; preserve the existing turn-specific
countdown behavior.
In `@apps/client/src/pages/computerGame.tsx`:
- Line 19: Update the computerGame page around the SideBar component to render a
game-result surface driven by gameOverInfo on screens below the sm breakpoint.
Reuse the existing result data and ensure the banner or modal is hidden at sm
and larger sizes, while preserving the current SideBar behavior.
In `@apps/server/src/game/game.ts`:
- Around line 140-141: Update the private evaluateGameOverState method to read
this.chess directly and remove its redundant chess parameter. In the callers
around the game-over handling, invoke evaluateGameOverState without an argument
and remove the surrounding isGameOver guards, relying on getGameOverInfo’s
internal check while preserving the existing game-over behavior.
In `@apps/server/src/sockets/socket.ts`:
- Around line 173-175: Replace the `as MoveMadeEvent` assertion in the
`game:move-made` emission with `satisfies MoveMadeEvent`, matching the
validation pattern used for `GameStartedEvent` while preserving the existing
payload fields and emission behavior.
In `@packages/shared/package.json`:
- Around line 17-21: Remove the `@types/chess.js` entry from the devDependencies
in packages/shared/package.json, relying on the bundled declarations provided by
the existing chess.js dependency.
In `@packages/shared/src/utils.ts`:
- Around line 12-18: Reorder the draw classification branches in the chess
result logic so position-based checks—stalemate and insufficient material—run
before counter-based checks such as the fifty-move rule, while preserving
threefold repetition handling. Add a fallback reason in the draw branch so
`reason` is always defined when `gameOver` is true and no specific condition
matches.
---
Outside diff comments:
In `@apps/client/src/hooks/game/useStockfish.ts`:
- Around line 44-55: Stabilize the Stockfish callback across renders: in
apps/client/src/hooks/game/useStockfish.ts:44-55, store onMove in a ref, invoke
onMoveRef.current() from the bestmove handler, and remove onMove from the
initialization effect dependencies; in
apps/client/src/hooks/game/useComputerGame.ts:36-41, wrap the onMove body in
useCallback with [chessGame] and pass the memoized callback.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 58d41c35-9559-46d3-a5ce-5ced551687f7
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (28)
apps/client/src/components/Timer.tsxapps/client/src/components/profile/deleteAccountBtn.tsxapps/client/src/components/profile/logoutBtn.tsxapps/client/src/hooks/auth/useAuth.tsapps/client/src/hooks/auth/useAuthForm.tsapps/client/src/hooks/game/useChessGame.tsapps/client/src/hooks/game/useCompTimer.tsapps/client/src/hooks/game/useComputerGame.tsapps/client/src/hooks/game/useCreateGame.tsapps/client/src/hooks/game/useJoinGame.tsapps/client/src/hooks/game/useStockfish.tsapps/client/src/hooks/game/useTimer.tsapps/client/src/hooks/useApi.tsapps/client/src/hooks/useFetchUser.tsapps/client/src/hooks/useTimer.tsapps/client/src/layouts/NotLoggedIn.tsxapps/client/src/layouts/RequireAuth.tsxapps/client/src/layouts/SocketProvider.tsxapps/client/src/pages/computerGame.tsxapps/client/src/pages/homePage.tsxapps/client/src/pages/loginPage.tsxapps/client/src/pages/playerGame.tsxapps/client/src/pages/signupPage.tsxapps/server/src/game/game.tsapps/server/src/sockets/socket.tspackages/shared/package.jsonpackages/shared/src/types.tspackages/shared/src/utils.ts
💤 Files with no reviewable changes (1)
- apps/client/src/hooks/useTimer.ts
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 17
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/client/src/hooks/game/useStockfish.ts (1)
44-55: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick winStockfish is reset on every render. The shared root cause is an unstable
onMovecallback identity wired into an effect dependency array.useComputerGamepasses a new arrow function on every render, anduseStockfishlists it as a dependency of the effect that initializes the engine. The cleanup posts"stop"and the setup posts"ucinewgame", so each render aborts the in-flight search and resets engine state. The second effect does not re-run, becauseturn,chessGame,stockfishSide, andisGameOverare unchanged, so the search is never restarted.useCompTimerre-renders the tree every 250 ms, which is shorter than ago depth 15search, so Stockfish stops producing moves. Fix both sites together.
apps/client/src/hooks/game/useStockfish.ts#L44-L55: storeonMovein a ref, callonMoveRef.current()in thebestmovehandler, and removeonMovefrom the dependency array on Line 48.apps/client/src/hooks/game/useComputerGame.ts#L36-L41: wrap theonMovebody inuseCallbackwith[chessGame]as the dependency list and pass the memoized callback.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/client/src/hooks/game/useStockfish.ts` around lines 44 - 55, Stabilize the Stockfish callback across renders: in apps/client/src/hooks/game/useStockfish.ts:44-55, store onMove in a ref, invoke onMoveRef.current() from the bestmove handler, and remove onMove from the initialization effect dependencies; in apps/client/src/hooks/game/useComputerGame.ts:36-41, wrap the onMove body in useCallback with [chessGame] and pass the memoized callback.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/client/src/components/Timer.tsx`:
- Around line 5-10: Update the TimerType interface properties displayTime and
playerName to optional props, preserving their existing number/string types and
the Timer component’s playerName default value.
In `@apps/client/src/hooks/auth/useAuth.ts`:
- Around line 4-9: Remove the local useAuth implementations from useAuthForm and
SocketProvider, and import and use the shared default useAuth hook defined here.
Preserve each consumer’s existing authentication behavior while ensuring both
rely on the shared hook contract.
In `@apps/client/src/hooks/game/useChessGame.ts`:
- Line 20: Update the chessGame state initialization to use a lazy useState
initializer, matching the existing lazy pattern on the next line, so new Chess
instances are created only during initial state setup.
- Line 87: Remove the dead !color condition from the move guard in the chess
game hook, since color is always a valid PlayerColor. If pre-sync move blocking
is required, replace it with an explicit check for the sync state rather than
relying on color.
- Around line 61-76: Remove the debug console.log(res) from the game:sync
acknowledgement callback to avoid logging user identifiers. In the surrounding
effect, add a cancellation flag and have the callback return before any state
updates when cleanup has run; set that flag during the effect cleanup alongside
socket.off. Preserve the existing error handling and successful sync updates
while the effect remains active.
- Around line 116-135: Update the game:move socket emission in the move-handling
flow to use socket.timeout(ms).emit with the acknowledgement callback signature
(error, data). Treat a timeout or missing/failed acknowledgement like a rejected
move by restoring previousFen, chessPosition, and turn; retain the existing
successful acknowledgement updates for valid data.ok responses.
In `@apps/client/src/hooks/game/useCompTimer.ts`:
- Around line 11-25: Update useCompTimer to track each active turn’s deadline
with Date.now() rather than decrementing timeMs by fixed intervals. Use a ref to
preserve the deadline across effect re-runs, derive and clamp remaining time to
zero, and ensure turn changes do not discard elapsed partial time or introduce
drift while retaining the existing isGameOver cleanup behavior.
In `@apps/client/src/hooks/game/useComputerGame.ts`:
- Line 10: Update the chessPosition state initializer to read the starting FEN
from the existing chessGame instance instead of creating another Chess instance,
preserving custom initial positions. In the timeout winner logic near the
useCompTimer call, derive the winner from side rather than turn so it identifies
the human player's expired clock.
In `@apps/client/src/hooks/game/useCreateGame.ts`:
- Around line 14-27: Update the request handling in
apps/client/src/hooks/game/useCreateGame.ts (lines 14-27) and
apps/client/src/hooks/game/useJoinGame.ts (lines 18-29) to use one per-request
finalizer that clears the timeout, removes the connect_error listener, and marks
the request as finalized. Invoke it from the timeout handler, onError, and the
game:create/game:join acknowledgement callbacks; ignore any later
acknowledgements, and ensure cancelled requests do not update errorMessage.
In `@apps/client/src/hooks/game/useJoinGame.ts`:
- Around line 13-27: Update the validation in the join-game hook to trim gameId
before checking whether it is empty, so whitespace-only input is rejected. Reuse
that trimmed value for the game:join socket emission and subsequent navigation
instead of the untrimmed input.
In `@apps/client/src/hooks/game/useTimer.ts`:
- Line 18: Update the guard in the useTimer hook to check gameOverInfo?.gameOver
rather than gameOverInfo object presence, while retaining the existing !timeInfo
early return. This must allow timer updates when a GameStateEvent exists with
gameOver: false, matching the gating behavior in useChessGame.
- Around line 20-29: The useTimer interval must not derive elapsed time from
server lastMoveTime and client Date.now(). Capture a client receipt timestamp
when getTimeInfo() data arrives, use that timestamp as the local timer anchor,
and update the server response so whiteTimeMs/blackTimeMs are already
decremented through the emission time; preserve the existing turn-specific
countdown behavior.
In `@apps/client/src/pages/computerGame.tsx`:
- Line 19: Update the computerGame page around the SideBar component to render a
game-result surface driven by gameOverInfo on screens below the sm breakpoint.
Reuse the existing result data and ensure the banner or modal is hidden at sm
and larger sizes, while preserving the current SideBar behavior.
In `@apps/server/src/game/game.ts`:
- Around line 140-141: Update the private evaluateGameOverState method to read
this.chess directly and remove its redundant chess parameter. In the callers
around the game-over handling, invoke evaluateGameOverState without an argument
and remove the surrounding isGameOver guards, relying on getGameOverInfo’s
internal check while preserving the existing game-over behavior.
In `@apps/server/src/sockets/socket.ts`:
- Around line 173-175: Replace the `as MoveMadeEvent` assertion in the
`game:move-made` emission with `satisfies MoveMadeEvent`, matching the
validation pattern used for `GameStartedEvent` while preserving the existing
payload fields and emission behavior.
In `@packages/shared/package.json`:
- Around line 17-21: Remove the `@types/chess.js` entry from the devDependencies
in packages/shared/package.json, relying on the bundled declarations provided by
the existing chess.js dependency.
In `@packages/shared/src/utils.ts`:
- Around line 12-18: Reorder the draw classification branches in the chess
result logic so position-based checks—stalemate and insufficient material—run
before counter-based checks such as the fifty-move rule, while preserving
threefold repetition handling. Add a fallback reason in the draw branch so
`reason` is always defined when `gameOver` is true and no specific condition
matches.
---
Outside diff comments:
In `@apps/client/src/hooks/game/useStockfish.ts`:
- Around line 44-55: Stabilize the Stockfish callback across renders: in
apps/client/src/hooks/game/useStockfish.ts:44-55, store onMove in a ref, invoke
onMoveRef.current() from the bestmove handler, and remove onMove from the
initialization effect dependencies; in
apps/client/src/hooks/game/useComputerGame.ts:36-41, wrap the onMove body in
useCallback with [chessGame] and pass the memoized callback.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 58d41c35-9559-46d3-a5ce-5ced551687f7
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (28)
apps/client/src/components/Timer.tsxapps/client/src/components/profile/deleteAccountBtn.tsxapps/client/src/components/profile/logoutBtn.tsxapps/client/src/hooks/auth/useAuth.tsapps/client/src/hooks/auth/useAuthForm.tsapps/client/src/hooks/game/useChessGame.tsapps/client/src/hooks/game/useCompTimer.tsapps/client/src/hooks/game/useComputerGame.tsapps/client/src/hooks/game/useCreateGame.tsapps/client/src/hooks/game/useJoinGame.tsapps/client/src/hooks/game/useStockfish.tsapps/client/src/hooks/game/useTimer.tsapps/client/src/hooks/useApi.tsapps/client/src/hooks/useFetchUser.tsapps/client/src/hooks/useTimer.tsapps/client/src/layouts/NotLoggedIn.tsxapps/client/src/layouts/RequireAuth.tsxapps/client/src/layouts/SocketProvider.tsxapps/client/src/pages/computerGame.tsxapps/client/src/pages/homePage.tsxapps/client/src/pages/loginPage.tsxapps/client/src/pages/playerGame.tsxapps/client/src/pages/signupPage.tsxapps/server/src/game/game.tsapps/server/src/sockets/socket.tspackages/shared/package.jsonpackages/shared/src/types.tspackages/shared/src/utils.ts
💤 Files with no reviewable changes (1)
- apps/client/src/hooks/useTimer.ts
🛑 Comments failed to post (3)
apps/client/src/hooks/auth/useAuth.ts (1)
4-9: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
Use the shared hook in all authentication consumers.
apps/client/src/hooks/auth/useAuthForm.tsandapps/client/src/layouts/SocketProvider.tsxstill define localuseAuthimplementations. Remove those duplicates and import this hook instead. This prevents the authentication contract from diverging.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/client/src/hooks/auth/useAuth.ts` around lines 4 - 9, Remove the local useAuth implementations from useAuthForm and SocketProvider, and import and use the shared default useAuth hook defined here. Preserve each consumer’s existing authentication behavior while ensuring both rely on the shared hook contract.apps/client/src/hooks/game/useCreateGame.ts (1)
14-27: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail echo "Files:" fd -a 'useCreateGame|useJoinGame' . || true echo echo "useCreateGame outline:" ast-grep outline apps/client/src/hooks/game/useCreateGame.ts --view expanded || true echo echo "useJoinGame outline:" ast-grep outline apps/client/src/hooks/game/useJoinGame.ts --view expanded || true echo echo "useCreateGame:" cat -n apps/client/src/hooks/game/useCreateGame.ts echo echo "useJoinGame:" cat -n apps/client/src/hooks/game/useJoinGame.tsRepository: MohamedSayed0573/ChessLab
Length of output: 3711
Finalize each socket request on every terminal path.
The timeout path keeps
onErrorregistered, andonErrorleavesgame:create/game:joinacknowledgements available until a reply arrives. If a late acknowledgement returnsok, these hooks navigate after showing an error. A cancelled request path should not updateerrorMessage.Use one finalizer per request that clears the timeout, removes
onError, and prevents later acknowledgement processing. Call it from the timeout handler,onError, and the acknowledgement callback inuseCreateGame.tsanduseJoinGame.ts.📍 Affects 2 files
apps/client/src/hooks/game/useCreateGame.ts#L14-L27(this comment)apps/client/src/hooks/game/useJoinGame.ts#L18-L29🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/client/src/hooks/game/useCreateGame.ts` around lines 14 - 27, Update the request handling in apps/client/src/hooks/game/useCreateGame.ts (lines 14-27) and apps/client/src/hooks/game/useJoinGame.ts (lines 18-29) to use one per-request finalizer that clears the timeout, removes the connect_error listener, and marks the request as finalized. Invoke it from the timeout handler, onError, and the game:create/game:join acknowledgement callbacks; ignore any later acknowledgements, and ensure cancelled requests do not update errorMessage.apps/client/src/hooks/game/useJoinGame.ts (1)
13-27: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Validate the trimmed game ID.
Whitespace-only input passes the current check. The hook then emits an empty game ID.
Trim
gameIdbefore validation. Use the trimmed value for the socket event and navigation.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/client/src/hooks/game/useJoinGame.ts` around lines 13 - 27, Update the validation in the join-game hook to trim gameId before checking whether it is empty, so whitespace-only input is rejected. Reuse that trimmed value for the game:join socket emission and subsequent navigation instead of the untrimmed input.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/client/src/components/chessSidebar.tsx`:
- Line 11: The fixed sidebar container should not occupy 30rem on narrow
screens. Update the responsive classes on the sidebar element to hide it or make
it a dismissible mobile drawer while preserving the current desktop layout; use
the component’s existing state or controls if available to support dismissal.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 0647cac3-5d60-4ad2-9607-cf8682046d1f
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (12)
apps/client/src/components/Timer.tsxapps/client/src/components/chessSidebar.tsxapps/client/src/hooks/game/useChessGame.tsapps/client/src/hooks/game/useCompTimer.tsapps/client/src/hooks/game/useTimer.tsapps/client/src/pages/computerGame.tsxapps/server/src/game/game.tsapps/server/src/sockets/socket.tseslint.config.jspackages/shared/package.jsonpackages/shared/src/types.tspackages/shared/src/utils.ts
💤 Files with no reviewable changes (1)
- packages/shared/package.json
Note
Add time tracking to multiplayer and computer chess games
useTimerfor multiplayer games that syncs white/black countdowns from server-providedTimeInfo, updating every 250ms with accurate active-side decrement.useChessGamehook consolidating all multiplayer socket interactions (moves, sync, game-over, time) anduseComputerGamehook wiring Stockfish with per-side countdown viauseCompTimer.playerGame.tsxandcomputerGame.tsxto use these hooks, removing inline socket logic and addingTimerandSideBarcomponents.MoveMadeEvent,GameMoveAck,GameSync, newGameStartedEvent) and server socket emissions to includetimeInfoon all relevant events.hooks/auth/andhooks/game/subdirectories and adds a sharedgetGameOverInfoutility used by both client and server.Macroscope summarized 8ffa38f.
TimeInfoin game start, move, acknowledgement, and synchronization events.Timerto accept an optionaldisplayTimevalue.useAuthand updated related import paths.TimeInfoandGameStartedEventtypes.chess.jsas a runtime dependency of the shared package.