feat : useScreenSize for board size

This commit is contained in:
GuillaumeSD
2024-02-26 01:20:17 +01:00
parent ebdfc9ae33
commit 5bcaf12a5d
15 changed files with 106 additions and 74 deletions

View File

@@ -2,18 +2,30 @@ import { useEffect, useState } from "react";
export const useScreenSize = () => { export const useScreenSize = () => {
const [screenSize, setScreenSize] = useState({ const [screenSize, setScreenSize] = useState({
width: window?.innerWidth ?? 500, width: document?.querySelector(".MuiGrid-root")?.clientWidth ?? 500,
height: window?.innerHeight ?? 500, height: window?.innerHeight - 120 ?? 500,
}); });
useEffect(() => { useEffect(() => {
if (window === undefined) return; const mainDiv = document?.querySelector(".MuiGrid-root");
if (!mainDiv) return;
const observer = new ResizeObserver(() =>
setScreenSize((prev) => ({ ...prev, width: mainDiv.clientWidth }))
);
observer.observe(mainDiv);
return () => {
observer.disconnect();
};
}, []);
useEffect(() => {
const handleResize = () => { const handleResize = () => {
setScreenSize({ setScreenSize((prev) => ({
width: window.innerWidth, ...prev,
height: window.innerHeight, height: window.innerHeight - 120,
}); }));
}; };
window.addEventListener("resize", handleResize); window.addEventListener("resize", handleResize);
@@ -23,5 +35,17 @@ export const useScreenSize = () => {
}; };
}, []); }, []);
return screenSize; const getBoardSize = () => {
const width = screenSize.width;
const height = screenSize.height;
// 900 is the md layout breakpoint
if (width < 900) {
return Math.min(width, height) * 0.95;
}
return Math.min(width - 500, height) * 0.95;
};
return { ...screenSize, boardSize: getBoardSize() };
}; };

View File

@@ -4,8 +4,6 @@ import "@fontsource/roboto/500.css";
import "@fontsource/roboto/700.css"; import "@fontsource/roboto/700.css";
import { AppProps } from "next/app"; import { AppProps } from "next/app";
import Head from "next/head"; import Head from "next/head";
// import "../../styles/global.css";
// import "../../styles/index.css";
import Layout from "@/sections/layout"; import Layout from "@/sections/layout";
export default function MyApp({ Component, pageProps }: AppProps) { export default function MyApp({ Component, pageProps }: AppProps) {

View File

@@ -152,10 +152,8 @@ export default function GameDatabase() {
marginTop={6} marginTop={6}
> >
<Grid item container xs={12} justifyContent="center" alignItems="center"> <Grid item container xs={12} justifyContent="center" alignItems="center">
<Grid item container justifyContent="center" sx={{ maxWidth: "250px" }}>
<LoadGameButton /> <LoadGameButton />
</Grid> </Grid>
</Grid>
<Grid item container xs={12} justifyContent="center" alignItems="center"> <Grid item container xs={12} justifyContent="center" alignItems="center">
<Typography variant="subtitle2"> <Typography variant="subtitle2">

View File

@@ -38,7 +38,7 @@ export default function GameReport() {
rowGap={6} rowGap={6}
justifyContent="center" justifyContent="center"
alignItems="start" alignItems="start"
marginTop={1} gap={6}
> >
<Grid <Grid
item item
@@ -46,8 +46,7 @@ export default function GameReport() {
justifyContent="center" justifyContent="center"
alignItems="center" alignItems="center"
xs={12} xs={12}
md={9} md
lg={6}
> >
<Board /> <Board />
</Grid> </Grid>
@@ -55,11 +54,11 @@ export default function GameReport() {
<Grid <Grid
item item
container container
paddingLeft={{ xs: 0, lg: 6 }} marginTop={{ xs: 0, md: "2.5em" }}
justifyContent="center" justifyContent="center"
alignItems="center" alignItems="center"
xs={12} xs={12}
lg={6} md
> >
<Grid <Grid
container container
@@ -76,7 +75,7 @@ export default function GameReport() {
borderWidth: 2, borderWidth: 2,
}} }}
padding={3} padding={3}
gap={4} gap={3}
> >
<ReviewPanelHeader /> <ReviewPanelHeader />

View File

@@ -13,9 +13,11 @@ import { useChessActions } from "@/hooks/useChess";
import { useMemo, useRef } from "react"; import { useMemo, useRef } from "react";
import PlayerInfo from "./playerInfo"; import PlayerInfo from "./playerInfo";
import EvaluationBar from "./evaluationBar"; import EvaluationBar from "./evaluationBar";
import { useScreenSize } from "@/hooks/useScreenSize";
export default function Board() { export default function Board() {
const boardRef = useRef<HTMLDivElement>(null); const boardRef = useRef<HTMLDivElement>(null);
const { boardSize } = useScreenSize();
const board = useAtomValue(boardAtom); const board = useAtomValue(boardAtom);
const boardOrientation = useAtomValue(boardOrientationAtom); const boardOrientation = useAtomValue(boardOrientationAtom);
const showBestMoveArrow = useAtomValue(showBestMoveArrowAtom); const showBestMoveArrow = useAtomValue(showBestMoveArrowAtom);
@@ -76,10 +78,10 @@ export default function Board() {
container container
justifyContent="center" justifyContent="center"
alignItems="center" alignItems="center"
xs={12}
wrap="nowrap" wrap="nowrap"
width={boardSize}
> >
<EvaluationBar height={boardRef?.current?.offsetHeight || 800} /> <EvaluationBar height={boardRef?.current?.offsetHeight || boardSize} />
<Grid <Grid
item item

View File

@@ -17,7 +17,7 @@ export default function PlayerInfo({ color }: Props) {
return ( return (
<Grid item container xs={12} justifyContent="center" alignItems="center"> <Grid item container xs={12} justifyContent="center" alignItems="center">
<Typography variant="h5"> <Typography variant="h6">
{playerName || (color === "white" ? "White" : "Black")} {playerName || (color === "white" ? "White" : "Black")}
</Typography> </Typography>
</Grid> </Grid>

View File

@@ -35,7 +35,7 @@ export default function ReviewPanelBody() {
xs={12} xs={12}
justifyContent="center" justifyContent="center"
alignItems="center" alignItems="center"
gap={2} gap={1}
> >
<Grid <Grid
item item
@@ -48,16 +48,16 @@ export default function ReviewPanelBody() {
<Icon <Icon
icon="pepicons-pop:star-filled-circle" icon="pepicons-pop:star-filled-circle"
color="#27f019" color="#27f019"
height={30} height={25}
/> />
<Typography variant="h5" align="center"> <Typography variant="h6" align="center">
Game Review Engine evaluation
</Typography> </Typography>
</Grid> </Grid>
{!!bestMove && ( {!!bestMove && (
<Grid item xs={12}> <Grid item xs={12}>
<Typography variant="h6" align="center"> <Typography align="center">
{`${bestMove} was the best move`} {`${bestMove} was the best move`}
</Typography> </Typography>
</Grid> </Grid>
@@ -65,9 +65,7 @@ export default function ReviewPanelBody() {
{isGameOver && ( {isGameOver && (
<Grid item xs={12}> <Grid item xs={12}>
<Typography variant="h6" align="center"> <Typography align="center">Game is over</Typography>
Game is over
</Typography>
</Grid> </Grid>
)} )}

View File

@@ -58,7 +58,7 @@ export default function AnalyzeButton() {
return ( return (
<LoadingButton <LoadingButton
variant="contained" variant="contained"
size="large" size="small"
startIcon={ startIcon={
!evaluationInProgress && ( !evaluationInProgress && (
<Icon icon="streamline:magnifying-glass-solid" /> <Icon icon="streamline:magnifying-glass-solid" />

View File

@@ -10,13 +10,7 @@ export default function GamePanel() {
const hasGameInfo = gameFromUrl !== undefined || !!game.header().White; const hasGameInfo = gameFromUrl !== undefined || !!game.header().White;
if (!hasGameInfo) { if (!hasGameInfo) return null;
return (
<Grid item container xs={12} justifyContent="center" alignItems="center">
<Typography variant="h6">No game loaded</Typography>
</Grid>
);
}
return ( return (
<Grid <Grid
@@ -25,14 +19,12 @@ export default function GamePanel() {
xs={12} xs={12}
justifyContent="center" justifyContent="center"
alignItems="center" alignItems="center"
gap={2} gap={1}
> >
<Grid item container xs={12} justifyContent="center" alignItems="center"> <Grid item container xs={12} justifyContent="center" alignItems="center">
<PlayerInfo color="white" /> <PlayerInfo color="white" />
<Grid item container xs={1} justifyContent="center" alignItems="center"> <Typography marginX={1.5}>vs</Typography>
<Typography variant="h6">vs</Typography>
</Grid>
<PlayerInfo color="black" /> <PlayerInfo color="black" />
</Grid> </Grid>
@@ -40,10 +32,11 @@ export default function GamePanel() {
<Grid <Grid
item item
container container
xs={10} xs={11}
justifyContent="space-evenly" justifyContent="space-evenly"
alignItems="center" alignItems="center"
gap={2} rowGap={1}
columnGap={3}
> >
<Typography> <Typography>
Site : {gameFromUrl?.site || game.header().Site || "?"} Site : {gameFromUrl?.site || game.header().Site || "?"}

View File

@@ -26,13 +26,13 @@ export default function PlayerInfo({ color }: Props) {
xs={5} xs={5}
justifyContent={color === "white" ? "flex-end" : "flex-start"} justifyContent={color === "white" ? "flex-end" : "flex-start"}
alignItems="center" alignItems="center"
gap={1} gap={0.5}
> >
<Typography variant="h6"> <Typography>
{playerName || (color === "white" ? "White" : "Black")} {playerName || (color === "white" ? "White" : "Black")}
</Typography> </Typography>
<Typography variant="h6">{rating ? `(${rating})` : "(?)"}</Typography> <Typography>{rating ? `(${rating})` : "(?)"}</Typography>
</Grid> </Grid>
); );
} }

View File

@@ -13,34 +13,47 @@ export default function ReviewPanelHeader() {
justifyContent="center" justifyContent="center"
alignItems="center" alignItems="center"
xs={12} xs={12}
gap={3} rowGap={3}
> >
<Grid <Grid
item item
container container
xs={12} xs={12}
justifyContent="space-between"
alignItems="center"
>
<Grid item xs={1} />
<Grid
item
container
xs
justifyContent="center" justifyContent="center"
alignItems="center" alignItems="center"
columnGap={1} columnGap={1}
> >
<Icon icon="ph:file-magnifying-glass-fill" height={40} /> <Icon icon="ph:file-magnifying-glass-fill" height={28} />
<Typography variant="h4" align="center">
<Typography variant="h5" align="center">
Game Report Game Report
</Typography> </Typography>
</Grid> </Grid>
<EngineSettingsButton />
</Grid>
<Grid <Grid
item item
container container
xs={12} xs={12}
justifyContent="center" justifyContent="center"
alignItems="center" alignItems="center"
gap={3} rowGap={3}
columnGap={15}
> >
<GamePanel /> <GamePanel />
<LoadGame /> <LoadGame />
<AnalyzeButton /> <AnalyzeButton />
<EngineSettingsButton />
</Grid> </Grid>
</Grid> </Grid>
); );

View File

@@ -1,4 +1,3 @@
import { Grid } from "@mui/material";
import LoadGameButton from "../../loadGame/loadGameButton"; import LoadGameButton from "../../loadGame/loadGameButton";
import { useCallback, useEffect } from "react"; import { useCallback, useEffect } from "react";
import { useChessActions } from "@/hooks/useChess"; import { useChessActions } from "@/hooks/useChess";
@@ -50,14 +49,13 @@ export default function LoadGame() {
const isGameLoaded = gameFromUrl !== undefined || !!game.header().White; const isGameLoaded = gameFromUrl !== undefined || !!game.header().White;
return ( return (
<Grid item container xs={12} justifyContent="center" alignItems="center">
<LoadGameButton <LoadGameButton
label={isGameLoaded ? "Load another game" : "Load game"} label={isGameLoaded ? "Load another game" : "Load game"}
size="small"
setGame={async (game) => { setGame={async (game) => {
await router.push("/"); await router.push("/");
resetAndSetGamePgn(game.pgn()); resetAndSetGamePgn(game.pgn());
}} }}
/> />
</Grid>
); );
} }

View File

@@ -1,15 +1,18 @@
import { Button } from "@mui/material"; import { IconButton, Tooltip } from "@mui/material";
import { useState } from "react"; import { useState } from "react";
import EngineSettingsDialog from "./engineSettingsDialog"; import EngineSettingsDialog from "./engineSettingsDialog";
import { Icon } from "@iconify/react";
export default function EngineSettingsButton() { export default function EngineSettingsButton() {
const [openDialog, setOpenDialog] = useState(false); const [openDialog, setOpenDialog] = useState(false);
return ( return (
<> <>
<Button variant="contained" onClick={() => setOpenDialog(true)}> <Tooltip title="Engine settings">
Engine Settings <IconButton onClick={() => setOpenDialog(true)}>
</Button> <Icon icon="ri:settings-3-line" height={20} />
</IconButton>
</Tooltip>
<EngineSettingsDialog <EngineSettingsDialog
open={openDialog} open={openDialog}

View File

@@ -28,9 +28,10 @@ export default function EngineSettingsDialog({ open, onClose }: Props) {
<DialogTitle marginY={1} variant="h5"> <DialogTitle marginY={1} variant="h5">
Set engine parameters Set engine parameters
</DialogTitle> </DialogTitle>
<DialogContent> <DialogContent sx={{ paddingBottom: 0 }}>
<Typography> <Typography>
Only Stockfish 16 is available now, more engine choices will come ! Stockfish 16 is the only engine available now, more engine choices
will come soon !
</Typography> </Typography>
<Grid <Grid
marginTop={4} marginTop={4}

View File

@@ -6,14 +6,19 @@ import { Chess } from "chess.js";
interface Props { interface Props {
setGame?: (game: Chess) => void; setGame?: (game: Chess) => void;
label?: string; label?: string;
size?: "small" | "medium" | "large";
} }
export default function LoadGameButton({ setGame, label }: Props) { export default function LoadGameButton({ setGame, label, size }: Props) {
const [openDialog, setOpenDialog] = useState(false); const [openDialog, setOpenDialog] = useState(false);
return ( return (
<> <>
<Button variant="contained" onClick={() => setOpenDialog(true)}> <Button
variant="contained"
onClick={() => setOpenDialog(true)}
size={size}
>
{label || "Add game"} {label || "Add game"}
</Button> </Button>