From 3bf77d7c3144b16d55f35998dddc0d67bb8c17b2 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Tue, 7 Jun 2022 21:38:00 +0200 Subject: ... --- overlays/spm/frontend/src/app/app.component.ts | 89 ++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 5 deletions(-) (limited to 'overlays/spm/frontend/src/app/app.component.ts') diff --git a/overlays/spm/frontend/src/app/app.component.ts b/overlays/spm/frontend/src/app/app.component.ts index 7c231203..11c0f772 100644 --- a/overlays/spm/frontend/src/app/app.component.ts +++ b/overlays/spm/frontend/src/app/app.component.ts @@ -1,6 +1,18 @@ -import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Component, OnInit, OnDestroy, Inject, Renderer2, RendererFactory2 } from '@angular/core'; +import { DOCUMENT } from '@angular/common'; +import { MediaMatcher } from '@angular/cdk/layout'; +import { LocalStorage } from 'ngx-webstorage'; +import { BehaviorSubject, Subscription, Subject } from 'rxjs'; +import { Router, RouterEvent, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; -import { ColorSchemeService } from './color-scheme.service'; +import { map, filter } from 'rxjs/operators'; + +type ColorScheme = 'dark' | 'light'; + +export interface DomainResponse { + domain: string; +} @Component({ selector: 'app-root', @@ -8,14 +20,81 @@ import { ColorSchemeService } from './color-scheme.service'; styleUrls: ['./app.component.sass'] }) export class AppComponent implements OnInit, OnDestroy { + private renderer: Renderer2; + colorSchemeMatcher: MediaQueryList; + title = 'spm-frontend'; - constructor(private colorSchemeService: ColorSchemeService) {} + public activeColorScheme$: BehaviorSubject = new BehaviorSubject('dark'); + + @LocalStorage('prefers-color-scheme') + public colorSchemeOverride?: ColorScheme; + + colorSchemeSubscription?: Subscription; + + router: Router; + public routerLoading$: Subject = new Subject(); + routerEventSubscription?: Subscription; + + http: HttpClient; + apiDomain$: Subject = new Subject(); + + constructor( rendererFactory: RendererFactory2, + mediaMatcher: MediaMatcher, + @Inject(DOCUMENT) private document: Document, + router: Router, + http: HttpClient, + ) { + this.renderer = rendererFactory.createRenderer(null, null); + this.colorSchemeMatcher = mediaMatcher.matchMedia('(prefers-color-scheme: dark)'); + this.document = document; + + this.colorSchemeListener = this.colorSchemeListener.bind(this); + this.colorSchemeMatcher.addEventListener('change', this.colorSchemeListener); + this.activeColorScheme$.next(this.getColorScheme()); + + this.router = router; + this.http = http; + } + + private colorSchemeListener(event: { matches: boolean; }) { + this.activeColorScheme$.next(this.getColorScheme(event)); + } + + private getColorScheme(event?: { matches: boolean; }): ColorScheme { + if (this.colorSchemeOverride) { + return this.colorSchemeOverride; + } else if (event) { + return event.matches ? 'dark' : 'light'; + } else { + return this.colorSchemeMatcher.matches ? 'dark' : 'light'; + } + } + + updateColorScheme(scheme: ColorScheme) { + this.colorSchemeOverride = scheme; + this.activeColorScheme$.next(scheme); + } ngOnInit() { - this.colorSchemeService.init(); + this.colorSchemeSubscription = this.activeColorScheme$.subscribe(scheme => { this.renderer.setAttribute(this.document.body, 'data-color-scheme', scheme); }); + + this.routerEventSubscription = this.router.events.pipe( + filter(event => + event instanceof NavigationStart || + event instanceof NavigationEnd || + event instanceof NavigationCancel || + event instanceof NavigationError + ), + map(event => event instanceof NavigationStart) + ).subscribe(this.routerLoading$); + + this.http.get('/domain', { headers: new HttpHeaders({ 'Accept': 'application/json' }) }).pipe(map((resp: DomainResponse) => resp.domain)).subscribe(this.apiDomain$); } ngOnDestroy() { - this.colorSchemeService.destroy(); + this.colorSchemeMatcher.removeEventListener('change', this.colorSchemeListener); + + this.colorSchemeSubscription?.unsubscribe(); + this.routerEventSubscription?.unsubscribe(); } } -- cgit v1.2.3