diff --git a/ui/src/app/app.component.html b/ui/src/app/app.component.html index 87644b14b..c83f6484e 100644 --- a/ui/src/app/app.component.html +++ b/ui/src/app/app.component.html @@ -165,11 +165,29 @@ - + diff --git a/ui/src/app/app.component.ts b/ui/src/app/app.component.ts index c2d594202..7b7c4cc8c 100644 --- a/ui/src/app/app.component.ts +++ b/ui/src/app/app.component.ts @@ -3,7 +3,7 @@ import { Storage } from '@ionic/storage-angular' import { AuthService, AuthState } from './services/auth.service' import { ApiService } from './services/api/embassy-api.service' import { Router, RoutesRecognized } from '@angular/router' -import { debounceTime, distinctUntilChanged, filter, take } from 'rxjs/operators' +import { debounceTime, distinctUntilChanged, filter, finalize, take, takeUntil, takeWhile } from 'rxjs/operators' import { AlertController, IonicSafeString, LoadingController, ToastController } from '@ionic/angular' import { Emver } from './services/emver.service' import { SplitPaneTracker } from './services/split-pane.service' @@ -14,7 +14,7 @@ import { ServerStatus } from './services/patch-db/data-model' import { ConnectionFailure, ConnectionService } from './services/connection.service' import { StartupAlertsService } from './services/startup-alerts.service' import { ConfigService } from './services/config.service' -import { debounce, isEmptyObject } from './util/misc.util' +import { debounce, isEmptyObject, pauseFor } from './util/misc.util' import { ErrorToastService } from './services/error-toast.service' import { Subscription } from 'rxjs' @@ -40,6 +40,7 @@ export class AppComponent { serverName: string unreadCount: number subscriptions: Subscription[] = [] + osUpdateProgress: { size: number, downloaded: number } appPages = [ { title: 'Services', @@ -243,10 +244,35 @@ export class AppComponent { this.showMenu = true this.router.navigate([''], { replaceUrl: true }) } - if ([ServerStatus.Updating, ServerStatus.BackingUp].includes(status) && !route.startsWith(maintenance)) { + if (ServerStatus.BackingUp === status && !route.startsWith(maintenance)) { this.showMenu = false this.router.navigate([maintenance], { replaceUrl: true }) } + if (ServerStatus.Updating === status) { + this.watchUpdateProgress() + } + }) + } + + private watchUpdateProgress (): Subscription { + return this.patch.watch$('server-info', 'update-progress') + .pipe( + filter(progress => !!progress), + takeWhile(progress => progress.downloaded < progress.size), + finalize(async () => { + const maintenance = '/maintenance' + const route = this.router.url + if (!route.startsWith(maintenance)) { + this.showMenu = false + this.router.navigate([maintenance], { replaceUrl: true }) + } + if (this.osUpdateProgress) this.osUpdateProgress.downloaded = this.osUpdateProgress.size + await pauseFor(200) + this.osUpdateProgress = undefined + }), + ) + .subscribe(progress => { + this.osUpdateProgress = progress }) } diff --git a/ui/src/app/components/install-wizard/prebaked-wizards.ts b/ui/src/app/components/install-wizard/prebaked-wizards.ts index d961c2400..3bf99090f 100644 --- a/ui/src/app/components/install-wizard/prebaked-wizards.ts +++ b/ui/src/app/components/install-wizard/prebaked-wizards.ts @@ -105,7 +105,10 @@ export class WizardBaker { action, verb: 'beginning update for', title, - executeAction: () => this.embassyApi.updateServer({ }), + executeAction: async () => { + this.embassyApi.updateServer({ }) + return + }, }, }, bottomBar: { diff --git a/ui/src/app/services/api/embassy-mock-api.service.ts b/ui/src/app/services/api/embassy-mock-api.service.ts index 4487c2fbf..225e7d49c 100644 --- a/ui/src/app/services/api/embassy-mock-api.service.ts +++ b/ui/src/app/services/api/embassy-mock-api.service.ts @@ -105,7 +105,7 @@ export class MockApiService extends ApiService { size: 10000, downloaded: 0, } - console.log('here') + const patch = [ { op: PatchOp.REPLACE, @@ -119,8 +119,10 @@ export class MockApiService extends ApiService { }, ] const res = await this.http.rpcRequest>({ method: 'db.patch', params: { patch } }) + console.log('update progress created') await this.updateOSProgress(initialProgress.size) + console.log('about to update') setTimeout(async () => { const patch = [ { @@ -134,10 +136,11 @@ export class MockApiService extends ApiService { value: '3.1.0', }, { - op: PatchOp.REPLACE, + op: PatchOp.REMOVE, path: '/server-info/update-progress', }, ] + await this.http.rpcRequest>({ method: 'db.patch', params: { patch } }) // quickly revert patch to proper version to prevent infinite refresh loop const patch2 = [