Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/components/Board/GameBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Chessground from '@react-chess/chessground'
import { BaseGame, GameNode, Color } from 'src/types'
import { MoveClassificationIcon } from 'src/components/Common/MoveIcons'
import type { DrawBrushes, DrawShape } from 'chessground/draw'
import { useCallback, useMemo, Dispatch, SetStateAction } from 'react'
import { useCallback, useEffect, useMemo, Dispatch, SetStateAction } from 'react'

interface MoveClassification {
blunder: boolean
Expand Down Expand Up @@ -71,6 +71,19 @@ export const GameBoard: React.FC<Props> = ({
const { playMoveSound } = useSound()
const boardInstanceKey = game?.id ?? 'board'

// After every position change, post-render layout shifts (stats panel,
// move list) can move the board without changing its size, leaving
// Chessground's cached bounds stale. Dispatching resize clears the cache
// so the next click re-measures from the correct DOM position.
// Chessground registers a permanent window.resize → bounds.clear() listener
// at init, so this is the correct low-impact way to invalidate it.
useEffect(() => {
const timeout = window.setTimeout(() => {
window.dispatchEvent(new Event('resize'))
}, 50)
return () => window.clearTimeout(timeout)
}, [currentNode])

const after = useCallback(
(from: string, to: string) => {
if (onPlayerMakeMove) onPlayerMakeMove([from, to])
Expand Down