refactor: isolate network toast and login redirect to separate services (#1412)

* refactor: isolate network toast and login redirect to separate services

* chore: remove accidentally committed sketch of a service

* chore: tidying things up

* feat: add `GlobalModule` encapsulating all global subscription services

* remove angular build cache when building deps

* chore: fix more issues found while testing

* chore: fix issues reported by testing

* chore: fix template error

* chore: fix server-info

* chore: fix server-info

* fix: switch to Observable to fix race conditions

* fix embassy name display on load

* update patchdb

* clean up patch data watch

Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
This commit is contained in:
Alex Inkin
2022-05-27 01:56:47 +03:00
committed by GitHub
parent 4829637b46
commit 4f3223d3ad
88 changed files with 1379 additions and 1079 deletions

View File

@@ -147,7 +147,7 @@ export class MarketplacesPage {
{ 'server-id': this.patch.getData()['server-info'].id },
url,
)
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
loader.dismiss()
return
@@ -158,7 +158,7 @@ export class MarketplacesPage {
try {
marketplace['selected-id'] = id
await this.api.setDbValue({ pointer: `/marketplace`, value: marketplace })
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
loader.dismiss()
}
@@ -190,7 +190,7 @@ export class MarketplacesPage {
try {
delete marketplace['known-hosts'][id]
await this.api.setDbValue({ pointer: `/marketplace`, value: marketplace })
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
} finally {
loader.dismiss()
@@ -223,7 +223,7 @@ export class MarketplacesPage {
url,
)
marketplace['known-hosts'][id] = { name, url }
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
loader.dismiss()
return
@@ -233,7 +233,7 @@ export class MarketplacesPage {
try {
await this.api.setDbValue({ pointer: `/marketplace`, value: marketplace })
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
} finally {
loader.dismiss()
@@ -266,7 +266,7 @@ export class MarketplacesPage {
)
marketplace['known-hosts'][id] = { name, url }
marketplace['selected-id'] = id
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
loader.dismiss()
return
@@ -276,7 +276,7 @@ export class MarketplacesPage {
try {
await this.api.setDbValue({ pointer: `/marketplace`, value: marketplace })
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
loader.dismiss()
return

View File

@@ -7,24 +7,23 @@
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding-top">
<ion-item-group *ngIf="patch.data['server-info'] as server">
<ion-content *ngIf="ui$ | async as ui" class="ion-padding-top">
<ion-item-group *ngIf="server$ | async as server">
<ion-item-divider>General</ion-item-divider>
<ion-item button (click)="presentModalName()">
<ion-item button (click)="presentModalName('Embassy-' + server.id)">
<ion-label>Device Name</ion-label>
<ion-note slot="end">{{ patch.data.ui.name || defaultName }}</ion-note>
<ion-note slot="end">{{ ui.name || 'Embassy-' + server.id }}</ion-note>
</ion-item>
<ion-item-divider>Marketplace</ion-item-divider>
<ion-item
button
(click)="serverConfig.presentAlert('auto-check-updates', patch.data.ui['auto-check-updates'] !== false)"
(click)="serverConfig.presentAlert('auto-check-updates', ui['auto-check-updates'] !== false)"
>
<ion-label>Auto Check for Updates</ion-label>
<ion-note slot="end"
>{{ patch.data.ui['auto-check-updates'] !== false ? 'Enabled' :
'Disabled' }}</ion-note
>
<ion-note slot="end">
{{ ui['auto-check-updates'] !== false ? 'Enabled' : 'Disabled' }}
</ion-note>
</ion-item>
</ion-item-group>
</ion-content>

View File

@@ -21,39 +21,37 @@ import { LocalStorageService } from '../../../services/local-storage.service'
})
export class PreferencesPage {
@ViewChild(IonContent) content: IonContent
defaultName: string
clicks = 0
constructor (
readonly ui$ = this.patch.watch$('ui')
readonly server$ = this.patch.watch$('server-info')
constructor(
private readonly loadingCtrl: LoadingController,
private readonly modalCtrl: ModalController,
private readonly api: ApiService,
private readonly toastCtrl: ToastController,
private readonly localStorageService: LocalStorageService,
public readonly serverConfig: ServerConfigService,
public readonly patch: PatchDbService,
) { }
private readonly patch: PatchDbService,
readonly serverConfig: ServerConfigService,
) {}
ngOnInit () {
this.defaultName = `Embassy-${this.patch.getData()['server-info'].id}`
}
ngAfterViewInit () {
ngAfterViewInit() {
this.content.scrollToPoint(undefined, 1)
}
async presentModalName (): Promise<void> {
async presentModalName(placeholder: string): Promise<void> {
const options: GenericInputOptions = {
title: 'Edit Device Name',
message: 'This is for your reference only.',
label: 'Device Name',
useMask: false,
placeholder: this.defaultName,
placeholder,
nullable: true,
initialValue: this.patch.getData().ui.name,
buttonText: 'Save',
submitFn: (value: string) =>
this.setDbValue('name', value || this.defaultName),
this.setDbValue('name', value || placeholder),
}
const modal = await this.modalCtrl.create({
@@ -66,7 +64,7 @@ export class PreferencesPage {
await modal.present()
}
private async setDbValue (key: string, value: string): Promise<void> {
private async setDbValue(key: string, value: string): Promise<void> {
const loader = await this.loadingCtrl.create({
spinner: 'lines',
message: 'Saving...',
@@ -81,7 +79,7 @@ export class PreferencesPage {
}
}
async addClick () {
async addClick() {
this.clicks++
if (this.clicks >= 5) {
this.clicks = 0

View File

@@ -55,7 +55,7 @@ export class ServerMetricsPage {
private async getMetrics(): Promise<void> {
try {
this.metrics = await this.embassyApi.getServerMetrics({})
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
this.stopDaemon()
}

View File

@@ -1,12 +1,11 @@
<ion-header>
<ion-toolbar>
<ion-title *ngIf="!patch.loaded"
>Loading<span class="loading-dots"></span
></ion-title>
<ion-title *ngIf="patch.loaded"
>{{ patch.data.ui.name || "Embassy-" + patch.data['server-info'].id
}}</ion-title
>
<ion-title *ngIf="patch.loaded else loading">
{{ (ui$ | async).name || "Embassy-" + (server$ | async).id }}
</ion-title>
<ng-template #loading>
<ion-title>Loading<span class="loading-dots"></span></ion-title>
</ng-template>
<ion-buttons slot="end">
<badge-menu-button></badge-menu-button>
</ion-buttons>
@@ -22,18 +21,19 @@
<!-- not loading -->
<ng-template #data>
<ion-item-group>
<ion-item-group *ngIf="server$ | async as server">
<div *ngFor="let cat of settings | keyvalue : asIsOrder">
<ion-item-divider>
<ion-text color="dark" *ngIf="cat.key !== 'Power'"
>{{ cat.key }}</ion-text
>
<ion-text color="dark" *ngIf="cat.key !== 'Power'">
{{ cat.key }}
</ion-text>
<ion-text
color="dark"
*ngIf="cat.key === 'Power'"
(click)="addClick()"
>{{ cat.key }}</ion-text
>
{{ cat.key }}
</ion-text>
</ion-item-divider>
<ng-container *ngFor="let button of cat.value">
<ion-item
@@ -50,16 +50,13 @@
<!-- "Create Backup" button only -->
<p *ngIf="button.title === 'Create Backup'">
<ng-container
*ngIf="patch.data['server-info']['status-info'] as statusInfo"
>
<ng-container *ngIf="server['status-info'] as statusInfo">
<ion-text
color="warning"
*ngIf="!statusInfo['backing-up'] && !statusInfo['update-progress']"
>
Last Backup: {{ patch.data['server-info']['last-backup'] ?
(patch.data['server-info']['last-backup'] | date: 'short') :
'never' }}
Last Backup: {{ server['last-backup'] ?
(server['last-backup'] | date: 'short') : 'never' }}
</ion-text>
<span *ngIf="!!statusInfo['backing-up']" class="inline">
<ion-spinner
@@ -74,7 +71,7 @@
<p *ngIf="button.title === 'Software Update'">
<ng-container *ngIf="button.disabled | async; else enabled">
<ion-text
*ngIf="patch.data['server-info']['status-info'].updated"
*ngIf="server['status-info'].updated"
class="inline"
color="warning"
>

View File

@@ -15,7 +15,6 @@ import { WizardBaker } from 'src/app/components/install-wizard/prebaked-wizards'
import { wizardModal } from 'src/app/components/install-wizard/install-wizard.component'
import { exists, isEmptyObject, ErrorToastService } from '@start9labs/shared'
import { EOSService } from 'src/app/services/eos.service'
import { ServerStatus } from 'src/app/services/patch-db/data-model'
import { LocalStorageService } from 'src/app/services/local-storage.service'
@Component({
@@ -24,10 +23,12 @@ import { LocalStorageService } from 'src/app/services/local-storage.service'
styleUrls: ['server-show.page.scss'],
})
export class ServerShowPage {
ServerStatus = ServerStatus
hasRecoveredPackage: boolean
clicks = 0
readonly server$ = this.patch.watch$('server-info')
readonly ui$ = this.patch.watch$('ui')
constructor(
private readonly alertCtrl: AlertController,
private readonly modalCtrl: ModalController,
@@ -164,7 +165,7 @@ export class ServerShowPage {
this.embassyApi.repairDisk({}).then(_ => {
this.restart()
})
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
}
},
@@ -185,7 +186,7 @@ export class ServerShowPage {
try {
await this.embassyApi.restartServer({})
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
} finally {
loader.dismiss()
@@ -202,7 +203,7 @@ export class ServerShowPage {
try {
await this.embassyApi.shutdownServer({})
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
} finally {
loader.dismiss()
@@ -219,7 +220,7 @@ export class ServerShowPage {
try {
await this.embassyApi.systemRebuild({})
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
} finally {
loader.dismiss()
@@ -239,7 +240,7 @@ export class ServerShowPage {
if (updateAvailable) {
this.updateEos()
}
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
} finally {
loader.dismiss()
@@ -387,7 +388,8 @@ export class ServerShowPage {
},
{
title: 'Kernel Logs',
description: 'Diagnostic log stream for device drivers and other kernel processes',
description:
'Diagnostic log stream for device drivers and other kernel processes',
icon: 'receipt-outline',
action: () =>
this.navCtrl.navigateForward(['kernel-logs'], {

View File

@@ -8,10 +8,9 @@
</ion-header>
<ion-content>
<ion-item-divider>Basic</ion-item-divider>
<ion-item-group *ngIf="patch.data['server-info'] as server">
<ion-item-group *ngIf="server$ | async as server">
<ion-item>
<ion-label>
<h2>EmbassyOS Version</h2>
@@ -47,5 +46,4 @@
</ion-button>
</ion-item>
</ion-item-group>
</ion-content>
</ion-content>

View File

@@ -12,20 +12,23 @@ import { ConfigService } from 'src/app/services/config.service'
export class ServerSpecsPage {
@ViewChild(IonContent) content: IonContent
constructor (
private readonly toastCtrl: ToastController,
public readonly patch: PatchDbService,
public readonly config: ConfigService,
) { }
readonly server$ = this.patch.watch$('server-info')
ngAfterViewInit () {
constructor(
private readonly toastCtrl: ToastController,
private readonly patch: PatchDbService,
public readonly config: ConfigService,
) {}
ngAfterViewInit() {
this.content.scrollToPoint(undefined, 1)
}
async copy (address: string) {
async copy(address: string) {
let message = ''
await copyToClipboard(address || '')
.then(success => { message = success ? 'copied to clipboard!' : 'failed to copy'})
await copyToClipboard(address || '').then(success => {
message = success ? 'copied to clipboard!' : 'failed to copy'
})
const toast = await this.toastCtrl.create({
header: message,
@@ -35,7 +38,7 @@ export class ServerSpecsPage {
await toast.present()
}
asIsOrder (a: any, b: any) {
asIsOrder(a: any, b: any) {
return 0
}
}

View File

@@ -23,7 +23,7 @@ export class SessionsPage {
async ngOnInit() {
try {
this.sessionInfo = await this.embassyApi.getSessions({})
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
} finally {
this.loading = false
@@ -62,7 +62,7 @@ export class SessionsPage {
try {
await this.embassyApi.killSessions({ ids: [id] })
delete this.sessionInfo.sessions[id]
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
} finally {
loader.dismiss()

View File

@@ -37,7 +37,7 @@ export class SSHKeysPage {
async getKeys(): Promise<void> {
try {
this.sshKeys = await this.embassyApi.getSshKeys({})
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
} finally {
this.loading = false
@@ -111,7 +111,7 @@ export class SSHKeysPage {
const entry = this.sshKeys[i]
await this.embassyApi.deleteSshKey({ fingerprint: entry.fingerprint })
this.sshKeys.splice(i, 1)
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
} finally {
loader.dismiss()

View File

@@ -49,7 +49,7 @@ export class WifiPage {
if (!this.wifi.country) {
await this.presentAlertCountry()
}
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
} finally {
this.loading = false
@@ -179,7 +179,7 @@ export class WifiPage {
await this.api.setWifiCountry({ country })
await this.getWifi()
this.wifi.country = country
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
} finally {
loader.dismiss()
@@ -271,7 +271,7 @@ export class WifiPage {
try {
await this.api.connectWifi({ ssid })
await this.confirmWifi(ssid)
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
} finally {
loader.dismiss()
@@ -290,7 +290,7 @@ export class WifiPage {
await this.api.deleteWifi({ ssid })
await this.getWifi()
delete this.wifi.ssids[ssid]
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
} finally {
loader.dismiss()
@@ -313,7 +313,7 @@ export class WifiPage {
connect: false,
})
await this.getWifi()
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
} finally {
loader.dismiss()
@@ -337,7 +337,7 @@ export class WifiPage {
})
await this.confirmWifi(ssid, true)
} catch (e) {
} catch (e: any) {
this.errToast.present(e)
} finally {
loader.dismiss()