adapt key backup view(model) to changes in session, show backup progress

This commit is contained in:
Bruno Windels 2022-01-28 15:14:23 +01:00
parent 504f420293
commit bd2c70b923
2 changed files with 95 additions and 20 deletions

View file

@ -18,7 +18,7 @@ import {ViewModel} from "../../ViewModel.js";
import {KeyType} from "../../../matrix/ssss/index"; import {KeyType} from "../../../matrix/ssss/index";
import {createEnum} from "../../../utils/enum"; import {createEnum} from "../../../utils/enum";
export const Status = createEnum("Enabled", "SetupKey", "SetupPhrase", "Pending"); export const Status = createEnum("Enabled", "SetupKey", "SetupPhrase", "Pending", "NewVersionAvailable");
export class KeyBackupViewModel extends ViewModel { export class KeyBackupViewModel extends ViewModel {
constructor(options) { constructor(options) {
@ -28,8 +28,11 @@ export class KeyBackupViewModel extends ViewModel {
this._isBusy = false; this._isBusy = false;
this._dehydratedDeviceId = undefined; this._dehydratedDeviceId = undefined;
this._status = undefined; this._status = undefined;
this._needsNewKeySubscription = undefined;
this._operationSubscription = undefined;
this._operationProgressSubscription = undefined;
this._reevaluateStatus(); this._reevaluateStatus();
this.track(this._session.hasSecretStorageKey.subscribe(() => { this.track(this._session.keyBackup.subscribe(() => {
if (this._reevaluateStatus()) { if (this._reevaluateStatus()) {
this.emitChange("status"); this.emitChange("status");
} }
@ -41,14 +44,31 @@ export class KeyBackupViewModel extends ViewModel {
return false; return false;
} }
let status; let status;
const hasSecretStorageKey = this._session.hasSecretStorageKey.get(); const keyBackup = this._session.keyBackup.get();
if (hasSecretStorageKey === true) { if (keyBackup) {
status = this._session.keyBackup ? Status.Enabled : Status.SetupKey; if (!this._needsNewKeySubscription) {
} else if (hasSecretStorageKey === false) { this._needsNewKeySubscription = this.track(keyBackup.needsNewKey.subscribe(() => this._reevaluateStatus()));
status = Status.SetupKey;
} else {
status = Status.Pending;
} }
if (!this._operationSubscription) {
this._operationSubscription = this.track(keyBackup.operationInProgress.subscribe(op => {
if (op && !this._operationProgressSubscription) {
this._operationProgressSubscription = this.track(op.progress.subscribe(() => this.emitChange("backupPercentage")));
} else if (!op && this._operationProgressSubscription) {
this._operationProgressSubscription = this.disposeTracked(this._operationProgressSubscription);
}
this.emitChange("isBackingUp");
}));
}
status = keyBackup.needsNewKey.get() ? Status.NewVersionAvailable : Status.Enabled;
} else {
this._needsNewKeySubscription = this.disposeTracked(this._needsNewKeySubscription);
this._operationSubscription = this.disposeTracked(this._operationSubscription);
this._operationProgressSubscription = this.disposeTracked(this._operationProgressSubscription);
status = this.showPhraseSetup() ? Status.SetupPhrase : Status.SetupKey;
} /* TODO: bring back "waiting to get online"
else {
status = Status.Pending;
} */
const changed = status !== this._status; const changed = status !== this._status;
this._status = status; this._status = status;
return changed; return changed;
@ -75,7 +95,7 @@ export class KeyBackupViewModel extends ViewModel {
} }
get backupVersion() { get backupVersion() {
return this._session.keyBackup?.version; return this._session.keyBackup.get()?.version;
} }
get status() { get status() {
@ -144,4 +164,45 @@ export class KeyBackupViewModel extends ViewModel {
this.emitChange(""); this.emitChange("");
} }
} }
get isBackingUp() {
const keyBackup = this._session.keyBackup.get();
if (keyBackup) {
return !!keyBackup.operationInProgress.get();
}
return undefined;
}
get backupPercentage() {
const keyBackup = this._session.keyBackup.get();
if (keyBackup) {
const op = keyBackup.operationInProgress.get();
const progress = op.progress.get();
if (progress) {
return Math.round(progress.finished / progress.total) * 100;
}
}
return 0;
}
get backupInProgressLabel() {
const keyBackup = this._session.keyBackup.get();
if (keyBackup) {
const op = keyBackup.operationInProgress.get();
if (op) {
const progress = op.progress.get();
if (progress) {
return this.i18n`${progress.finished} of ${progress.total}`;
} else {
return this.i18n``;
}
}
}
return undefined;
}
cancelBackup() {
this._session.keyBackup.get()?.operationInProgress.get()?.abort();
}
} }

View file

@ -14,19 +14,33 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import {TemplateView, InlineTemplateView} from "../../general/TemplateView"; import {TemplateView} from "../../general/TemplateView";
import {StaticView} from "../../general/StaticView.js";
export class KeyBackupSettingsView extends TemplateView { export class KeyBackupSettingsView extends TemplateView {
render(t, vm) { render(t) {
return t.mapView(vm => vm.status, status => { return t.div([
t.map(vm => vm.status, (status, t, vm) => {
switch (status) { switch (status) {
case "Enabled": return new InlineTemplateView(vm, renderEnabled) case "Enabled": return renderEnabled(t, vm);
case "SetupKey": return new InlineTemplateView(vm, renderEnableFromKey) case "SetupKey": return renderEnableFromKey(t, vm);
case "SetupPhrase": return new InlineTemplateView(vm, renderEnableFromPhrase) case "SetupPhrase": return renderEnableFromPhrase(t, vm);
case "Pending": return new StaticView(vm, t => t.p(vm.i18n`Waiting to go online…`)) case "NewVersionAvailable": return t.p(vm.i18n`A new backup version has been created. Disable key backup and enable it again with the new key.`);
case "Pending": return t.p(vm.i18n`Waiting to go online…`);
} }
}),
t.map(vm => vm.isBackingUp, (backingUp, t, vm) => {
if (backingUp) {
const progress = t.progress({
min: 0,
max: 100,
value: vm => vm.backupPercentage,
}); });
return t.div([`Backup in progress `, progress, " ", vm => vm.backupInProgressLabel]);
} else {
return t.p("All keys are backed up.");
}
})
]);
} }
} }