mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-04 14:29:45 +00:00
save
This commit is contained in:
committed by
Aiden McClelland
parent
7417bfdbfa
commit
833941b031
@@ -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],
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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 })
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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': {
|
||||||
|
|||||||
Reference in New Issue
Block a user