Skip to content

Commit

Permalink
Godind/issue136 (#213)
Browse files Browse the repository at this point in the history
  • Loading branch information
godind authored Nov 16, 2023
1 parent d8a047a commit 820e0bc
Show file tree
Hide file tree
Showing 17 changed files with 213 additions and 54 deletions.
1 change: 1 addition & 0 deletions src/app/app-settings.interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface IConfig {

export interface IAppConfig {
configVersion: number;
autoNightMode: boolean;
dataSets: IDataSet[];
unitDefaults: IUnitDefaults;
notificationConfig: INotificationConfig;
Expand Down
34 changes: 31 additions & 3 deletions src/app/app-settings.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { DefaultNotificationConfig } from './config.blank.notification.const';
import { DemoAppConfig, DemoConnectionConfig, DemoWidgetConfig, DemoLayoutConfig, DemoThemeConfig, DemoZonesConfig } from './config.demo.const';

import { StorageService } from './storage.service';
import { IAuthorizationToken } from './auththetication.service';

const defaultTheme = 'modern-dark';
const configVersion = 9; // used to invalidate old configs. connectionConfig and appConfig use this same version.
Expand All @@ -29,6 +28,7 @@ export class AppSettingsService {
private unitDefaults: BehaviorSubject<IUnitDefaults> = new BehaviorSubject<IUnitDefaults>({});
private themeName: BehaviorSubject<string> = new BehaviorSubject<string>(defaultTheme);
private kipKNotificationConfig: BehaviorSubject<INotificationConfig> = new BehaviorSubject<INotificationConfig>(DefaultNotificationConfig);
private autoNightMode: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

private useDeviceToken: boolean = false;
private loginName: string;
Expand All @@ -49,7 +49,7 @@ export class AppSettingsService {
constructor(
@Inject(APP_BASE_HREF) private baseHref: string,
private router: Router,
private storage: StorageService,
private storage: StorageService
)
{
console.log("[AppSettings Service] Service startup...");
Expand Down Expand Up @@ -143,6 +143,7 @@ export class AppSettingsService {
private upgradeAppConfig(appConfig: any): IAppConfig {
let upgradedConfig: IAppConfig = {
configVersion: 9,
autoNightMode: this.autoNightMode.getValue(),
dataSets: cloneDeep(appConfig.dataSets),
notificationConfig: cloneDeep(appConfig.notificationConfig),
unitDefaults: cloneDeep(appConfig.unitDefaults)
Expand Down Expand Up @@ -215,7 +216,12 @@ export class AppSettingsService {
this.zones.next(this.activeConfig.zones.zones);
this.splitSets = this.activeConfig.layout.splitSets;
this.rootSplits = this.activeConfig.layout.rootSplits;
}

if (this.activeConfig.app.autoNightMode === undefined) {
this.setAutoNightMode(false);
} else
this.autoNightMode.next(this.activeConfig.app.autoNightMode);
}

//UnitDefaults
public getDefaultUnitsAsO() {
Expand Down Expand Up @@ -312,10 +318,31 @@ export class AppSettingsService {
return this.themeName.getValue();;
}

// Auto night mode
public getAutoNightModeAsO() {
return this.autoNightMode.asObservable();
}

public setAutoNightMode(enabled: boolean) {
this.autoNightMode.next(enabled);
const appConf = this.buildAppStorageObject();

if (this.useSharedConfig) {
this.storage.patchConfig('IAppConfig', appConf);
} else {
this.saveAppConfigToLocalStorage();
}
}

public getAutoNightMode(): boolean {
return this.autoNightMode.getValue();
}

// Widgets
public getWidgets() {
return this.widgets;
}

public saveWidgets(widgets: Array<IWidget>) {
this.widgets = widgets;
if (this.useSharedConfig) {
Expand Down Expand Up @@ -473,6 +500,7 @@ export class AppSettingsService {

let storageObject: IAppConfig = {
configVersion: configVersion,
autoNightMode: this.autoNightMode.getValue(),
dataSets: this.dataSets,
unitDefaults: this.unitDefaults.getValue(),
notificationConfig: this.kipKNotificationConfig.getValue(),
Expand Down
6 changes: 5 additions & 1 deletion src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { AppSettingsService } from './app-settings.service';
import { DataSetService } from './data-set.service';
import { NotificationsService } from './notifications.service';
import { SignalKDeltaService, IStreamStatus } from './signalk-delta.service';
import { AppService } from './app.service';

declare var NoSleep: any; //3rd party

Expand Down Expand Up @@ -51,6 +52,7 @@ export class AppComponent implements OnInit, OnDestroy {
private notificationsService: NotificationsService, // needs AppSettingsService SignalKConnectionService
public auththeticationService: AuththeticationService,
private deltaService: SignalKDeltaService,
private appService: AppService,
// below services are needed: first service instanciation after Init Service
private signalKDeltaService: SignalKDeltaService, // needs SignalKService & NotificationsService & SignalKConnectionService
) { }
Expand All @@ -72,7 +74,8 @@ export class AppComponent implements OnInit, OnDestroy {
this.overlayContainer.getContainerElement().classList.remove(this.activeTheme);
}

if (!this.isNightMode) {
if (newTheme != 'nightMode') {
this.isNightMode = false;
if (newTheme !== this.themeName) {
this.overlayContainer.getContainerElement().classList.add(newTheme);
this.themeName = newTheme;
Expand All @@ -81,6 +84,7 @@ export class AppComponent implements OnInit, OnDestroy {
}
} else {
this.overlayContainer.getContainerElement().classList.add(newTheme);
this.isNightMode = true;
}
this.activeTheme = newTheme;
}
Expand Down
4 changes: 2 additions & 2 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ import { WidgetGaugeNgRadialComponent } from './widgets/widget-gauge-ng-radial/w
import { AlarmMenuComponent } from './alarm-menu/alarm-menu.component';
import { WidgetAutopilotComponent } from './widgets/widget-autopilot/widget-autopilot.component';
import { SvgAutopilotComponent } from './widgets/svg-autopilot/svg-autopilot.component';
import { SettingsNotificationsComponent } from './settings/notifications/notifications.component';
import { SettingsGeneralComponent } from './settings/general/general.component';
import { SvgSimpleLinearGaugeComponent } from './widgets/svg-simple-linear-gauge/svg-simple-linear-gauge.component';
import { WidgetSimpleLinearComponent } from './widgets/widget-simple-linear/widget-simple-linear.component';
import { DataBrowserComponent } from './data-browser/data-browser.component';
Expand Down Expand Up @@ -175,7 +175,7 @@ const appNetworkInitializerFn = (appNetInitSvc: AppNetworkInitService) => {
ModalPathSelectorComponent,
ModalUserCredentialComponent,
AlarmMenuComponent,
SettingsNotificationsComponent,
SettingsGeneralComponent,
DataBrowserComponent,
DataBrowserRowComponent
],
Expand Down
16 changes: 16 additions & 0 deletions src/app/app.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';

import { AppService } from './app.service';

describe('AppService', () => {
let service: AppService;

beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(AppService);
});

it('should be created', () => {
expect(service).toBeTruthy();
});
});
79 changes: 79 additions & 0 deletions src/app/app.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { IStreamStatus, SignalKDeltaService } from './signalk-delta.service';
import { NotificationsService } from './notifications.service';
import { IConnectionConfig } from './app-settings.interfaces';
import { AppSettingsService } from './app-settings.service';
import { Injectable } from '@angular/core';
import { SignalKService } from './signalk.service';
import { Observable } from 'rxjs';

const sunPath: string = 'self.environment.sun';

@Injectable({
providedIn: 'root'
})
export class AppService {
public autoNightMode: boolean; // from Config value
private sunValue: string = 'day';
private dayTheme: string;

constructor(
private settings: AppSettingsService,
private delta: SignalKDeltaService,
private sk: SignalKService,
private notification: NotificationsService
) {
this.autoNightMode = this.settings.getAutoNightMode();
this.autoNightModeObserver();
}

private autoNightModeObserver(): void {
let deltaStatus = this.delta.getDataStreamStatusAsO(); // wait for delta service to start
deltaStatus.subscribe(stat => {
stat as IStreamStatus;
if(stat.operation == 2) {

setTimeout(() => { // Wait for path data to come in on startup
const autoNightMode: Observable<boolean> = this.settings.getAutoNightModeAsO();
autoNightMode.subscribe(mode => {
this.autoNightMode = mode;
if (mode) {
if (this.sk.getPathObject(sunPath) !== null) {

// capture none nightMode theme name changes
this.settings.getThemeNameAsO().subscribe(theme => {
if (theme != 'nightMode')
this.dayTheme = theme;
});

const connConf: IConnectionConfig = this.settings.getConnectionConfig(); // get app UUUID

this.sk.subscribePath(connConf.kipUUID, sunPath, 'default').subscribe(sun => {
if (sun.value == 'night' && this.sunValue != sun.value) {
this.sunValue = sun.value;
this.settings.setThemName('nightMode');
} else if (sun.value == 'day' && this.sunValue != sun.value) {
this.sunValue = sun.value;
this.settings.setThemName(this.dayTheme);
}
});
}
}
});
}, 0);
}
});
}

public validateAutoNighModeSupported(): boolean {
if (this.sk.getPathObject(sunPath) == null) {
this.notification.sendSnackbarNotification("Dependency Error: self.environment.sun path was not found. To enable Automatic Night Mode, verify that the following Signal K requirements are meet: 1) The Derived Data plugin is installed and enabled. 2) The plugin's Sun:Sets environment.sun parameter is checked.", 0);
return false;
}
return true;
}

public set autoNightModeConfig(isEnabled : boolean) {
this.settings.setAutoNightMode(isEnabled);
}

}
1 change: 1 addition & 0 deletions src/app/config.blank.const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { DefaultUnitsConfig } from "./config.blank.units.const";

export const DefaultAppConfig: IAppConfig = {
"configVersion": 9,
"autoNightMode": false,
"dataSets": [],
"unitDefaults": DefaultUnitsConfig,
"notificationConfig": DefaultNotificationConfig,
Expand Down
1 change: 1 addition & 0 deletions src/app/config.demo.const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { IConfig, IAppConfig, IConnectionConfig, IThemeConfig, ILayoutConfig, IW
// Demo Mode config settings file
export const DemoAppConfig: IAppConfig = {
"configVersion": 9,
"autoNightMode": false,
"dataSets": [
{
"uuid": "afbe4e41-26f5-404f-a55d-9f7b9b76fbd1",
Expand Down
2 changes: 1 addition & 1 deletion src/app/settings/config/config.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ <h3>Operations</h3>
<h3>Local Configration Editor</h3>
<i>Config is in raw json and no validation on save. Make sure you double
check your changes, else you lose your configuration. A good choice is
to back up first using the Save feature above first!</i>
to back up first using the Save feature above!</i>
</div>
<div style="margin-left: 10px; margin-right: 10px; width: 100%;">
<form (ngSubmit)="rawConfigSave('IConnectionConfig')">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<div class="mat-typography">
<form name="notificationSetting">
<h1>Server Notifications</h1>
<form #general="ngForm" name="GeneraSetting">
<h2>Night Vision</h2>
<mat-checkbox [(ngModel)]="autoNightModeConfig" [ngModelOptions]="{standalone: false}" name="autoNightMode" (change)="isAutoNightPathSupported($event)">Automatically change between Day and Night display modes based on sun phases</mat-checkbox>
<br/><br/>
<h2>Notifications</h2>
<p class="mat-card-subtitle">Notifications are a special type of data sent from Signal K and displayed in the
notification menu. They are meant to alert or inform operators. Set server
notification preferences such as types of messages to display and audio prompts.</p>
Expand Down Expand Up @@ -41,7 +44,7 @@ <h1>Server Notifications</h1>
</mat-accordion>
<div class="formActionFooter">
<mat-divider class="formActionDivider"></mat-divider>
<button mat-raised-button color="accent" class="formActionButton" (click)='saveNotificationsSettings()'>Save</button>
<button mat-raised-button color="accent" class="formActionButton" (click)='saveAllSettings()'>Save</button>
</div>
</form>
</div>
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';

import { SettingsNotificationsComponent } from './notifications.component';
import { SettingsGeneralComponent } from './general.component';

describe('SettingsNotificationsComponent', () => {
let component: SettingsNotificationsComponent;
let fixture: ComponentFixture<SettingsNotificationsComponent>;
let component: SettingsGeneralComponent;
let fixture: ComponentFixture<SettingsGeneralComponent>;

beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ SettingsNotificationsComponent ]
declarations: [ SettingsGeneralComponent ]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(SettingsNotificationsComponent);
fixture = TestBed.createComponent(SettingsGeneralComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
Expand Down
55 changes: 55 additions & 0 deletions src/app/settings/general/general.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Component, OnInit } from '@angular/core';
import { INotificationConfig } from '../../app-settings.interfaces';
import { AppService } from '../../app.service';
import { AppSettingsService } from '../../app-settings.service';
import { NotificationsService } from '../../notifications.service';


@Component({
selector: 'settings-general',
templateUrl: './general.component.html',
styleUrls: ['./general.component.css'],
})
export class SettingsGeneralComponent implements OnInit {

public notificationConfig: INotificationConfig;
public autoNightModeConfig: boolean;

constructor(
private notifications: NotificationsService,
private app: AppService,
private settings: AppSettingsService,
) { }

ngOnInit() {
this.notificationConfig = this.settings.getNotificationConfig();
this.autoNightModeConfig = this.app.autoNightMode;
}

public saveAllSettings():void {
try {
this.saveNotificationsSettings();
this.saveAutoNightMode();
this.notifications.sendSnackbarNotification("General settings saved", 5000, false);
} catch (error) {
this.notifications.sendSnackbarNotification("Error saving settings: " + error, 5000, false);
}

}

public saveNotificationsSettings(): void {
this.settings.setNotificationConfig(this.notificationConfig);
}

public saveAutoNightMode() {
this.app.autoNightModeConfig = this.autoNightModeConfig;
}

public isAutoNightPathSupported(event):void {
if (event.checked) {
if (!this.app.validateAutoNighModeSupported()) {
this.autoNightModeConfig = false;
}
}
}
}
Loading

0 comments on commit 820e0bc

Please sign in to comment.