diff options
Diffstat (limited to 'packages/ui-new/src/models')
| -rw-r--r-- | packages/ui-new/src/models/auth.ts | 142 | ||||
| -rw-r--r-- | packages/ui-new/src/models/instances.ts | 135 | ||||
| -rw-r--r-- | packages/ui-new/src/models/settings.ts | 75 |
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 } }); - }, -})); |