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 { 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],

View File

@@ -18,7 +18,14 @@
<p>
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
</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>
<div style="margin-top: 30px">
@@ -33,7 +40,7 @@
<div class="close-button">
<ion-button fill="outline" (click)="dismiss()">
Close
Begin
</ion-button>
</div>
</div>

View File

@@ -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 })
)
}
}

View File

@@ -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<void>()
private embassy: PropertySubject<S9Server>
@@ -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<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 (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<void> {
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

View File

@@ -167,6 +167,7 @@ export class MockApiService extends ApiService {
}
async patchServerConfig (attr: string, value: any): Promise<EmptyResponse> {
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',

View File

@@ -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<string | undefined> {
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<string | undefined> {
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())
})
}

View File

@@ -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': {