fix: disable deleting moves while a game is in progress (#874)
This commit is contained in:
1 parent
654f884a5c
commit
2e25128e73
4 files changed
+49
-2
No files matched your search
@@ -804,7 +804,7 @@ function BoardGame() {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<MoveControls />
|
<MoveControls readOnly={gameState === "playing"} />
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
</Portal>
|
</Portal>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { useStore } from "zustand";
|
import { useStore } from "zustand";
|
||||||
import { useStoreWithEqualityFn } from "zustand/traditional";
|
import { useStoreWithEqualityFn } from "zustand/traditional";
|
||||||
import Comment from "@/components/common/Comment";
|
import Comment from "@/components/common/Comment";
|
||||||
import { currentTabAtom } from "@/state/atoms";
|
import { currentGameInProgressAtom, currentTabAtom } from "@/state/atoms";
|
||||||
import type { Annotation } from "@/utils/annotation";
|
import type { Annotation } from "@/utils/annotation";
|
||||||
import { hasMorePriority, stripClock } from "@/utils/chess";
|
import { hasMorePriority, stripClock } from "@/utils/chess";
|
||||||
import { getTabFile } from "@/utils/tabs";
|
import { getTabFile } from "@/utils/tabs";
|
||||||
@@ -106,6 +106,7 @@ function CompleteMoveCell({
|
|||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const currentTab = useAtomValue(currentTabAtom);
|
const currentTab = useAtomValue(currentTabAtom);
|
||||||
const tabFile = getTabFile(currentTab);
|
const tabFile = getTabFile(currentTab);
|
||||||
|
const gameInProgress = useAtomValue(currentGameInProgressAtom);
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@@ -181,6 +182,7 @@ function CompleteMoveCell({
|
|||||||
<Menu.Item
|
<Menu.Item
|
||||||
color="red"
|
color="red"
|
||||||
leftSection={<IconX size="0.875rem" />}
|
leftSection={<IconX size="0.875rem" />}
|
||||||
|
disabled={gameInProgress}
|
||||||
onClick={() => deleteMove(movePath)}
|
onClick={() => deleteMove(movePath)}
|
||||||
>
|
>
|
||||||
{t("Menu.DeleteMove")}
|
{t("Menu.DeleteMove")}
|
||||||
|
|||||||
@@ -449,6 +449,11 @@ type GameState = "settingUp" | "playing" | "gameOver";
|
|||||||
const gameStateFamily = atomFamily((_tab: string) => atom<GameState>("settingUp"));
|
const gameStateFamily = atomFamily((_tab: string) => atom<GameState>("settingUp"));
|
||||||
export const currentGameStateAtom = tabValue(gameStateFamily);
|
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) =>
|
const playersFamily = atomFamily((_tab: string) =>
|
||||||
atom<{
|
atom<{
|
||||||
white: OpponentSettings;
|
white: OpponentSettings;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
});
|
||||||
Reference in new issue
Block a user