diff --git a/src/components/prettyMoveSan/index.tsx b/src/components/prettyMoveSan/index.tsx index 7c011d0..954f696 100644 --- a/src/components/prettyMoveSan/index.tsx +++ b/src/components/prettyMoveSan/index.tsx @@ -54,7 +54,7 @@ export default function PrettyMoveSan({ )} - + {text} {additionalText} diff --git a/src/pages/index.tsx b/src/pages/index.tsx index a929c8f..5065dcf 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -36,6 +36,7 @@ export default function GameAnalysis() { const { reset: resetGame } = useChessActions(gameAtom); const [gameEval, setGameEval] = useAtom(gameEvalAtom); const game = useAtomValue(gameAtom); + const board = useAtomValue(boardAtom); const setBoardOrientation = useSetAtom(boardOrientationAtom); const router = useRouter(); @@ -50,12 +51,12 @@ export default function GameAnalysis() { } }, [gameId, setGameEval, setBoardOrientation, resetBoard, resetGame]); - const isGameLoaded = game.history().length > 0; + const showMovesTab = game.history().length > 0 || board.history().length > 0; useEffect(() => { - if (tab === 1 && !isGameLoaded) setTab(0); + if (tab === 1 && !showMovesTab) setTab(0); if (tab === 2 && !gameEval) setTab(0); - }, [isGameLoaded, gameEval, tab]); + }, [showMovesTab, gameEval, tab]); return ( @@ -65,7 +66,7 @@ export default function GameAnalysis() { {isLgOrGreater ? ( - + + + + ) : ( )} - {isLgOrGreater && } - {!isLgOrGreater && !gameEval && } {!isLgOrGreater && !gameEval && ( @@ -108,6 +107,7 @@ export default function GameAnalysis() { {!isLgOrGreater && ( - {isGameLoaded && ( - diff --git a/src/sections/analysis/board/index.tsx b/src/sections/analysis/board/index.tsx index 7f8d3ce..6cc9048 100644 --- a/src/sections/analysis/board/index.tsx +++ b/src/sections/analysis/board/index.tsx @@ -25,7 +25,7 @@ export default function BoardContainer() { // 1200 is the lg layout breakpoint if (window?.innerWidth < 1200) { - return Math.min(width, height - 150); + return Math.min(width - 15, height - 150); } return Math.min(width - 700, height * 0.92); diff --git a/src/sections/analysis/panelBody/analysisTab/engineLines/index.tsx b/src/sections/analysis/panelBody/analysisTab/engineLines/index.tsx new file mode 100644 index 0000000..f554afb --- /dev/null +++ b/src/sections/analysis/panelBody/analysisTab/engineLines/index.tsx @@ -0,0 +1,35 @@ +import { Grid2 as Grid, Grid2Props as GridProps, List } from "@mui/material"; +import LineEvaluation from "./lineEvaluation"; +import { + boardAtom, + currentPositionAtom, + engineMultiPvAtom, +} from "../../../states"; +import { useAtomValue } from "jotai"; +import { LineEval } from "@/types/eval"; + +export default function EngineLines(props: GridProps) { + const board = useAtomValue(boardAtom); + const linesNumber = useAtomValue(engineMultiPvAtom); + const position = useAtomValue(currentPositionAtom); + + const linesSkeleton: LineEval[] = Array.from({ length: linesNumber }).map( + (_, i) => ({ pv: [`${i}`], depth: 0, multiPv: i + 1 }) + ); + + const engineLines = position?.eval?.lines?.length + ? position.eval.lines + : linesSkeleton; + + if (board.isCheckmate()) return null; + + return ( + + + {engineLines.map((line) => ( + + ))} + + + ); +} diff --git a/src/sections/analysis/panelBody/analysisTab/lineEvaluation.tsx b/src/sections/analysis/panelBody/analysisTab/engineLines/lineEvaluation.tsx similarity index 98% rename from src/sections/analysis/panelBody/analysisTab/lineEvaluation.tsx rename to src/sections/analysis/panelBody/analysisTab/engineLines/lineEvaluation.tsx index 522131d..e503f23 100644 --- a/src/sections/analysis/panelBody/analysisTab/lineEvaluation.tsx +++ b/src/sections/analysis/panelBody/analysisTab/engineLines/lineEvaluation.tsx @@ -1,7 +1,7 @@ import { LineEval } from "@/types/eval"; import { ListItem, Skeleton, Typography } from "@mui/material"; import { useAtomValue } from "jotai"; -import { boardAtom } from "../../states"; +import { boardAtom } from "../../../states"; import { getLineEvalLabel, moveLineUciToSan } from "@/lib/chess"; import { useChessActions } from "@/hooks/useChessActions"; import PrettyMoveSan from "@/components/prettyMoveSan"; diff --git a/src/sections/analysis/panelBody/analysisTab/index.tsx b/src/sections/analysis/panelBody/analysisTab/index.tsx index cf4cdba..f44fe00 100644 --- a/src/sections/analysis/panelBody/analysisTab/index.tsx +++ b/src/sections/analysis/panelBody/analysisTab/index.tsx @@ -1,74 +1,76 @@ -import { Grid2 as Grid, Grid2Props as GridProps, List } from "@mui/material"; -import { useAtomValue } from "jotai"; import { - boardAtom, - currentPositionAtom, - engineMultiPvAtom, - gameEvalAtom, -} from "../../states"; -import LineEvaluation from "./lineEvaluation"; -import { LineEval } from "@/types/eval"; + Grid2 as Grid, + Grid2Props as GridProps, + Stack, + Typography, +} from "@mui/material"; +import { useAtomValue } from "jotai"; +import { boardAtom, gameAtom, gameEvalAtom } from "../../states"; import PlayersMetric from "./playersMetric"; import MoveInfo from "./moveInfo"; import Opening from "./opening"; +import EngineLines from "./engineLines"; export default function AnalysisTab(props: GridProps) { - const linesNumber = useAtomValue(engineMultiPvAtom); - const position = useAtomValue(currentPositionAtom); - const board = useAtomValue(boardAtom); const gameEval = useAtomValue(gameEvalAtom); + const game = useAtomValue(gameAtom); + const board = useAtomValue(boardAtom); - const linesSkeleton: LineEval[] = Array.from({ length: linesNumber }).map( - (_, i) => ({ pv: [`${i}`], depth: 0, multiPv: i + 1 }) - ); + const boardHistory = board.history(); + const gameHistory = game.history(); - const engineLines = position?.eval?.lines?.length - ? position.eval.lines - : linesSkeleton; + const isGameOver = + boardHistory.length > 0 && + (board.isCheckmate() || + board.isDraw() || + boardHistory.join() === gameHistory.join()); return ( - {gameEval && ( - - )} + + {gameEval && ( + + )} - {gameEval?.estimatedElo && ( - - )} + {gameEval?.estimatedElo && ( + + )} - + - + - - - {!board.isCheckmate() && - engineLines.map((line) => ( - - ))} - - + {isGameOver && ( + + Game is over + + )} + + + ); } diff --git a/src/sections/analysis/panelBody/analysisTab/moveInfo.tsx b/src/sections/analysis/panelBody/analysisTab/moveInfo.tsx index 0887c0f..4e84e51 100644 --- a/src/sections/analysis/panelBody/analysisTab/moveInfo.tsx +++ b/src/sections/analysis/panelBody/analysisTab/moveInfo.tsx @@ -1,6 +1,6 @@ -import { Grid2 as Grid, Skeleton, Stack, Typography } from "@mui/material"; +import { Skeleton, Stack, Typography } from "@mui/material"; import { useAtomValue } from "jotai"; -import { boardAtom, currentPositionAtom, gameAtom } from "../../states"; +import { boardAtom, currentPositionAtom } from "../../states"; import { useMemo } from "react"; import { moveLineUciToSan } from "@/lib/chess"; import { MoveClassification } from "@/types/enums"; @@ -10,7 +10,6 @@ import PrettyMoveSan from "@/components/prettyMoveSan"; export default function MoveInfo() { const position = useAtomValue(currentPositionAtom); const board = useAtomValue(boardAtom); - const game = useAtomValue(gameAtom); const bestMove = position?.lastEval?.bestMove; @@ -23,36 +22,22 @@ export default function MoveInfo() { return moveLineUciToSan(lastPosition)(bestMove); }, [bestMove, board]); - const boardHistory = board.history(); - const gameHistory = game.history(); - if (board.history().length === 0) return null; - const isGameOver = - boardHistory.length > 0 && - (board.isCheckmate() || - board.isDraw() || - boardHistory.join() === gameHistory.join()); - if (!bestMoveSan) { return ( - + placeholder - + ); } @@ -66,12 +51,13 @@ export default function MoveInfo() { moveClassification !== MoveClassification.Perfect; return ( - {moveClassification && ( @@ -121,13 +107,7 @@ export default function MoveInfo() { /> )} - - {isGameOver && ( - - Game is over - - )} - + ); } diff --git a/src/sections/analysis/panelBody/analysisTab/opening.tsx b/src/sections/analysis/panelBody/analysisTab/opening.tsx index 9dc6b3a..1372778 100644 --- a/src/sections/analysis/panelBody/analysisTab/opening.tsx +++ b/src/sections/analysis/panelBody/analysisTab/opening.tsx @@ -12,7 +12,7 @@ export default function Opening() { if (!opening) { return ( - + + {opening} diff --git a/src/sections/analysis/panelBody/analysisTab/playersMetric.tsx b/src/sections/analysis/panelBody/analysisTab/playersMetric.tsx index 207eb10..b4c543b 100644 --- a/src/sections/analysis/panelBody/analysisTab/playersMetric.tsx +++ b/src/sections/analysis/panelBody/analysisTab/playersMetric.tsx @@ -1,4 +1,4 @@ -import { Grid2 as Grid, Typography } from "@mui/material"; +import { Stack, Typography } from "@mui/material"; interface Props { title: string; @@ -12,21 +12,20 @@ export default function PlayersMetric({ blackValue, }: Props) { return ( - - + {title} - + ); } @@ -50,6 +49,7 @@ const ValueBlock = ({ padding={0.8} fontWeight="500" border="1px solid #424242" + noWrap > {value} diff --git a/src/sections/analysis/panelBody/classificationTab/index.tsx b/src/sections/analysis/panelBody/classificationTab/index.tsx index c08a49e..d401b19 100644 --- a/src/sections/analysis/panelBody/classificationTab/index.tsx +++ b/src/sections/analysis/panelBody/classificationTab/index.tsx @@ -8,8 +8,8 @@ export default function ClassificationTab(props: GridProps) { container justifyContent="center" alignItems="start" - height="100%" - maxHeight={{ xs: "18rem", lg: "none" }} + size={12} + flexGrow={1} {...props} sx={ props.hidden ? { display: "none" } : { overflow: "hidden", ...props.sx } diff --git a/src/sections/analysis/panelBody/classificationTab/movesPanel/index.tsx b/src/sections/analysis/panelBody/classificationTab/movesPanel/index.tsx index 7d8e48c..5f04d8c 100644 --- a/src/sections/analysis/panelBody/classificationTab/movesPanel/index.tsx +++ b/src/sections/analysis/panelBody/classificationTab/movesPanel/index.tsx @@ -2,15 +2,19 @@ import { Grid2 as Grid } from "@mui/material"; import MovesLine from "./movesLine"; import { useMemo } from "react"; import { useAtomValue } from "jotai"; -import { gameAtom, gameEvalAtom } from "../../../states"; +import { boardAtom, gameAtom, gameEvalAtom } from "../../../states"; import { MoveClassification } from "@/types/enums"; export default function MovesPanel() { const game = useAtomValue(gameAtom); + const board = useAtomValue(boardAtom); const gameEval = useAtomValue(gameEvalAtom); const gameMoves = useMemo(() => { - const history = game.history(); + const gameHistory = game.history(); + const boardHistory = board.history(); + const history = gameHistory.length ? gameHistory : boardHistory; + if (!history.length) return undefined; const moves: { san: string; moveClassification?: MoveClassification }[][] = @@ -20,14 +24,18 @@ export default function MovesPanel() { const items = [ { san: history[i], - moveClassification: gameEval?.positions[i + 1]?.moveClassification, + moveClassification: gameHistory.length + ? gameEval?.positions[i + 1]?.moveClassification + : undefined, }, ]; if (history[i + 1]) { items.push({ san: history[i + 1], - moveClassification: gameEval?.positions[i + 2]?.moveClassification, + moveClassification: gameHistory.length + ? gameEval?.positions[i + 2]?.moveClassification + : undefined, }); } @@ -35,17 +43,19 @@ export default function MovesPanel() { } return moves; - }, [game, gameEval]); + }, [game, board, gameEval]); + + if (!gameMoves?.length) return null; return ( diff --git a/src/sections/analysis/panelBody/classificationTab/movesPanel/moveItem.tsx b/src/sections/analysis/panelBody/classificationTab/movesPanel/moveItem.tsx index b954234..c4898bb 100644 --- a/src/sections/analysis/panelBody/classificationTab/movesPanel/moveItem.tsx +++ b/src/sections/analysis/panelBody/classificationTab/movesPanel/moveItem.tsx @@ -23,6 +23,7 @@ export default function MoveItem({ moveColor, }: Props) { const game = useAtomValue(gameAtom); + const board = useAtomValue(boardAtom); const { goToMove } = useChessActions(boardAtom); const position = useAtomValue(currentPositionAtom); const color = getMoveColor(moveClassification); @@ -42,7 +43,8 @@ export default function MoveItem({ const handleClick = () => { if (isCurrentMove) return; - goToMove(moveIdx, game); + const gameToUse = game.moveNumber() > 1 ? game : board; + goToMove(moveIdx, gameToUse); }; return ( @@ -82,7 +84,11 @@ export default function MoveItem({ /> )} - + ); } diff --git a/src/sections/analysis/panelBody/graphTab/index.tsx b/src/sections/analysis/panelBody/graphTab/index.tsx index 643bcc4..bac5f8c 100644 --- a/src/sections/analysis/panelBody/graphTab/index.tsx +++ b/src/sections/analysis/panelBody/graphTab/index.tsx @@ -87,20 +87,17 @@ export default function GraphTab(props: GridProps) {