2020-08-05 18:38:55 +02:00
|
|
|
/*
|
|
|
|
Copyright 2020 Bruno Windels <bruno@windels.cloud>
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2020-05-05 23:16:51 +02:00
|
|
|
import {ViewModel} from "../ViewModel.js";
|
2021-11-17 11:24:44 +01:00
|
|
|
import {createEnum} from "../../utils/enum";
|
2021-11-22 10:46:46 +01:00
|
|
|
import {ConnectionStatus} from "../../matrix/net/Reconnector";
|
2020-05-05 23:16:51 +02:00
|
|
|
import {SyncStatus} from "../../matrix/Sync.js";
|
|
|
|
|
|
|
|
const SessionStatus = createEnum(
|
|
|
|
"Disconnected",
|
|
|
|
"Connecting",
|
|
|
|
"FirstSync",
|
|
|
|
"Sending",
|
2020-05-07 00:05:21 +02:00
|
|
|
"Syncing",
|
|
|
|
"SyncError"
|
2020-05-05 23:16:51 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
export class SessionStatusViewModel extends ViewModel {
|
|
|
|
constructor(options) {
|
|
|
|
super(options);
|
2020-09-17 18:00:00 +02:00
|
|
|
const {sync, reconnector, session} = options;
|
2020-05-07 00:05:21 +02:00
|
|
|
this._sync = sync;
|
2020-05-05 23:16:51 +02:00
|
|
|
this._reconnector = reconnector;
|
2020-05-07 00:05:21 +02:00
|
|
|
this._status = this._calculateState(reconnector.connectionStatus.get(), sync.status.get());
|
2020-09-17 18:00:00 +02:00
|
|
|
this._session = session;
|
2022-01-26 09:51:48 +01:00
|
|
|
this._setupKeyBackupUrl = this.urlCreator.urlForSegment("settings");
|
2020-10-20 14:42:17 +02:00
|
|
|
this._dismissSecretStorage = false;
|
2020-05-05 23:16:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
start() {
|
|
|
|
const update = () => this._updateStatus();
|
2020-05-07 00:05:21 +02:00
|
|
|
this.track(this._sync.status.subscribe(update));
|
2020-05-05 23:16:51 +02:00
|
|
|
this.track(this._reconnector.connectionStatus.subscribe(update));
|
2022-01-26 09:51:48 +01:00
|
|
|
this.track(this._session.needsKeyBackup.subscribe(() => {
|
2020-09-17 18:00:00 +02:00
|
|
|
this.emitChange();
|
|
|
|
}));
|
2020-05-05 23:16:51 +02:00
|
|
|
}
|
|
|
|
|
2022-01-26 09:51:48 +01:00
|
|
|
get setupKeyBackupUrl () {
|
|
|
|
return this._setupKeyBackupUrl;
|
2020-10-20 14:42:17 +02:00
|
|
|
}
|
|
|
|
|
2020-05-05 23:16:51 +02:00
|
|
|
get isShown() {
|
2022-01-26 09:51:48 +01:00
|
|
|
return (this._session.needsKeyBackup.get() && !this._dismissSecretStorage) || this._status !== SessionStatus.Syncing;
|
2020-05-05 23:16:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
get statusLabel() {
|
|
|
|
switch (this._status) {
|
|
|
|
case SessionStatus.Disconnected:{
|
|
|
|
const retryIn = Math.round(this._reconnector.retryIn / 1000);
|
|
|
|
return this.i18n`Disconnected, trying to reconnect in ${retryIn}s…`;
|
|
|
|
}
|
|
|
|
case SessionStatus.Connecting:
|
|
|
|
return this.i18n`Trying to reconnect now…`;
|
|
|
|
case SessionStatus.FirstSync:
|
|
|
|
return this.i18n`Catching up with your conversations…`;
|
2020-05-07 00:05:21 +02:00
|
|
|
case SessionStatus.SyncError:
|
|
|
|
return this.i18n`Sync failed because of ${this._sync.error}`;
|
2020-05-05 23:16:51 +02:00
|
|
|
}
|
2022-01-26 09:51:48 +01:00
|
|
|
if (this._session.needsKeyBackup.get()) {
|
2020-10-20 14:42:17 +02:00
|
|
|
return this.i18n`Set up session backup to decrypt older messages.`;
|
2020-09-17 18:00:00 +02:00
|
|
|
}
|
2020-05-05 23:16:51 +02:00
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
get isWaiting() {
|
|
|
|
switch (this._status) {
|
|
|
|
case SessionStatus.Connecting:
|
|
|
|
case SessionStatus.FirstSync:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_updateStatus() {
|
|
|
|
const newStatus = this._calculateState(
|
|
|
|
this._reconnector.connectionStatus.get(),
|
2020-05-07 00:05:21 +02:00
|
|
|
this._sync.status.get()
|
2020-05-05 23:16:51 +02:00
|
|
|
);
|
|
|
|
if (newStatus !== this._status) {
|
|
|
|
if (newStatus === SessionStatus.Disconnected) {
|
|
|
|
this._retryTimer = this.track(this.clock.createInterval(() => {
|
|
|
|
this.emitChange("statusLabel");
|
|
|
|
}, 1000));
|
|
|
|
} else {
|
|
|
|
this._retryTimer = this.disposeTracked(this._retryTimer);
|
|
|
|
}
|
|
|
|
this._status = newStatus;
|
|
|
|
this.emitChange();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_calculateState(connectionStatus, syncStatus) {
|
|
|
|
if (connectionStatus !== ConnectionStatus.Online) {
|
|
|
|
switch (connectionStatus) {
|
|
|
|
case ConnectionStatus.Reconnecting:
|
|
|
|
return SessionStatus.Connecting;
|
|
|
|
case ConnectionStatus.Waiting:
|
|
|
|
return SessionStatus.Disconnected;
|
|
|
|
}
|
|
|
|
} else if (syncStatus !== SyncStatus.Syncing) {
|
|
|
|
switch (syncStatus) {
|
|
|
|
// InitialSync should be awaited in the SessionLoadViewModel,
|
|
|
|
// but include it here anyway
|
|
|
|
case SyncStatus.InitialSync:
|
|
|
|
case SyncStatus.CatchupSync:
|
|
|
|
return SessionStatus.FirstSync;
|
2020-05-07 00:05:21 +02:00
|
|
|
case SyncStatus.Stopped:
|
|
|
|
return SessionStatus.SyncError;
|
2020-05-05 23:16:51 +02:00
|
|
|
}
|
|
|
|
} /* else if (session.pendingMessageCount) {
|
|
|
|
return SessionStatus.Sending;
|
|
|
|
} */ else {
|
|
|
|
return SessionStatus.Syncing;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
get isConnectNowShown() {
|
|
|
|
return this._status === SessionStatus.Disconnected;
|
|
|
|
}
|
|
|
|
|
2020-09-17 18:00:00 +02:00
|
|
|
get isSecretStorageShown() {
|
2020-09-17 18:54:55 +02:00
|
|
|
// TODO: we need a model here where we can have multiple messages queued up and their buttons don't bleed into each other.
|
2022-01-26 09:51:48 +01:00
|
|
|
return this._status === SessionStatus.Syncing && this._session.needsKeyBackup.get() && !this._dismissSecretStorage;
|
2020-10-20 14:42:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
get canDismiss() {
|
|
|
|
return this.isSecretStorageShown;
|
|
|
|
}
|
|
|
|
|
|
|
|
dismiss() {
|
|
|
|
if (this.isSecretStorageShown) {
|
|
|
|
this._dismissSecretStorage = true;
|
|
|
|
this.emitChange();
|
|
|
|
}
|
2020-09-17 18:00:00 +02:00
|
|
|
}
|
|
|
|
|
2020-05-05 23:16:51 +02:00
|
|
|
connectNow() {
|
|
|
|
if (this.isConnectNowShown) {
|
|
|
|
this._reconnector.tryNow();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|