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 && (
-
- )}
+
{isLgOrGreater && (
-
+
)}
- {!isLgOrGreater && gameEval && }
{!isLgOrGreater && gameEval && (
-
+
+
+
+
)}
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) {