mirror of
https://github.com/samsonjs/immich.git
synced 2026-03-25 09:15:56 +00:00
* chore(web): upgrade ESLint and plugins, simplify linting configuration - Update eslint from ^9.18.0 to ^9.36.0 - Update eslint plugins: - eslint-plugin-svelte: ^3.9.0 → ^3.12.4 - eslint-plugin-unicorn: ^60.0.0 → ^61.0.2 - svelte-eslint-parser: ^1.2.0 → ^1.3.3 - typescript-eslint: ^8.28.0 → ^8.45.0 - Remove eslint-p dependency in favor of native eslint concurrency - Add unicorn/no-array-sort rule exception - Update linting scripts to use eslint's native --concurrency flag - Update Makefile and mise.toml to reflect simplified lint commands - Update GitHub Actions workflow to use standard pnpm lint command * pnpm dedupe --------- Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
78 lines
1.8 KiB
TypeScript
78 lines
1.8 KiB
TypeScript
import { browser } from '$app/environment';
|
|
import { Theme } from '$lib/constants';
|
|
import { eventManager } from '$lib/managers/event-manager.svelte';
|
|
import { PersistedLocalStorage } from '$lib/utils/persisted';
|
|
|
|
export interface ThemeSetting {
|
|
value: Theme;
|
|
system: boolean;
|
|
}
|
|
|
|
const getDefaultTheme = () => {
|
|
if (!browser) {
|
|
return Theme.DARK;
|
|
}
|
|
|
|
return globalThis.matchMedia('(prefers-color-scheme: dark)').matches ? Theme.DARK : Theme.LIGHT;
|
|
};
|
|
|
|
class ThemeManager {
|
|
#theme = new PersistedLocalStorage<ThemeSetting>(
|
|
'color-theme',
|
|
{ value: getDefaultTheme(), system: false },
|
|
{
|
|
valid: (value): value is ThemeSetting => {
|
|
return Object.values(Theme).includes((value as ThemeSetting)?.value);
|
|
},
|
|
},
|
|
);
|
|
|
|
get theme() {
|
|
return this.#theme.current;
|
|
}
|
|
|
|
value = $derived(this.theme.value);
|
|
|
|
isDark = $derived(this.value === Theme.DARK);
|
|
|
|
constructor() {
|
|
eventManager.on('app.init', () => this.#onAppInit());
|
|
}
|
|
|
|
setSystem(system: boolean) {
|
|
this.#update(system ? 'system' : getDefaultTheme());
|
|
}
|
|
|
|
setTheme(theme: Theme) {
|
|
this.#update(theme);
|
|
}
|
|
|
|
toggleTheme() {
|
|
this.#update(this.value === Theme.DARK ? Theme.LIGHT : Theme.DARK);
|
|
}
|
|
|
|
#onAppInit() {
|
|
globalThis.matchMedia('(prefers-color-scheme: dark)').addEventListener(
|
|
'change',
|
|
() => {
|
|
if (this.theme.system) {
|
|
this.#update('system');
|
|
}
|
|
},
|
|
{ passive: true },
|
|
);
|
|
}
|
|
|
|
#update(value: Theme | 'system') {
|
|
const theme: ThemeSetting =
|
|
value === 'system' ? { system: true, value: getDefaultTheme() } : { system: false, value };
|
|
|
|
document.documentElement.classList.toggle('dark', !(theme.value === Theme.LIGHT));
|
|
|
|
this.#theme.current = theme;
|
|
|
|
eventManager.emit('theme.change', theme);
|
|
}
|
|
}
|
|
|
|
export const themeManager = new ThemeManager();
|