feat : add board interactions

This commit is contained in:
GuillaumeSD
2024-02-23 04:01:18 +01:00
parent 2af0959e82
commit 814d3ecf09
19 changed files with 458 additions and 107 deletions

View File

@@ -0,0 +1,14 @@
import { useSetAtom } from "jotai";
import { boardOrientationAtom } from "../states";
import { IconButton } from "@mui/material";
import { Icon } from "@iconify/react";
export default function FlipBoardButton() {
const setBoardOrientation = useSetAtom(boardOrientationAtom);
return (
<IconButton onClick={() => setBoardOrientation((prev) => !prev)}>
<Icon icon="eva:flip-fill" />
</IconButton>
);
}

View File

@@ -0,0 +1,28 @@
import { Icon } from "@iconify/react";
import { IconButton } from "@mui/material";
import { useAtomValue } from "jotai";
import { boardAtom, gameAtom } from "../states";
import { useChessActions } from "@/hooks/useChess";
export default function GoToLastPositionButton() {
const boardActions = useChessActions(boardAtom);
const game = useAtomValue(gameAtom);
const board = useAtomValue(boardAtom);
const gameHistory = game.history();
const boardHistory = board.history();
const isButtonDisabled = boardHistory >= gameHistory;
return (
<IconButton
onClick={() => {
if (isButtonDisabled) return;
boardActions.setPgn(game.pgn());
}}
disabled={isButtonDisabled}
>
<Icon icon="ri:skip-forward-line" />
</IconButton>
);
}

View File

@@ -0,0 +1,46 @@
import { Divider, Grid, IconButton } from "@mui/material";
import { Icon } from "@iconify/react";
import { useAtomValue } from "jotai";
import { boardAtom } from "../states";
import { useChessActions } from "@/hooks/useChess";
import FlipBoardButton from "./flipBoardButton";
import NextMoveButton from "./nextMoveButton";
import GoToLastPositionButton from "./goToLastPositionButton";
import SaveButton from "./saveButton";
export default function ReviewPanelToolBar() {
const board = useAtomValue(boardAtom);
const boardActions = useChessActions(boardAtom);
const boardHistory = board.history();
return (
<>
<Divider sx={{ width: "90%", marginY: 3 }} />
<Grid container item justifyContent="center" alignItems="center" xs={12}>
<FlipBoardButton />
<IconButton
onClick={() => boardActions.reset()}
disabled={boardHistory.length === 0}
>
<Icon icon="ri:skip-back-line" />
</IconButton>
<IconButton
onClick={() => boardActions.undo()}
disabled={boardHistory.length === 0}
>
<Icon icon="ri:arrow-left-s-line" height={30} />
</IconButton>
<NextMoveButton />
<GoToLastPositionButton />
<SaveButton />
</Grid>
</>
);
}

View File

@@ -0,0 +1,42 @@
import { Icon } from "@iconify/react";
import { IconButton } from "@mui/material";
import { useAtomValue } from "jotai";
import { boardAtom, gameAtom } from "../states";
import { useChessActions } from "@/hooks/useChess";
export default function NextMoveButton() {
const boardActions = useChessActions(boardAtom);
const game = useAtomValue(gameAtom);
const board = useAtomValue(boardAtom);
const gameHistory = game.history();
const boardHistory = board.history();
const isButtonEnabled =
boardHistory.length < gameHistory.length &&
gameHistory.slice(0, boardHistory.length).join() === boardHistory.join();
const addNextGameMoveToBoard = () => {
if (!isButtonEnabled) return;
const nextMoveIndex = boardHistory.length;
const nextMove = game.history({ verbose: true })[nextMoveIndex];
if (nextMove) {
boardActions.move({
from: nextMove.from,
to: nextMove.to,
promotion: nextMove.promotion,
});
}
};
return (
<IconButton
onClick={() => addNextGameMoveToBoard()}
disabled={!isButtonEnabled}
>
<Icon icon="ri:arrow-right-s-line" height={30} />
</IconButton>
);
}

View File

@@ -0,0 +1,36 @@
import { useGameDatabase } from "@/hooks/useGameDatabase";
import { Icon } from "@iconify/react";
import { IconButton } from "@mui/material";
import { useAtomValue } from "jotai";
import { useRouter } from "next/router";
import { gameAtom } from "../states";
export default function SaveButton() {
const game = useAtomValue(gameAtom);
const { addGame } = useGameDatabase();
const router = useRouter();
const { gameId } = router.query;
const isButtonEnabled = router.isReady && typeof gameId === undefined;
return (
<IconButton
onClick={async () => {
if (!isButtonEnabled) return;
const gameId = await addGame(game);
router.replace(
{
query: { gameId: gameId },
pathname: router.pathname,
},
undefined,
{ shallow: true, scroll: false }
);
}}
disabled={!isButtonEnabled}
>
<Icon icon="ri:save-3-line" />
</IconButton>
);
}