Skip to content

Commit b08c6b9

Browse files
feat: make move map moves clickable + improve opacity
1 parent 6501caf commit b08c6b9

6 files changed

Lines changed: 62 additions & 43 deletions

File tree

src/components/Analysis/MoveMap.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ interface Props {
3232
moveMap?: MoveMapEntry[]
3333
colorSanMapping: ColorSanMapping
3434
setHoverArrow: React.Dispatch<React.SetStateAction<DrawShape | null>>
35+
makeMove: (move: string) => void
3536
}
3637

3738
// Helper function to convert hex color to rgba with alpha
@@ -50,6 +51,7 @@ export const MoveMap: React.FC<Props> = ({
5051
moveMap,
5152
colorSanMapping,
5253
setHoverArrow,
54+
makeMove,
5355
}: Props) => {
5456
const { isMobile, width } = useContext(WindowSizeContext)
5557
const [hoveredMove, setHoveredMove] = useState<string | null>(null)
@@ -146,7 +148,6 @@ export const MoveMap: React.FC<Props> = ({
146148
setMousePosition(null)
147149
}
148150

149-
// Handle mouse leaving the entire component
150151
const onContainerMouseLeave = () => {
151152
onMouseLeave()
152153
}
@@ -262,7 +263,8 @@ export const MoveMap: React.FC<Props> = ({
262263
/>
263264
</YAxis>
264265
{moveMap?.map((entry, index) => {
265-
const opacity = entry.opacity ?? 1
266+
// Set minimum opacity to 0.5 to ensure visibility
267+
const opacity = Math.max(entry.opacity ?? 1, 0.5)
266268
const size = entry.size ?? (isMobile ? 8 : 10)
267269
const baseColor = colorSanMapping[entry.move]?.color ?? '#fff'
268270
const fillColor = baseColor.startsWith('#')
@@ -283,6 +285,7 @@ export const MoveMap: React.FC<Props> = ({
283285
onMouseEnter(entry.move, entry, event)
284286
}
285287
onMouseLeave={onMouseLeave}
288+
onMouseDown={() => makeMove(entry.move)}
286289
style={{ cursor: 'pointer' }}
287290
/>
288291
</Scatter>

src/components/Openings/OpeningDrillAnalysis.tsx

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ interface Props {
1717
analysisController: any // Analysis controller passed from parent
1818
hover: (move?: string) => void
1919
setHoverArrow: React.Dispatch<React.SetStateAction<DrawShape | null>>
20+
makeMove: (move: string) => void
2021
}
2122

2223
export const OpeningDrillAnalysis: React.FC<Props> = ({
@@ -29,6 +30,7 @@ export const OpeningDrillAnalysis: React.FC<Props> = ({
2930
analysisController,
3031
hover: parentHover,
3132
setHoverArrow: parentSetHoverArrow,
33+
makeMove: parentMakeMove,
3234
}) => {
3335
const toastId = useRef<string | null>(null)
3436

@@ -67,44 +69,9 @@ export const OpeningDrillAnalysis: React.FC<Props> = ({
6769

6870
const makeMove = useCallback(
6971
(move: string) => {
70-
if (!analysisEnabled || !currentNode || !gameTree) return
71-
72-
const chess = new Chess(currentNode.fen)
73-
const moveAttempt = chess.move({
74-
from: move.slice(0, 2),
75-
to: move.slice(2, 4),
76-
promotion: move[4] ? (move[4] as PieceSymbol) : undefined,
77-
})
78-
79-
if (moveAttempt) {
80-
const newFen = chess.fen()
81-
const moveString =
82-
moveAttempt.from +
83-
moveAttempt.to +
84-
(moveAttempt.promotion ? moveAttempt.promotion : '')
85-
const san = moveAttempt.san
86-
87-
// For opening drills, always update the main line instead of creating variations
88-
// If the move already exists as the main child, just navigate to it
89-
if (currentNode.mainChild?.move === moveString) {
90-
analysisController.goToNode(currentNode.mainChild)
91-
} else {
92-
// Remove any existing children first to replace the main line from this point forward
93-
currentNode.removeAllChildren()
94-
95-
// Create new main line continuation
96-
const newNode = gameTree.addMainMove(
97-
currentNode,
98-
newFen,
99-
moveString,
100-
san,
101-
analysisController.currentMaiaModel,
102-
)
103-
analysisController.goToNode(newNode)
104-
}
105-
}
72+
parentMakeMove(move)
10673
},
107-
[analysisEnabled, currentNode, gameTree, analysisController],
74+
[parentMakeMove],
10875
)
10976

11077
// No-op handlers for blurred analysis components when disabled
@@ -232,6 +199,7 @@ export const OpeningDrillAnalysis: React.FC<Props> = ({
232199
setHoverArrow={
233200
analysisEnabled ? parentSetHoverArrow : mockSetHoverArrow
234201
}
202+
makeMove={analysisEnabled ? makeMove : mockMakeMove}
235203
/>
236204
</div>
237205
<BlunderMeter
@@ -340,6 +308,7 @@ export const OpeningDrillAnalysis: React.FC<Props> = ({
340308
setHoverArrow={
341309
analysisEnabled ? parentSetHoverArrow : mockSetHoverArrow
342310
}
311+
makeMove={analysisEnabled ? makeMove : mockMakeMove}
343312
/>
344313
</div>
345314
{!analysisEnabled && (

src/pages/analysis/[...id].tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,7 @@ const Analysis: React.FC<Props> = ({
728728
moveMap={controller.moveMap}
729729
colorSanMapping={controller.colorSanMapping}
730730
setHoverArrow={setHoverArrow}
731+
makeMove={makeMove}
731732
/>
732733
</div>
733734
<BlunderMeter
@@ -781,6 +782,7 @@ const Analysis: React.FC<Props> = ({
781782
moveMap={controller.moveMap}
782783
colorSanMapping={controller.colorSanMapping}
783784
setHoverArrow={setHoverArrow}
785+
makeMove={makeMove}
784786
/>
785787
</div>
786788
</div>
@@ -943,6 +945,7 @@ const Analysis: React.FC<Props> = ({
943945
moveMap={controller.moveMap}
944946
colorSanMapping={controller.colorSanMapping}
945947
setHoverArrow={setHoverArrow}
948+
makeMove={makeMove}
946949
/>
947950
</div>
948951
<ConfigurableScreens

src/pages/analysis/index.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import { NextPage } from 'next'
22
import { useRouter } from 'next/router'
3-
import { useContext, useEffect, useState } from 'react'
4-
53
import { Loading } from 'src/components'
6-
import { AnalysisListContext } from 'src/contexts'
7-
import { useLocalStorage } from 'src/hooks'
84
import { getAnalysisGameList } from 'src/api'
5+
import { AnalysisListContext } from 'src/contexts'
6+
import { useContext, useEffect, useState } from 'react'
97

108
const AnalysisPage: NextPage = () => {
119
const { push } = useRouter()

src/pages/openings/index.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,48 @@ const OpeningsPage: NextPage = () => {
347347
// No special handling needed for opening drills
348348
}, [])
349349

350+
// Make move function for analysis components
351+
const makeMove = useCallback(
352+
async (move: string) => {
353+
if (
354+
!controller.analysisEnabled ||
355+
!analysisController.currentNode ||
356+
!analyzedGame?.tree
357+
)
358+
return
359+
360+
const chess = new Chess(analysisController.currentNode.fen)
361+
const moveAttempt = chess.move({
362+
from: move.slice(0, 2),
363+
to: move.slice(2, 4),
364+
promotion: move[4] ? (move[4] as PieceSymbol) : undefined,
365+
})
366+
367+
if (moveAttempt) {
368+
const newFen = chess.fen()
369+
const moveString =
370+
moveAttempt.from +
371+
moveAttempt.to +
372+
(moveAttempt.promotion ? moveAttempt.promotion : '')
373+
const san = moveAttempt.san
374+
375+
if (analysisController.currentNode.mainChild?.move === moveString) {
376+
analysisController.goToNode(analysisController.currentNode.mainChild)
377+
} else {
378+
const newVariation = analyzedGame.tree.addVariation(
379+
analysisController.currentNode,
380+
newFen,
381+
moveString,
382+
san,
383+
analysisController.currentMaiaModel,
384+
)
385+
analysisController.goToNode(newVariation)
386+
}
387+
}
388+
},
389+
[controller.analysisEnabled, analysisController, analyzedGame],
390+
)
391+
350392
// Show download modal if Maia model needs to be downloaded
351393
if (
352394
analysisController.maiaStatus === 'no-cache' ||
@@ -542,6 +584,7 @@ const OpeningsPage: NextPage = () => {
542584
analysisController={analysisController}
543585
hover={hover}
544586
setHoverArrow={setHoverArrow}
587+
makeMove={makeMove}
545588
/>
546589
</div>
547590
</div>

src/pages/train.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,7 @@ const Train: React.FC<Props> = ({
887887
setHoverArrow={
888888
showAnalysis ? setHoverArrow : mockSetHoverArrow
889889
}
890+
makeMove={showAnalysis ? makeMove : mockMakeMove}
890891
/>
891892
</div>
892893
<BlunderMeter
@@ -922,6 +923,7 @@ const Train: React.FC<Props> = ({
922923
setHoverArrow={
923924
showAnalysis ? setHoverArrow : mockSetHoverArrow
924925
}
926+
makeMove={showAnalysis ? makeMove : mockMakeMove}
925927
/>
926928
{!showAnalysis && (
927929
<div className="absolute inset-0 z-10 flex items-center justify-center overflow-hidden rounded bg-background-1/80 backdrop-blur-sm">
@@ -1178,6 +1180,7 @@ const Train: React.FC<Props> = ({
11781180
setHoverArrow={
11791181
showAnalysis ? setHoverArrow : mockSetHoverArrow
11801182
}
1183+
makeMove={showAnalysis ? makeMove : mockMakeMove}
11811184
/>
11821185
{!showAnalysis && (
11831186
<div className="absolute inset-0 z-10 flex items-center justify-center bg-background-1/80 backdrop-blur-sm">

0 commit comments

Comments
 (0)