Squashed commit of the following:
commit d9209a78cff1c05be3e6a87e27cd1a5a4d5f91c5 Author: GuillaumeSD <47183782+GuillaumeSD@users.noreply.github.com> Date: Wed Jul 24 11:55:35 2024 +0200 style : UI analysis panel adjustment commit 3c2e19bdb9d97f3bb7e8ceaefd630aad64d755c4 Author: GuillaumeSD <47183782+GuillaumeSD@users.noreply.github.com> Date: Wed Jul 24 11:10:07 2024 +0200 feat : graph dot color match move classification commit 4a99ccb2fe19d3806ff320370ebc55af984d719a Author: GuillaumeSD <47183782+GuillaumeSD@users.noreply.github.com> Date: Wed Jul 24 11:09:35 2024 +0200 fix : load pgn with no moves commit 9eeb0e7f2869e544700b7da963b74f707fa6ea2f Author: GuillaumeSD <47183782+GuillaumeSD@users.noreply.github.com> Date: Wed Jul 24 00:09:03 2024 +0200 feat : add current move reference line in graph commit febb9962a0b366aeac1dc266e0470b75bd619e68 Author: GuillaumeSD <47183782+GuillaumeSD@users.noreply.github.com> Date: Tue Jul 23 23:08:17 2024 +0200 fix : handle tab change on new game commit a105239a728dc05211a0ae99d8fd56f179108a0e Author: GuillaumeSD <47183782+GuillaumeSD@users.noreply.github.com> Date: Tue Jul 23 03:46:49 2024 +0200 style : small chart UI tweaks commit 4878ebf87b4ddbac75db70619fe452a3a317ca09 Author: GuillaumeSD <47183782+GuillaumeSD@users.noreply.github.com> Date: Tue Jul 23 03:38:40 2024 +0200 feat : add eval graph commit 29c5a001da03ee288d2a2c133426b1d2ca435930 Author: GuillaumeSD <47183782+GuillaumeSD@users.noreply.github.com> Date: Tue Jul 23 00:30:25 2024 +0200 refacto : analysis directory commit a8b966cc07152bb117b8c68f54af3498ca2a5d2f Author: GuillaumeSD <47183782+GuillaumeSD@users.noreply.github.com> Date: Tue Jul 23 00:07:07 2024 +0200 style : add settings floating button commit 7edc54f09ce7d4b4c4beb310a9c7f985363ff5ee Author: GuillaumeSD <47183782+GuillaumeSD@users.noreply.github.com> Date: Sun Jul 21 22:29:48 2024 +0200 feat : tab analysis panel
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
import { Color, MoveClassification } from "@/types/enums";
|
||||
import { Grid, Typography } from "@mui/material";
|
||||
import { useAtomValue } from "jotai";
|
||||
import { boardAtom, gameAtom, gameEvalAtom } from "../../../states";
|
||||
import { useMemo } from "react";
|
||||
import Image from "next/image";
|
||||
import { capitalize } from "@/lib/helpers";
|
||||
import { useChessActions } from "@/hooks/useChessActions";
|
||||
import { moveClassificationColors } from "@/lib/chess";
|
||||
|
||||
interface Props {
|
||||
classification: MoveClassification;
|
||||
}
|
||||
|
||||
export default function ClassificationRow({ classification }: Props) {
|
||||
const gameEval = useAtomValue(gameEvalAtom);
|
||||
const board = useAtomValue(boardAtom);
|
||||
const game = useAtomValue(gameAtom);
|
||||
const { goToMove } = useChessActions(boardAtom);
|
||||
|
||||
const whiteNb = useMemo(() => {
|
||||
if (!gameEval) return 0;
|
||||
return gameEval.positions.filter(
|
||||
(position, idx) =>
|
||||
idx % 2 !== 0 && position.moveClassification === classification
|
||||
).length;
|
||||
}, [gameEval, classification]);
|
||||
|
||||
const blackNb = useMemo(() => {
|
||||
if (!gameEval) return 0;
|
||||
return gameEval.positions.filter(
|
||||
(position, idx) =>
|
||||
idx % 2 === 0 && position.moveClassification === classification
|
||||
).length;
|
||||
}, [gameEval, classification]);
|
||||
|
||||
const handleClick = (color: Color) => {
|
||||
if (
|
||||
!gameEval ||
|
||||
(color === Color.White && !whiteNb) ||
|
||||
(color === Color.Black && !blackNb)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const filterColor = (idx: number) =>
|
||||
(idx % 2 !== 0 && color === Color.White) ||
|
||||
(idx % 2 === 0 && color === Color.Black);
|
||||
const moveIdx = board.history().length;
|
||||
|
||||
const nextPositionIdx = gameEval.positions.findIndex(
|
||||
(position, idx) =>
|
||||
filterColor(idx) &&
|
||||
position.moveClassification === classification &&
|
||||
idx > moveIdx
|
||||
);
|
||||
|
||||
if (nextPositionIdx > 0) {
|
||||
goToMove(nextPositionIdx, game);
|
||||
} else {
|
||||
const firstPositionIdx = gameEval.positions.findIndex(
|
||||
(position, idx) =>
|
||||
filterColor(idx) && position.moveClassification === classification
|
||||
);
|
||||
if (firstPositionIdx > 0 && firstPositionIdx !== moveIdx) {
|
||||
goToMove(firstPositionIdx, game);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
item
|
||||
justifyContent="space-evenly"
|
||||
alignItems="center"
|
||||
xs={12}
|
||||
wrap="nowrap"
|
||||
color={moveClassificationColors[classification]}
|
||||
>
|
||||
<Grid
|
||||
container
|
||||
item
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
width={"3rem"}
|
||||
style={{ cursor: whiteNb ? "pointer" : "default" }}
|
||||
onClick={() => handleClick(Color.White)}
|
||||
fontSize="0.9rem"
|
||||
>
|
||||
{whiteNb}
|
||||
</Grid>
|
||||
|
||||
<Grid
|
||||
container
|
||||
item
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
width={"7rem"}
|
||||
gap={1}
|
||||
wrap="nowrap"
|
||||
>
|
||||
<Image
|
||||
src={`/icons/${classification}.png`}
|
||||
alt="move-icon"
|
||||
width={18}
|
||||
height={18}
|
||||
style={{
|
||||
maxWidth: "3.5vw",
|
||||
maxHeight: "3.5vw",
|
||||
}}
|
||||
/>
|
||||
|
||||
<Typography align="center" fontSize="0.9rem">
|
||||
{capitalize(classification)}
|
||||
</Typography>
|
||||
</Grid>
|
||||
|
||||
<Grid
|
||||
container
|
||||
item
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
width={"3rem"}
|
||||
style={{ cursor: blackNb ? "pointer" : "default" }}
|
||||
onClick={() => handleClick(Color.Black)}
|
||||
fontSize="0.9rem"
|
||||
>
|
||||
{blackNb}
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user