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 }
|