@@ -3,13 +3,15 @@ import { DOCUMENT } from '@angular/common';
3
3
import { MediaMatcher } from '@angular/cdk/layout' ;
4
4
import { StorageService } from '../../services/storage.service' ;
5
5
6
+ type Theme = 'light' | 'dark' ;
7
+
6
8
@Component ( {
7
9
selector : 'app-theme-mode-toggle' ,
8
10
templateUrl : './theme-mode-toggle.component.html' ,
9
11
styleUrls : [ './theme-mode-toggle.component.scss' ] ,
10
12
} )
11
13
export class ThemeModeToggleComponent implements OnInit {
12
- isDarkMode : boolean ;
14
+ theme : Theme ;
13
15
14
16
constructor (
15
17
@Inject ( DOCUMENT )
@@ -19,31 +21,35 @@ export class ThemeModeToggleComponent implements OnInit {
19
21
) { }
20
22
21
23
ngOnInit ( ) {
22
- // This is commented out because by default the theme mode is set to light (at least for now)
23
- // const userPrefersTheme =
24
- // this.mediaMatcher.matchMedia &&
25
- // this.mediaMatcher.matchMedia('(prefers-color-scheme: light)').matches;
26
- // this.setThemeMode(this.getUserSettingsIsDarkMode() || userPrefersTheme);
27
-
28
- const isDarkMode = this . getUserSettingsIsDarkMode ( ) ;
29
- this . setThemeMode ( isDarkMode ) ;
24
+ const preferredScheme = this . mediaMatcher . matchMedia (
25
+ '(prefers-color-scheme: dark)' ,
26
+ ) ;
27
+
28
+ preferredScheme . onchange = ( ) => {
29
+ if ( ! this . getStoredTheme ( ) ) this . toggleTheme ( true ) ;
30
+ } ;
31
+
32
+ const isDarkSchemePreferred = preferredScheme . matches ;
33
+ const storedTheme = this . getStoredTheme ( ) ;
34
+
35
+ this . theme = storedTheme ?? ( isDarkSchemePreferred ? 'dark' : 'light' ) ;
36
+ this . setTheme ( this . theme ) ;
30
37
}
31
38
32
- toggleThemeMode ( ) {
33
- const isDarkMode = ! this . isDarkMode ;
34
- this . storageService . set ( 'theme-mode' , isDarkMode . toString ( ) ) ;
35
- this . setThemeMode ( isDarkMode ) ;
39
+ toggleTheme ( skipStorage = false ) {
40
+ this . theme = this . theme === 'dark' ? 'light' : 'dark' ;
41
+ // NOTE: We should skip saving theme in storage when toggle is caused by matchMedia change event
42
+ // Otherwise, once saved, it'll no longer correspond to the system preferences,
43
+ // despite the user not touching the toggle button themselves
44
+ if ( ! skipStorage ) this . storageService . set ( 'theme' , this . theme ) ;
45
+ this . setTheme ( this . theme ) ;
36
46
}
37
47
38
- private getUserSettingsIsDarkMode ( ) : boolean {
39
- return this . storageService . get ( 'theme-mode ' ) === 'true' ;
48
+ private getStoredTheme ( ) {
49
+ return this . storageService . get ( 'theme' ) as Theme | null ;
40
50
}
41
51
42
- private setThemeMode ( isDarkMode : boolean ) {
43
- this . isDarkMode = isDarkMode ;
44
- this . document . documentElement . setAttribute (
45
- 'mode' ,
46
- isDarkMode ? 'dark' : 'light' ,
47
- ) ;
52
+ private setTheme ( theme : Theme ) {
53
+ this . document . documentElement . setAttribute ( 'mode' , theme ) ;
48
54
}
49
55
}
0 commit comments