aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/packages/ui-new/src/models
diff options
context:
space:
mode:
author苏向夜 <fu050409@163.com>2026-02-25 01:32:51 +0800
committer苏向夜 <fu050409@163.com>2026-02-25 01:32:51 +0800
commit66668d85d603c5841d755a6023aa1925559fc6d4 (patch)
tree485464148c76b0021efb55b7d2afd1c3004ceee0 /packages/ui-new/src/models
parenta6773bd092db654360c599ca6b0108ea0e456e8c (diff)
downloadDropOut-66668d85d603c5841d755a6023aa1925559fc6d4.tar.gz
DropOut-66668d85d603c5841d755a6023aa1925559fc6d4.zip
chore(workspace): replace legacy codes
Diffstat (limited to 'packages/ui-new/src/models')
-rw-r--r--packages/ui-new/src/models/auth.ts142
-rw-r--r--packages/ui-new/src/models/instances.ts135
-rw-r--r--packages/ui-new/src/models/settings.ts75
3 files changed, 0 insertions, 352 deletions
diff --git a/packages/ui-new/src/models/auth.ts b/packages/ui-new/src/models/auth.ts
deleted file mode 100644
index 10b2a0d..0000000
--- a/packages/ui-new/src/models/auth.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-import { listen, type UnlistenFn } from "@tauri-apps/api/event";
-import { open } from "@tauri-apps/plugin-shell";
-import { Mutex } from "es-toolkit";
-import { toString as stringify } from "es-toolkit/compat";
-import { toast } from "sonner";
-import { create } from "zustand";
-import {
- completeMicrosoftLogin,
- getActiveAccount,
- loginOffline,
- logout,
- startMicrosoftLogin,
-} from "@/client";
-import type { Account, DeviceCodeResponse } from "@/types";
-
-export interface AuthState {
- account: Account | null;
- loginMode: Account["type"] | null;
- deviceCode: DeviceCodeResponse | null;
- _pollingInterval: number | null;
- _mutex: Mutex;
- statusMessage: string | null;
- _progressUnlisten: UnlistenFn | null;
-
- init: () => Promise<void>;
- setLoginMode: (mode: Account["type"] | null) => void;
- loginOnline: (onSuccess?: () => void | Promise<void>) => Promise<void>;
- _pollLoginStatus: (
- deviceCode: string,
- onSuccess?: () => void | Promise<void>,
- ) => Promise<void>;
- cancelLoginOnline: () => Promise<void>;
- loginOffline: (username: string) => Promise<void>;
- logout: () => Promise<void>;
-}
-
-export const useAuthStore = create<AuthState>((set, get) => ({
- account: null,
- loginMode: null,
- deviceCode: null,
- _pollingInterval: null,
- statusMessage: null,
- _progressUnlisten: null,
- _mutex: new Mutex(),
-
- init: async () => {
- try {
- const account = await getActiveAccount();
- set({ account });
- } catch (error) {
- console.error("Failed to initialize auth store:", error);
- }
- },
- setLoginMode: (mode) => set({ loginMode: mode }),
- loginOnline: async (onSuccess) => {
- const { _pollLoginStatus } = get();
-
- set({ statusMessage: "Waiting for authorization..." });
-
- try {
- const unlisten = await listen("auth-progress", (event) => {
- const message = event.payload;
- console.log(message);
- set({ statusMessage: stringify(message), _progressUnlisten: unlisten });
- });
- } catch (error) {
- console.warn("Failed to attch auth-progress listener:", error);
- toast.warning("Failed to attch auth-progress listener");
- }
-
- const deviceCode = await startMicrosoftLogin();
- navigator.clipboard?.writeText(deviceCode.userCode).catch((err) => {
- console.error("Failed to copy to clipboard:", err);
- });
- open(deviceCode.verificationUri).catch((err) => {
- console.error("Failed to open browser:", err);
- });
- const ms = Number(deviceCode.interval) * 1000;
- const interval = setInterval(() => {
- _pollLoginStatus(deviceCode.deviceCode, onSuccess);
- }, ms);
- set({ _pollingInterval: interval, deviceCode });
- },
- _pollLoginStatus: async (deviceCode, onSuccess) => {
- const { _pollingInterval, _mutex: mutex, _progressUnlisten } = get();
- if (mutex.isLocked) return;
- mutex.acquire();
- try {
- const account = await completeMicrosoftLogin(deviceCode);
- clearInterval(_pollingInterval ?? undefined);
- _progressUnlisten?.();
- onSuccess?.();
- set({ account, loginMode: "microsoft" });
- } catch (error) {
- if (error === "authorization_pending") {
- console.log("Authorization pending...");
- } else {
- console.error("Failed to poll login status:", error);
- toast.error("Failed to poll login status");
- }
- } finally {
- mutex.release();
- }
- },
- cancelLoginOnline: async () => {
- const { account, logout, _pollingInterval, _progressUnlisten } = get();
- clearInterval(_pollingInterval ?? undefined);
- _progressUnlisten?.();
- if (account) {
- await logout();
- }
- set({
- loginMode: null,
- _pollingInterval: null,
- statusMessage: null,
- _progressUnlisten: null,
- });
- },
- loginOffline: async (username: string) => {
- const trimmedUsername = username.trim();
- if (trimmedUsername.length === 0) {
- throw new Error("Username cannot be empty");
- }
-
- try {
- const account = await loginOffline(trimmedUsername);
- set({ account, loginMode: "offline" });
- } catch (error) {
- console.error("Failed to login offline:", error);
- toast.error("Failed to login offline");
- }
- },
- logout: async () => {
- try {
- await logout();
- set({ account: null });
- } catch (error) {
- console.error("Failed to logout:", error);
- toast.error("Failed to logout");
- }
- },
-}));
diff --git a/packages/ui-new/src/models/instances.ts b/packages/ui-new/src/models/instances.ts
deleted file mode 100644
index f434c7c..0000000
--- a/packages/ui-new/src/models/instances.ts
+++ /dev/null
@@ -1,135 +0,0 @@
-import { toast } from "sonner";
-import { create } from "zustand";
-import {
- createInstance,
- deleteInstance,
- duplicateInstance,
- getActiveInstance,
- getInstance,
- listInstances,
- setActiveInstance,
- updateInstance,
-} from "@/client";
-import type { Instance } from "@/types";
-
-interface InstancesState {
- // State
- instances: Instance[];
- activeInstance: Instance | null;
-
- // Actions
- refresh: () => Promise<void>;
- create: (name: string) => Promise<Instance | null>;
- delete: (id: string) => Promise<void>;
- update: (instance: Instance) => Promise<void>;
- setActiveInstance: (instance: Instance) => Promise<void>;
- duplicate: (id: string, newName: string) => Promise<Instance | null>;
- getInstance: (id: string) => Promise<Instance | null>;
-}
-
-export const useInstancesStore = create<InstancesState>((set, get) => ({
- // Initial state
- instances: [],
- activeInstance: null,
-
- // Actions
- refresh: async () => {
- const { setActiveInstance } = get();
- try {
- const instances = await listInstances();
- const active = await getActiveInstance();
-
- if (!active && instances.length > 0) {
- // If no active instance but instances exist, set the first one as active
- await setActiveInstance(instances[0]);
- }
-
- set({ instances });
- } catch (e) {
- console.error("Failed to load instances:", e);
- toast.error("Error loading instances");
- }
- },
-
- create: async (name) => {
- const { refresh } = get();
- try {
- const instance = await createInstance(name);
- await refresh();
- toast.success(`Instance "${name}" created successfully`);
- return instance;
- } catch (e) {
- console.error("Failed to create instance:", e);
- toast.error("Error creating instance");
- return null;
- }
- },
-
- delete: async (id) => {
- const { refresh, instances, activeInstance, setActiveInstance } = get();
- try {
- await deleteInstance(id);
- await refresh();
-
- // If deleted instance was active, set another as active
- if (activeInstance?.id === id) {
- if (instances.length > 0) {
- await setActiveInstance(instances[0]);
- } else {
- set({ activeInstance: null });
- }
- }
-
- toast.success("Instance deleted successfully");
- } catch (e) {
- console.error("Failed to delete instance:", e);
- toast.error("Error deleting instance");
- }
- },
-
- update: async (instance) => {
- const { refresh } = get();
- try {
- await updateInstance(instance);
- await refresh();
- toast.success("Instance updated successfully");
- } catch (e) {
- console.error("Failed to update instance:", e);
- toast.error("Error updating instance");
- }
- },
-
- setActiveInstance: async (instance) => {
- try {
- await setActiveInstance(instance.id);
- set({ activeInstance: instance });
- toast.success("Active instance changed");
- } catch (e) {
- console.error("Failed to set active instance:", e);
- toast.error("Error setting active instance");
- }
- },
-
- duplicate: async (id, newName) => {
- const { refresh } = get();
- try {
- const instance = await duplicateInstance(id, newName);
- await refresh();
- toast.success(`Instance duplicated as "${newName}"`);
- return instance;
- } catch (e) {
- console.error("Failed to duplicate instance:", e);
- toast.error("Error duplicating instance");
- return null;
- }
- },
-
- getInstance: async (id) => {
- try {
- return await getInstance(id);
- } catch (e) {
- console.error("Failed to get instance:", e);
- return null;
- }
- },
-}));
diff --git a/packages/ui-new/src/models/settings.ts b/packages/ui-new/src/models/settings.ts
deleted file mode 100644
index 9f4119c..0000000
--- a/packages/ui-new/src/models/settings.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import { toast } from "sonner";
-import { create } from "zustand/react";
-import { getConfigPath, getSettings, saveSettings } from "@/client";
-import type { LauncherConfig } from "@/types";
-
-export interface SettingsState {
- config: LauncherConfig | null;
- configPath: string | null;
-
- /* Theme getter */
- get theme(): string;
- /* Apply theme to the document */
- applyTheme: (theme?: string) => void;
-
- /* Refresh settings from the backend */
- refresh: () => Promise<void>;
- /* Save settings to the backend */
- save: () => Promise<void>;
- /* Update settings in the backend */
- update: (config: LauncherConfig) => Promise<void>;
- /* Merge settings with the current config without saving */
- merge: (config: Partial<LauncherConfig>) => void;
-}
-
-export const useSettingsStore = create<SettingsState>((set, get) => ({
- config: null,
- configPath: null,
-
- get theme() {
- const { config } = get();
- return config?.theme || "dark";
- },
- applyTheme: (theme?: string) => {
- const { config } = get();
- if (!config) return;
- if (!theme) theme = config.theme;
- let themeValue = theme;
- if (theme === "system") {
- themeValue = window.matchMedia("(prefers-color-scheme: dark)").matches
- ? "dark"
- : "light";
- }
- document.documentElement.classList.remove("light", "dark");
- document.documentElement.setAttribute("data-theme", themeValue);
- document.documentElement.classList.add(themeValue);
- set({ config: { ...config, theme } });
- },
-
- refresh: async () => {
- const { applyTheme } = get();
- try {
- const settings = await getSettings();
- const path = await getConfigPath();
- set({ config: settings, configPath: path });
- applyTheme(settings.theme);
- } catch (error) {
- console.error("Failed to load settings:", error);
- toast.error("Failed to load settings");
- }
- },
- save: async () => {
- const { config } = get();
- if (!config) return;
- await saveSettings(config);
- },
- update: async (config) => {
- await saveSettings(config);
- set({ config });
- },
- merge: (config) => {
- const { config: currentConfig } = get();
- if (!currentConfig) throw new Error("Settings not loaded");
- set({ config: { ...currentConfig, ...config } });
- },
-}));