feat : useScreenSize for board size
This commit is contained in:
@@ -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() };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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 />
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
@@ -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 || "?"}
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user