|
1 | 1 | import { Injectable } from '@angular/core'; |
2 | 2 | import { BehaviorSubject } from 'rxjs'; |
3 | 3 |
|
| 4 | +export type AppTheme = 'light' | 'dark'; |
| 5 | + |
4 | 6 | @Injectable({ providedIn: 'root' }) |
5 | 7 | export class ThemeService { |
6 | | - private themeSubject = new BehaviorSubject<string>('light'); |
| 8 | + private readonly STORAGE_KEY = 'theme'; |
| 9 | + private readonly defaultTheme: AppTheme = 'light'; |
| 10 | + |
| 11 | + private themeSubject = new BehaviorSubject<AppTheme>(this.defaultTheme); |
7 | 12 | public readonly theme$ = this.themeSubject.asObservable(); |
8 | 13 |
|
9 | 14 | constructor() {} |
10 | 15 |
|
11 | 16 | initTheme(): void { |
12 | | - const saved = localStorage.getItem('theme') || 'light'; |
13 | | - this.setTheme(saved); |
| 17 | + const stored = localStorage.getItem(this.STORAGE_KEY); |
| 18 | + const theme: AppTheme = stored === 'dark' ? 'dark' : this.defaultTheme; |
| 19 | + this.setTheme(theme); |
| 20 | + } |
| 21 | + |
| 22 | + setTheme(theme: AppTheme): void { |
| 23 | + if (this.themeSubject.value === theme) return; |
| 24 | + this.applyTheme(theme); |
14 | 25 | } |
15 | 26 |
|
16 | | - setTheme(theme: string): void { |
| 27 | + private applyTheme(theme: AppTheme): void { |
17 | 28 | document.body.classList.remove('light-theme', 'dark-theme'); |
18 | 29 | document.body.classList.add(`${theme}-theme`); |
19 | | - localStorage.setItem('theme', theme); |
| 30 | + |
| 31 | + localStorage.setItem(this.STORAGE_KEY, theme); |
20 | 32 | this.themeSubject.next(theme); |
21 | 33 | } |
22 | 34 |
|
23 | | - getTheme(): string { |
| 35 | + getTheme(): AppTheme { |
24 | 36 | return this.themeSubject.value; |
25 | 37 | } |
| 38 | + |
| 39 | + toggleTheme(): void { |
| 40 | + this.setTheme(this.themeSubject.value === 'light' ? 'dark' : 'light'); |
| 41 | + } |
26 | 42 | } |
0 commit comments