@@ -22,6 +22,7 @@ import {
2222 Tooltip ,
2323} from 'recharts'
2424import { ModalContainer , MovesContainer } from 'src/components'
25+ import { BoardController } from 'src/components/Board/BoardController'
2526import { DrillPerformanceData , MoveAnalysis } from 'src/types/openings'
2627import { MaiaRatingInsights } from './MaiaRatingInsights'
2728import { WindowSizeContext , TreeControllerContext } from 'src/contexts'
@@ -92,6 +93,7 @@ const AnimatedGameReplay: React.FC<{
9293} > = ( { openingFen, playerColor, gameTree, openingEndNode } ) => {
9394 const [ currentFen , setCurrentFen ] = useState ( openingFen )
9495 const [ currentNode , setCurrentNode ] = useState < GameNode | null > ( null )
96+ const [ orientation , setOrientation ] = useState < 'white' | 'black' > ( playerColor )
9597
9698 const treeController = useContext ( TreeControllerContext )
9799
@@ -109,6 +111,25 @@ const AnimatedGameReplay: React.FC<{
109111 }
110112 } , [ treeController . currentNode ] )
111113
114+ // Ensure we don't navigate before the opening end as the "root" for this view
115+ const goToPreviousNode = useCallback ( ( ) => {
116+ if ( ! treeController . currentNode ) return
117+ if ( treeController . currentNode . fen === openingEndNode . fen ) return
118+ if ( treeController . currentNode . parent ) {
119+ treeController . goToNode ( treeController . currentNode . parent )
120+ }
121+ } , [ treeController , openingEndNode . fen ] )
122+
123+ const goToNextNode = useCallback ( ( ) => {
124+ if ( ! treeController . currentNode ?. mainChild ) return
125+ treeController . goToNode ( treeController . currentNode . mainChild )
126+ } , [ treeController ] )
127+
128+ const goToRootNode = useCallback ( ( ) => {
129+ // Treat the opening end node as the root for this modal
130+ treeController . goToNode ( openingEndNode )
131+ } , [ treeController , openingEndNode ] )
132+
112133 // Get arrows for optimal moves from the current position
113134 const getArrowsForCurrentMove = useCallback ( ( ) : DrawShape [ ] => {
114135 if ( ! currentNode ) return [ ]
@@ -201,7 +222,7 @@ const AnimatedGameReplay: React.FC<{
201222 config = { {
202223 viewOnly : true ,
203224 fen : currentFen ,
204- orientation : playerColor ,
225+ orientation,
205226 coordinates : true ,
206227 animation : { enabled : true , duration : 200 } ,
207228 drawable : {
@@ -229,17 +250,31 @@ const AnimatedGameReplay: React.FC<{
229250 </ div >
230251 </ div >
231252
232- { /* Move History - Use MovesContainer for consistency */ }
233253 < div className = "flex min-h-0 flex-1 flex-col border-t border-white/10" >
234254 < MovesContainer
235255 game = { {
236256 id : 'drill-performance' ,
237257 tree : gameTree ,
238258 } }
239259 startFromNode = { openingEndNode }
260+ restrictNavigationBefore = { openingEndNode }
240261 showAnnotations = { true }
241262 showVariations = { false }
242263 />
264+ < BoardController
265+ orientation = { orientation }
266+ setOrientation = { setOrientation }
267+ currentNode = { currentNode }
268+ plyCount = { 0 }
269+ goToNode = { treeController . goToNode }
270+ goToNextNode = { goToNextNode }
271+ goToPreviousNode = { goToPreviousNode }
272+ goToRootNode = { goToRootNode }
273+ gameTree = { gameTree }
274+ disablePrevious = { currentNode ?. fen === openingEndNode . fen }
275+ disableKeyboardNavigation = { true }
276+ embedded
277+ />
243278 </ div >
244279 </ div >
245280 )
@@ -346,7 +381,7 @@ const CustomTooltip: React.FC<{
346381 }
347382
348383 return (
349- < div className = "rounded border border-white/10 from-white/10 to-white/5 bg-gradient-to-br p-3 backdrop-blur-md" >
384+ < div className = "rounded border border-white/10 bg-gradient-to-br from-white/10 to-white/5 p-3 backdrop-blur-md" >
350385 < p className = "text-sm font-medium text-primary" >
351386 { data . san ? `${ moveNotation } ${ data . san } ` : `${ moveNotation } ` }
352387 </ p >
0 commit comments