Skip to content

Commit

Permalink
feat(settings): auto night mode, settings persistence, layout enhance…
Browse files Browse the repository at this point in the history
…ments
  • Loading branch information
tomastrajan committed Jan 29, 2018
1 parent 894f7ca commit 982f6c8
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 33 deletions.
20 changes: 11 additions & 9 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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',
Expand Down Expand Up @@ -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)
Expand Down
21 changes: 12 additions & 9 deletions src/app/settings/settings.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { LocalStorageService } from '@app/core';
import {
SETTINGS_KEY,
SettingsActionTypes,
ActionSettingsChangeTheme
ActionSettingsPersist
} from './settings.reducer';

@Injectable()
Expand All @@ -20,13 +20,16 @@ export class SettingsEffects {
) {}

@Effect({ dispatch: false })
persistThemeSettings(): Observable<Action> {
return this.actions$.ofType(SettingsActionTypes.CHANGE_THEME).pipe(
tap((action: ActionSettingsChangeTheme) =>
this.localStorageService.setItem(SETTINGS_KEY, {
theme: action.payload.theme
})
)
);
persistSettings(): Observable<Action> {
return this.actions$
.ofType(SettingsActionTypes.PERSIST)
.pipe(
tap((action: ActionSettingsPersist) =>
this.localStorageService.setItem(
SETTINGS_KEY,
action.payload.settings
)
)
);
}
}
31 changes: 27 additions & 4 deletions src/app/settings/settings.reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,40 @@ 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 {
readonly type = SettingsActionTypes.CHANGE_THEME;
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 =>
<SettingsState>(state.settings || { theme: '' });

export function settingsReducer(
state: SettingsState = initialState,
Expand All @@ -27,11 +46,15 @@ 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;
}
}

export interface SettingsState {
theme: string;
autoNightMode: boolean;
}
29 changes: 23 additions & 6 deletions src/app/settings/settings/settings.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,28 @@
</div>
<br>
<div class="row">
<mat-select class="col-md-6" placeholder="Select theme" name="theme"
[ngModel]="theme" (change)="onThemeSelect($event)">
<mat-option *ngFor="let t of themes" [value]="t.value">
{{t.label}}
</mat-option>
</mat-select>
<div class="col-md-6 icon-form-field">
<mat-icon color="accent">color_lens</mat-icon>
<mat-form-field>
<mat-select placeholder="Color theme" name="theme"
[ngModel]="settings?.theme" (change)="onThemeSelect($event)">
<mat-option *ngFor="let t of themes" [value]="t.value">
{{t.label}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-md-6 icon-form-field">
<mat-icon color="accent">lightbulb_outline</mat-icon>
<mat-form-field>
<mat-select placeholder="Auto night mode (from 21:00 to 7:00)"
name="auto-night-mode"
[ngModel]="settings?.autoNightMode?.toString()"
(change)="onAutoNightModeSelect($event)">
<mat-option value="false">Off</mat-option>
<mat-option value="true">On</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
13 changes: 13 additions & 0 deletions src/app/settings/settings/settings.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
23 changes: 18 additions & 5 deletions src/app/settings/settings/settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import { takeUntil } from 'rxjs/operators/takeUntil';

import {
selectorSettings,
ActionSettingsChangeTheme
ActionSettingsChangeTheme,
ActionSettingsChangeAutoNightMode,
SettingsState,
ActionSettingsPersist
} from '../settings.reducer';

@Component({
Expand All @@ -15,19 +18,19 @@ import {
})
export class SettingsComponent implements OnInit, OnDestroy {
private unsubscribe$: Subject<void> = new Subject<void>();
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<any>) {
store
.select(selectorSettings)
.pipe(takeUntil(this.unsubscribe$))
.subscribe(({ theme }) => (this.theme = theme));
.subscribe(settings => (this.settings = settings));
}

ngOnInit() {}
Expand All @@ -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 }));
}
}

0 comments on commit 982f6c8

Please sign in to comment.