import { darkMode, deepMerge, MenuModeEnum, MenuTypeEnum, Persistent, ThemeEnum, } from '@eciol/shared'; import type { HeaderSetting, MenuSetting, MultiTabsSetting, ProjectConfig, TransitionSetting, } from '@eciol/types'; import { context } from '../context'; import { acceptHMRUpdate, defineStore, pinia } from '../index'; interface BeforeMiniState { menuCollapsed?: boolean; menuSplit?: boolean; menuMode?: MenuModeEnum; menuType?: MenuTypeEnum; } interface AppState { darkMode?: ThemeEnum; // Page loading status pageLoading: boolean; // project config projectConfig: ProjectConfig | null; // When the window shrinks, remember some states, and restore these states when the window is restored beforeMiniInfo: BeforeMiniState; } let timeId: TimeoutHandle; export const useAppStore = defineStore('shared-app-store', { persist: { // 持久化 paths: ['darkMode', 'projectConfig'], }, state: (): AppState => ({ darkMode: undefined, pageLoading: false, projectConfig: context.projectSetting ?? null, beforeMiniInfo: {}, }), getters: { getPageLoading(state): boolean { return state.pageLoading; }, getDarkMode(state): 'light' | 'dark' | string { return state.darkMode || context.darkMode || darkMode; }, getLightTheme(state) { return state.projectConfig?.lightTheme || {}; }, getDarkTheme(state) { return state.projectConfig?.darkTheme || {}; }, getBeforeMiniInfo(state): BeforeMiniState { return state.beforeMiniInfo; }, getProjectConfig(state): ProjectConfig { return state.projectConfig || ({} as ProjectConfig); }, getHeaderSetting(): HeaderSetting { return this.getProjectConfig.headerSetting; }, getMenuSetting(): MenuSetting { return this.getProjectConfig.menuSetting; }, getTransitionSetting(): TransitionSetting { return this.getProjectConfig.transitionSetting; }, getMultiTabsSetting(): MultiTabsSetting { return this.getProjectConfig.multiTabsSetting; }, }, actions: { setPageLoading(loading: boolean): void { this.pageLoading = loading; }, setDarkMode(mode: ThemeEnum): void { this.darkMode = mode; }, setBeforeMiniInfo(state: BeforeMiniState): void { this.beforeMiniInfo = state; }, setProjectConfig(config: DeepPartial): void { this.projectConfig = deepMerge(this.projectConfig || {}, config) as any; }, async resetAllState() { context.resetRouter?.(); Persistent.clearAll(); }, async setPageLoadingAction(loading: boolean): Promise { if (loading) { clearTimeout(timeId); // Prevent flicker timeId = setTimeout(() => { this.setPageLoading(loading); }, 50); } else { this.setPageLoading(loading); clearTimeout(timeId); } }, }, }); // 解决热更新问题 const hot = import.meta.hot; if (hot) { hot.accept(acceptHMRUpdate(useAppStore, hot)); } // Need to be used outside the setup export function useAppStoreWithOut() { return useAppStore(pinia); }