初始化
This commit is contained in:
229
src/store/modules/theme/index.ts
Normal file
229
src/store/modules/theme/index.ts
Normal file
@@ -0,0 +1,229 @@
|
||||
import { computed, effectScope, onScopeDispose, ref, toRefs, watch } from 'vue';
|
||||
import type { Ref } from 'vue';
|
||||
import { usePreferredColorScheme } from '@vueuse/core';
|
||||
import { defineStore } from 'pinia';
|
||||
import { getPaletteColorByNumber } from '@sa/color';
|
||||
import { localStg } from '@/utils/storage';
|
||||
import { themeSettings } from '@/theme/settings';
|
||||
import { SetupStoreId } from '@/enum';
|
||||
import {
|
||||
addThemeVarsToGlobal,
|
||||
createThemeToken,
|
||||
getNaiveTheme,
|
||||
initThemeSettings,
|
||||
toggleAuxiliaryColorModes,
|
||||
toggleCssDarkMode
|
||||
} from './shared';
|
||||
|
||||
/** Theme store */
|
||||
export const useThemeStore = defineStore(SetupStoreId.Theme, () => {
|
||||
const scope = effectScope();
|
||||
const osTheme = usePreferredColorScheme();
|
||||
|
||||
/** Theme settings */
|
||||
const settings: Ref<App.Theme.ThemeSetting> = ref(initThemeSettings());
|
||||
|
||||
/** Dark mode */
|
||||
const darkMode = computed(() => {
|
||||
if (settings.value.themeScheme === 'auto') {
|
||||
return osTheme.value === 'dark';
|
||||
}
|
||||
return settings.value.themeScheme === 'dark';
|
||||
});
|
||||
|
||||
/** grayscale mode */
|
||||
const grayscaleMode = computed(() => settings.value.grayscale);
|
||||
|
||||
/** colourWeakness mode */
|
||||
const colourWeaknessMode = computed(() => settings.value.colourWeakness);
|
||||
|
||||
/** Theme colors */
|
||||
const themeColors = computed(() => {
|
||||
const { themeColor, otherColor, isInfoFollowPrimary } = settings.value;
|
||||
const colors: App.Theme.ThemeColor = {
|
||||
primary: themeColor,
|
||||
...otherColor,
|
||||
info: isInfoFollowPrimary ? themeColor : otherColor.info
|
||||
};
|
||||
return colors;
|
||||
});
|
||||
|
||||
/** UI theme */
|
||||
const uiTheme = computed(() => getNaiveTheme(themeColors.value, settings.value.recommendColor));
|
||||
|
||||
/**
|
||||
* Settings json
|
||||
*
|
||||
* It is for copy settings
|
||||
*/
|
||||
const settingsJson = computed(() => JSON.stringify(settings.value));
|
||||
|
||||
/** Reset store */
|
||||
function resetStore() {
|
||||
settings.value = themeSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set theme scheme
|
||||
*
|
||||
* @param themeScheme
|
||||
*/
|
||||
function setThemeScheme(themeScheme: UnionKey.ThemeScheme) {
|
||||
settings.value.themeScheme = themeScheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set grayscale value
|
||||
*
|
||||
* @param isGrayscale
|
||||
*/
|
||||
function setGrayscale(isGrayscale: boolean) {
|
||||
settings.value.grayscale = isGrayscale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set colourWeakness value
|
||||
*
|
||||
* @param isColourWeakness
|
||||
*/
|
||||
function setColourWeakness(isColourWeakness: boolean) {
|
||||
settings.value.colourWeakness = isColourWeakness;
|
||||
}
|
||||
|
||||
/** Toggle theme scheme */
|
||||
function toggleThemeScheme() {
|
||||
const themeSchemes: UnionKey.ThemeScheme[] = ['light', 'dark', 'auto'];
|
||||
|
||||
const index = themeSchemes.findIndex(item => item === settings.value.themeScheme);
|
||||
|
||||
const nextIndex = index === themeSchemes.length - 1 ? 0 : index + 1;
|
||||
|
||||
const nextThemeScheme = themeSchemes[nextIndex];
|
||||
|
||||
setThemeScheme(nextThemeScheme);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update theme colors
|
||||
*
|
||||
* @param key Theme color key
|
||||
* @param color Theme color
|
||||
*/
|
||||
function updateThemeColors(key: App.Theme.ThemeColorKey, color: string) {
|
||||
let colorValue = color;
|
||||
|
||||
if (settings.value.recommendColor) {
|
||||
// get a color palette by provided color and color name, and use the suitable color
|
||||
|
||||
colorValue = getPaletteColorByNumber(color, 500, true);
|
||||
}
|
||||
|
||||
if (key === 'primary') {
|
||||
settings.value.themeColor = colorValue;
|
||||
} else {
|
||||
settings.value.otherColor[key] = colorValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set theme layout
|
||||
*
|
||||
* @param mode Theme layout mode
|
||||
*/
|
||||
function setThemeLayout(mode: UnionKey.ThemeLayoutMode) {
|
||||
settings.value.layout.mode = mode;
|
||||
}
|
||||
|
||||
/** Setup theme vars to global */
|
||||
function setupThemeVarsToGlobal() {
|
||||
const { themeTokens, darkThemeTokens } = createThemeToken(
|
||||
themeColors.value,
|
||||
settings.value.tokens,
|
||||
settings.value.recommendColor
|
||||
);
|
||||
addThemeVarsToGlobal(themeTokens, darkThemeTokens);
|
||||
}
|
||||
/**
|
||||
* Set layout reverse horizontal mix
|
||||
*
|
||||
* @param reverse Reverse horizontal mix
|
||||
*/
|
||||
function setLayoutReverseHorizontalMix(reverse: boolean) {
|
||||
settings.value.layout.reverseHorizontalMix = reverse;
|
||||
}
|
||||
|
||||
/** Cache theme settings */
|
||||
function cacheThemeSettings() {
|
||||
const isProd = import.meta.env.MODE === 'prod';
|
||||
|
||||
if (!isProd) return;
|
||||
|
||||
localStg.set('themeSettings', settings.value);
|
||||
}
|
||||
|
||||
// cache theme settings when page is closed or refreshed
|
||||
// useEventListener(window, 'beforeunload', () => {
|
||||
// cacheThemeSettings();
|
||||
// });
|
||||
|
||||
// watch store
|
||||
scope.run(() => {
|
||||
// watch dark mode
|
||||
watch(
|
||||
darkMode,
|
||||
val => {
|
||||
toggleCssDarkMode(val);
|
||||
localStg.set('darkMode', val);
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
[grayscaleMode, colourWeaknessMode],
|
||||
val => {
|
||||
toggleAuxiliaryColorModes(val[0], val[1]);
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// themeColors change, update css vars and storage theme color
|
||||
watch(
|
||||
themeColors,
|
||||
val => {
|
||||
setupThemeVarsToGlobal();
|
||||
localStg.set('themeColor', val.primary);
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// cache theme settings when settings change
|
||||
watch(
|
||||
settings,
|
||||
() => {
|
||||
cacheThemeSettings();
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
});
|
||||
|
||||
/** On scope dispose */
|
||||
onScopeDispose(() => {
|
||||
scope.stop();
|
||||
});
|
||||
|
||||
return {
|
||||
...toRefs(settings.value),
|
||||
darkMode,
|
||||
themeColors,
|
||||
uiTheme,
|
||||
settingsJson,
|
||||
setGrayscale,
|
||||
setColourWeakness,
|
||||
resetStore,
|
||||
setThemeScheme,
|
||||
toggleThemeScheme,
|
||||
updateThemeColors,
|
||||
setThemeLayout,
|
||||
setLayoutReverseHorizontalMix
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user