Files
DeskClaw/src/stores/settings.ts

179 lines
5.9 KiB
TypeScript

/**
* Settings State Store
* Manages application settings
*/
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import i18n from '@/i18n';
import { hostApiFetch } from '@/lib/host-api';
import { resolveSupportedLanguage } from '../../shared/language';
type Theme = 'light' | 'dark' | 'system';
type UpdateChannel = 'stable' | 'beta' | 'dev';
interface SettingsState {
// General
theme: Theme;
language: string;
startMinimized: boolean;
launchAtStartup: boolean;
telemetryEnabled: boolean;
// Gateway
gatewayAutoStart: boolean;
gatewayPort: number;
proxyEnabled: boolean;
proxyServer: string;
proxyHttpServer: string;
proxyHttpsServer: string;
proxyAllServer: string;
proxyBypassRules: string;
// Update
updateChannel: UpdateChannel;
autoCheckUpdate: boolean;
autoDownloadUpdate: boolean;
// UI State
sidebarCollapsed: boolean;
devModeUnlocked: boolean;
// Setup
setupComplete: boolean;
// Actions
init: () => Promise<void>;
setTheme: (theme: Theme) => void;
setLanguage: (language: string) => void;
setStartMinimized: (value: boolean) => void;
setLaunchAtStartup: (value: boolean) => void;
setTelemetryEnabled: (value: boolean) => void;
setGatewayAutoStart: (value: boolean) => void;
setGatewayPort: (port: number) => void;
setProxyEnabled: (value: boolean) => void;
setProxyServer: (value: string) => void;
setProxyHttpServer: (value: string) => void;
setProxyHttpsServer: (value: string) => void;
setProxyAllServer: (value: string) => void;
setProxyBypassRules: (value: string) => void;
setUpdateChannel: (channel: UpdateChannel) => void;
setAutoCheckUpdate: (value: boolean) => void;
setAutoDownloadUpdate: (value: boolean) => void;
setSidebarCollapsed: (value: boolean) => void;
setDevModeUnlocked: (value: boolean) => void;
markSetupComplete: () => void;
resetSettings: () => void;
}
const defaultSettings = {
theme: 'system' as Theme,
language: resolveSupportedLanguage(typeof navigator !== 'undefined' ? navigator.language : undefined),
startMinimized: false,
launchAtStartup: false,
telemetryEnabled: true,
gatewayAutoStart: true,
gatewayPort: 18789,
proxyEnabled: false,
proxyServer: '',
proxyHttpServer: '',
proxyHttpsServer: '',
proxyAllServer: '',
proxyBypassRules: '<local>;localhost;127.0.0.1;::1',
updateChannel: 'stable' as UpdateChannel,
autoCheckUpdate: true,
autoDownloadUpdate: false,
sidebarCollapsed: false,
devModeUnlocked: false,
setupComplete: false,
};
export const useSettingsStore = create<SettingsState>()(
persist(
(set) => ({
...defaultSettings,
init: async () => {
try {
const settings = await hostApiFetch<Partial<typeof defaultSettings>>('/api/settings');
const resolvedLanguage = settings.language
? resolveSupportedLanguage(settings.language)
: undefined;
set((state) => ({
...state,
...settings,
...(resolvedLanguage ? { language: resolvedLanguage } : {}),
}));
if (resolvedLanguage) {
i18n.changeLanguage(resolvedLanguage);
}
} catch {
// Keep renderer-persisted settings as a fallback when the main
// process store is not reachable.
}
},
setTheme: (theme) => set({ theme }),
setLanguage: (language) => {
const resolvedLanguage = resolveSupportedLanguage(language);
i18n.changeLanguage(resolvedLanguage);
set({ language: resolvedLanguage });
void hostApiFetch('/api/settings/language', {
method: 'PUT',
body: JSON.stringify({ value: resolvedLanguage }),
}).catch(() => { });
},
setStartMinimized: (startMinimized) => set({ startMinimized }),
setLaunchAtStartup: (launchAtStartup) => {
set({ launchAtStartup });
void hostApiFetch('/api/settings/launchAtStartup', {
method: 'PUT',
body: JSON.stringify({ value: launchAtStartup }),
}).catch(() => { });
},
setTelemetryEnabled: (telemetryEnabled) => {
set({ telemetryEnabled });
void hostApiFetch('/api/settings/telemetryEnabled', {
method: 'PUT',
body: JSON.stringify({ value: telemetryEnabled }),
}).catch(() => { });
},
setGatewayAutoStart: (gatewayAutoStart) => {
set({ gatewayAutoStart });
void hostApiFetch('/api/settings/gatewayAutoStart', {
method: 'PUT',
body: JSON.stringify({ value: gatewayAutoStart }),
}).catch(() => { });
},
setGatewayPort: (gatewayPort) => {
set({ gatewayPort });
void hostApiFetch('/api/settings/gatewayPort', {
method: 'PUT',
body: JSON.stringify({ value: gatewayPort }),
}).catch(() => { });
},
setProxyEnabled: (proxyEnabled) => set({ proxyEnabled }),
setProxyServer: (proxyServer) => set({ proxyServer }),
setProxyHttpServer: (proxyHttpServer) => set({ proxyHttpServer }),
setProxyHttpsServer: (proxyHttpsServer) => set({ proxyHttpsServer }),
setProxyAllServer: (proxyAllServer) => set({ proxyAllServer }),
setProxyBypassRules: (proxyBypassRules) => set({ proxyBypassRules }),
setUpdateChannel: (updateChannel) => set({ updateChannel }),
setAutoCheckUpdate: (autoCheckUpdate) => set({ autoCheckUpdate }),
setAutoDownloadUpdate: (autoDownloadUpdate) => set({ autoDownloadUpdate }),
setSidebarCollapsed: (sidebarCollapsed) => set({ sidebarCollapsed }),
setDevModeUnlocked: (devModeUnlocked) => {
set({ devModeUnlocked });
void hostApiFetch('/api/settings/devModeUnlocked', {
method: 'PUT',
body: JSON.stringify({ value: devModeUnlocked }),
}).catch(() => { });
},
markSetupComplete: () => set({ setupComplete: true }),
resetSettings: () => set(defaultSettings),
}),
{
name: 'clawx-settings',
}
)
);