diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 01f72be17..7e843105f 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -5,7 +5,6 @@ import { ActivationEnd, Router } from '@angular/router'; import { Store } from '@ngrx/store'; import { Subject } from 'rxjs/Subject'; import { takeUntil } from 'rxjs/operators/takeUntil'; -import { map } from 'rxjs/operators/map'; import { filter } from 'rxjs/operators/filter'; import { @@ -16,7 +15,7 @@ import { } from '@app/core'; import { environment as env } from '@env/environment'; -import { selectorSettings } from './settings'; +import { NIGHT_MODE_THEME, selectorSettings } from './settings'; @Component({ selector: 'anms-root', @@ -55,18 +54,21 @@ export class AppComponent implements OnInit, OnDestroy { ngOnInit(): void { this.store .select(selectorSettings) - .pipe( - takeUntil(this.unsubscribe$), - map(({ theme }) => theme.toLowerCase()) - ) - .subscribe(theme => { - this.componentCssClass = theme; + .pipe(takeUntil(this.unsubscribe$)) + .subscribe(settings => { + const { theme, autoNightMode } = settings; + const hours = new Date().getHours(); + const effectiveTheme = (autoNightMode && (hours >= 20 || hours <= 6) + ? NIGHT_MODE_THEME + : theme + ).toLowerCase(); + this.componentCssClass = effectiveTheme; const classList = this.overlayContainer.getContainerElement().classList; const toRemove = Array.from(classList).filter((item: string) => item.includes('-theme') ); classList.remove(...toRemove); - classList.add(theme); + classList.add(effectiveTheme); }); this.store .select(selectorAuth) diff --git a/src/app/settings/settings.effects.ts b/src/app/settings/settings.effects.ts index 514a209fc..0c7920127 100644 --- a/src/app/settings/settings.effects.ts +++ b/src/app/settings/settings.effects.ts @@ -9,7 +9,7 @@ import { LocalStorageService } from '@app/core'; import { SETTINGS_KEY, SettingsActionTypes, - ActionSettingsChangeTheme + ActionSettingsPersist } from './settings.reducer'; @Injectable() @@ -20,13 +20,16 @@ export class SettingsEffects { ) {} @Effect({ dispatch: false }) - persistThemeSettings(): Observable { - return this.actions$.ofType(SettingsActionTypes.CHANGE_THEME).pipe( - tap((action: ActionSettingsChangeTheme) => - this.localStorageService.setItem(SETTINGS_KEY, { - theme: action.payload.theme - }) - ) - ); + persistSettings(): Observable { + return this.actions$ + .ofType(SettingsActionTypes.PERSIST) + .pipe( + tap((action: ActionSettingsPersist) => + this.localStorageService.setItem( + SETTINGS_KEY, + action.payload.settings + ) + ) + ); } } diff --git a/src/app/settings/settings.reducer.ts b/src/app/settings/settings.reducer.ts index 3288acee0..987490f67 100644 --- a/src/app/settings/settings.reducer.ts +++ b/src/app/settings/settings.reducer.ts @@ -3,7 +3,9 @@ import { Action } from '@ngrx/store'; export const SETTINGS_KEY = 'SETTINGS'; export enum SettingsActionTypes { - CHANGE_THEME = '[Settings] Change Theme' + CHANGE_THEME = '[Settings] Change Theme', + CHANGE_AUTO_NIGHT_AUTO_MODE = '[Settings] Change Auto Night Mode', + PERSIST = '[Settings] Persist' } export class ActionSettingsChangeTheme implements Action { @@ -11,13 +13,30 @@ export class ActionSettingsChangeTheme implements Action { constructor(public payload: { theme: string }) {} } -export type SettingsActions = ActionSettingsChangeTheme; +export class ActionSettingsChangeAutoNightMode implements Action { + readonly type = SettingsActionTypes.CHANGE_AUTO_NIGHT_AUTO_MODE; + constructor(public payload: { autoNightMode: boolean }) {} +} + +export class ActionSettingsPersist implements Action { + readonly type = SettingsActionTypes.PERSIST; + constructor(public payload: { settings: SettingsState }) {} +} + +export type SettingsActions = + | ActionSettingsPersist + | ActionSettingsChangeTheme + | ActionSettingsChangeAutoNightMode; + +export const NIGHT_MODE_THEME = 'BLACK-THEME'; export const initialState: SettingsState = { - theme: 'DEFAULT-THEME' + theme: 'DEFAULT-THEME', + autoNightMode: false }; -export const selectorSettings = state => state.settings || { theme: '' }; +export const selectorSettings = state => + (state.settings || { theme: '' }); export function settingsReducer( state: SettingsState = initialState, @@ -27,6 +46,9 @@ export function settingsReducer( case SettingsActionTypes.CHANGE_THEME: return { ...state, theme: action.payload.theme }; + case SettingsActionTypes.CHANGE_AUTO_NIGHT_AUTO_MODE: + return { ...state, autoNightMode: action.payload.autoNightMode }; + default: return state; } @@ -34,4 +56,5 @@ export function settingsReducer( export interface SettingsState { theme: string; + autoNightMode: boolean; } diff --git a/src/app/settings/settings/settings.component.html b/src/app/settings/settings/settings.component.html index b20475173..53976ce19 100644 --- a/src/app/settings/settings/settings.component.html +++ b/src/app/settings/settings/settings.component.html @@ -4,11 +4,28 @@
- - - {{t.label}} - - +
+ color_lens + + + + {{t.label}} + + + +
+
+ lightbulb_outline + + + Off + On + + +
diff --git a/src/app/settings/settings/settings.component.scss b/src/app/settings/settings/settings.component.scss index b2ea9982c..d0f7bb300 100644 --- a/src/app/settings/settings/settings.component.scss +++ b/src/app/settings/settings/settings.component.scss @@ -6,3 +6,16 @@ h1 { margin: 0 0 20px 0; text-transform: uppercase; } + +.icon-form-field { + display: flex; + align-items: center; +} + +mat-icon { + margin: 0 10px 0 0; +} + +mat-form-field { + flex: 1 0 auto; +} diff --git a/src/app/settings/settings/settings.component.ts b/src/app/settings/settings/settings.component.ts index 7675db223..beb74c0ca 100644 --- a/src/app/settings/settings/settings.component.ts +++ b/src/app/settings/settings/settings.component.ts @@ -5,7 +5,10 @@ import { takeUntil } from 'rxjs/operators/takeUntil'; import { selectorSettings, - ActionSettingsChangeTheme + ActionSettingsChangeTheme, + ActionSettingsChangeAutoNightMode, + SettingsState, + ActionSettingsPersist } from '../settings.reducer'; @Component({ @@ -15,19 +18,19 @@ import { }) export class SettingsComponent implements OnInit, OnDestroy { private unsubscribe$: Subject = new Subject(); - theme: string; + settings: SettingsState; themes = [ - { value: 'DEFAULT-THEME', label: 'Default' }, + { value: 'DEFAULT-THEME', label: 'Blue' }, { value: 'LIGHT-THEME', label: 'Light' }, - { value: 'BLACK-THEME', label: 'Black' } + { value: 'BLACK-THEME', label: 'Dark' } ]; constructor(private store: Store) { store .select(selectorSettings) .pipe(takeUntil(this.unsubscribe$)) - .subscribe(({ theme }) => (this.theme = theme)); + .subscribe(settings => (this.settings = settings)); } ngOnInit() {} @@ -39,5 +42,15 @@ export class SettingsComponent implements OnInit, OnDestroy { onThemeSelect({ value: theme }) { this.store.dispatch(new ActionSettingsChangeTheme({ theme })); + this.store.dispatch(new ActionSettingsPersist({ settings: this.settings })); + } + + onAutoNightModeSelect({ value: autoNightMode }) { + this.store.dispatch( + new ActionSettingsChangeAutoNightMode({ + autoNightMode: autoNightMode === 'true' + }) + ); + this.store.dispatch(new ActionSettingsPersist({ settings: this.settings })); } }