fix: disable deleting moves while a game is in progress (#874)

This commit is contained in:
dualfroz committed 2026-09-26 09:46:11 +02:00
1 parent 654f884a5c
commit 2e25128e73
4 files changed
+49 -2

No files matched your search

+1 -1
View File
@@ -804,7 +804,7 @@ function BoardGame() {
/>
}
/>
<MoveControls />
<MoveControls readOnly={gameState === "playing"} />
</Stack>
)}
</Portal>
+3 -1
View File
@@ -15,7 +15,7 @@ import { useTranslation } from "react-i18next";
import { useStore } from "zustand";
import { useStoreWithEqualityFn } from "zustand/traditional";
import Comment from "@/components/common/Comment";
import { currentTabAtom } from "@/state/atoms";
import { currentGameInProgressAtom, currentTabAtom } from "@/state/atoms";
import type { Annotation } from "@/utils/annotation";
import { hasMorePriority, stripClock } from "@/utils/chess";
import { getTabFile } from "@/utils/tabs";
@@ -106,6 +106,7 @@ function CompleteMoveCell({
const [open, setOpen] = useState(false);
const currentTab = useAtomValue(currentTabAtom);
const tabFile = getTabFile(currentTab);
const gameInProgress = useAtomValue(currentGameInProgressAtom);
const { t } = useTranslation();
@@ -181,6 +182,7 @@ function CompleteMoveCell({
<Menu.Item
color="red"
leftSection={<IconX size="0.875rem" />}
disabled={gameInProgress}
onClick={() => deleteMove(movePath)}
>
{t("Menu.DeleteMove")}
+5
View File
@@ -449,6 +449,11 @@ type GameState = "settingUp" | "playing" | "gameOver";
const gameStateFamily = atomFamily((_tab: string) => atom<GameState>("settingUp"));
export const currentGameStateAtom = tabValue(gameStateFamily);
export const currentGameInProgressAtom = atom((get) => {
const tab = get(currentTabAtom);
return tab?.type === "play" && get(gameStateFamily(tab.value)) === "playing";
});
const playersFamily = atomFamily((_tab: string) =>
atom<{
white: OpponentSettings;
+40
View File
@@ -0,0 +1,40 @@
import { createStore } from "jotai";
import { expect, test } from "vitest";
import {
activeTabAtom,
currentGameInProgressAtom,
currentGameStateAtom,
tabsAtom,
} from "@/state/atoms";
import type { Tab } from "@/utils/tabs";
function storeWithTab(type: Tab["type"]) {
const store = createStore();
store.set(tabsAtom, [{ name: "Tab", value: "tab", type, gameOrigin: { kind: "none" } }]);
store.set(activeTabAtom, "tab");
return store;
}
test("a play tab is in progress only while the game is playing", () => {
const store = storeWithTab("play");
expect(store.get(currentGameInProgressAtom)).toBe(false);
store.set(currentGameStateAtom, "playing");
expect(store.get(currentGameInProgressAtom)).toBe(true);
store.set(currentGameStateAtom, "gameOver");
expect(store.get(currentGameInProgressAtom)).toBe(false);
});
test("an analysis tab is never in progress", () => {
const store = storeWithTab("analysis");
store.set(currentGameStateAtom, "playing");
expect(store.get(currentGameInProgressAtom)).toBe(false);
});
test("no tab selected is not in progress", () => {
const store = createStore();
store.set(tabsAtom, []);
store.set(activeTabAtom, null);
expect(store.get(currentGameInProgressAtom)).toBe(false);
});