Skip to content

Feature/chess game time - #6

Merged
MohamedSayed0573 merged 9 commits into
mainfrom
feature/chess-game-time
Aug 8, 2026
Merged

Feature/chess game time#6
MohamedSayed0573 merged 9 commits into
mainfrom
feature/chess-game-time

Conversation

@MohamedSayed0573

@MohamedSayed0573 MohamedSayed0573 commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Note

Add time tracking to multiplayer and computer chess games

  • Adds useTimer for multiplayer games that syncs white/black countdowns from server-provided TimeInfo, updating every 250ms with accurate active-side decrement.
  • Adds useChessGame hook consolidating all multiplayer socket interactions (moves, sync, game-over, time) and useComputerGame hook wiring Stockfish with per-side countdown via useCompTimer.
  • Refactors playerGame.tsx and computerGame.tsx to use these hooks, removing inline socket logic and adding Timer and SideBar components.
  • Extends shared event types (MoveMadeEvent, GameMoveAck, GameSync, new GameStartedEvent) and server socket emissions to include timeInfo on all relevant events.
  • Reorganizes hooks into hooks/auth/ and hooks/game/ subdirectories and adds a shared getGameOverInfo utility used by both client and server.

Macroscope summarized 8ffa38f.

  • Added ten-minute timers for multiplayer and computer chess games.
  • Added hooks for chess state, timers, game creation, and game joining.
  • Added optimistic move handling with server synchronization and rollback for rejected moves.
  • Added timeout handling and shared game-over detection.
  • Included TimeInfo in game start, move, acknowledgement, and synchronization events.
  • Refactored game pages to use shared hooks and board configuration.
  • Updated Timer to accept an optional displayTime value.
  • Centralized useAuth and updated related import paths.
  • Added shared TimeInfo and GameStartedEvent types.
  • Added chess.js as a runtime dependency of the shared package.
  • Kept the chess sidebar visible at all viewport sizes.

Copilot AI lite review requested due to automatic review settings August 8, 2026 19:15
@vercel

vercel Bot commented Aug 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
chesslab Ready Ready Preview Aug 8, 2026 9:30pm

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The 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)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies chess game time as the primary feature added by the pull request.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread apps/client/src/hooks/game/useCompTimer.ts
Comment thread apps/server/src/sockets/socket.ts

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 TimeInfo to shared types and propagate it through server socket events (game:game-started, game:move-made, game:sync).
  • Add shared getGameOverInfo helper and update the server Game logic 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-over payload shape is inconsistent: this handler emits a raw GameStateEvent, but other handlers in this file emit { GameStateEvent: ... }. The client subscribes expecting GameStateEvent directly, so timeout/abandonment events can break at runtime. Standardize the event payload across all game:game-over emits.
			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.

Comment thread apps/server/src/sockets/socket.ts Outdated
Comment thread apps/client/src/hooks/game/useChessGame.ts Outdated
Comment thread apps/client/src/hooks/game/useChessGame.ts Outdated
Comment thread apps/client/src/hooks/game/useCompTimer.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 win

Stockfish is reset on every render. The shared root cause is an unstable onMove callback identity wired into an effect dependency array. useComputerGame passes a new arrow function on every render, and useStockfish lists 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, because turn, chessGame, stockfishSide, and isGameOver are unchanged, so the search is never restarted. useCompTimer re-renders the tree every 250 ms, which is shorter than a go depth 15 search, so Stockfish stops producing moves. Fix both sites together.

  • apps/client/src/hooks/game/useStockfish.ts#L44-L55: store onMove in a ref, call onMoveRef.current() in the bestmove handler, and remove onMove from the dependency array on Line 48.
  • apps/client/src/hooks/game/useComputerGame.ts#L36-L41: wrap the onMove body in useCallback with [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

📥 Commits

Reviewing files that changed from the base of the PR and between c986e5b and e123ec0.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (28)
  • apps/client/src/components/Timer.tsx
  • apps/client/src/components/profile/deleteAccountBtn.tsx
  • apps/client/src/components/profile/logoutBtn.tsx
  • apps/client/src/hooks/auth/useAuth.ts
  • apps/client/src/hooks/auth/useAuthForm.ts
  • apps/client/src/hooks/game/useChessGame.ts
  • apps/client/src/hooks/game/useCompTimer.ts
  • apps/client/src/hooks/game/useComputerGame.ts
  • apps/client/src/hooks/game/useCreateGame.ts
  • apps/client/src/hooks/game/useJoinGame.ts
  • apps/client/src/hooks/game/useStockfish.ts
  • apps/client/src/hooks/game/useTimer.ts
  • apps/client/src/hooks/useApi.ts
  • apps/client/src/hooks/useFetchUser.ts
  • apps/client/src/hooks/useTimer.ts
  • apps/client/src/layouts/NotLoggedIn.tsx
  • apps/client/src/layouts/RequireAuth.tsx
  • apps/client/src/layouts/SocketProvider.tsx
  • apps/client/src/pages/computerGame.tsx
  • apps/client/src/pages/homePage.tsx
  • apps/client/src/pages/loginPage.tsx
  • apps/client/src/pages/playerGame.tsx
  • apps/client/src/pages/signupPage.tsx
  • apps/server/src/game/game.ts
  • apps/server/src/sockets/socket.ts
  • packages/shared/package.json
  • packages/shared/src/types.ts
  • packages/shared/src/utils.ts
💤 Files with no reviewable changes (1)
  • apps/client/src/hooks/useTimer.ts

Comment thread apps/client/src/components/Timer.tsx Outdated
Comment thread apps/client/src/hooks/game/useChessGame.ts Outdated
Comment thread apps/client/src/hooks/game/useChessGame.ts
Comment thread apps/client/src/hooks/game/useChessGame.ts Outdated
Comment thread apps/client/src/hooks/game/useChessGame.ts
Comment thread apps/client/src/pages/computerGame.tsx
Comment thread apps/server/src/game/game.ts Outdated
Comment thread apps/server/src/sockets/socket.ts Outdated
Comment thread packages/shared/package.json Outdated
Comment thread packages/shared/src/utils.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 win

Stockfish is reset on every render. The shared root cause is an unstable onMove callback identity wired into an effect dependency array. useComputerGame passes a new arrow function on every render, and useStockfish lists 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, because turn, chessGame, stockfishSide, and isGameOver are unchanged, so the search is never restarted. useCompTimer re-renders the tree every 250 ms, which is shorter than a go depth 15 search, so Stockfish stops producing moves. Fix both sites together.

  • apps/client/src/hooks/game/useStockfish.ts#L44-L55: store onMove in a ref, call onMoveRef.current() in the bestmove handler, and remove onMove from the dependency array on Line 48.
  • apps/client/src/hooks/game/useComputerGame.ts#L36-L41: wrap the onMove body in useCallback with [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

📥 Commits

Reviewing files that changed from the base of the PR and between c986e5b and e123ec0.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (28)
  • apps/client/src/components/Timer.tsx
  • apps/client/src/components/profile/deleteAccountBtn.tsx
  • apps/client/src/components/profile/logoutBtn.tsx
  • apps/client/src/hooks/auth/useAuth.ts
  • apps/client/src/hooks/auth/useAuthForm.ts
  • apps/client/src/hooks/game/useChessGame.ts
  • apps/client/src/hooks/game/useCompTimer.ts
  • apps/client/src/hooks/game/useComputerGame.ts
  • apps/client/src/hooks/game/useCreateGame.ts
  • apps/client/src/hooks/game/useJoinGame.ts
  • apps/client/src/hooks/game/useStockfish.ts
  • apps/client/src/hooks/game/useTimer.ts
  • apps/client/src/hooks/useApi.ts
  • apps/client/src/hooks/useFetchUser.ts
  • apps/client/src/hooks/useTimer.ts
  • apps/client/src/layouts/NotLoggedIn.tsx
  • apps/client/src/layouts/RequireAuth.tsx
  • apps/client/src/layouts/SocketProvider.tsx
  • apps/client/src/pages/computerGame.tsx
  • apps/client/src/pages/homePage.tsx
  • apps/client/src/pages/loginPage.tsx
  • apps/client/src/pages/playerGame.tsx
  • apps/client/src/pages/signupPage.tsx
  • apps/server/src/game/game.ts
  • apps/server/src/sockets/socket.ts
  • packages/shared/package.json
  • packages/shared/src/types.ts
  • packages/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.ts and apps/client/src/layouts/SocketProvider.tsx still define local useAuth implementations. 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.ts

Repository: MohamedSayed0573/ChessLab

Length of output: 3711


Finalize each socket request on every terminal path.

The timeout path keeps onError registered, and onError leaves game:create / game:join acknowledgements available until a reply arrives. If a late acknowledgement returns ok, these hooks navigate after showing an error. A cancelled request path should not update errorMessage.

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 in useCreateGame.ts and useJoinGame.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 gameId before 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.

Comment thread apps/client/src/hooks/game/useCompTimer.ts
Comment thread apps/client/src/hooks/game/useChessGame.ts
Comment thread apps/client/src/hooks/game/useChessGame.ts Outdated
Comment thread apps/client/src/components/chessSidebar.tsx
Comment thread apps/client/src/hooks/game/useTimer.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between e123ec0 and e48bb3c.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (12)
  • apps/client/src/components/Timer.tsx
  • apps/client/src/components/chessSidebar.tsx
  • apps/client/src/hooks/game/useChessGame.ts
  • apps/client/src/hooks/game/useCompTimer.ts
  • apps/client/src/hooks/game/useTimer.ts
  • apps/client/src/pages/computerGame.tsx
  • apps/server/src/game/game.ts
  • apps/server/src/sockets/socket.ts
  • eslint.config.js
  • packages/shared/package.json
  • packages/shared/src/types.ts
  • packages/shared/src/utils.ts
💤 Files with no reviewable changes (1)
  • packages/shared/package.json

Comment thread apps/client/src/components/chessSidebar.tsx
Comment thread apps/client/src/hooks/game/useChessGame.ts
@MohamedSayed0573
MohamedSayed0573 merged commit 7278907 into main Aug 8, 2026
4 checks passed
@MohamedSayed0573
MohamedSayed0573 deleted the feature/chess-game-time branch August 9, 2026 01:36
@MohamedSayed0573
MohamedSayed0573 restored the feature/chess-game-time branch August 9, 2026 01:36
@MohamedSayed0573
MohamedSayed0573 deleted the feature/chess-game-time branch August 9, 2026 01:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants