import { ref, computed, watch } from 'vue' import { useSettingStore } from '@/store/modules/setting' import { storeToRefs } from 'pinia' import { useBreakpoints } from '@vueuse/core' import AppConfig from '@/config' import { SystemThemeEnum, MenuTypeEnum } from '@/enums/appEnum' import { mittBus } from '@/utils/sys' import { StorageConfig } from '@/utils' import { useTheme } from '@/hooks/core/useTheme' import { useCeremony } from '@/hooks/core/useCeremony' import { useSettingsState } from './useSettingsState' import { useSettingsHandlers } from './useSettingsHandlers' function useSettingsPanel() { const settingStore = useSettingStore() const { systemThemeType, systemThemeMode, menuType } = storeToRefs(settingStore) const { openFestival, cleanup } = useCeremony() const { setSystemTheme, setSystemAutoTheme } = useTheme() const { initColorWeak } = useSettingsState() const { domOperations } = useSettingsHandlers() const showDrawer = ref(false) const breakpoints = useBreakpoints({ tablet: 1e3 }) const isMobile = breakpoints.smaller('tablet') const getStoredDesktopMenuType = () => { const storedMenuType = localStorage.getItem(StorageConfig.RESPONSIVE_MENU_TYPE_KEY) return Object.values(MenuTypeEnum).includes(storedMenuType) ? storedMenuType : void 0 } const setStoredDesktopMenuType = (type) => { localStorage.setItem(StorageConfig.RESPONSIVE_MENU_TYPE_KEY, type) } const clearStoredDesktopMenuType = () => { localStorage.removeItem(StorageConfig.RESPONSIVE_MENU_TYPE_KEY) } const storedDesktopMenuType = getStoredDesktopMenuType() const beforeMenuType = ref(storedDesktopMenuType) const hasChangedMenu = ref(Boolean(storedDesktopMenuType)) const systemThemeColor = computed(() => settingStore.systemThemeColor) const useThemeHandlers = () => { const initSystemColor = () => { if (!AppConfig.systemMainColor.includes(systemThemeColor.value)) { settingStore.setElementTheme(AppConfig.systemMainColor[0]) settingStore.reload() } } const initSystemTheme = () => { if (systemThemeMode.value === SystemThemeEnum.AUTO) { setSystemAutoTheme() } else { setSystemTheme(systemThemeType.value) } } const listenerSystemTheme = () => { const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)') mediaQuery.addEventListener('change', initSystemTheme) return () => { mediaQuery.removeEventListener('change', initSystemTheme) } } return { initSystemColor, initSystemTheme, listenerSystemTheme } } const useResponsiveLayout = () => { const stopWatch = watch( isMobile, (mobile) => { if (mobile) { if (!hasChangedMenu.value) { beforeMenuType.value = menuType.value if (menuType.value !== MenuTypeEnum.LEFT) { setStoredDesktopMenuType(menuType.value) useSettingsState().switchMenuLayouts(MenuTypeEnum.LEFT) hasChangedMenu.value = true } } settingStore.setMenuOpen(false) } else { if (hasChangedMenu.value && beforeMenuType.value) { if (menuType.value === MenuTypeEnum.LEFT) { useSettingsState().switchMenuLayouts(beforeMenuType.value) } clearStoredDesktopMenuType() hasChangedMenu.value = false } settingStore.setMenuOpen(true) } }, { immediate: true } ) return { stopWatch } } const useDrawerControl = () => { let themeChangeTimer = null const handleOpen = () => { if (themeChangeTimer) { clearTimeout(themeChangeTimer) } themeChangeTimer = setTimeout(() => { domOperations.setBodyClass('theme-change', true) themeChangeTimer = null }, 500) } const handleClose = () => { if (themeChangeTimer) { clearTimeout(themeChangeTimer) themeChangeTimer = null } domOperations.setBodyClass('theme-change', false) } const openSetting = () => { showDrawer.value = true } const closeDrawer = () => { showDrawer.value = false } return { handleOpen, handleClose, openSetting, closeDrawer } } const usePropsWatcher = (props) => { watch( () => props.open, (val) => { if (val !== void 0) { showDrawer.value = val } } ) } const useSettingsInitializer = () => { const themeHandlers = useThemeHandlers() const { openSetting } = useDrawerControl() const { stopWatch } = useResponsiveLayout() let themeCleanup = null const initializeSettings = () => { mittBus.on('openSetting', openSetting) themeHandlers.initSystemColor() themeCleanup = themeHandlers.listenerSystemTheme() initColorWeak() const boxMode = settingStore.boxBorderMode ? 'border-mode' : 'shadow-mode' domOperations.setRootAttribute('data-box-mode', boxMode) themeHandlers.initSystemTheme() openFestival() } const cleanupSettings = () => { stopWatch() themeCleanup?.() cleanup() } return { initializeSettings, cleanupSettings } } return { // 状态 showDrawer, // 方法组合 useThemeHandlers, useResponsiveLayout, useDrawerControl, usePropsWatcher, useSettingsInitializer } } export { useSettingsPanel }