Skip to content

Commit 4e966f9

Browse files
feat: refactor OpeningDrillAnalysis to use parent hover functions and improve hover handling; update styles in OpeningDrillSidebar and OpeningSelectionModal for better layout
1 parent 70c1d7a commit 4e966f9

4 files changed

Lines changed: 79 additions & 42 deletions

File tree

src/components/Openings/OpeningDrillAnalysis.tsx

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ interface Props {
1515
playerColor: 'white' | 'black'
1616
maiaVersion: string
1717
analysisController: any // Analysis controller passed from parent
18+
hover: (move?: string) => void
19+
setHoverArrow: React.Dispatch<React.SetStateAction<DrawShape | null>>
1820
}
1921

2022
export const OpeningDrillAnalysis: React.FC<Props> = ({
@@ -25,8 +27,9 @@ export const OpeningDrillAnalysis: React.FC<Props> = ({
2527
playerColor,
2628
maiaVersion,
2729
analysisController,
30+
hover: parentHover,
31+
setHoverArrow: parentSetHoverArrow,
2832
}) => {
29-
const [hoverArrow, setHoverArrow] = useState<DrawShape | null>(null)
3033
const toastId = useRef<string | null>(null)
3134

3235
// Toast notifications for Maia model status
@@ -54,17 +57,12 @@ export const OpeningDrillAnalysis: React.FC<Props> = ({
5457
const hover = useCallback(
5558
(move?: string) => {
5659
if (move && analysisEnabled) {
57-
setHoverArrow({
58-
orig: move.slice(0, 2) as Key,
59-
dest: move.slice(2, 4) as Key,
60-
brush: 'green',
61-
modifiers: { lineWidth: 10 },
62-
})
60+
parentHover(move)
6361
} else {
64-
setHoverArrow(null)
62+
parentHover()
6563
}
6664
},
67-
[analysisEnabled],
65+
[analysisEnabled, parentHover],
6866
)
6967

7068
const makeMove = useCallback(
@@ -86,27 +84,23 @@ export const OpeningDrillAnalysis: React.FC<Props> = ({
8684
(moveAttempt.promotion ? moveAttempt.promotion : '')
8785
const san = moveAttempt.san
8886

89-
// Check if this move already exists as a child
90-
const existingChild = currentNode.children.find(
91-
(child: any) => child.move === moveString,
92-
)
93-
94-
if (existingChild) {
95-
// Move already exists, just navigate to it
96-
analysisController.goToNode(existingChild)
97-
} else if (currentNode.mainChild?.move === moveString) {
98-
// This is the main child move
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) {
9990
analysisController.goToNode(currentNode.mainChild)
10091
} else {
101-
// Create new variation
102-
const newVariation = gameTree.addVariation(
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(
10397
currentNode,
10498
newFen,
10599
moveString,
106100
san,
107101
analysisController.currentMaiaModel,
108102
)
109-
analysisController.goToNode(newVariation)
103+
analysisController.goToNode(newNode)
110104
}
111105
}
112106
},
@@ -225,7 +219,7 @@ export const OpeningDrillAnalysis: React.FC<Props> = ({
225219
analysisEnabled ? analysisController.colorSanMapping : {}
226220
}
227221
setHoverArrow={
228-
analysisEnabled ? setHoverArrow : mockSetHoverArrow
222+
analysisEnabled ? parentSetHoverArrow : mockSetHoverArrow
229223
}
230224
/>
231225
</div>

src/components/Openings/OpeningDrillSidebar.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export const OpeningDrillSidebar: React.FC<Props> = ({
6060
return (
6161
<div className="flex h-[85vh] w-72 min-w-60 max-w-72 flex-col gap-2 overflow-hidden 2xl:min-w-72">
6262
<GameInfo title="Drill Openings" icon="school" type="analysis">
63-
<div className="space-y-2">
63+
<div className="flex flex-col gap-2">
6464
<div className="min-h-[30px]">
6565
<p className="text-sm text-secondary">
6666
Current Opening:{' '}
@@ -143,13 +143,13 @@ export const OpeningDrillSidebar: React.FC<Props> = ({
143143
<div className="flex items-center gap-1 text-xs text-secondary">
144144
{selection.variation && (
145145
<>
146-
<span className="truncate">
146+
<span className="truncate whitespace-nowrap">
147147
{selection.variation.name}
148148
</span>
149149
<span></span>
150150
</>
151151
)}
152-
<span>
152+
<span className="whitespace-nowrap">
153153
v. Maia {selection.maiaVersion.replace('maia_kdd_', '')}
154154
</span>
155155
</div>

src/components/Openings/OpeningSelectionModal.tsx

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,9 @@ export const OpeningSelectionModal: React.FC<Props> = ({
117117
return (
118118
<ModalContainer dismiss={onClose}>
119119
<motion.div
120-
initial={{ opacity: 0, scale: 0.95 }}
121-
animate={{ opacity: 1, scale: 1 }}
122-
exit={{ opacity: 0, scale: 0.95 }}
120+
initial={{ opacity: 0 }}
121+
animate={{ opacity: 1 }}
122+
exit={{ opacity: 0 }}
123123
className="relative flex h-[90vh] max-h-[800px] w-[98vw] max-w-[1400px] rounded-lg bg-background-1 shadow-2xl"
124124
>
125125
{/* Close Button - Top Right of Modal */}
@@ -156,15 +156,15 @@ export const OpeningSelectionModal: React.FC<Props> = ({
156156
</div>
157157

158158
<div
159-
className="flex-1 overflow-y-auto p-4"
159+
className="red-scrollbar flex flex-1 flex-col gap-1 overflow-y-auto p-4"
160160
style={{ userSelect: 'none' }}
161161
>
162162
{filteredOpenings.map((opening) => (
163-
<div key={opening.id} className="mb-4">
163+
<div key={opening.id} className="flex flex-col">
164164
<div
165165
role="button"
166166
tabIndex={0}
167-
className={`cursor-pointer rounded p-3 transition-colors ${
167+
className={`mb-2 cursor-pointer rounded p-3 transition-colors ${
168168
previewOpening.id === opening.id && !previewVariation
169169
? 'bg-human-2/20'
170170
: 'hover:bg-human-2/10'
@@ -192,7 +192,6 @@ export const OpeningSelectionModal: React.FC<Props> = ({
192192
</div>
193193
</div>
194194
</div>
195-
196195
{opening.variations.map((variation) => (
197196
<div
198197
key={variation.id}
@@ -252,7 +251,7 @@ export const OpeningSelectionModal: React.FC<Props> = ({
252251
</div>
253252

254253
{/* Selection Controls */}
255-
<div className="space-y-4 border-t border-white/10 p-4">
254+
<div className="flex flex-col gap-4 border-t border-white/10 p-4">
256255
{/* Color Selection */}
257256
<div>
258257
<p className="mb-2 text-sm font-medium">Play as:</p>
@@ -290,8 +289,10 @@ export const OpeningSelectionModal: React.FC<Props> = ({
290289
onChange={(e) => {
291290
const version = MAIA_VERSIONS.find(
292291
(v) => v.id === e.target.value,
293-
)!
294-
setSelectedMaiaVersion(version)
292+
)
293+
if (version) {
294+
setSelectedMaiaVersion(version)
295+
}
295296
}}
296297
className="w-full rounded bg-background-2 p-2 text-sm focus:outline-none"
297298
>
@@ -330,7 +331,7 @@ export const OpeningSelectionModal: React.FC<Props> = ({
330331
drilling.
331332
</p>
332333
) : (
333-
<div className="space-y-3">
334+
<div className="flex flex-col">
334335
{selections.map((selection) => (
335336
<div
336337
key={selection.id}
@@ -384,11 +385,11 @@ export const OpeningSelectionModal: React.FC<Props> = ({
384385
)}
385386
</div>
386387

387-
<div className="border-t border-white/10 p-4">
388+
<div className="p-4">
388389
<button
389390
onClick={handleStartDrilling}
390391
disabled={selections.length === 0}
391-
className="w-full rounded bg-human-4 py-3 font-medium transition-colors hover:bg-human-4/80 disabled:cursor-not-allowed disabled:opacity-50"
392+
className="w-full rounded bg-human-4 py-2 text-sm font-medium transition-colors hover:bg-human-4/80 disabled:cursor-not-allowed disabled:opacity-50"
392393
>
393394
Start Drilling ({selections.length} opening
394395
{selections.length !== 1 ? 's' : ''})

src/pages/openings/index.tsx

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
BoardController,
1919
PromotionOverlay,
2020
PlayerInfo,
21+
DownloadModelModal,
2122
} from 'src/components'
2223
import {
2324
useOpeningDrillController,
@@ -187,12 +188,26 @@ const OpeningsPage: NextPage = () => {
187188
setHoverArrow(null)
188189
}, [controller.currentNode])
189190

190-
// Show selection modal when no selections are made
191+
// Hover function for analysis components
192+
const hover = useCallback((move?: string) => {
193+
if (move) {
194+
setHoverArrow({
195+
orig: move.slice(0, 2) as Key,
196+
dest: move.slice(2, 4) as Key,
197+
brush: 'green',
198+
modifiers: { lineWidth: 10 },
199+
})
200+
} else {
201+
setHoverArrow(null)
202+
}
203+
}, [])
204+
205+
// Show selection modal when no selections are made and Maia model is ready
191206
useEffect(() => {
192-
if (selections.length === 0) {
207+
if (selections.length === 0 && analysisController.maiaStatus === 'ready') {
193208
setShowSelectionModal(true)
194209
}
195-
}, [selections.length])
210+
}, [selections.length, analysisController.maiaStatus])
196211

197212
const handleCompleteSelection = useCallback(
198213
(newSelections: OpeningSelection[]) => {
@@ -313,6 +328,31 @@ const OpeningsPage: NextPage = () => {
313328
}
314329
}, [controller.currentSelection, controller.orientation])
315330

331+
// Show download modal if Maia model needs to be downloaded
332+
if (
333+
analysisController.maiaStatus === 'no-cache' ||
334+
analysisController.maiaStatus === 'downloading'
335+
) {
336+
return (
337+
<>
338+
<Head>
339+
<title>Opening Drills – Maia Chess</title>
340+
<meta
341+
name="description"
342+
content="Practice chess openings against Maia"
343+
/>
344+
</Head>
345+
<AnimatePresence>
346+
<DownloadModelModal
347+
progress={analysisController.maiaProgress}
348+
download={analysisController.downloadMaia}
349+
/>
350+
</AnimatePresence>
351+
</>
352+
)
353+
}
354+
355+
// Show selection modal when no selections are made (after model is ready)
316356
if (selections.length === 0 || showSelectionModal) {
317357
return (
318358
<>
@@ -417,6 +457,8 @@ const OpeningsPage: NextPage = () => {
417457
controller.currentSelection?.maiaVersion || 'maia_kdd_1500'
418458
}
419459
analysisController={analysisController}
460+
hover={hover}
461+
setHoverArrow={setHoverArrow}
420462
/>
421463
</div>
422464
</div>

0 commit comments

Comments
 (0)