Skip to content

Commit 8025d93

Browse files
committed
feat(key-storage): adds key-storage feature
1 parent d5ccb64 commit 8025d93

File tree

16 files changed

+217
-123
lines changed

16 files changed

+217
-123
lines changed

apps/www/src/app/app.module.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { NgModule } from '@angular/core';
2-
import { BrowserModule } from '@angular/platform-browser';
3-
import { RouterModule } from '@angular/router';
1+
import {NgModule} from '@angular/core';
2+
import {BrowserModule} from '@angular/platform-browser';
3+
import {RouterModule} from '@angular/router';
44

5-
import { AppComponent } from './app.component';
6-
import { appRoutes } from './app.routes';
5+
import {AppComponent} from './app.component';
6+
import {appRoutes} from './app.routes';
77
import {MastheadComponent} from "./components/masthead";
88

99
@NgModule({
@@ -16,4 +16,5 @@ import {MastheadComponent} from "./components/masthead";
1616
providers: [],
1717
bootstrap: [AppComponent],
1818
})
19-
export class AppModule {}
19+
export class AppModule {
20+
}

apps/www/src/app/components/masthead/masthead.component.ts

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
import {Component, HostBinding, OnDestroy} from "@angular/core";
1+
import {Component, HostBinding, OnDestroy, OnInit} from "@angular/core";
22
import {FormControl, ReactiveFormsModule} from "@angular/forms";
3+
import {Subscription} from "rxjs";
34
import {SegmentedControlButtonComponent, SegmentedControlComponent} from "../segmented-control";
45
import {RadioValueAccessorDirective} from "../../library-components/directives";
56
import {ColorModeService, ColourMode} from "../../library-components/services";
67
import {ContainerComponent} from "../container";
78
import {IconComponent} from "../icon";
8-
import {distinctUntilChanged} from "rxjs";
9-
109

1110
@Component({
1211
// eslint-disable-next-line @angular-eslint/component-selector
@@ -23,24 +22,15 @@ import {distinctUntilChanged} from "rxjs";
2322
],
2423
standalone: true
2524
})
26-
export class MastheadComponent implements OnDestroy {
25+
export class MastheadComponent implements OnInit, OnDestroy {
2726
protected ColorMode = ColourMode;
27+
protected mode = new FormControl(ColourMode.AUTO);
2828
protected expanded = false;
29-
protected mode = new FormControl<ColourMode>(ColourMode.AUTO);
30-
31-
protected mode$ = this.mode
32-
.valueChanges
33-
.pipe(distinctUntilChanged())
34-
.subscribe((value) => value
35-
? this.colorModeService.set(value)
36-
: this.colorModeService.set(ColourMode.AUTO));
3729

38-
protected globalMode$ = this.colorModeService
39-
.asObservable
40-
.subscribe((value) => this.mode.setValue(value))
30+
private mode$!: Subscription;
31+
private storageMode$!: Subscription;
4132

42-
@HostBinding('class.masthead')
43-
readonly hbClassMasthead = true;
33+
@HostBinding('class.masthead') readonly hbClassMasthead = true;
4434

4535
@HostBinding('class.masthead--expanded')
4636
get hbClassMastheadExpanded() {
@@ -50,11 +40,25 @@ export class MastheadComponent implements OnDestroy {
5040
constructor(protected colorModeService: ColorModeService) {
5141
}
5242

43+
ngOnInit() {
44+
this.mode$ = this.mode.valueChanges.subscribe(this.onValueChange);
45+
this.storageMode$ = this.colorModeService.asObservable.subscribe(this.onStorageChange);
46+
}
47+
5348
ngOnDestroy() {
5449
this.mode$.unsubscribe();
55-
this.globalMode$.unsubscribe();
50+
this.storageMode$.unsubscribe();
5651
}
5752

53+
onStorageChange = (value: ColourMode) => {
54+
this.mode.setValue(value);
55+
}
56+
57+
onValueChange = (value: ColourMode | null) =>
58+
value
59+
? this.colorModeService.set(value)
60+
: this.colorModeService.set(ColourMode.AUTO)
61+
5862
toggleExpanded() {
5963
this.expanded = !this.expanded;
6064
}

apps/www/src/app/library-components/services/color-mode.service.ts

Lines changed: 0 additions & 93 deletions
This file was deleted.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import {Inject, Injectable} from "@angular/core";
2+
import {DOCUMENT} from "@angular/common";
3+
import {BehaviorSubject, distinctUntilChanged} from "rxjs";
4+
5+
import {ColorModeStore} from "./color-mode.storage";
6+
import {ColourMode} from "./storage-mode.interface";
7+
8+
import type {KeyStorage} from "../../utilities/key-storage";
9+
10+
@Injectable({
11+
providedIn: 'root'
12+
})
13+
export class ColorModeService {
14+
private _mode = new BehaviorSubject<ColourMode>(this.storage.getItem());
15+
public asObservable = this._mode.pipe(distinctUntilChanged());
16+
public value = this._mode.value;
17+
18+
constructor(
19+
@Inject(DOCUMENT) private document: Document,
20+
@Inject(ColorModeStore) private storage: KeyStorage<ColourMode>,
21+
) {
22+
}
23+
24+
public set(mode: ColourMode) {
25+
if (mode === ColourMode.LIGHT) {
26+
return this.setLight();
27+
}
28+
29+
if (mode === ColourMode.DARK) {
30+
return this.setDark();
31+
}
32+
33+
return this.setAuto();
34+
}
35+
36+
private setAuto() {
37+
this._mode.next(ColourMode.AUTO);
38+
this.storage.clear();
39+
this.document.body.classList?.remove(ColourMode.LIGHT);
40+
this.document.body.classList?.remove(ColourMode.DARK);
41+
}
42+
43+
private setDark() {
44+
this._mode.next(ColourMode.DARK);
45+
this.storage.setItem(ColourMode.DARK);
46+
this.document.body.classList?.remove(ColourMode.LIGHT);
47+
this.document.body.classList?.add(ColourMode.DARK);
48+
}
49+
50+
private setLight() {
51+
this._mode.next(ColourMode.LIGHT);
52+
this.storage.setItem(ColourMode.LIGHT);
53+
this.document.body.classList?.remove(ColourMode.DARK);
54+
this.document.body.classList?.add(ColourMode.LIGHT);
55+
}
56+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import {createKeyStorage} from "../../utilities/key-storage";
2+
import {ColourMode} from "./storage-mode.interface";
3+
4+
export const ColorModeStore = createKeyStorage<ColourMode>('color-mode', ColourMode.AUTO);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './color-mode.service';
2+
export * from './color-mode.storage';
3+
export * from './storage-mode.interface';
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export enum ColourMode {
2+
LIGHT = 'light',
3+
DARK = 'dark',
4+
AUTO = 'auto'
5+
}
6+
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from './color-mode.service';
1+
export * from './color-mode';
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import {InjectionToken} from "@angular/core";
2+
import {KeyStorage} from "./key-storage";
3+
import {localStorageStore} from "./stores";
4+
5+
export const createKeyStorage = <T = unknown>(
6+
key: string,
7+
defaultValue: T,
8+
store: Storage = localStorageStore,
9+
) =>
10+
new InjectionToken(
11+
`storage-key-${key}`, {
12+
providedIn: 'root',
13+
factory: () => new KeyStorage<T>(key, defaultValue, store)
14+
});
15+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './stores';
2+
export * from './key-storage';
3+
export * from './create-key-storage';

0 commit comments

Comments
 (0)