diff --git a/ui/src/app/modals/os-welcome/os-welcome.module.ts b/ui/src/app/modals/os-welcome/os-welcome.module.ts index 30dbd1773..c897cee39 100644 --- a/ui/src/app/modals/os-welcome/os-welcome.module.ts +++ b/ui/src/app/modals/os-welcome/os-welcome.module.ts @@ -3,11 +3,13 @@ import { CommonModule } from '@angular/common' import { IonicModule } from '@ionic/angular' import { OSWelcomePage } from './os-welcome.page' import { SharingModule } from 'src/app/modules/sharing.module' +import { FormsModule } from '@angular/forms' @NgModule({ imports: [ CommonModule, IonicModule, + FormsModule, SharingModule, ], declarations: [OSWelcomePage], diff --git a/ui/src/app/modals/os-welcome/os-welcome.page.html b/ui/src/app/modals/os-welcome/os-welcome.page.html index 44ab51f24..2a3087fb1 100644 --- a/ui/src/app/modals/os-welcome/os-welcome.page.html +++ b/ui/src/app/modals/os-welcome/os-welcome.page.html @@ -18,7 +18,14 @@

0.2.8 is a small but important update designed to enhance awareness around potential pitfalls of using certain services. It introduces warnings for installing, uninstalling, backing up, and restoring backups of stateful services such as LND or c-lightning. - 0.2.8 introduces automatic checks for updates, a setting that can be enabled or disabled in your Embassy config, and it also draws a distinction between services that are designed to be launched inside the browser and those that are designed to run in the background. + Additionally, it draws a distinction between services that are designed to be launched inside the browser and those that are designed to run in the background +

+

+ 0.2.8 also introduces automatic checks for OS updates. With this enabled, each time you visit your embassy you will be notified if a new OS version is available. This setting can be edited in your Embassy Config page. + + Auto Check for Updates + +

@@ -33,7 +40,7 @@
- Close + Begin
diff --git a/ui/src/app/modals/os-welcome/os-welcome.page.ts b/ui/src/app/modals/os-welcome/os-welcome.page.ts index 27bd863f5..17e8f4a34 100644 --- a/ui/src/app/modals/os-welcome/os-welcome.page.ts +++ b/ui/src/app/modals/os-welcome/os-welcome.page.ts @@ -1,5 +1,9 @@ import { Component, Input } from '@angular/core' import { ModalController } from '@ionic/angular' +import { ServerModel } from 'src/app/models/server-model' +import { ApiService } from 'src/app/services/api/api.service' +import { LoaderService } from 'src/app/services/loader.service' +import { pauseFor } from 'src/app/util/misc.util' @Component({ selector: 'os-welcome', @@ -9,11 +13,24 @@ import { ModalController } from '@ionic/angular' export class OSWelcomePage { @Input() version: string + autoCheckUpdates = true + constructor ( private readonly modalCtrl: ModalController, + private readonly apiService: ApiService, + private readonly serverModel: ServerModel, + private readonly loader: LoaderService, ) { } - dismiss () { - this.modalCtrl.dismiss() + async dismiss () { + await this.loader.displayDuringP( + this.apiService + .patchServerConfig('autoCheckUpdates', this.autoCheckUpdates) + .then(() => this.serverModel.update({ autoCheckUpdates: this.autoCheckUpdates })) + .then(() => pauseFor(600000)) + .catch(console.error), + ).then( + () => this.modalCtrl.dismiss({ autoCheckUpdates: this.autoCheckUpdates }) + ) } } diff --git a/ui/src/app/models/server-model.ts b/ui/src/app/models/server-model.ts index 5f57de591..ee72ee064 100644 --- a/ui/src/app/models/server-model.ts +++ b/ui/src/app/models/server-model.ts @@ -1,16 +1,23 @@ import { Injectable } from '@angular/core' -import { Subject, BehaviorSubject } from 'rxjs' +import { Subject, BehaviorSubject, Observable } from 'rxjs' import { PropertySubject, peekProperties, initPropertySubject } from '../util/property-subject.util' import { AppModel } from './app-model' import { ConfigService } from 'src/app/services/config.service' import { Storage } from '@ionic/storage' -import { throttleTime, delay } from 'rxjs/operators' +import { throttleTime, delay, filter, map } from 'rxjs/operators' import { StorageKeys } from './storage-keys' +import { exists } from '../util/misc.util' +export enum ServerModelState { + BOOT, + LOCALSTORAGE, + LIVE, +} @Injectable({ providedIn: 'root', }) export class ServerModel { + $modelState$ = new BehaviorSubject(ServerModelState.BOOT) lastUpdateTimestamp: Date $delta$ = new Subject() private embassy: PropertySubject @@ -26,6 +33,7 @@ export class ServerModel { ).subscribe(() => { this.commitCache() }) + this.$modelState$.subscribe(s => console.log('model state', s)) } // client fxns @@ -37,7 +45,19 @@ export class ServerModel { return peekProperties(this.embassy) } - update (update: Partial, timestamp: Date = new Date()): void { + nextState (s: ServerModelState) { + this.$modelState$.subscribe(s2 => { + if (s > s2) this.$modelState$.next(s) + }) + } + + sync (update: Partial, timestamp: Date = new Date()): void { + return this.update(update, timestamp, ServerModelState.LIVE) + } + + update (update: Partial, timestamp: Date = new Date(), src?: ServerModelState): void { + console.log('updating:', update) + console.log('present:', this.peek()) if (this.lastUpdateTimestamp > timestamp) return if (update.versionInstalled && (update.versionInstalled !== this.config.version) && this.embassy.status.getValue() === ServerStatus.RUNNING) { @@ -59,6 +79,7 @@ export class ServerModel { }, ) this.$delta$.next() + if (src) this.$modelState$.next(src) this.lastUpdateTimestamp = timestamp } @@ -77,7 +98,7 @@ export class ServerModel { async restoreCache (): Promise { const emb = await this.storage.get(StorageKeys.SERVER_CACHE_KEY) - if (emb && emb.versionInstalled === this.config.version) this.update(emb) + if (emb && emb.versionInstalled === this.config.version) this.update(emb, new Date(), ServerModelState.LOCALSTORAGE) } // server state change @@ -110,7 +131,6 @@ export class ServerModel { }) } } - export interface S9Server { serverId: string name: string diff --git a/ui/src/app/services/api/mock-api.service.ts b/ui/src/app/services/api/mock-api.service.ts index ea8797331..6b837c1b9 100644 --- a/ui/src/app/services/api/mock-api.service.ts +++ b/ui/src/app/services/api/mock-api.service.ts @@ -167,6 +167,7 @@ export class MockApiService extends ApiService { } async patchServerConfig (attr: string, value: any): Promise { + console.log('huh', attr, value) await mockPatchServerConfig() this.serverModel.update({ [attr]: value }) return { } @@ -409,7 +410,7 @@ const mockApiServer: () => ReqRes.GetServerRes = () => ({ versionLatest: '0.2.9', status: ServerStatus.RUNNING, alternativeRegistryUrl: 'beta-registry.start9labs.com', - welcomeAck: true, + welcomeAck: false, autoCheckUpdates: true, specs: { 'Tor Address': 'nfsnjkcnaskjnlkasnfahj7dh23fdnieqwjdnhjewbfijendiueqwbd.onion', diff --git a/ui/src/app/services/startup-alerts.notifier.ts b/ui/src/app/services/startup-alerts.notifier.ts index 1e9d6b509..c53de9420 100644 --- a/ui/src/app/services/startup-alerts.notifier.ts +++ b/ui/src/app/services/startup-alerts.notifier.ts @@ -1,10 +1,10 @@ import { Injectable } from '@angular/core' import { AlertController, ModalController, NavController } from '@ionic/angular' import { combineLatest, Observable, of } from 'rxjs' -import { concatMap, filter, map, switchMap, take } from 'rxjs/operators' +import { concatMap, debounceTime, distinctUntilChanged, filter, map, switchMap, take } from 'rxjs/operators' import { OSWelcomePage } from '../modals/os-welcome/os-welcome.page' -import { ServerModel } from '../models/server-model' -import { exists } from '../util/misc.util' +import { ServerModel, ServerModelState } from '../models/server-model' +import { exists, traceWheel } from '../util/misc.util' import { ApiService } from './api/api.service' import { ConfigService } from './config.service' import { LoaderService } from './loader.service' @@ -45,15 +45,16 @@ export class GlobalAlertsNotifier { private welcomeNeeded$ (): Observable { const { welcomeAck, versionInstalled } = this.server.watch() - return combineLatest([ welcomeAck, versionInstalled ]).pipe( - filter(([_, vi]) => !!vi), - map(([wa, vi]) => !wa && vi === this.config.version ? vi : undefined), + return combineLatest([ this.server.$modelState$, welcomeAck, versionInstalled ]).pipe( + filter(([ms, _, vi]) => ms === ServerModelState.LIVE && !!vi), + map(([_, wa, vi]) => !wa && vi === this.config.version ? vi : undefined), ) } // emits versionLatest whenever autoCheckUpdates becomes true and checkForUpdates yields a new version private osUpdateAlertNeeded$ (): Observable { return this.server.watch().autoCheckUpdates.pipe( + distinctUntilChanged(), filter(exists), // concatMap(() => this.osUpdateService.checkForUpdates$()), ) @@ -90,7 +91,7 @@ export class GlobalAlertsNotifier { console.error(`Unable to acknowledge OS welcome`, e) }) await modal.present() - modal.onWillDismiss().then(() => resolve()) + modal.onDidDismiss().then(() => resolve()) }) } diff --git a/ui/src/app/services/sync.service.ts b/ui/src/app/services/sync.service.ts index d7ad8645b..6888b04ee 100644 --- a/ui/src/app/services/sync.service.ts +++ b/ui/src/app/services/sync.service.ts @@ -54,7 +54,7 @@ export class SyncDaemon { switch (serverRes.result) { case 'resolve': { - this.serverModel.update(serverRes.value, now) + this.serverModel.sync(serverRes.value, now) break } case 'reject': {