2025-04-20 00:49:14 +08:00
|
|
|
import { theme, type TokenType as AntdTheme } from 'ant-design-vue';
|
2025-04-28 00:43:33 +08:00
|
|
|
import { chain } from 'lodash-es';
|
2025-04-20 00:49:14 +08:00
|
|
|
import { ref, watch } from 'vue';
|
|
|
|
|
2025-04-28 00:43:33 +08:00
|
|
|
const THEME_FILES = import.meta.glob('asset/themes/*.json', { eager: true, import: 'default' });
|
|
|
|
const THEME_MAP = chain(THEME_FILES)
|
|
|
|
.mapKeys((_, k) => k.match(/^.*[\\|\\/](.+?)\.[^\\.]+$/)?.[1])
|
|
|
|
.mapValues((v) => <Record<string, string>>v)
|
|
|
|
.value();
|
|
|
|
|
2025-04-20 00:49:14 +08:00
|
|
|
enum Theme {
|
|
|
|
Light = 'light',
|
|
|
|
Dark = 'dark',
|
|
|
|
}
|
|
|
|
export const THEMES = Object.freeze<[string, Theme][]>(Object.entries(Theme));
|
|
|
|
|
2025-04-27 00:05:18 +08:00
|
|
|
const THEME_STORAGE_KEY = 'theme';
|
2025-04-20 00:49:14 +08:00
|
|
|
|
|
|
|
class ThemeService {
|
|
|
|
#theme = ref<Theme>(<Theme>localStorage.getItem(THEME_STORAGE_KEY) || Theme.Dark);
|
|
|
|
public get theme(): Theme {
|
|
|
|
return this.#theme.value;
|
|
|
|
}
|
|
|
|
public set theme(v: Theme) {
|
|
|
|
this.#theme.value = v;
|
|
|
|
localStorage.setItem(THEME_STORAGE_KEY, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
public get ant(): AntdTheme {
|
|
|
|
switch (this.#theme.value) {
|
|
|
|
case Theme.Dark:
|
2025-05-05 01:06:09 +08:00
|
|
|
return { algorithm: theme.darkAlgorithm };
|
2025-04-20 00:49:14 +08:00
|
|
|
case Theme.Light:
|
|
|
|
return { algorithm: theme.defaultAlgorithm };
|
2025-05-05 01:06:09 +08:00
|
|
|
default:
|
|
|
|
return {};
|
2025-04-20 00:49:14 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-04-28 00:43:33 +08:00
|
|
|
public get editor(): object {
|
|
|
|
return THEME_MAP[`editor-${this.#theme.value}`] ?? {};
|
|
|
|
}
|
|
|
|
|
2025-05-05 23:21:31 +08:00
|
|
|
public get empty(): string {
|
|
|
|
const { href } = new URL(`../assets/images/empty-${this.#theme.value}.png`, import.meta.url);
|
|
|
|
return href;
|
|
|
|
}
|
|
|
|
|
2025-04-20 00:49:14 +08:00
|
|
|
constructor() {
|
|
|
|
watch(this.#theme, (v) => this.#load(v), { immediate: true });
|
|
|
|
}
|
|
|
|
|
|
|
|
#load(theme: Theme): void {
|
|
|
|
document.documentElement.setAttribute('theme', theme);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
export default new ThemeService();
|