ui rebuild
This commit is contained in:
64
ui/src/app/core/services/theme.service.ts
Normal file
64
ui/src/app/core/services/theme.service.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { Injectable, signal, effect } from '@angular/core';
|
||||
|
||||
export type Theme = 'light' | 'dark' | 'system';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ThemeService {
|
||||
theme = signal<Theme>(this.loadTheme());
|
||||
|
||||
constructor() {
|
||||
effect(() => {
|
||||
this.applyTheme(this.theme());
|
||||
});
|
||||
|
||||
// Listen for system preference changes
|
||||
if (typeof window !== 'undefined') {
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
||||
if (this.theme() === 'system') {
|
||||
this.applyTheme('system');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private loadTheme(): Theme {
|
||||
if (typeof localStorage === 'undefined') return 'system';
|
||||
const stored = localStorage.getItem('onebox-theme');
|
||||
if (stored === 'light' || stored === 'dark' || stored === 'system') {
|
||||
return stored;
|
||||
}
|
||||
return 'system';
|
||||
}
|
||||
|
||||
setTheme(theme: Theme): void {
|
||||
this.theme.set(theme);
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
localStorage.setItem('onebox-theme', theme);
|
||||
}
|
||||
}
|
||||
|
||||
toggle(): void {
|
||||
const resolved = this.resolvedTheme();
|
||||
this.setTheme(resolved === 'dark' ? 'light' : 'dark');
|
||||
}
|
||||
|
||||
isDark(): boolean {
|
||||
return this.resolvedTheme() === 'dark';
|
||||
}
|
||||
|
||||
resolvedTheme(): 'light' | 'dark' {
|
||||
if (this.theme() === 'system') {
|
||||
if (typeof window === 'undefined') return 'light';
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
}
|
||||
return this.theme() as 'light' | 'dark';
|
||||
}
|
||||
|
||||
private applyTheme(theme: Theme): void {
|
||||
if (typeof document === 'undefined') return;
|
||||
const resolved = theme === 'system'
|
||||
? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
|
||||
: theme;
|
||||
document.documentElement.classList.toggle('dark', resolved === 'dark');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user