aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/packages/ui/src/stores/game-store.ts
diff options
context:
space:
mode:
author苏向夜 <46275354+fu050409@users.noreply.github.com>2026-03-29 21:35:34 +0800
committerGitHub <noreply@github.com>2026-03-29 21:35:34 +0800
commit70348cefb7de8c1e044800296a99177309c5a81e (patch)
treeeb0fdfbcc880574e9b386a3f2fc9b3a89489e5b5 /packages/ui/src/stores/game-store.ts
parentf2f5383a1b615a7493316d558dc55271198e772a (diff)
parent1c115141cc7b676e6a07786594155c3ac293fe34 (diff)
downloadDropOut-70348cefb7de8c1e044800296a99177309c5a81e.tar.gz
DropOut-70348cefb7de8c1e044800296a99177309c5a81e.zip
refactor(ui): full rewrite instance and code struct (#129)
## Summary by Sourcery Refactor the UI to modernize effect handling, routing, and legacy APIs while adding a reusable alert dialog component and cleaning up obsolete stores. New Features: - Introduce a shared SaturnEffect context via ParticleBackground so pages can access the effect without relying on global window APIs. - Add a Base UI–powered alert dialog component for consistent confirmation and warning flows across the app. - Define a central router configuration module with instance routes to standardize page wiring. Bug Fixes: - Ensure SaturnEffect nullish checks are handled safely when forwarding pointer and touch events from the home view. Enhancements: - Rewrite ParticleBackground to manage its own SaturnEffect lifecycle via React state and context instead of global accessors. - Update the home view to use the SaturnEffect hook, simplify pointer/touch handlers, and remove legacy game and release store usage. - Refine layout and accessibility attributes for various form field and label components, including field grouping and error rendering keys. - Simplify sidebar navigation and adjust the user dropdown trigger to work with the updated dropdown menu API. - Wrap the root outlet for the home route with ParticleBackground only on the index path to limit the effect to the intended view. - Clean up imports and code style in radio group and other UI primitives for consistency. Chores: - Remove deprecated UI stores and utility modules that are no longer used with the new architecture. - Add changeset entries documenting the Saturn effect refactor, ParticleBackground rewrite, and removal of legacy store code.
Diffstat (limited to 'packages/ui/src/stores/game-store.ts')
-rw-r--r--packages/ui/src/stores/game-store.ts182
1 files changed, 0 insertions, 182 deletions
diff --git a/packages/ui/src/stores/game-store.ts b/packages/ui/src/stores/game-store.ts
deleted file mode 100644
index 1eaf7e7..0000000
--- a/packages/ui/src/stores/game-store.ts
+++ /dev/null
@@ -1,182 +0,0 @@
-import { listen, type UnlistenFn } from "@tauri-apps/api/event";
-import { toast } from "sonner";
-import { create } from "zustand";
-import {
- getVersions,
- getVersionsOfInstance,
- startGame as startGameCommand,
- stopGame as stopGameCommand,
-} from "@/client";
-import type { Account } from "@/types/bindings/auth";
-import type { GameExitedEvent } from "@/types/bindings/core";
-import type { Version } from "@/types/bindings/manifest";
-
-interface GameState {
- versions: Version[];
- selectedVersion: string;
- runningInstanceId: string | null;
- runningVersionId: string | null;
- launchingInstanceId: string | null;
- stoppingInstanceId: string | null;
- lifecycleUnlisten: UnlistenFn | null;
-
- latestRelease: Version | undefined;
- isGameRunning: boolean;
-
- initLifecycle: () => Promise<void>;
- loadVersions: (instanceId?: string) => Promise<void>;
- startGame: (
- currentAccount: Account | null,
- openLoginModal: () => void,
- activeInstanceId: string | null,
- versionId: string | null,
- setView: (view: string) => void,
- ) => Promise<string | null>;
- stopGame: (instanceId?: string | null) => Promise<string | null>;
- setSelectedVersion: (version: string) => void;
- setVersions: (versions: Version[]) => void;
-}
-
-export const useGameStore = create<GameState>((set, get) => ({
- versions: [],
- selectedVersion: "",
- runningInstanceId: null,
- runningVersionId: null,
- launchingInstanceId: null,
- stoppingInstanceId: null,
- lifecycleUnlisten: null,
-
- get latestRelease() {
- return get().versions.find((v) => v.type === "release");
- },
-
- get isGameRunning() {
- return get().runningInstanceId !== null;
- },
-
- initLifecycle: async () => {
- if (get().lifecycleUnlisten) {
- return;
- }
-
- const unlisten = await listen<GameExitedEvent>("game-exited", (event) => {
- const { instanceId, versionId, wasStopped } = event.payload;
-
- set({
- runningInstanceId: null,
- runningVersionId: null,
- launchingInstanceId: null,
- stoppingInstanceId: null,
- });
-
- if (wasStopped) {
- toast.success(`Stopped Minecraft ${versionId} for instance ${instanceId}`);
- } else {
- toast.info(`Minecraft ${versionId} exited for instance ${instanceId}`);
- }
- });
-
- set({ lifecycleUnlisten: unlisten });
- },
-
- loadVersions: async (instanceId?: string) => {
- try {
- const versions = instanceId
- ? await getVersionsOfInstance(instanceId)
- : await getVersions();
- set({ versions: versions ?? [] });
- } catch (e) {
- console.error("Failed to load versions:", e);
- set({ versions: [] });
- }
- },
-
- startGame: async (
- currentAccount,
- openLoginModal,
- activeInstanceId,
- versionId,
- setView,
- ) => {
- const { isGameRunning } = get();
- const targetVersion = versionId ?? get().selectedVersion;
-
- if (!currentAccount) {
- toast.info("Please login first");
- openLoginModal();
- return null;
- }
-
- if (!targetVersion) {
- toast.info("Please select a version first");
- return null;
- }
-
- if (!activeInstanceId) {
- toast.info("Please select an instance first");
- setView("instances");
- return null;
- }
-
- if (isGameRunning) {
- toast.info("A game is already running");
- return null;
- }
-
- set({
- launchingInstanceId: activeInstanceId,
- selectedVersion: targetVersion,
- });
- toast.info(`Preparing to launch ${targetVersion}...`);
-
- try {
- const message = await startGameCommand(activeInstanceId, targetVersion);
- set({
- launchingInstanceId: null,
- runningInstanceId: activeInstanceId,
- runningVersionId: targetVersion,
- });
- toast.success(message);
- return message;
- } catch (e) {
- console.error(e);
- set({ launchingInstanceId: null });
- toast.error(`Error: ${e}`);
- return null;
- }
- },
-
- stopGame: async (instanceId) => {
- const { runningInstanceId } = get();
-
- if (!runningInstanceId) {
- toast.info("No running game found");
- return null;
- }
-
- if (instanceId && instanceId !== runningInstanceId) {
- toast.info("That instance is not the one currently running");
- return null;
- }
-
- set({ stoppingInstanceId: runningInstanceId });
-
- try {
- return await stopGameCommand();
- } catch (e) {
- console.error("Failed to stop game:", e);
- toast.error(`Failed to stop game: ${e}`);
- return null;
- } finally {
- set({ stoppingInstanceId: null });
- }
- },
-
- setSelectedVersion: (version: string) => {
- set({ selectedVersion: version });
- },
-
- setVersions: (versions: Version[]) => {
- set({ versions });
- },
-}));