diff --git a/src/client/chessboard/board-container.tsx b/src/client/chessboard/board-container.tsx index 914cdcb..eb69259 100644 --- a/src/client/chessboard/board-container.tsx +++ b/src/client/chessboard/board-container.tsx @@ -6,6 +6,7 @@ import { Side } from "../../common/game-types"; interface BoardContainerProps extends PropsWithChildren { side: Side; onWidthChange: (width: number) => void; + rotation: number; } export function BoardContainer(props: BoardContainerProps) { @@ -27,7 +28,7 @@ export function BoardContainer(props: BoardContainerProps) { ...transform, transform: props.side === Side.SPECTATOR ? - "rotate(" + Math.random() * 360 + "deg)" + "rotate(" + (props.rotation%180) + "deg)" : "", }} > diff --git a/src/client/chessboard/chessboard-wrapper.tsx b/src/client/chessboard/chessboard-wrapper.tsx index e951b3c..281c358 100644 --- a/src/client/chessboard/chessboard-wrapper.tsx +++ b/src/client/chessboard/chessboard-wrapper.tsx @@ -7,6 +7,7 @@ import { Move } from "../../common/game-types"; import { Side, PieceType } from "../../common/game-types"; import { customSquareRenderer } from "./custom-square-renderer"; import { CustomSquareContext } from "./custom-square-context"; +import { BoardOrientation } from "react-chessboard/dist/chessboard/types"; interface ChessboardWrapperProps { /** @@ -17,6 +18,10 @@ interface ChessboardWrapperProps { * The side of the current player. */ side: Side; + /** + * The rotation of the current player. + */ + rotation: number; /** * A callback function this component invokes whenever a move is made. */ @@ -41,6 +46,8 @@ export function ChessboardWrapper(props: ChessboardWrapperProps): JSX.Element { Square | undefined >(); + const [orientation, setOrientation] = useState("white"); + // Maps squares to style objects let legalSquares: string[] = []; if (lastClickedSquare !== undefined) { @@ -62,12 +69,35 @@ export function ChessboardWrapper(props: ChessboardWrapperProps): JSX.Element { setLastClickedSquare(undefined); }; + + switch (props.side) { + case Side.WHITE: + if(orientation !== "white") + setOrientation("white"); + break; + case Side.BLACK: + if(orientation !== "black") + setOrientation("black"); + break; + default: + if ((props.rotation%360) < 180) { + if(orientation !== "black"){ + setOrientation("black"); + } + } else { + if(orientation !== "white"){ + setOrientation("white"); + } + } + } + + // Don't render while width isn't set let chessboard: JSX.Element | null = null; if (width !== undefined) { chessboard = ( { @@ -151,7 +181,11 @@ export function ChessboardWrapper(props: ChessboardWrapperProps): JSX.Element { } return ( - + diff --git a/src/client/game/game.tsx b/src/client/game/game.tsx index 10ca9f4..0a8f1ed 100644 --- a/src/client/game/game.tsx +++ b/src/client/game/game.tsx @@ -49,6 +49,7 @@ export function Game(): JSX.Element { const [gameInterruptedReason, setGameInterruptedReason] = useState(); const [gameHoldReason, setGameHoldReason] = useState(); + const [rotation, setRotation] = useState(0); const sendMessage = useSocket( getMessageHandler( @@ -121,12 +122,13 @@ export function Game(): JSX.Element { return ( <> - +
{gameEndDialog} {gameOfferDialog} diff --git a/src/client/game/navbar-menu.tsx b/src/client/game/navbar-menu.tsx index 267dc77..32dd128 100644 --- a/src/client/game/navbar-menu.tsx +++ b/src/client/game/navbar-menu.tsx @@ -16,15 +16,32 @@ import { } from "../../common/game-end-reasons"; import { SendMessage } from "../../common/message/message"; import { Side } from "../../common/game-types"; +import { Dispatch } from "react"; interface NavbarMenuProps { sendMessage: SendMessage; side: Side; + setRotation: Dispatch> //set state type } export function NavbarMenu(props: NavbarMenuProps): JSX.Element { // Store react router state for game const navigate = useNavigate(); + + const rotateButton = props.side===Side.SPECTATOR? +