This commit is contained in:
Aaron Greenspan
2021-01-20 12:43:00 -07:00
committed by Aiden McClelland
parent 7417bfdbfa
commit 833941b031
7 changed files with 66 additions and 18 deletions

View File

@@ -3,11 +3,13 @@ import { CommonModule } from '@angular/common'
import { IonicModule } from '@ionic/angular' import { IonicModule } from '@ionic/angular'
import { OSWelcomePage } from './os-welcome.page' import { OSWelcomePage } from './os-welcome.page'
import { SharingModule } from 'src/app/modules/sharing.module' import { SharingModule } from 'src/app/modules/sharing.module'
import { FormsModule } from '@angular/forms'
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, CommonModule,
IonicModule, IonicModule,
FormsModule,
SharingModule, SharingModule,
], ],
declarations: [OSWelcomePage], declarations: [OSWelcomePage],

View File

@@ -18,7 +18,14 @@
<p> <p>
0.2.8 is a small but important update designed to enhance awareness around potential pitfalls of using certain services. 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. 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
</p>
<p>
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.
<ion-item style="--border-radius: var(--icon-border-radius); margin-top: 15px">
<ion-label>Auto Check for Updates</ion-label>
<ion-toggle slot="end" [(ngModel)]="autoCheckUpdates"></ion-toggle>
</ion-item>
</p> </p>
<div style="margin-top: 30px"> <div style="margin-top: 30px">
@@ -33,7 +40,7 @@
<div class="close-button"> <div class="close-button">
<ion-button fill="outline" (click)="dismiss()"> <ion-button fill="outline" (click)="dismiss()">
Close Begin
</ion-button> </ion-button>
</div> </div>
</div> </div>

View File

@@ -1,5 +1,9 @@
import { Component, Input } from '@angular/core' import { Component, Input } from '@angular/core'
import { ModalController } from '@ionic/angular' 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({ @Component({
selector: 'os-welcome', selector: 'os-welcome',
@@ -9,11 +13,24 @@ import { ModalController } from '@ionic/angular'
export class OSWelcomePage { export class OSWelcomePage {
@Input() version: string @Input() version: string
autoCheckUpdates = true
constructor ( constructor (
private readonly modalCtrl: ModalController, private readonly modalCtrl: ModalController,
private readonly apiService: ApiService,
private readonly serverModel: ServerModel,
private readonly loader: LoaderService,
) { } ) { }
dismiss () { async dismiss () {
this.modalCtrl.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 })
)
} }
} }

View File

@@ -1,16 +1,23 @@
import { Injectable } from '@angular/core' 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 { PropertySubject, peekProperties, initPropertySubject } from '../util/property-subject.util'
import { AppModel } from './app-model' import { AppModel } from './app-model'
import { ConfigService } from 'src/app/services/config.service' import { ConfigService } from 'src/app/services/config.service'
import { Storage } from '@ionic/storage' 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 { StorageKeys } from './storage-keys'
import { exists } from '../util/misc.util'
export enum ServerModelState {
BOOT,
LOCALSTORAGE,
LIVE,
}
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class ServerModel { export class ServerModel {
$modelState$ = new BehaviorSubject(ServerModelState.BOOT)
lastUpdateTimestamp: Date lastUpdateTimestamp: Date
$delta$ = new Subject<void>() $delta$ = new Subject<void>()
private embassy: PropertySubject<S9Server> private embassy: PropertySubject<S9Server>
@@ -26,6 +33,7 @@ export class ServerModel {
).subscribe(() => { ).subscribe(() => {
this.commitCache() this.commitCache()
}) })
this.$modelState$.subscribe(s => console.log('model state', s))
} }
// client fxns // client fxns
@@ -37,7 +45,19 @@ export class ServerModel {
return peekProperties(this.embassy) return peekProperties(this.embassy)
} }
update (update: Partial<S9Server>, timestamp: Date = new Date()): void { nextState (s: ServerModelState) {
this.$modelState$.subscribe(s2 => {
if (s > s2) this.$modelState$.next(s)
})
}
sync (update: Partial<S9Server>, timestamp: Date = new Date()): void {
return this.update(update, timestamp, ServerModelState.LIVE)
}
update (update: Partial<S9Server>, timestamp: Date = new Date(), src?: ServerModelState): void {
console.log('updating:', update)
console.log('present:', this.peek())
if (this.lastUpdateTimestamp > timestamp) return if (this.lastUpdateTimestamp > timestamp) return
if (update.versionInstalled && (update.versionInstalled !== this.config.version) && this.embassy.status.getValue() === ServerStatus.RUNNING) { if (update.versionInstalled && (update.versionInstalled !== this.config.version) && this.embassy.status.getValue() === ServerStatus.RUNNING) {
@@ -59,6 +79,7 @@ export class ServerModel {
}, },
) )
this.$delta$.next() this.$delta$.next()
if (src) this.$modelState$.next(src)
this.lastUpdateTimestamp = timestamp this.lastUpdateTimestamp = timestamp
} }
@@ -77,7 +98,7 @@ export class ServerModel {
async restoreCache (): Promise<void> { async restoreCache (): Promise<void> {
const emb = await this.storage.get(StorageKeys.SERVER_CACHE_KEY) 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 // server state change
@@ -110,7 +131,6 @@ export class ServerModel {
}) })
} }
} }
export interface S9Server { export interface S9Server {
serverId: string serverId: string
name: string name: string

View File

@@ -167,6 +167,7 @@ export class MockApiService extends ApiService {
} }
async patchServerConfig (attr: string, value: any): Promise<EmptyResponse> { async patchServerConfig (attr: string, value: any): Promise<EmptyResponse> {
console.log('huh', attr, value)
await mockPatchServerConfig() await mockPatchServerConfig()
this.serverModel.update({ [attr]: value }) this.serverModel.update({ [attr]: value })
return { } return { }
@@ -409,7 +410,7 @@ const mockApiServer: () => ReqRes.GetServerRes = () => ({
versionLatest: '0.2.9', versionLatest: '0.2.9',
status: ServerStatus.RUNNING, status: ServerStatus.RUNNING,
alternativeRegistryUrl: 'beta-registry.start9labs.com', alternativeRegistryUrl: 'beta-registry.start9labs.com',
welcomeAck: true, welcomeAck: false,
autoCheckUpdates: true, autoCheckUpdates: true,
specs: { specs: {
'Tor Address': 'nfsnjkcnaskjnlkasnfahj7dh23fdnieqwjdnhjewbfijendiueqwbd.onion', 'Tor Address': 'nfsnjkcnaskjnlkasnfahj7dh23fdnieqwjdnhjewbfijendiueqwbd.onion',

View File

@@ -1,10 +1,10 @@
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core'
import { AlertController, ModalController, NavController } from '@ionic/angular' import { AlertController, ModalController, NavController } from '@ionic/angular'
import { combineLatest, Observable, of } from 'rxjs' 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 { OSWelcomePage } from '../modals/os-welcome/os-welcome.page'
import { ServerModel } from '../models/server-model' import { ServerModel, ServerModelState } from '../models/server-model'
import { exists } from '../util/misc.util' import { exists, traceWheel } from '../util/misc.util'
import { ApiService } from './api/api.service' import { ApiService } from './api/api.service'
import { ConfigService } from './config.service' import { ConfigService } from './config.service'
import { LoaderService } from './loader.service' import { LoaderService } from './loader.service'
@@ -45,15 +45,16 @@ export class GlobalAlertsNotifier {
private welcomeNeeded$ (): Observable<string | undefined> { private welcomeNeeded$ (): Observable<string | undefined> {
const { welcomeAck, versionInstalled } = this.server.watch() const { welcomeAck, versionInstalled } = this.server.watch()
return combineLatest([ welcomeAck, versionInstalled ]).pipe( return combineLatest([ this.server.$modelState$, welcomeAck, versionInstalled ]).pipe(
filter(([_, vi]) => !!vi), filter(([ms, _, vi]) => ms === ServerModelState.LIVE && !!vi),
map(([wa, vi]) => !wa && vi === this.config.version ? vi : undefined), map(([_, wa, vi]) => !wa && vi === this.config.version ? vi : undefined),
) )
} }
// emits versionLatest whenever autoCheckUpdates becomes true and checkForUpdates yields a new version // emits versionLatest whenever autoCheckUpdates becomes true and checkForUpdates yields a new version
private osUpdateAlertNeeded$ (): Observable<string | undefined> { private osUpdateAlertNeeded$ (): Observable<string | undefined> {
return this.server.watch().autoCheckUpdates.pipe( return this.server.watch().autoCheckUpdates.pipe(
distinctUntilChanged(),
filter(exists), // filter(exists), //
concatMap(() => this.osUpdateService.checkForUpdates$()), concatMap(() => this.osUpdateService.checkForUpdates$()),
) )
@@ -90,7 +91,7 @@ export class GlobalAlertsNotifier {
console.error(`Unable to acknowledge OS welcome`, e) console.error(`Unable to acknowledge OS welcome`, e)
}) })
await modal.present() await modal.present()
modal.onWillDismiss().then(() => resolve()) modal.onDidDismiss().then(() => resolve())
}) })
} }

View File

@@ -54,7 +54,7 @@ export class SyncDaemon {
switch (serverRes.result) { switch (serverRes.result) {
case 'resolve': { case 'resolve': {
this.serverModel.update(serverRes.value, now) this.serverModel.sync(serverRes.value, now)
break break
} }
case 'reject': { case 'reject': {