From 72826d03b29547877b6a4d0dbd7b5d9c3fc0789e Mon Sep 17 00:00:00 2001 From: GuillaumeSD Date: Sun, 17 Mar 2024 21:46:07 +0100 Subject: [PATCH] feat : add square highlight on right click --- src/sections/analysis/board/index.tsx | 14 ++++- .../analysis/board/squareRenderer.tsx | 55 +++++++++++++++++-- src/sections/analysis/states.ts | 1 + 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/sections/analysis/board/index.tsx b/src/sections/analysis/board/index.tsx index 742966c..b7cffb4 100644 --- a/src/sections/analysis/board/index.tsx +++ b/src/sections/analysis/board/index.tsx @@ -1,15 +1,16 @@ import { Grid } from "@mui/material"; import { Chessboard } from "react-chessboard"; -import { useAtomValue } from "jotai"; +import { useAtomValue, useSetAtom } from "jotai"; import { boardAtom, boardOrientationAtom, + clickedSquaresAtom, currentPositionAtom, showBestMoveArrowAtom, } from "../states"; import { Arrow, Square } from "react-chessboard/dist/chessboard/types"; import { useChessActions } from "@/hooks/useChessActions"; -import { useMemo, useRef } from "react"; +import { useEffect, useMemo, useRef } from "react"; import PlayerInfo from "./playerInfo"; import EvaluationBar from "./evaluationBar"; import { useScreenSize } from "@/hooks/useScreenSize"; @@ -24,6 +25,13 @@ export default function Board() { const showBestMoveArrow = useAtomValue(showBestMoveArrowAtom); const { makeMove: makeBoardMove } = useChessActions(boardAtom); const position = useAtomValue(currentPositionAtom); + const setClickedSquares = useSetAtom(clickedSquaresAtom); + + const boardFen = board.fen(); + + useEffect(() => { + setClickedSquares([]); + }, [boardFen]); const onPieceDrop = ( source: Square, @@ -96,7 +104,7 @@ export default function Board() { > (null); + const SquareRenderer = forwardRef( (props, ref) => { const { children, square, style } = props; const showPlayerMoveIcon = useAtomValue(showPlayerMoveIconAtom); const position = useAtomValue(currentPositionAtom); + const [clickedSquares, setClickedSquares] = useAtom(clickedSquaresAtom); + const [rightClickEventSquare, setRightClickEventSquare] = useAtom( + rightClickEventSquareAtom + ); const fromSquare = position.lastMove?.from; const toSquare = position.lastMove?.to; const moveClassification = position?.eval?.moveClassification; const customSquareStyle: CSSProperties | undefined = - fromSquare === square || toSquare === square + clickedSquares.includes(square) + ? { + position: "absolute", + width: "100%", + height: "100%", + backgroundColor: "#eb6150", + opacity: "0.8", + } + : fromSquare === square || toSquare === square ? { position: "absolute", width: "100%", @@ -28,8 +46,35 @@ const SquareRenderer = forwardRef( } : undefined; + const handleSquareLeftClick: MouseEventHandler = () => { + setClickedSquares([]); + }; + + const handleSquareRightClick: MouseEventHandler = ( + event + ) => { + if (event.button !== 2) return; + + if (rightClickEventSquare !== square) { + setRightClickEventSquare(null); + return; + } + + setClickedSquares((prev) => + prev.includes(square) + ? prev.filter((s) => s !== square) + : [...prev, square] + ); + }; + return ( -
+
e.button === 2 && setRightClickEventSquare(square)} + onMouseUp={handleSquareRightClick} + > {children} {customSquareStyle &&
} {moveClassification && showPlayerMoveIcon && square === toSquare && ( diff --git a/src/sections/analysis/states.ts b/src/sections/analysis/states.ts index e9e01f2..4327976 100644 --- a/src/sections/analysis/states.ts +++ b/src/sections/analysis/states.ts @@ -10,6 +10,7 @@ export const currentPositionAtom = atom({}); export const boardOrientationAtom = atom(true); export const showBestMoveArrowAtom = atom(true); export const showPlayerMoveIconAtom = atom(true); +export const clickedSquaresAtom = atom([]); export const engineDepthAtom = atom(16); export const engineMultiPvAtom = atom(3);