2024-12-07 01:04:16 +08:00

165 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { getAppDefaultLanguage } from '@/locales/utils'
import { colorToRgba, setStorage, updateObjectValue, setStyle } from '@/utils'
import { useI18n, useDayjs } from '@/hooks'
import { APP_CATCH_KEY, APP_THEME, GLOBAL_CLASS_NAMES } from '@/app-config'
import { getDefaultSettingConfig } from './constant'
import { merge } from 'lodash-es'
import type { SettingState } from '@/store/modules/setting/types'
import type { LocalKey } from '@/hooks'
import type { AnyFC } from '@/types'
export const piniaSettingStore = defineStore(
'setting',
() => {
const {
appPrimaryColor: { primaryColor, primaryFadeColor },
} = APP_THEME
const { locale } = useI18n()
const { locale: dayjsLocal } = useDayjs()
const settingState = reactive<SettingState>({
// 默认主题色
primaryColorOverride: {
common: {
primaryColor: primaryColor,
primaryColorHover: primaryFadeColor,
primaryColorPressed: primaryFadeColor,
primaryColorSuppl: colorToRgba(primaryColor, 0.9),
},
},
// 内部使用用于判断是否为黑夜主题为了兼容历史遗留版本true 为黑夜主题false 为明亮主题
_appTheme: false,
// 当前主题样式
appTheme: 'light',
// 默认国际化语言
localeLanguage: getAppDefaultLanguage(),
// 锁屏开关
lockScreenSwitch: false,
// 根路由信息
appRootRoute: {
name: 'Dashboard',
path: '/dashboard',
},
// 侧边栏设置
sideBarLogo: {
icon: 'ray',
title: 'Ray Template',
url: '/dashboard',
jumpType: 'station',
},
...getDefaultSettingConfig(),
})
// 修改当前语言
const updateLocale = (key: string) => {
locale(key)
dayjsLocal(key as LocalKey)
setStorage(APP_CATCH_KEY.localeLanguage, key, 'localStorage')
settingState.localeLanguage = key
}
/**
*
* @description
* 切换主题色,传递对应颜色即可更新 naive-ui 的主题色。
*/
const changePrimaryColor = (value: string, alpha = 0.8) => {
const alphaColor1 = colorToRgba(value, alpha)
const alphaColor2 = colorToRgba(value, 0.9)
const themeOverrides = {
primaryColor: value,
primaryColorHover: alphaColor1,
primaryColorPressed: alphaColor1,
primaryColorSuppl: alphaColor2,
}
const { rayTemplateThemePrimaryColor, rayTemplateThemePrimaryFadeColor } =
GLOBAL_CLASS_NAMES
const html = document.documentElement
settingState.primaryColorOverride.common = themeOverrides
// 设置主题色变量
html.style.setProperty(rayTemplateThemePrimaryColor, value)
// 设置主题色辅助色变量
html.style.setProperty(rayTemplateThemePrimaryFadeColor, alphaColor1)
}
/**
*
* @param key settingState 的 key
* @param value settingState 的 value
* @param cb 回调函数
*
* @description
* 更新 settingState 的值,如果 key 不存在与 settingState 中,则不会更新。
*
* @example
* updateSettingState('drawerPlacement', 'left')
* updateSettingState('appTheme', true)
*/
const updateSettingState = <
T extends keyof SettingState,
V extends typeof settingState,
C extends AnyFC,
>(
key: T,
value: Partial<V[T]>,
cb?: C,
) => {
updateObjectValue(settingState, key, value as V[T], cb)
}
const toggleColorWeakness = (bool: boolean) => {
const html = document.documentElement
updateSettingState('colorWeakness', bool)
setStyle(html, {
filter: bool ? 'invert(100%)' : '',
})
}
/**
*
* @description
* 初始化合并自定义主题色。
* 该方法会在初始化时执行一次,之后会在切换主题色时执行。
*/
watchEffect(() => {
settingState._appTheme
? (settingState.primaryColorOverride = merge(
{},
settingState.primaryColorOverride,
APP_THEME.appNaiveUIThemeOverrides.dark,
))
: (settingState.primaryColorOverride = merge(
{},
settingState.primaryColorOverride,
APP_THEME.appNaiveUIThemeOverrides.light,
))
toggleColorWeakness(settingState.colorWeakness)
if (!settingState.dynamicDocumentTitle) {
document.title = settingState.sideBarLogo?.title || 'Ray Template'
}
})
return {
...toRefs(settingState),
updateLocale,
changePrimaryColor,
updateSettingState,
toggleColorWeakness,
}
},
{
persist: {
key: APP_CATCH_KEY.appPiniaSettingStore,
omit: ['lockScreenSwitch'],
storage: window.localStorage,
},
},
)