forked from mystiq/hydrogen-web
add backupWriteStatus so binding can take multiple fields into account
This commit is contained in:
parent
6541aacf98
commit
06a1421e97
2 changed files with 68 additions and 17 deletions
|
@ -18,7 +18,8 @@ import {ViewModel} from "../../ViewModel.js";
|
|||
import {KeyType} from "../../../matrix/ssss/index";
|
||||
import {createEnum} from "../../../utils/enum";
|
||||
|
||||
export const Status = createEnum("Enabled", "SetupKey", "SetupPhrase", "Pending", "NewVersionAvailable");
|
||||
export const Status = createEnum("Enabled", "SetupKey", "SetupPhrase", "Pending", "NewVersionAvailable", "Error", "Cancelled");
|
||||
export const BackupWriteStatus = createEnum("Writing", "Stopped", "Done", "Pending");
|
||||
|
||||
export class KeyBackupViewModel extends ViewModel {
|
||||
constructor(options) {
|
||||
|
@ -30,7 +31,11 @@ export class KeyBackupViewModel extends ViewModel {
|
|||
this._status = undefined;
|
||||
this._backupOperation = this._session.keyBackup.flatMap(keyBackup => keyBackup.operationInProgress);
|
||||
this._progress = this._backupOperation.flatMap(op => op.progress);
|
||||
this.track(this._backupOperation.subscribe(() => this.emitChange("isBackingUp")));
|
||||
this.track(this._backupOperation.subscribe(() => {
|
||||
// see if needsNewKey might be set
|
||||
this._reevaluateStatus();
|
||||
this.emitChange("isBackingUp");
|
||||
}));
|
||||
this.track(this._progress.subscribe(() => this.emitChange("backupPercentage")));
|
||||
this._reevaluateStatus();
|
||||
this.track(this._session.keyBackup.subscribe(() => {
|
||||
|
@ -47,7 +52,7 @@ export class KeyBackupViewModel extends ViewModel {
|
|||
let status;
|
||||
const keyBackup = this._session.keyBackup.get();
|
||||
if (keyBackup) {
|
||||
status = keyBackup.needsNewKey.get() ? Status.NewVersionAvailable : Status.Enabled;
|
||||
status = keyBackup.needsNewKey ? Status.NewVersionAvailable : Status.Enabled;
|
||||
} else {
|
||||
status = this.showPhraseSetup() ? Status.SetupPhrase : Status.SetupKey;
|
||||
} /* TODO: bring back "waiting to get online"
|
||||
|
@ -83,6 +88,27 @@ export class KeyBackupViewModel extends ViewModel {
|
|||
return this._session.keyBackup.get()?.version;
|
||||
}
|
||||
|
||||
get backupWriteStatus() {
|
||||
const keyBackup = this._session.keyBackup.get();
|
||||
if (!keyBackup) {
|
||||
return BackupWriteStatus.Pending;
|
||||
} else if (keyBackup.hasStopped) {
|
||||
return BackupWriteStatus.Stopped;
|
||||
}
|
||||
const operation = keyBackup.operationInProgress.get();
|
||||
if (operation) {
|
||||
return BackupWriteStatus.Writing;
|
||||
} else if (keyBackup.hasBackedUpAllKeys) {
|
||||
return BackupWriteStatus.Done;
|
||||
} else {
|
||||
return BackupWriteStatus.Pending;
|
||||
}
|
||||
}
|
||||
|
||||
get backupError() {
|
||||
return this._session.keyBackup.get()?.error?.message;
|
||||
}
|
||||
|
||||
get status() {
|
||||
return this._status;
|
||||
}
|
||||
|
@ -171,7 +197,11 @@ export class KeyBackupViewModel extends ViewModel {
|
|||
}
|
||||
|
||||
cancelBackup() {
|
||||
this._session.keyBackup.get()?.operationInProgress.get()?.abort();
|
||||
this._backupOperation.get()?.abort();
|
||||
}
|
||||
|
||||
startBackup() {
|
||||
this._session.keyBackup.get()?.flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,22 +22,36 @@ export class KeyBackupSettingsView extends TemplateView {
|
|||
t.map(vm => vm.status, (status, t, vm) => {
|
||||
switch (status) {
|
||||
case "Enabled": return renderEnabled(t, vm);
|
||||
case "NewVersionAvailable": return renderNewVersionAvailable(t, vm);
|
||||
case "SetupKey": return renderEnableFromKey(t, vm);
|
||||
case "SetupPhrase": return renderEnableFromPhrase(t, vm);
|
||||
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.");
|
||||
t.map(vm => vm.backupWriteStatus, (status, t, vm) => {
|
||||
switch (status) {
|
||||
case "Writing": {
|
||||
const progress = t.progress({
|
||||
min: 0,
|
||||
max: 100,
|
||||
value: vm => vm.backupPercentage,
|
||||
});
|
||||
return t.div([`Backup in progress `, progress, " ", vm => vm.backupInProgressLabel]);
|
||||
}
|
||||
case "Stopped": {
|
||||
let label;
|
||||
const error = vm.backupError;
|
||||
if (error) {
|
||||
label = `Backup has stopped because of an error: ${vm.backupError}`;
|
||||
} else {
|
||||
label = `Backup has stopped`;
|
||||
}
|
||||
return t.p(label, " ", t.button({onClick: () => vm.startBackup()}, `Backup now`));
|
||||
}
|
||||
case "Done":
|
||||
return t.p(`All keys are backed up.`);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
})
|
||||
]);
|
||||
|
@ -46,7 +60,7 @@ export class KeyBackupSettingsView extends TemplateView {
|
|||
|
||||
function renderEnabled(t, vm) {
|
||||
const items = [
|
||||
t.p([vm.i18n`Session backup is enabled, using backup version ${vm.backupVersion}. `, t.button({onClick: () => vm.disable()}, vm.i18n`Disable`)])
|
||||
t.p([vm.i18n`Key backup is enabled, using backup version ${vm.backupVersion}. `, t.button({onClick: () => vm.disable()}, vm.i18n`Disable`)])
|
||||
];
|
||||
if (vm.dehydratedDeviceId) {
|
||||
items.push(t.p(vm.i18n`A dehydrated device id was set up with id ${vm.dehydratedDeviceId} which you can use during your next login with your secret storage key.`));
|
||||
|
@ -54,6 +68,13 @@ function renderEnabled(t, vm) {
|
|||
return t.div(items);
|
||||
}
|
||||
|
||||
function renderNewVersionAvailable(t, vm) {
|
||||
const items = [
|
||||
t.p([vm.i18n`A new backup version has been created from another device. Disable key backup and enable it again with the new key.`, t.button({onClick: () => vm.disable()}, vm.i18n`Disable`)])
|
||||
];
|
||||
return t.div(items);
|
||||
}
|
||||
|
||||
function renderEnableFromKey(t, vm) {
|
||||
const useASecurityPhrase = t.button({className: "link", onClick: () => vm.showPhraseSetup()}, vm.i18n`use a security phrase`);
|
||||
return t.div([
|
||||
|
@ -101,7 +122,7 @@ function renderEnableFieldRow(t, vm, label, callback) {
|
|||
function renderError(t) {
|
||||
return t.if(vm => vm.error, (t, vm) => {
|
||||
return t.div([
|
||||
t.p({className: "error"}, vm => vm.i18n`Could not enable session backup: ${vm.error}.`),
|
||||
t.p({className: "error"}, vm => vm.i18n`Could not enable key backup: ${vm.error}.`),
|
||||
t.p(vm.i18n`Try double checking that you did not mix up your security key, security phrase and login password as explained above.`)
|
||||
])
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue