Skip to content

Commit b04a879

Browse files
fix: moves container lag issues
1 parent c4cd054 commit b04a879

4 files changed

Lines changed: 67 additions & 103 deletions

File tree

src/components/Board/MovesContainer.tsx

Lines changed: 38 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,21 @@
11
/* eslint-disable jsx-a11y/no-static-element-interactions */
22
/* eslint-disable jsx-a11y/click-events-have-key-events */
3-
import { TuringGame } from 'src/types/turing'
4-
import React, { useContext, useMemo, Fragment, useEffect, useRef } from 'react'
3+
import { GameNode, Termination, BaseGame } from 'src/types'
54
import { TreeControllerContext, WindowSizeContext } from 'src/contexts'
6-
import { GameNode, AnalyzedGame, Termination, BaseGame } from 'src/types'
75
import { MoveClassificationIcon } from 'src/components/Common/MoveIcons'
6+
import React, { useContext, useMemo, Fragment, useEffect, useRef } from 'react'
87

9-
interface AnalysisProps {
10-
game: BaseGame | AnalyzedGame
11-
highlightIndices?: number[]
12-
termination?: Termination
13-
type: 'analysis'
14-
showAnnotations?: boolean
15-
showVariations?: boolean
16-
disableKeyboardNavigation?: boolean
17-
disableMoveClicking?: boolean
18-
}
19-
20-
interface TuringProps {
21-
game: TuringGame
22-
highlightIndices?: number[]
23-
termination?: Termination
24-
type: 'turing'
25-
showAnnotations?: boolean
26-
showVariations?: boolean
27-
disableKeyboardNavigation?: boolean
28-
disableMoveClicking?: boolean
29-
}
30-
31-
interface PlayProps {
8+
interface Props {
329
game: BaseGame
3310
highlightIndices?: number[]
3411
termination?: Termination
35-
type: 'play'
3612
showAnnotations?: boolean
3713
showVariations?: boolean
3814
disableKeyboardNavigation?: boolean
3915
disableMoveClicking?: boolean
4016
}
4117

42-
type Props = AnalysisProps | TuringProps | PlayProps
43-
44-
// Helper function to get move classification for display
45-
const getMoveClassification = (
46-
node: GameNode | null,
47-
currentMaiaModel?: string,
48-
) => {
18+
const getMoveClassification = (node: GameNode | null) => {
4919
if (!node) {
5020
return {
5121
blunder: false,
@@ -66,9 +36,8 @@ const getMoveClassification = (
6636
export const MovesContainer: React.FC<Props> = (props) => {
6737
const {
6838
game,
69-
highlightIndices,
7039
termination,
71-
type,
40+
highlightIndices,
7241
showAnnotations = true,
7342
showVariations = true,
7443
disableKeyboardNavigation = false,
@@ -78,42 +47,39 @@ export const MovesContainer: React.FC<Props> = (props) => {
7847
const containerRef = useRef<HTMLDivElement>(null)
7948
const currentMoveRef = useRef<HTMLDivElement>(null)
8049

81-
// Helper function to determine if move indicators should be shown
8250
const shouldShowIndicators = (node: GameNode | null) => {
8351
if (!node || !showAnnotations) return false
8452

85-
// Calculate ply from start: (moveNumber - 1) * 2 + (turn === 'b' ? 1 : 0)
8653
const moveNumber = node.moveNumber
8754
const turn = node.turn
8855
const plyFromStart = (moveNumber - 1) * 2 + (turn === 'b' ? 1 : 0)
8956

90-
// Only show indicators after the first 6 ply (moves 1, 2, and 3)
9157
return plyFromStart >= 6
9258
}
9359

94-
const baseController = useContext(TreeControllerContext)
60+
const controller = useContext(TreeControllerContext)
9561

9662
const mainLineNodes = useMemo(() => {
97-
return baseController.gameTree.getMainLine() ?? game.tree.getMainLine()
98-
}, [game, type, baseController.gameTree, baseController.currentNode])
63+
return controller.gameTree.getMainLine() ?? game.tree.getMainLine()
64+
}, [game, controller.gameTree, controller.currentNode])
9965

10066
useEffect(() => {
10167
if (disableKeyboardNavigation) return
10268

10369
const handleKeyDown = (event: KeyboardEvent) => {
104-
if (!baseController.currentNode) return
70+
if (!controller.currentNode) return
10571

10672
switch (event.key) {
10773
case 'ArrowRight':
10874
event.preventDefault()
109-
if (baseController.currentNode.mainChild) {
110-
baseController.goToNode(baseController.currentNode.mainChild)
75+
if (controller.currentNode.mainChild) {
76+
controller.goToNode(controller.currentNode.mainChild)
11177
}
11278
break
11379
case 'ArrowLeft':
11480
event.preventDefault()
115-
if (baseController.currentNode.parent) {
116-
baseController.goToNode(baseController.currentNode.parent)
81+
if (controller.currentNode.parent) {
82+
controller.goToNode(controller.currentNode.parent)
11783
}
11884
break
11985
default:
@@ -123,13 +89,8 @@ export const MovesContainer: React.FC<Props> = (props) => {
12389

12490
window.addEventListener('keydown', handleKeyDown)
12591
return () => window.removeEventListener('keydown', handleKeyDown)
126-
}, [
127-
baseController.currentNode,
128-
baseController.goToNode,
129-
disableKeyboardNavigation,
130-
])
92+
}, [controller.currentNode, controller.goToNode, disableKeyboardNavigation])
13193

132-
// Auto-scroll to current move
13394
useEffect(() => {
13495
if (currentMoveRef.current && containerRef.current) {
13596
currentMoveRef.current.scrollIntoView({
@@ -138,7 +99,7 @@ export const MovesContainer: React.FC<Props> = (props) => {
13899
inline: 'nearest',
139100
})
140101
}
141-
}, [baseController.currentNode])
102+
}, [controller.currentNode])
142103

143104
const moves = useMemo(() => {
144105
const nodes = mainLineNodes.slice(1)
@@ -159,7 +120,7 @@ export const MovesContainer: React.FC<Props> = (props) => {
159120
}
160121

161122
return rows
162-
}, [mainLineNodes])
123+
}, [game, mainLineNodes, controller.gameTree])
163124

164125
const highlightSet = useMemo(
165126
() => new Set(highlightIndices ?? []),
@@ -223,17 +184,17 @@ export const MovesContainer: React.FC<Props> = (props) => {
223184
{pair.whiteMove && (
224185
<div
225186
ref={
226-
baseController.currentNode === pair.whiteMove
187+
controller.currentNode === pair.whiteMove
227188
? currentMoveRef
228189
: null
229190
}
230191
onClick={() => {
231192
if (!disableMoveClicking) {
232-
baseController.goToNode(pair.whiteMove as GameNode)
193+
controller.goToNode(pair.whiteMove as GameNode)
233194
}
234195
}}
235196
className={`flex min-w-fit cursor-pointer flex-row items-center rounded px-2 py-1 text-sm ${
236-
baseController.currentNode === pair.whiteMove
197+
controller.currentNode === pair.whiteMove
237198
? 'bg-human-4/20'
238199
: 'hover:bg-background-2'
239200
} ${highlightSet.has(pairIndex * 2 + 1) ? 'bg-human-3/80' : ''}`}
@@ -253,7 +214,7 @@ export const MovesContainer: React.FC<Props> = (props) => {
253214
size="medium"
254215
onClick={() => {
255216
if (pair.whiteMove?.parent) {
256-
baseController.goToNode(pair.whiteMove.parent)
217+
controller.goToNode(pair.whiteMove.parent)
257218
}
258219
}}
259220
/>
@@ -263,17 +224,17 @@ export const MovesContainer: React.FC<Props> = (props) => {
263224
{pair.blackMove && (
264225
<div
265226
ref={
266-
baseController.currentNode === pair.blackMove
227+
controller.currentNode === pair.blackMove
267228
? currentMoveRef
268229
: null
269230
}
270231
onClick={() => {
271232
if (!disableMoveClicking) {
272-
baseController.goToNode(pair.blackMove as GameNode)
233+
controller.goToNode(pair.blackMove as GameNode)
273234
}
274235
}}
275236
className={`flex min-w-fit cursor-pointer flex-row items-center rounded px-2 py-1 text-sm ${
276-
baseController.currentNode === pair.blackMove
237+
controller.currentNode === pair.blackMove
277238
? 'bg-human-4/20'
278239
: 'hover:bg-background-2'
279240
} ${highlightSet.has(pairIndex * 2 + 2) ? 'bg-human-3/80' : ''}`}
@@ -293,7 +254,7 @@ export const MovesContainer: React.FC<Props> = (props) => {
293254
size="medium"
294255
onClick={() => {
295256
if (pair.blackMove?.parent) {
296-
baseController.goToNode(pair.blackMove.parent)
257+
controller.goToNode(pair.blackMove.parent)
297258
}
298259
}}
299260
/>
@@ -307,9 +268,7 @@ export const MovesContainer: React.FC<Props> = (props) => {
307268
className="min-w-fit cursor-pointer border border-primary/10 bg-background-1/90 px-4 py-1 text-sm opacity-90"
308269
onClick={() => {
309270
if (!disableMoveClicking) {
310-
baseController.goToNode(
311-
mainLineNodes[mainLineNodes.length - 1],
312-
)
271+
controller.goToNode(mainLineNodes[mainLineNodes.length - 1])
313272
}
314273
}}
315274
>
@@ -337,16 +296,14 @@ export const MovesContainer: React.FC<Props> = (props) => {
337296
{(whiteNode || blackNode)?.moveNumber}
338297
</span>
339298
<div
340-
ref={
341-
baseController.currentNode === whiteNode ? currentMoveRef : null
342-
}
299+
ref={controller.currentNode === whiteNode ? currentMoveRef : null}
343300
onClick={() => {
344301
if (whiteNode && !disableMoveClicking) {
345-
baseController.goToNode(whiteNode)
302+
controller.goToNode(whiteNode)
346303
}
347304
}}
348305
data-index={index * 2 + 1}
349-
className={`col-span-2 flex h-7 flex-1 cursor-pointer flex-row items-center justify-between px-2 text-sm hover:bg-background-2 ${baseController.currentNode === whiteNode && 'bg-human-4/10'} ${highlightSet.has(index * 2 + 1) && 'bg-human-3/80'}`}
306+
className={`col-span-2 flex h-7 flex-1 cursor-pointer flex-row items-center justify-between px-2 text-sm hover:bg-background-2 ${controller.currentNode === whiteNode && 'bg-human-4/10'} ${highlightSet.has(index * 2 + 1) && 'bg-human-3/80'}`}
350307
>
351308
<span
352309
style={{
@@ -363,7 +320,7 @@ export const MovesContainer: React.FC<Props> = (props) => {
363320
size="medium"
364321
onClick={() => {
365322
if (whiteNode?.parent) {
366-
baseController.goToNode(whiteNode.parent)
323+
controller.goToNode(whiteNode.parent)
367324
}
368325
}}
369326
/>
@@ -373,23 +330,21 @@ export const MovesContainer: React.FC<Props> = (props) => {
373330
<FirstVariation
374331
color="white"
375332
node={whiteNode}
376-
currentNode={baseController.currentNode}
377-
goToNode={baseController.goToNode}
333+
currentNode={controller.currentNode}
334+
goToNode={controller.goToNode}
378335
showAnnotations={showAnnotations}
379336
disableMoveClicking={disableMoveClicking}
380337
/>
381338
) : null}
382339
<div
383-
ref={
384-
baseController.currentNode === blackNode ? currentMoveRef : null
385-
}
340+
ref={controller.currentNode === blackNode ? currentMoveRef : null}
386341
onClick={() => {
387342
if (blackNode && !disableMoveClicking) {
388-
baseController.goToNode(blackNode)
343+
controller.goToNode(blackNode)
389344
}
390345
}}
391346
data-index={index * 2 + 2}
392-
className={`col-span-2 flex h-7 flex-1 cursor-pointer flex-row items-center justify-between px-2 text-sm hover:bg-background-2 ${baseController.currentNode === blackNode && 'bg-human-4/10'} ${highlightSet.has(index * 2 + 2) && 'bg-human-3/80'}`}
347+
className={`col-span-2 flex h-7 flex-1 cursor-pointer flex-row items-center justify-between px-2 text-sm hover:bg-background-2 ${controller.currentNode === blackNode && 'bg-human-4/10'} ${highlightSet.has(index * 2 + 2) && 'bg-human-3/80'}`}
393348
>
394349
<span
395350
style={{
@@ -406,7 +361,7 @@ export const MovesContainer: React.FC<Props> = (props) => {
406361
size="medium"
407362
onClick={() => {
408363
if (blackNode?.parent) {
409-
baseController.goToNode(blackNode.parent)
364+
controller.goToNode(blackNode.parent)
410365
}
411366
}}
412367
/>
@@ -416,8 +371,8 @@ export const MovesContainer: React.FC<Props> = (props) => {
416371
<FirstVariation
417372
color="black"
418373
node={blackNode}
419-
currentNode={baseController.currentNode}
420-
goToNode={baseController.goToNode}
374+
currentNode={controller.currentNode}
375+
goToNode={controller.goToNode}
421376
showAnnotations={showAnnotations}
422377
disableMoveClicking={disableMoveClicking}
423378
/>
@@ -430,7 +385,7 @@ export const MovesContainer: React.FC<Props> = (props) => {
430385
className="col-span-5 cursor-pointer rounded-sm border border-primary/10 bg-background-1/90 p-5 text-center opacity-90"
431386
onClick={() => {
432387
if (!disableMoveClicking) {
433-
baseController.goToNode(mainLineNodes[mainLineNodes.length - 1])
388+
controller.goToNode(mainLineNodes[mainLineNodes.length - 1])
434389
}
435390
}}
436391
>
@@ -500,7 +455,6 @@ function VariationTree({
500455
}) {
501456
const variations = node.getVariations()
502457

503-
// Helper function to determine if move indicators should be shown in variations
504458
const shouldShowVariationIndicators = (node: GameNode) => {
505459
if (!showAnnotations) return false
506460
const moveNumber = node.moveNumber
@@ -588,7 +542,6 @@ function InlineChain({
588542
const chain: GameNode[] = []
589543
let current = node
590544

591-
// Helper function to determine if move indicators should be shown in inline chains
592545
const shouldShowInlineIndicators = (node: GameNode) => {
593546
if (!showAnnotations) return false
594547
const moveNumber = node.moveNumber

0 commit comments

Comments
 (0)