Files
chesskit/src/sections/engineSettings/engineSettingsDialog.tsx
2025-05-11 18:21:45 +02:00

192 lines
5.3 KiB
TypeScript

import Slider from "@/components/slider";
import { EngineName } from "@/types/enums";
import {
MenuItem,
Select,
Button,
Dialog,
DialogTitle,
DialogContent,
FormControl,
InputLabel,
OutlinedInput,
DialogActions,
Typography,
Grid2 as Grid,
} from "@mui/material";
import {
engineNameAtom,
engineDepthAtom,
engineMultiPvAtom,
} from "../analysis/states";
import ArrowOptions from "./arrowOptions";
import { useAtomLocalStorage } from "@/hooks/useAtomLocalStorage";
import { useEffect } from "react";
import { isEngineSupported } from "@/lib/engine/shared";
import { Stockfish16_1 } from "@/lib/engine/stockfish16_1";
import { useAtom } from "jotai";
import { boardHueAtom, pieceSetAtom } from "@/components/board/states";
import {
DEFAULT_ENGINE,
ENGINE_LABELS,
PIECE_SETS,
STRONGEST_ENGINE,
} from "@/constants";
interface Props {
open: boolean;
onClose: () => void;
}
export default function EngineSettingsDialog({ open, onClose }: Props) {
const [depth, setDepth] = useAtomLocalStorage(
"engine-depth",
engineDepthAtom
);
const [multiPv, setMultiPv] = useAtomLocalStorage(
"engine-multi-pv",
engineMultiPvAtom
);
const [engineName, setEngineName] = useAtomLocalStorage(
"engine-name",
engineNameAtom
);
const [boardHue, setBoardHue] = useAtom(boardHueAtom);
const [pieceSet, setPieceSet] = useAtom(pieceSetAtom);
useEffect(() => {
if (!isEngineSupported(engineName)) {
if (Stockfish16_1.isSupported()) {
setEngineName(EngineName.Stockfish16_1Lite);
} else {
setEngineName(EngineName.Stockfish11);
}
}
}, [setEngineName, engineName]);
return (
<Dialog open={open} onClose={onClose} maxWidth="md" fullWidth>
<DialogTitle variant="h5">Settings</DialogTitle>
<DialogContent sx={{ paddingBottom: 0 }}>
<Grid
container
justifyContent="center"
alignItems="center"
spacing={3}
size={12}
>
<Grid
container
justifyContent="center"
size={{ xs: 12, sm: 7, md: 8 }}
>
<Typography>
{ENGINE_LABELS[DEFAULT_ENGINE].small} is the default engine if
your device support its requirements. It offers the best balance
between speed and strength.{" "}
{ENGINE_LABELS[STRONGEST_ENGINE].small} is the strongest engine
available, note that it requires a one time download of 75MB.
</Typography>
</Grid>
<Grid
container
justifyContent="center"
size={{ xs: 12, sm: 5, md: 4 }}
>
<FormControl variant="outlined">
<InputLabel id="dialog-select-label">Engine</InputLabel>
<Select
labelId="dialog-select-label"
id="dialog-select"
displayEmpty
input={<OutlinedInput label="Engine" />}
value={engineName}
onChange={(e) => setEngineName(e.target.value as EngineName)}
sx={{ width: 280, maxWidth: "100%" }}
>
{Object.values(EngineName).map((engine) => (
<MenuItem
key={engine}
value={engine}
disabled={!isEngineSupported(engine)}
>
{ENGINE_LABELS[engine].full}
</MenuItem>
))}
</Select>
</FormControl>
</Grid>
<Slider
label="Maximum depth"
value={depth}
setValue={setDepth}
min={10}
max={30}
marksFilter={2}
/>
<Slider
label="Number of lines"
value={multiPv}
setValue={setMultiPv}
min={2}
max={6}
marksFilter={1}
size={6}
/>
<ArrowOptions />
<Grid
container
justifyContent="center"
size={{ xs: 12, sm: 8, md: 9 }}
>
<Slider
label="Board hue"
value={boardHue}
setValue={setBoardHue}
min={0}
max={360}
/>
</Grid>
<Grid
container
justifyContent="center"
size={{ xs: 12, sm: 4, md: 3 }}
>
<FormControl variant="outlined">
<InputLabel id="dialog-select-label">Piece set</InputLabel>
<Select
labelId="dialog-select-label"
id="dialog-select"
displayEmpty
input={<OutlinedInput label="Piece set" />}
value={pieceSet}
onChange={(e) =>
setPieceSet(e.target.value as (typeof PIECE_SETS)[number])
}
sx={{ width: 200, maxWidth: "100%" }}
>
{PIECE_SETS.map((name) => (
<MenuItem key={name} value={name}>
{name}
</MenuItem>
))}
</Select>
</FormControl>
</Grid>
</Grid>
</DialogContent>
<DialogActions sx={{ m: 1 }}>
<Button variant="contained" onClick={onClose}>
Done
</Button>
</DialogActions>
</Dialog>
);
}