import type { StateCreator } from 'zustand/vanilla'; import type { AppStore } from '.'; import type { Config } from '@/types/config'; import type { BaseConfigManager } from '@/lib/configManager'; import type { NotificationType } from './initialState'; import type { AppConfig } from '@/types/appConfig'; import { DEFAULT_APP_CONFIG } from '@/constants/appConfig'; export interface AppActions { init: (configManager: BaseConfigManager, config?: Partial) => Promise; updateConfig: (key: keyof Config, value: any) => void; saveConfig: () => Promise; resetConfig: () => Promise; toggleSettings: (show?: boolean) => void; togglePanel: (show?: boolean) => void; showNotification: (message: string, type?: NotificationType, duration?: number) => void; hideNotification: (id: string) => void; registerUpdateHandler: (handler: () => Promise) => void; refreshStats: () => void; updateAvatar: () => Promise; } export const createActions: StateCreator< AppStore, [['zustand/devtools', never]], [], AppActions > = (set, get) => ({ init: async (configManager, appConfig) => { const config = await configManager.loadConfig(); await configManager.loadState(); // Ensure state is loaded const stats = configManager.getState(); const finalAppConfig = { ...DEFAULT_APP_CONFIG, ...appConfig }; set((state) => ({ configManager, config, stats, ui: { ...state.ui, title: finalAppConfig.title } })); }, updateConfig: (key, value) => { set((state) => ({ config: { ...state.config, [key]: value } })); }, saveConfig: async () => { const { configManager, config } = get(); if (configManager) { await configManager.saveConfig(config); } }, resetConfig: async () => { const { configManager } = get(); if (configManager) { await configManager.resetConfig(); const config = configManager.getConfig(); set({ config }); } }, toggleSettings: (show) => set( (state) => ({ ui: { ...state.ui, showSettings: show ?? !state.ui.showSettings } }) ), togglePanel: (show) => set( (state) => ({ ui: { ...state.ui, showPanel: show ?? !state.ui.showPanel } }) ), showNotification: (message, type = 'info', duration = 3000) => { if (get().config.enableNotifications) { const id = Date.now().toString() + Math.random().toString(36).slice(2, 9); set((state) => ({ ui: { ...state.ui, notifications: [...state.ui.notifications, { id, type, message, duration }] } })); if (duration > 0) { setTimeout(() => { get().hideNotification(id); }, duration); } } }, hideNotification: (id) => { set((state) => ({ ui: { ...state.ui, notifications: state.ui.notifications.filter((n) => n.id !== id) } })); }, refreshStats: () => { const { configManager } = get(); if (configManager) { set({ stats: configManager.getState() }); } }, updateAvatar: async () => { const { configManager, updateHandler, config } = get(); if (!configManager || !updateHandler) return; set((state) => ({ ui: { ...state.ui, isUpdating: true } })); try { // 启用开始时的通知 if (config.notifyOnStart) { get().showNotification('开始更新头像...', 'info'); } console.log('[updateAvatar] Starting avatar update...'); await get().updateHandler?.(); console.log('[updateAvatar] Avatar update completed.'); configManager.recordSuccess(); // 启用成功时的通知 if (config.notifyOnSuccess) { get().showNotification('头像更新成功', 'success', 3000); } } catch (error) { console.error('Update failed:', error); configManager.recordError(error instanceof Error ? error : new Error(String(error))); const message = error instanceof Error ? error.message : String(error); // 启用失败时的通知 if (config.notifyOnFailure) { get().showNotification(`失败: ${message}`, 'error', 5000); } } finally { set({ stats: configManager.getState() }); set((state) => ({ ui: { ...state.ui, isUpdating: false } })); } }, registerUpdateHandler: (handler) => { set({ updateHandler: handler }); }, })