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.
|
|
|
|
*/
|
|
|
|
|
2021-10-27 15:08:53 +02:00
|
|
|
import {AccountSetupViewModel} from "./AccountSetupViewModel.js";
|
2021-12-22 17:09:52 +01:00
|
|
|
import {LoadStatus} from "../matrix/Client.js";
|
2020-04-23 09:06:04 +02:00
|
|
|
import {SyncStatus} from "../matrix/Sync.js";
|
2022-02-14 17:53:59 +01:00
|
|
|
import {ViewModel} from "./ViewModel";
|
2020-04-23 09:06:04 +02:00
|
|
|
|
2020-05-04 19:23:11 +02:00
|
|
|
export class SessionLoadViewModel extends ViewModel {
|
2020-05-05 23:14:58 +02:00
|
|
|
constructor(options) {
|
|
|
|
super(options);
|
2021-12-22 17:09:52 +01:00
|
|
|
const {client, ready, homeserver, deleteSessionOnCancel} = options;
|
|
|
|
this._client = client;
|
2020-10-09 16:59:34 +02:00
|
|
|
this._ready = ready;
|
2020-04-23 09:06:04 +02:00
|
|
|
this._homeserver = homeserver;
|
2020-04-29 10:10:20 +02:00
|
|
|
this._deleteSessionOnCancel = deleteSessionOnCancel;
|
2020-04-23 09:06:04 +02:00
|
|
|
this._loading = false;
|
|
|
|
this._error = null;
|
2022-11-09 06:44:22 +01:00
|
|
|
this.backUrl = this.urlRouter.urlForSegment("session", true);
|
2021-10-27 15:08:53 +02:00
|
|
|
this._accountSetupViewModel = undefined;
|
|
|
|
|
2020-04-23 09:06:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
async start() {
|
|
|
|
if (this._loading) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
this._loading = true;
|
2020-06-24 22:42:39 +02:00
|
|
|
this.emitChange("loading");
|
2021-12-22 17:09:52 +01:00
|
|
|
this._waitHandle = this._client.loadStatus.waitFor(s => {
|
2021-10-27 15:08:53 +02:00
|
|
|
if (s === LoadStatus.AccountSetup) {
|
2022-02-17 09:24:18 +01:00
|
|
|
this._accountSetupViewModel = new AccountSetupViewModel(this.childOptions({accountSetup: this._client.accountSetup}));
|
2021-10-27 15:08:53 +02:00
|
|
|
} else {
|
|
|
|
this._accountSetupViewModel = undefined;
|
|
|
|
}
|
2020-06-24 22:42:39 +02:00
|
|
|
this.emitChange("loadLabel");
|
2020-04-23 09:06:04 +02:00
|
|
|
// wait for initial sync, but not catchup sync
|
|
|
|
const isCatchupSync = s === LoadStatus.FirstSync &&
|
2021-12-22 17:09:52 +01:00
|
|
|
this._client.sync.status.get() === SyncStatus.CatchupSync;
|
2020-04-23 09:06:04 +02:00
|
|
|
return isCatchupSync ||
|
|
|
|
s === LoadStatus.LoginFailed ||
|
|
|
|
s === LoadStatus.Error ||
|
|
|
|
s === LoadStatus.Ready;
|
|
|
|
});
|
|
|
|
try {
|
|
|
|
await this._waitHandle.promise;
|
|
|
|
} catch (err) {
|
2020-04-29 10:10:20 +02:00
|
|
|
return; // aborted by goBack
|
2020-04-23 09:06:04 +02:00
|
|
|
}
|
|
|
|
// TODO: should we deal with no connection during initial sync
|
|
|
|
// and we're retrying as well here?
|
|
|
|
// e.g. show in the label what is going on wrt connectionstatus
|
|
|
|
// much like we will once you are in the app. Probably a good idea
|
|
|
|
|
|
|
|
// did it finish or get stuck at LoginFailed or Error?
|
2021-12-22 17:09:52 +01:00
|
|
|
const loadStatus = this._client.loadStatus.get();
|
|
|
|
const loadError = this._client.loadError;
|
2020-04-23 09:06:04 +02:00
|
|
|
if (loadStatus === LoadStatus.FirstSync || loadStatus === LoadStatus.Ready) {
|
2021-12-22 17:09:52 +01:00
|
|
|
const client = this._client;
|
2020-10-09 16:59:34 +02:00
|
|
|
// session container is ready,
|
|
|
|
// don't dispose it anymore when
|
|
|
|
// we get disposed
|
2021-12-22 17:09:52 +01:00
|
|
|
this._client = null;
|
|
|
|
this._ready(client);
|
2020-04-23 09:06:04 +02:00
|
|
|
}
|
2020-10-09 16:59:34 +02:00
|
|
|
if (loadError) {
|
2023-03-24 13:42:19 +01:00
|
|
|
console.error("session load error", loadError.stack);
|
2020-09-02 14:54:57 +02:00
|
|
|
}
|
2020-04-23 09:06:04 +02:00
|
|
|
} catch (err) {
|
|
|
|
this._error = err;
|
2020-09-02 14:54:57 +02:00
|
|
|
console.error("error thrown during session load", err.stack);
|
2020-04-23 09:06:04 +02:00
|
|
|
} finally {
|
|
|
|
this._loading = false;
|
2021-12-22 17:09:52 +01:00
|
|
|
// loadLabel in case of client.loadError also gets updated through this
|
2020-06-24 22:42:39 +02:00
|
|
|
this.emitChange("loading");
|
2020-04-23 09:06:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-10-09 16:59:34 +02:00
|
|
|
dispose() {
|
2021-12-22 17:09:52 +01:00
|
|
|
if (this._client) {
|
|
|
|
this._client.dispose();
|
|
|
|
this._client = null;
|
2020-10-09 16:59:34 +02:00
|
|
|
}
|
|
|
|
if (this._waitHandle) {
|
|
|
|
// rejects with AbortError
|
|
|
|
this._waitHandle.dispose();
|
|
|
|
this._waitHandle = null;
|
2020-04-23 09:06:04 +02:00
|
|
|
}
|
2020-04-29 10:10:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// to show a spinner or not
|
|
|
|
get loading() {
|
2021-12-22 17:09:52 +01:00
|
|
|
const client = this._client;
|
|
|
|
if (client && client.loadStatus.get() === LoadStatus.AccountSetup) {
|
2021-10-27 15:08:53 +02:00
|
|
|
return false;
|
|
|
|
}
|
2020-04-29 10:10:20 +02:00
|
|
|
return this._loading;
|
2020-04-23 09:06:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
get loadLabel() {
|
2021-12-22 17:09:52 +01:00
|
|
|
const client = this._client;
|
2021-10-26 15:30:52 +02:00
|
|
|
const error = this._getError();
|
2021-12-22 17:09:52 +01:00
|
|
|
if (error || (client && client.loadStatus.get() === LoadStatus.Error)) {
|
2020-04-23 09:06:04 +02:00
|
|
|
return `Something went wrong: ${error && error.message}.`;
|
|
|
|
}
|
|
|
|
|
2021-08-20 19:27:13 +02:00
|
|
|
// Statuses related to login are handled by respective login view models
|
2021-12-22 17:09:52 +01:00
|
|
|
if (client) {
|
|
|
|
switch (client.loadStatus.get()) {
|
2021-10-26 18:47:46 +02:00
|
|
|
case LoadStatus.QueryAccount:
|
|
|
|
return `Querying account encryption setup…`;
|
2021-10-27 15:08:53 +02:00
|
|
|
case LoadStatus.AccountSetup:
|
2021-10-29 16:40:35 +02:00
|
|
|
return ""; // we'll show a header ing AccountSetupView
|
2020-09-08 17:16:34 +02:00
|
|
|
case LoadStatus.SessionSetup:
|
|
|
|
return `Setting up your encryption keys…`;
|
2020-04-23 09:06:04 +02:00
|
|
|
case LoadStatus.Loading:
|
|
|
|
return `Loading your conversations…`;
|
|
|
|
case LoadStatus.FirstSync:
|
|
|
|
return `Getting your conversations from the server…`;
|
|
|
|
default:
|
2021-12-22 17:09:52 +01:00
|
|
|
return this._client.loadStatus.get();
|
2020-04-23 09:06:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return `Preparing…`;
|
|
|
|
}
|
2021-10-26 15:30:52 +02:00
|
|
|
|
|
|
|
_getError() {
|
2021-12-22 17:09:52 +01:00
|
|
|
return this._error || this._client?.loadError;
|
2021-10-26 15:30:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
get hasError() {
|
|
|
|
return !!this._getError();
|
|
|
|
}
|
|
|
|
|
|
|
|
async exportLogs() {
|
|
|
|
const logExport = await this.logger.export();
|
|
|
|
this.platform.saveFileAs(logExport.asBlob(), `hydrogen-logs-${this.platform.clock.now()}.json`);
|
|
|
|
}
|
2021-10-26 18:47:46 +02:00
|
|
|
|
2021-10-28 11:47:31 +02:00
|
|
|
async logout() {
|
2022-11-08 07:59:26 +01:00
|
|
|
await this._client.startLogout(this.navigation.path.get("session").value);
|
2021-10-28 11:47:31 +02:00
|
|
|
this.navigation.push("session", true);
|
|
|
|
}
|
|
|
|
|
2021-10-27 15:08:53 +02:00
|
|
|
get accountSetupViewModel() {
|
|
|
|
return this._accountSetupViewModel;
|
2021-10-26 18:47:46 +02:00
|
|
|
}
|
2020-04-23 09:06:04 +02:00
|
|
|
}
|