From 4c294566d7d99903bfa2b122fe3c9aa74ebc6937 Mon Sep 17 00:00:00 2001 From: Drew Ansbacher Date: Thu, 22 Jul 2021 16:14:57 -0600 Subject: [PATCH] Progress bar (#377) * looking for unnecessary watches * on init data initialization * prog pipe * install progress everywhere * titlecase status * include updateing state in app show for install progress Co-authored-by: Drew Ansbacher Co-authored-by: Matt Hill --- ui/src/app/guards/maintenance.guard.ts | 2 +- ui/src/app/guards/unmaintenance.guard.ts | 1 - ui/src/app/modules/sharing.module.ts | 3 ++ .../app-instructions/app-instructions.page.ts | 2 +- .../apps-routes/app-list/app-list.page.html | 3 +- .../apps-routes/app-list/app-list.page.scss | 6 +++ .../apps-routes/app-list/app-list.page.ts | 6 +-- .../apps-routes/app-show/app-show.page.html | 35 +++++++++++++--- .../apps-routes/app-show/app-show.page.ts | 1 + .../marketplace-list.page.html | 15 +++---- .../marketplace-show.page.html | 42 ++++++++++--------- .../marketplace-show.page.scss | 2 +- .../marketplace-show/marketplace-show.page.ts | 4 +- ui/src/app/pipes/install-state.pipe.ts | 39 +++++++++++++++++ .../api/embassy/embassy-mock-api.service.ts | 3 +- .../marketplace-mock-api.service.ts | 2 +- .../app/services/patch-db/patch-db.service.ts | 4 +- 17 files changed, 120 insertions(+), 50 deletions(-) create mode 100644 ui/src/app/pipes/install-state.pipe.ts diff --git a/ui/src/app/guards/maintenance.guard.ts b/ui/src/app/guards/maintenance.guard.ts index d69bea4a0..2720d0748 100644 --- a/ui/src/app/guards/maintenance.guard.ts +++ b/ui/src/app/guards/maintenance.guard.ts @@ -22,7 +22,7 @@ export class MaintenanceGuard implements CanActivate, CanActivateChild { } private runServerStatusCheck (): boolean { - if ([ServerStatus.Updating, ServerStatus.BackingUp].includes(this.patch.data['server-info']?.status)) { + if ([ServerStatus.Updating, ServerStatus.BackingUp].includes(this.patch.getData()['server-info']?.status)) { this.router.navigate(['/maintenance'], { replaceUrl: true }) return false } else { diff --git a/ui/src/app/guards/unmaintenance.guard.ts b/ui/src/app/guards/unmaintenance.guard.ts index aa10dd0e4..4724b5767 100644 --- a/ui/src/app/guards/unmaintenance.guard.ts +++ b/ui/src/app/guards/unmaintenance.guard.ts @@ -1,6 +1,5 @@ import { Injectable } from '@angular/core' import { CanActivate, Router } from '@angular/router' -import { tap } from 'rxjs/operators' import { ServerStatus } from '../services/patch-db/data-model' import { PatchDbService } from '../services/patch-db/patch-db.service' diff --git a/ui/src/app/modules/sharing.module.ts b/ui/src/app/modules/sharing.module.ts index a35d53e21..ce9067fba 100644 --- a/ui/src/app/modules/sharing.module.ts +++ b/ui/src/app/modules/sharing.module.ts @@ -9,6 +9,7 @@ import { MaskPipe } from '../pipes/mask.pipe' import { HasUiPipe, LaunchablePipe } from '../pipes/ui.pipe' import { EmptyPipe } from '../pipes/empty.pipe' import { NotificationColorPipe } from '../pipes/notification-color.pipe' +import { InstallState } from '../pipes/install-state.pipe' @NgModule({ declarations: [ @@ -16,6 +17,7 @@ import { NotificationColorPipe } from '../pipes/notification-color.pipe' EmverSatisfiesPipe, TypeofPipe, IncludesPipe, + InstallState, MarkdownPipe, AnnotationStatusPipe, TruncateCenterPipe, @@ -40,6 +42,7 @@ import { NotificationColorPipe } from '../pipes/notification-color.pipe' MaskPipe, EmverDisplayPipe, HasUiPipe, + InstallState, LaunchablePipe, EmptyPipe, NotificationColorPipe, diff --git a/ui/src/app/pages/apps-routes/app-instructions/app-instructions.page.ts b/ui/src/app/pages/apps-routes/app-instructions/app-instructions.page.ts index f968e2a4a..11622a22d 100644 --- a/ui/src/app/pages/apps-routes/app-instructions/app-instructions.page.ts +++ b/ui/src/app/pages/apps-routes/app-instructions/app-instructions.page.ts @@ -26,7 +26,7 @@ export class AppInstructionsPage { async ngOnInit () { const pkgId = this.route.snapshot.paramMap.get('pkgId') - const url = this.patch.data['package-data'][pkgId]['static-files'].instructions + const url = this.patch.getData()['package-data'][pkgId]['static-files'].instructions try { this.instructions = await this.embassyApi.getStatic(url) diff --git a/ui/src/app/pages/apps-routes/app-list/app-list.page.html b/ui/src/app/pages/apps-routes/app-list/app-list.page.html index 89d3d6bc7..baf87a241 100644 --- a/ui/src/app/pages/apps-routes/app-list/app-list.page.html +++ b/ui/src/app/pages/apps-routes/app-list/app-list.page.html @@ -36,7 +36,8 @@ - + +

{{ pkg.value.entry.state | titlecase }}...{{ (pkg.value.entry['install-progress'] | installState).totalProgress }}%

{{ pkg.value.entry.manifest.title }}
diff --git a/ui/src/app/pages/apps-routes/app-list/app-list.page.scss b/ui/src/app/pages/apps-routes/app-list/app-list.page.scss index 0fdfaa11e..0678b11ce 100644 --- a/ui/src/app/pages/apps-routes/app-list/app-list.page.scss +++ b/ui/src/app/pages/apps-routes/app-list/app-list.page.scss @@ -78,3 +78,9 @@ position: absolute; right: 0px; } + +.installing-status { + font-size: calc(8px + .4vw); + font-weight: bold; + margin: 0; +} diff --git a/ui/src/app/pages/apps-routes/app-list/app-list.page.ts b/ui/src/app/pages/apps-routes/app-list/app-list.page.ts index 714a7c885..b8052a8a3 100644 --- a/ui/src/app/pages/apps-routes/app-list/app-list.page.ts +++ b/ui/src/app/pages/apps-routes/app-list/app-list.page.ts @@ -2,10 +2,10 @@ import { Component } from '@angular/core' import { ConfigService } from 'src/app/services/config.service' import { ConnectionFailure, ConnectionService } from 'src/app/services/connection.service' import { PatchDbService } from 'src/app/services/patch-db/patch-db.service' -import { PackageDataEntry } from 'src/app/services/patch-db/data-model' +import { PackageDataEntry, PackageState } from 'src/app/services/patch-db/data-model' import { Subscription } from 'rxjs' import { PkgStatusRendering, renderPkgStatus } from 'src/app/services/pkg-status-rendering.service' -import { distinctUntilChanged, filter } from 'rxjs/operators' +import { filter } from 'rxjs/operators' @Component({ selector: 'app-list', @@ -24,6 +24,7 @@ export class AppListPage { statusRendering: PkgStatusRendering | null sub: Subscription | null }} = { } + PackageState = PackageState constructor ( private readonly config: ConfigService, @@ -41,7 +42,6 @@ export class AppListPage { ) .subscribe(pkgs => { const ids = Object.keys(pkgs) - console.log('PKGSPKGS', ids) Object.keys(this.pkgs).forEach(id => { if (!ids.includes(id)) { diff --git a/ui/src/app/pages/apps-routes/app-show/app-show.page.html b/ui/src/app/pages/apps-routes/app-show/app-show.page.html index afede4879..c847f5e01 100644 --- a/ui/src/app/pages/apps-routes/app-show/app-show.page.html +++ b/ui/src/app/pages/apps-routes/app-show/app-show.page.html @@ -25,7 +25,7 @@
{{ pkg.manifest.version | displayEmver }}
- +
@@ -41,13 +41,36 @@ Start
- - - Launch Web Interface - - + + + + Launch Web Interface + + + +
+

Downloading: {{ (pkg['install-progress'] | installState).downloadProgress }}%

+ + +

Validating: {{ (pkg['install-progress'] | installState).validateProgress }}%

+ + +

Installing: {{ (pkg['install-progress'] | installState).unpackProgress }}%

+ +
+ + diff --git a/ui/src/app/pages/apps-routes/app-show/app-show.page.ts b/ui/src/app/pages/apps-routes/app-show/app-show.page.ts index 2a930f87e..65f234782 100644 --- a/ui/src/app/pages/apps-routes/app-show/app-show.page.ts +++ b/ui/src/app/pages/apps-routes/app-show/app-show.page.ts @@ -28,6 +28,7 @@ export class AppShowPage { PackageState = PackageState DependencyErrorType = DependencyErrorType rendering: PkgStatusRendering + Math = Math @ViewChild(IonContent) content: IonContent subs: Subscription[] = [] diff --git a/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.html b/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.html index bc1352bd5..17e93fbe4 100644 --- a/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.html +++ b/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.html @@ -58,17 +58,12 @@ Installed Update Available

-

- Installing - +

+ {{ localPkg.state | titlecase }}...{{ (localPkg['install-progress'] | installState).totalProgress }}%

-

- Updating - -

-

- Removing - +

+ {{ localPkg.state | Removing }} +

diff --git a/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.html b/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.html index 0c2e66fcd..2ff0e04e2 100644 --- a/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.html +++ b/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.html @@ -25,41 +25,43 @@

{{ pkg.manifest.title }}

{{ pkg.manifest.version | displayEmver }}

- -

+ +

Not Installed

- + -

- - {{ installedPkg.state }} - -

- -

- Installed at {{ installedPkg.manifest.version | displayEmver }} -

-
+

+ Installed at {{ localPkg.manifest.version | displayEmver }} +

+ +

+ {{ localPkg.state | titlecase }}...{{ (localPkg['install-progress'] | installState).totalProgress }}% +

+ +

+ {{ localPkg.state | titlecase }} + +

- - + + Install - - + + - - + + Update - + Downgrade diff --git a/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.scss b/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.scss index db758772c..1ac08994f 100644 --- a/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.scss +++ b/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.scss @@ -21,7 +21,7 @@ .header-status { p { margin: 0; - font-size: calc(6px + 1vw) + font-size: calc(16px + 1vw) } } } diff --git a/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.ts b/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.ts index efe0be868..53460f01c 100644 --- a/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.ts +++ b/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.ts @@ -22,7 +22,7 @@ export class MarketplaceShowPage { @ViewChild(IonContent) content: IonContent loading = true pkgId: string - installedPkg: PackageDataEntry + localPkg: PackageDataEntry PackageState = PackageState rec: Recommendation | null = null showRec = true @@ -48,7 +48,7 @@ export class MarketplaceShowPage { this.subs = [ this.patch.watch$('package-data', this.pkgId) .subscribe(pkg => { - this.installedPkg = pkg + this.localPkg = pkg }), ] diff --git a/ui/src/app/pipes/install-state.pipe.ts b/ui/src/app/pipes/install-state.pipe.ts new file mode 100644 index 000000000..22d731c59 --- /dev/null +++ b/ui/src/app/pipes/install-state.pipe.ts @@ -0,0 +1,39 @@ +import { Pipe, PipeTransform } from '@angular/core' +import { InstallProgress } from '../services/patch-db/data-model' + +@Pipe({ + name: 'installState', +}) +export class InstallState implements PipeTransform { + + transform (loadData: InstallProgress): ProgressData { + const { downloaded, validated, unpacked, size } = loadData + + const downloadWeight = 1 + const validateWeight = .2 + const unpackWeight = .7 + + const numerator = Math.floor( + downloadWeight * downloaded + + validateWeight * validated + + unpackWeight * unpacked) + + const denominator = Math.floor(loadData.size * (downloadWeight + validateWeight + unpackWeight)) + + return { + totalProgress: Math.round(100 * numerator / denominator), + downloadProgress: Math.round(100 * downloaded / size), + validateProgress: Math.round(100 * validated / size), + unpackProgress: Math.round(100 * unpacked / size), + isComplete: loadData['download-complete'] && loadData['validation-complete'] && loadData['unpack-complete'], + } + } +} + +export interface ProgressData { + totalProgress: number + downloadProgress: number + validateProgress: number + unpackProgress: number + isComplete: boolean +} \ No newline at end of file diff --git a/ui/src/app/services/api/embassy/embassy-mock-api.service.ts b/ui/src/app/services/api/embassy/embassy-mock-api.service.ts index 492538536..6e29b7ddc 100644 --- a/ui/src/app/services/api/embassy/embassy-mock-api.service.ts +++ b/ui/src/app/services/api/embassy/embassy-mock-api.service.ts @@ -485,12 +485,11 @@ export class MockApiService extends ApiService { ] for (let phase of phases) { let i = initialProgress[phase.progress] - console.log('PHASE', phase) console.log('Initial i', i) while (i < initialProgress.size) { console.log(i) await pauseFor(1000) - i = Math.min(i + 40, initialProgress.size) + i = Math.min(i + 5, initialProgress.size) initialProgress[phase.progress] = i if (i === initialProgress.size) { initialProgress[phase.completion] = true diff --git a/ui/src/app/services/api/marketplace/marketplace-mock-api.service.ts b/ui/src/app/services/api/marketplace/marketplace-mock-api.service.ts index a945b8ac0..7033697ce 100644 --- a/ui/src/app/services/api/marketplace/marketplace-mock-api.service.ts +++ b/ui/src/app/services/api/marketplace/marketplace-mock-api.service.ts @@ -85,7 +85,7 @@ export class MarketplaceMockApiService extends MarketplaceApiService { if (this.useLocal(url)) { await pauseFor(2000) return params.ids.reduce((obj, id) => { - obj[id] = this.patch.data['package-data']?.[id]?.manifest.version.replace('0', '1') + obj[id] = this.patch.getData()['package-data']?.[id]?.manifest.version.replace('0', '1') return obj }, { }) } diff --git a/ui/src/app/services/patch-db/patch-db.service.ts b/ui/src/app/services/patch-db/patch-db.service.ts index 0b66ac142..b960133b1 100644 --- a/ui/src/app/services/patch-db/patch-db.service.ts +++ b/ui/src/app/services/patch-db/patch-db.service.ts @@ -22,8 +22,9 @@ export class PatchDbService { connectionStatus$ = new BehaviorSubject(ConnectionStatus.Initializing) private patchDb: PatchDB private patchSub: Subscription + data: DataModel - get data () { return this.patchDb.store.cache.data } + getData () { return this.patchDb.store.cache.data } constructor ( @Inject(PATCH_SOURCE) private readonly source: Source, @@ -34,6 +35,7 @@ export class PatchDbService { async init (): Promise { const cache = await this.bootstrapper.init() this.patchDb = new PatchDB([this.source, this.http], this.http, cache) + this.data = this.patchDb.store.cache.data } start (): void {