@@ -483,11 +483,32 @@ const Analysis: React.FC<Props> = ({
483483 const [ showAnalysisConfigModal , setShowAnalysisConfigModal ] = useState ( false )
484484 const [ refreshTrigger , setRefreshTrigger ] = useState ( 0 )
485485 const [ analysisEnabled , setAnalysisEnabled ] = useState ( true )
486+ const [
487+ desktopMoveListScrollResetSignal ,
488+ setDesktopMoveListScrollResetSignal ,
489+ ] = useState ( 0 )
486490 const [ lastMoveResult , setLastMoveResult ] = useState <
487491 'correct' | 'incorrect' | 'not-learning'
488492 > ( 'not-learning' )
489493
490494 const controller = useAnalysisController ( analyzedGame )
495+ const userGamePovOrientation = useMemo ( ( ) => {
496+ if ( ! [ 'play' , 'hand' , 'brain' ] . includes ( analyzedGame . type ) ) {
497+ return null
498+ }
499+
500+ const whiteName = analyzedGame . whitePlayer . name . toLowerCase ( )
501+ const blackName = analyzedGame . blackPlayer . name . toLowerCase ( )
502+
503+ if ( whiteName . includes ( 'maia' ) ) return 'black'
504+ if ( blackName . includes ( 'maia' ) ) return 'white'
505+
506+ return null
507+ } , [
508+ analyzedGame . blackPlayer . name ,
509+ analyzedGame . type ,
510+ analyzedGame . whitePlayer . name ,
511+ ] )
491512 const destinationBadges = useMemo ( ( ) => {
492513 if (
493514 ! analysisEnabled ||
@@ -522,6 +543,11 @@ const Analysis: React.FC<Props> = ({
522543 }
523544 } , [ analyzedGame ] )
524545
546+ useEffect ( ( ) => {
547+ if ( ! userGamePovOrientation ) return
548+ controller . setOrientation ( userGamePovOrientation )
549+ } , [ analyzedGame . tree , controller . setOrientation , userGamePovOrientation ] )
550+
525551 useEffect ( ( ) => {
526552 setHoverArrow ( null )
527553 } , [ controller . currentNode ] )
@@ -1194,6 +1220,12 @@ const Analysis: React.FC<Props> = ({
11941220 const [ desktopLeftPanelTab , setDesktopLeftPanelTab ] = useState <
11951221 ( typeof desktopLeftPanelTabs ) [ number ] [ 'id' ]
11961222 > ( desktopLeftPanelTabs [ 0 ] . id )
1223+ const showDesktopMovesAfterNavigation = useCallback ( ( ) => {
1224+ if ( desktopLeftPanelTab !== 'select-game' ) return
1225+
1226+ setDesktopLeftPanelTab ( 'moves' )
1227+ setDesktopMoveListScrollResetSignal ( ( prev ) => prev + 1 )
1228+ } , [ desktopLeftPanelTab ] )
11971229
11981230 useEffect ( ( ) => {
11991231 if ( useMobileStyleAnalysisLayout || desktopLeftPanelTab !== 'select-game' ) {
@@ -1222,15 +1254,15 @@ const Analysis: React.FC<Props> = ({
12221254 event . preventDefault ( )
12231255 event . stopPropagation ( )
12241256 controller . goToPreviousNode ( )
1225- setDesktopLeftPanelTab ( 'moves' )
1257+ showDesktopMovesAfterNavigation ( )
12261258 return
12271259 }
12281260
12291261 if ( event . key === 'ArrowRight' && controller . currentNode ?. mainChild ) {
12301262 event . preventDefault ( )
12311263 event . stopPropagation ( )
12321264 controller . goToNextNode ( )
1233- setDesktopLeftPanelTab ( 'moves' )
1265+ showDesktopMovesAfterNavigation ( )
12341266 }
12351267 }
12361268
@@ -1244,6 +1276,7 @@ const Analysis: React.FC<Props> = ({
12441276 controller . goToPreviousNode ,
12451277 controller . learnFromMistakes . state . isActive ,
12461278 desktopLeftPanelTab ,
1279+ showDesktopMovesAfterNavigation ,
12471280 useMobileStyleAnalysisLayout ,
12481281 ] )
12491282
@@ -1457,74 +1490,75 @@ const Analysis: React.FC<Props> = ({
14571490 )
14581491 } ) }
14591492 </ div >
1460- < div className = "relative flex min-h-0 flex-1 overflow-hidden" >
1461- < div
1462- aria-hidden = { desktopLeftPanelTab !== 'moves' }
1463- className = { `red-scrollbar absolute inset-0 flex h-full flex-col overflow-y-auto transition-opacity duration-150 ${
1464- desktopLeftPanelTab === 'moves'
1465- ? 'visible opacity-100'
1466- : 'pointer-events-none invisible opacity-0'
1467- } `}
1468- >
1469- < MovesContainer
1470- game = { analyzedGame }
1471- termination = { analyzedGame . termination }
1472- showAnnotations = { true }
1473- disableKeyboardNavigation = {
1474- controller . gameAnalysis . progress . isAnalyzing ||
1475- controller . learnFromMistakes . state . isActive
1476- }
1477- disableMoveClicking = {
1478- controller . learnFromMistakes . state . isActive
1479- }
1480- embedded
1481- heightClass = "h-40"
1482- />
1483- { /* No spacer here to keep controller tight to moves */ }
1484- < BoardController
1485- gameTree = { controller . gameTree }
1486- orientation = { controller . orientation }
1487- setOrientation = { controller . setOrientation }
1488- currentNode = { controller . currentNode }
1489- plyCount = { controller . plyCount }
1490- goToNode = { controller . goToNode }
1491- goToNextNode = { controller . goToNextNode }
1492- goToPreviousNode = { controller . goToPreviousNode }
1493- goToRootNode = { controller . goToRootNode }
1494- disableKeyboardNavigation = {
1495- controller . gameAnalysis . progress . isAnalyzing ||
1496- controller . learnFromMistakes . state . isActive
1497- }
1498- disableNavigation = {
1499- controller . learnFromMistakes . state . isActive
1500- }
1501- embedded
1502- />
1503- </ div >
1504- < div
1505- aria-hidden = { desktopLeftPanelTab !== 'select-game' }
1506- className = { `absolute inset-0 flex min-h-0 flex-col transition-opacity duration-150 ${
1507- desktopLeftPanelTab === 'select-game'
1508- ? 'visible opacity-100'
1509- : 'pointer-events-none invisible opacity-0'
1510- } `}
1511- >
1512- < AnalysisGameList
1513- currentId = { currentId }
1514- loadNewWorldChampionshipGame = { ( newId , setCurrentMove ) =>
1515- getAndSetTournamentGame ( newId , setCurrentMove )
1516- }
1517- loadNewLichessGame = { ( id , pgn , setCurrentMove ) =>
1518- getAndSetLichessGame ( id , pgn , setCurrentMove )
1519- }
1520- loadNewMaiaGame = { ( id , type , setCurrentMove ) =>
1521- getAndSetUserGame ( id , type , setCurrentMove )
1522- }
1523- onCustomAnalysis = { ( ) => setShowCustomModal ( true ) }
1524- refreshTrigger = { refreshTrigger }
1525- embedded
1526- />
1493+ < div className = "flex min-h-0 flex-1 flex-col overflow-hidden" >
1494+ < div className = "relative min-h-0 flex-1 overflow-hidden" >
1495+ < div
1496+ aria-hidden = { desktopLeftPanelTab !== 'moves' }
1497+ className = { `absolute inset-0 flex h-full flex-col transition-opacity duration-150 ${
1498+ desktopLeftPanelTab === 'moves'
1499+ ? 'visible opacity-100'
1500+ : 'pointer-events-none invisible opacity-0'
1501+ } `}
1502+ >
1503+ < MovesContainer
1504+ game = { analyzedGame }
1505+ termination = { analyzedGame . termination }
1506+ showAnnotations = { true }
1507+ disableKeyboardNavigation = {
1508+ controller . gameAnalysis . progress . isAnalyzing ||
1509+ controller . learnFromMistakes . state . isActive
1510+ }
1511+ disableMoveClicking = {
1512+ controller . learnFromMistakes . state . isActive
1513+ }
1514+ scrollToTopSignal = { desktopMoveListScrollResetSignal }
1515+ embedded
1516+ heightClass = "h-40"
1517+ />
1518+ </ div >
1519+ < div
1520+ aria-hidden = { desktopLeftPanelTab !== 'select-game' }
1521+ className = { `absolute inset-0 flex min-h-0 flex-col transition-opacity duration-150 ${
1522+ desktopLeftPanelTab === 'select-game'
1523+ ? 'visible opacity-100'
1524+ : 'pointer-events-none invisible opacity-0'
1525+ } `}
1526+ >
1527+ < AnalysisGameList
1528+ currentId = { currentId }
1529+ loadNewWorldChampionshipGame = { ( newId , setCurrentMove ) =>
1530+ getAndSetTournamentGame ( newId , setCurrentMove )
1531+ }
1532+ loadNewLichessGame = { ( id , pgn , setCurrentMove ) =>
1533+ getAndSetLichessGame ( id , pgn , setCurrentMove )
1534+ }
1535+ loadNewMaiaGame = { ( id , type , setCurrentMove ) =>
1536+ getAndSetUserGame ( id , type , setCurrentMove )
1537+ }
1538+ onCustomAnalysis = { ( ) => setShowCustomModal ( true ) }
1539+ refreshTrigger = { refreshTrigger }
1540+ embedded
1541+ />
1542+ </ div >
15271543 </ div >
1544+ < BoardController
1545+ gameTree = { controller . gameTree }
1546+ orientation = { controller . orientation }
1547+ setOrientation = { controller . setOrientation }
1548+ currentNode = { controller . currentNode }
1549+ plyCount = { controller . plyCount }
1550+ goToNode = { controller . goToNode }
1551+ goToNextNode = { controller . goToNextNode }
1552+ goToPreviousNode = { controller . goToPreviousNode }
1553+ goToRootNode = { controller . goToRootNode }
1554+ disableKeyboardNavigation = {
1555+ controller . gameAnalysis . progress . isAnalyzing ||
1556+ controller . learnFromMistakes . state . isActive
1557+ }
1558+ disableNavigation = { controller . learnFromMistakes . state . isActive }
1559+ onNavigate = { showDesktopMovesAfterNavigation }
1560+ embedded
1561+ />
15281562 </ div >
15291563 </ div >
15301564 </ motion . div >
0 commit comments