Skip to content
This repository was archived by the owner on Feb 6, 2024. It is now read-only.

Commit e92f018

Browse files
feat(#773): use stencil/store for theme
1 parent bb50cd9 commit e92f018

File tree

5 files changed

+32
-76
lines changed

5 files changed

+32
-76
lines changed

remote/src/app/app-root.tsx

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import {Build, Component, h, State} from '@stencil/core';
22

3-
import {Subscription} from 'rxjs';
4-
53
import {TimerService} from './services/timer/timer.service';
64
import {AccelerometerService} from './services/accelerometer/accelerometer.service';
75
import {ThemeService} from './services/theme/theme.service';
@@ -14,11 +12,8 @@ export class AppRoot {
1412
private timerService: TimerService;
1513
private accelerometerService: AccelerometerService;
1614

17-
private themeSubscription: Subscription;
1815
private themeService: ThemeService;
1916

20-
private domBodyClassList: DOMTokenList = document.body.classList;
21-
2217
@State()
2318
private loading: boolean = true;
2419

@@ -29,10 +24,6 @@ export class AppRoot {
2924
}
3025

3126
async componentWillLoad() {
32-
this.themeSubscription = this.themeService.watch().subscribe((dark: boolean) => {
33-
this.updateDarkModePreferences(dark);
34-
});
35-
3627
await this.themeService.initDarkModePreference();
3728
}
3829

@@ -48,14 +39,6 @@ export class AppRoot {
4839

4940
async componentDidUnload() {
5041
await this.timerService.destroy();
51-
52-
if (this.themeSubscription) {
53-
this.themeSubscription.unsubscribe();
54-
}
55-
}
56-
57-
private updateDarkModePreferences(dark: boolean) {
58-
dark ? this.domBodyClassList.add('dark') : this.domBodyClassList.remove('dark');
5942
}
6043

6144
render() {

remote/src/app/components/app-header/app-header.tsx

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,16 @@
1-
import {Component, h, State} from '@stencil/core';
1+
import {Component, h} from '@stencil/core';
22

3-
import {Subscription} from 'rxjs';
4-
5-
import {ThemeService} from '../../services/theme/theme.service';
3+
import themeStore from '../../stores/theme.store';
64

75
@Component({
86
tag: 'app-header',
9-
styleUrl: 'app-header.scss'
7+
styleUrl: 'app-header.scss',
108
})
119
export class AppHeader {
12-
private themeSubscription: Subscription;
13-
private themeService: ThemeService;
14-
15-
@State()
16-
private darkTheme: boolean;
17-
18-
constructor() {
19-
this.themeService = ThemeService.getInstance();
20-
}
21-
22-
async componentWillLoad() {
23-
this.themeSubscription = this.themeService.watch().subscribe((dark: boolean) => {
24-
this.darkTheme = dark;
25-
});
26-
}
27-
28-
componentWillUnload() {
29-
if (this.themeSubscription) {
30-
this.themeSubscription.unsubscribe();
31-
}
32-
}
33-
3410
render() {
3511
return (
3612
<ion-header>
37-
<ion-toolbar color={this.darkTheme ? 'dark' : 'primary'}>
13+
<ion-toolbar color={themeStore.state.darkTheme ? 'dark' : 'primary'}>
3814
<slot name="start">
3915
<ion-buttons slot="start">
4016
<ion-menu-toggle>
Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import {Component, h, State} from '@stencil/core';
1+
import {Component, h} from '@stencil/core';
22

3-
import {take} from 'rxjs/operators';
3+
import themeStore from '../../../stores/theme.store';
44

55
import {ThemeService} from '../../../services/theme/theme.service';
66

77
@Component({
8-
tag: 'app-general-settings'
8+
tag: 'app-general-settings',
99
})
1010
export class AppGeneralSettings {
1111
private themeService: ThemeService;
@@ -14,34 +14,21 @@ export class AppGeneralSettings {
1414
this.themeService = ThemeService.getInstance();
1515
}
1616

17-
componentWillLoad() {
18-
this.themeService
19-
.watch()
20-
.pipe(take(1))
21-
.subscribe((dark: boolean) => {
22-
this.darkTheme = dark;
23-
});
24-
}
25-
2617
async toggleTheme() {
27-
this.darkTheme = !this.darkTheme;
28-
await this.themeService.switch(this.darkTheme);
18+
await this.themeService.switch(!themeStore.state.darkTheme);
2919
}
3020

31-
@State()
32-
private darkTheme: boolean;
33-
3421
render() {
3522
return [
3623
<h1 class="ion-padding-top">Settings</h1>,
3724
<ion-list class="ion-padding-top ion-padding-bottom">
3825
<ion-item>
3926
<ion-label>
40-
{this.darkTheme ? 'Dark' : 'Light'} theme {this.darkTheme ? '🌑' : '☀️'}
27+
{themeStore.state.darkTheme ? 'Dark' : 'Light'} theme {themeStore.state.darkTheme ? '🌑' : '☀️'}
4128
</ion-label>
42-
<ion-toggle slot="end" checked={this.darkTheme} mode="md" color="switcher" onIonChange={() => this.toggleTheme()}></ion-toggle>
29+
<ion-toggle slot="end" checked={themeStore.state.darkTheme} mode="md" color="switcher" onIonChange={() => this.toggleTheme()}></ion-toggle>
4330
</ion-item>
44-
</ion-list>
31+
</ion-list>,
4532
];
4633
}
4734
}
Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import {Observable, ReplaySubject} from 'rxjs';
1+
import themeStore from '../../stores/theme.store';
22

33
import {get, set} from 'idb-keyval';
44

55
export class ThemeService {
66
private static instance: ThemeService;
77

8-
private darkTheme: ReplaySubject<boolean> = new ReplaySubject<boolean>(1);
9-
108
private constructor() {
119
// Private constructor, singleton
1210
}
@@ -18,12 +16,8 @@ export class ThemeService {
1816
return ThemeService.instance;
1917
}
2018

21-
watch(): Observable<boolean> {
22-
return this.darkTheme.asObservable();
23-
}
24-
2519
async switch(dark: boolean) {
26-
this.darkTheme.next(dark);
20+
themeStore.state.darkTheme = dark;
2721

2822
try {
2923
await set('deckdeckgo_dark_mode', dark);
@@ -38,17 +32,17 @@ export class ThemeService {
3832

3933
// If user already specified once a preference, we use that as default
4034
if (savedDarkModePreference !== undefined) {
41-
this.switch(savedDarkModePreference);
35+
await this.switch(savedDarkModePreference);
4236
return;
4337
}
4438
} catch (err) {
45-
this.switch(false);
39+
await this.switch(false);
4640
return;
4741
}
4842

4943
// Otherwise we check the prefers-color-scheme of the OS
5044
const darkModePreferenceFromMedia: MediaQueryList = window.matchMedia('(prefers-color-scheme: dark)');
5145

52-
this.switch(darkModePreferenceFromMedia.matches);
46+
await this.switch(darkModePreferenceFromMedia.matches);
5347
}
5448
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import {createStore} from '@stencil/store';
2+
3+
interface DarkThemeStore {
4+
darkTheme: boolean | undefined;
5+
}
6+
7+
const {state, onChange} = createStore({
8+
darkTheme: undefined,
9+
} as DarkThemeStore);
10+
11+
onChange('darkTheme', (dark: boolean | undefined) => {
12+
const domBodyClassList: DOMTokenList = document.body.classList;
13+
dark ? domBodyClassList.add('dark') : domBodyClassList.remove('dark');
14+
});
15+
16+
export default {state};

0 commit comments

Comments
 (0)