style : analysis card UI rework for desktop
This commit is contained in:
@@ -1,15 +1,9 @@
|
||||
import {
|
||||
Grid2 as Grid,
|
||||
Grid2Props as GridProps,
|
||||
List,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { Grid2 as Grid, Grid2Props as GridProps, List } from "@mui/material";
|
||||
import { useAtomValue } from "jotai";
|
||||
import {
|
||||
boardAtom,
|
||||
currentPositionAtom,
|
||||
engineMultiPvAtom,
|
||||
gameAtom,
|
||||
gameEvalAtom,
|
||||
} from "../../states";
|
||||
import LineEvaluation from "./lineEvaluation";
|
||||
@@ -21,19 +15,9 @@ import Opening from "./opening";
|
||||
export default function AnalysisTab(props: GridProps) {
|
||||
const linesNumber = useAtomValue(engineMultiPvAtom);
|
||||
const position = useAtomValue(currentPositionAtom);
|
||||
const game = useAtomValue(gameAtom);
|
||||
const board = useAtomValue(boardAtom);
|
||||
const gameEval = useAtomValue(gameEvalAtom);
|
||||
|
||||
const boardHistory = board.history();
|
||||
const gameHistory = game.history();
|
||||
|
||||
const isGameOver =
|
||||
boardHistory.length > 0 &&
|
||||
(board.isCheckmate() ||
|
||||
board.isDraw() ||
|
||||
boardHistory.join() === gameHistory.join());
|
||||
|
||||
const linesSkeleton: LineEval[] = Array.from({ length: linesNumber }).map(
|
||||
(_, i) => ({ pv: [`${i}`], depth: 0, multiPv: i + 1 })
|
||||
);
|
||||
@@ -49,7 +33,7 @@ export default function AnalysisTab(props: GridProps) {
|
||||
justifyContent="center"
|
||||
alignItems="start"
|
||||
height="100%"
|
||||
rowGap={1.2}
|
||||
rowGap={0.8}
|
||||
{...props}
|
||||
sx={
|
||||
props.hidden
|
||||
@@ -77,16 +61,8 @@ export default function AnalysisTab(props: GridProps) {
|
||||
|
||||
<Opening />
|
||||
|
||||
{isGameOver && (
|
||||
<Grid size={12}>
|
||||
<Typography align="center" fontSize="0.9rem">
|
||||
Game is over
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
<Grid container justifyContent="center" alignItems="center" size={12}>
|
||||
<List sx={{ maxWidth: "95%", padding: 0 }}>
|
||||
<List sx={{ width: { xs: "95%", lg: "90%" }, padding: 0 }}>
|
||||
{!board.isCheckmate() &&
|
||||
engineLines.map((line) => (
|
||||
<LineEvaluation key={line.multiPv} line={line} />
|
||||
|
||||
@@ -50,11 +50,12 @@ export default function LineEvaluation({ line }: Props) {
|
||||
<ListItem disablePadding>
|
||||
<Typography
|
||||
marginRight={1.5}
|
||||
marginY={0.5}
|
||||
marginY={0.3}
|
||||
paddingY={0.2}
|
||||
noWrap
|
||||
overflow="visible"
|
||||
width="3.5em"
|
||||
minWidth="3.5em"
|
||||
textAlign="center"
|
||||
fontSize="0.8rem"
|
||||
sx={{
|
||||
@@ -78,13 +79,9 @@ export default function LineEvaluation({ line }: Props) {
|
||||
)}
|
||||
</Typography>
|
||||
|
||||
<Typography
|
||||
noWrap
|
||||
maxWidth={{ xs: "12em", sm: "25em", md: "30em", lg: "25em" }}
|
||||
fontSize="0.9rem"
|
||||
>
|
||||
<Typography noWrap fontSize="0.9rem">
|
||||
{showSkeleton ? (
|
||||
<Skeleton variant="rounded" animation="wave" width="15em" />
|
||||
<Skeleton variant="rounded" animation="wave" width="20em" />
|
||||
) : (
|
||||
line.pv.map((uci, i) => {
|
||||
const san = uciToSan(uci);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Grid2 as Grid, Skeleton, Stack, Typography } from "@mui/material";
|
||||
import { useAtomValue } from "jotai";
|
||||
import { boardAtom, currentPositionAtom } from "../../states";
|
||||
import { boardAtom, currentPositionAtom, gameAtom } from "../../states";
|
||||
import { useMemo } from "react";
|
||||
import { moveLineUciToSan } from "@/lib/chess";
|
||||
import { MoveClassification } from "@/types/enums";
|
||||
@@ -9,6 +9,7 @@ import Image from "next/image";
|
||||
export default function MoveInfo() {
|
||||
const position = useAtomValue(currentPositionAtom);
|
||||
const board = useAtomValue(boardAtom);
|
||||
const game = useAtomValue(gameAtom);
|
||||
|
||||
const bestMove = position?.lastEval?.bestMove;
|
||||
|
||||
@@ -21,8 +22,17 @@ export default function MoveInfo() {
|
||||
return moveLineUciToSan(lastPosition)(bestMove);
|
||||
}, [bestMove, board]);
|
||||
|
||||
const boardHistory = board.history();
|
||||
const gameHistory = game.history();
|
||||
|
||||
if (board.history().length === 0) return null;
|
||||
|
||||
const isGameOver =
|
||||
boardHistory.length > 0 &&
|
||||
(board.isCheckmate() ||
|
||||
board.isDraw() ||
|
||||
boardHistory.join() === gameHistory.join());
|
||||
|
||||
if (!bestMoveSan) {
|
||||
return (
|
||||
<Grid
|
||||
@@ -86,6 +96,7 @@ export default function MoveInfo() {
|
||||
</Typography>
|
||||
</Stack>
|
||||
)}
|
||||
|
||||
{bestMoveLabel && (
|
||||
<Stack direction="row" alignItems="center" spacing={1}>
|
||||
<Image
|
||||
@@ -103,6 +114,12 @@ export default function MoveInfo() {
|
||||
</Typography>
|
||||
</Stack>
|
||||
)}
|
||||
|
||||
{isGameOver && (
|
||||
<Typography align="center" fontSize="0.9rem">
|
||||
Game is over
|
||||
</Typography>
|
||||
)}
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ export default function ClassificationTab(props: GridProps) {
|
||||
justifyContent="center"
|
||||
alignItems="start"
|
||||
height="100%"
|
||||
maxHeight="18rem"
|
||||
maxHeight={{ xs: "18rem", lg: "none" }}
|
||||
{...props}
|
||||
sx={
|
||||
props.hidden ? { display: "none" } : { overflow: "hidden", ...props.sx }
|
||||
|
||||
@@ -16,9 +16,10 @@ export default function MovesClassificationsRecap() {
|
||||
container
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
rowGap={1}
|
||||
rowGap={0.7}
|
||||
sx={{ scrollbarWidth: "thin", overflowY: "auto" }}
|
||||
maxHeight="100%"
|
||||
height="100%"
|
||||
maxHeight="22rem"
|
||||
size={6}
|
||||
>
|
||||
<Grid
|
||||
|
||||
@@ -42,9 +42,9 @@ export default function MovesPanel() {
|
||||
container
|
||||
justifyContent="center"
|
||||
alignItems="start"
|
||||
gap={0.8}
|
||||
gap={0.6}
|
||||
sx={{ scrollbarWidth: "thin", overflowY: "auto" }}
|
||||
maxHeight="100%"
|
||||
height="100%"
|
||||
size={6}
|
||||
id="moves-panel"
|
||||
>
|
||||
|
||||
@@ -93,14 +93,14 @@ export default function GraphTab(props: GridProps) {
|
||||
sx={
|
||||
props.hidden
|
||||
? { display: "none" }
|
||||
: { marginY: 1, overflow: "hidden", overflowY: "auto", ...props.sx }
|
||||
: { overflow: "hidden", overflowY: "auto", ...props.sx }
|
||||
}
|
||||
>
|
||||
<Box
|
||||
width="max(35rem, 90%)"
|
||||
maxWidth="100%"
|
||||
height="max(8rem, 100%)"
|
||||
maxHeight="15rem"
|
||||
height="min(8rem, 8vh)"
|
||||
maxHeight="6rem"
|
||||
sx={{
|
||||
backgroundColor: "#2e2e2e",
|
||||
borderRadius: "15px",
|
||||
|
||||
@@ -47,13 +47,13 @@ export default function NavBar({ darkMode, switchDarkMode }: Props) {
|
||||
}}
|
||||
enableColorOnDark
|
||||
>
|
||||
<Toolbar>
|
||||
<Toolbar variant="dense">
|
||||
<IconButton
|
||||
size="large"
|
||||
edge="start"
|
||||
color="inherit"
|
||||
aria-label="menu"
|
||||
sx={{ mr: "min(0.5vw, 0.6rem)" }}
|
||||
sx={{ mr: "min(0.5vw, 0.6rem)", padding: 1, my: 1 }}
|
||||
onClick={() => setDrawerOpen((val) => !val)}
|
||||
>
|
||||
<Icon icon="mdi:menu" />
|
||||
|
||||
@@ -36,7 +36,7 @@ export default function Layout({ children }: PropsWithChildren) {
|
||||
darkMode={isDarkMode}
|
||||
switchDarkMode={() => setDarkMode((val) => !val)}
|
||||
/>
|
||||
<main style={{ margin: "3vh 2vw" }}>{children}</main>
|
||||
<main style={{ margin: "2vh 1vw" }}>{children}</main>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user