forked from mystiq/hydrogen-web
notify UI when we need session backup
This commit is contained in:
parent
06ccd74680
commit
494c5cbcf0
5 changed files with 37 additions and 7 deletions
|
@ -31,10 +31,11 @@ const SessionStatus = createEnum(
|
|||
export class SessionStatusViewModel extends ViewModel {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
const {sync, reconnector} = options;
|
||||
const {sync, reconnector, session} = options;
|
||||
this._sync = sync;
|
||||
this._reconnector = reconnector;
|
||||
this._status = this._calculateState(reconnector.connectionStatus.get(), sync.status.get());
|
||||
this._session = session;
|
||||
|
||||
}
|
||||
|
||||
|
@ -42,10 +43,13 @@ export class SessionStatusViewModel extends ViewModel {
|
|||
const update = () => this._updateStatus();
|
||||
this.track(this._sync.status.subscribe(update));
|
||||
this.track(this._reconnector.connectionStatus.subscribe(update));
|
||||
this.track(this._session.needsSessionBackup.subscribe(() => {
|
||||
this.emitChange();
|
||||
}));
|
||||
}
|
||||
|
||||
get isShown() {
|
||||
return this._status !== SessionStatus.Syncing;
|
||||
return this._session.needsSessionBackup.get() || this._status !== SessionStatus.Syncing;
|
||||
}
|
||||
|
||||
get statusLabel() {
|
||||
|
@ -61,6 +65,9 @@ export class SessionStatusViewModel extends ViewModel {
|
|||
case SessionStatus.SyncError:
|
||||
return this.i18n`Sync failed because of ${this._sync.error}`;
|
||||
}
|
||||
if (this._session.needsSessionBackup.get()) {
|
||||
return this.i18n`Some messages could not be decrypted. Connect to your secret storage to decrypt them.`;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
@ -122,9 +129,19 @@ export class SessionStatusViewModel extends ViewModel {
|
|||
return this._status === SessionStatus.Disconnected;
|
||||
}
|
||||
|
||||
get isSecretStorageShown() {
|
||||
return this._session.needsSessionBackup.get();
|
||||
}
|
||||
|
||||
connectNow() {
|
||||
if (this.isConnectNowShown) {
|
||||
this._reconnector.tryNow();
|
||||
}
|
||||
}
|
||||
|
||||
enterPassphrase(passphrase) {
|
||||
if (passphrase) {
|
||||
this._session.enableSecretStorage("passphrase", passphrase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,8 @@ export class SessionViewModel extends ViewModel {
|
|||
this._session = sessionContainer.session;
|
||||
this._sessionStatusViewModel = this.track(new SessionStatusViewModel(this.childOptions({
|
||||
sync: sessionContainer.sync,
|
||||
reconnector: sessionContainer.reconnector
|
||||
reconnector: sessionContainer.reconnector,
|
||||
session: sessionContainer.session,
|
||||
})));
|
||||
this._currentRoomTileViewModel = null;
|
||||
this._currentRoomViewModel = null;
|
||||
|
|
|
@ -36,6 +36,7 @@ import {
|
|||
writeKey as ssssWriteKey,
|
||||
} from "./ssss/index.js";
|
||||
import {SecretStorage} from "./ssss/SecretStorage.js";
|
||||
import {ObservableValue} from "../observable/ObservableValue.js";
|
||||
|
||||
const PICKLE_KEY = "DEFAULT_KEY";
|
||||
|
||||
|
@ -74,6 +75,7 @@ export class Session {
|
|||
});
|
||||
}
|
||||
this._createRoomEncryption = this._createRoomEncryption.bind(this);
|
||||
this.needsSessionBackup = new ObservableValue(false);
|
||||
}
|
||||
|
||||
// called once this._e2eeAccount is assigned
|
||||
|
@ -140,6 +142,11 @@ export class Session {
|
|||
storage: this._storage,
|
||||
sessionBackup: this._sessionBackup,
|
||||
encryptionParams,
|
||||
notifyMissingMegolmSession: () => {
|
||||
if (!this._sessionBackup) {
|
||||
this.needsSessionBackup.set(true)
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -185,6 +192,7 @@ export class Session {
|
|||
}
|
||||
}
|
||||
}
|
||||
this.needsSessionBackup.set(false);
|
||||
}
|
||||
|
||||
// called after load
|
||||
|
|
|
@ -22,7 +22,7 @@ import {makeTxnId} from "../common.js";
|
|||
const ENCRYPTED_TYPE = "m.room.encrypted";
|
||||
|
||||
export class RoomEncryption {
|
||||
constructor({room, deviceTracker, olmEncryption, megolmEncryption, megolmDecryption, encryptionParams, storage, sessionBackup}) {
|
||||
constructor({room, deviceTracker, olmEncryption, megolmEncryption, megolmDecryption, encryptionParams, storage, sessionBackup, notifyMissingMegolmSession}) {
|
||||
this._room = room;
|
||||
this._deviceTracker = deviceTracker;
|
||||
this._olmEncryption = olmEncryption;
|
||||
|
@ -38,15 +38,18 @@ export class RoomEncryption {
|
|||
this._senderDeviceCache = new Map();
|
||||
this._storage = storage;
|
||||
this._sessionBackup = sessionBackup;
|
||||
this._notifyMissingMegolmSession = notifyMissingMegolmSession;
|
||||
}
|
||||
|
||||
enableSessionBackup(sessionBackup) {
|
||||
async enableSessionBackup(sessionBackup) {
|
||||
if (this._sessionBackup) {
|
||||
return;
|
||||
}
|
||||
this._sessionBackup = sessionBackup;
|
||||
// TODO: query session backup for all missing sessions so far
|
||||
// can we query multiple? no, only for sessionId, all for room, or all
|
||||
for(const key of this._eventIdsByMissingSession.keys()) {
|
||||
const [senderKey, sessionId] = key.split("|");
|
||||
await this._requestMissingSessionFromBackup(senderKey, sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
notifyTimelineClosed() {
|
||||
|
|
|
@ -26,6 +26,7 @@ export class SessionStatusView extends TemplateView {
|
|||
spinner(t, {hidden: vm => !vm.isWaiting}),
|
||||
t.p(vm => vm.statusLabel),
|
||||
t.if(vm => vm.isConnectNowShown, t.createTemplate(t => t.button({onClick: () => vm.connectNow()}, "Retry now"))),
|
||||
t.if(vm => vm.isSecretStorageShown, t.createTemplate(t => t.button({onClick: () => vm.enterPassphrase(prompt("passphrase"))}, "Enter passphrase"))),
|
||||
window.DEBUG ? t.button({id: "showlogs"}, "Show logs") : ""
|
||||
]);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue