From 4c5b884af7b8c7e5b9fca6e17f7e981ef02b0143 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 17 Jan 2022 16:30:22 +0100 Subject: [PATCH] create and hook up logout viewmodel, on /logout/ path --- src/domain/LogoutViewModel.js | 63 +++++++++++++++++++ src/domain/RootViewModel.js | 20 +++++- src/domain/navigation/index.js | 2 +- .../session/settings/SettingsViewModel.js | 8 +-- 4 files changed, 84 insertions(+), 9 deletions(-) create mode 100644 src/domain/LogoutViewModel.js diff --git a/src/domain/LogoutViewModel.js b/src/domain/LogoutViewModel.js new file mode 100644 index 00000000..2607ca32 --- /dev/null +++ b/src/domain/LogoutViewModel.js @@ -0,0 +1,63 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +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. +*/ + +import {ViewModel} from "./ViewModel.js"; +import {Client} from "../matrix/Client.js"; + +export class LogoutViewModel extends ViewModel { + constructor(options) { + super(options); + this._sessionId = options.sessionId; + this._busy = false; + this._showConfirm = true; + this._error = undefined; + } + + get showConfirm() { + return this._showConfirm; + } + + get busy() { + return this._busy; + } + + get cancelUrl() { + return this.urlCreator.urlForSegment("session", true); + } + + async logout() { + this._busy = true; + this._showConfirm = false; + this.emitChange("busy"); + try { + const client = new Client(this.platform); + await client.startLogout(this._sessionId); + this.navigation.push("session", true); + } catch (err) { + this._error = err; + this._busy = false; + this.emitChange("busy"); + } + } + + get status() { + if (this._error) { + return this.i18n`Could not log out of device: ${this._error.message}`; + } else { + return this.i18n`Logging out…`; + } + } +} diff --git a/src/domain/RootViewModel.js b/src/domain/RootViewModel.js index b754f0ce..70f5b554 100644 --- a/src/domain/RootViewModel.js +++ b/src/domain/RootViewModel.js @@ -18,6 +18,7 @@ import {Client} from "../matrix/Client.js"; import {SessionViewModel} from "./session/SessionViewModel.js"; import {SessionLoadViewModel} from "./SessionLoadViewModel.js"; import {LoginViewModel} from "./login/LoginViewModel.js"; +import {LogoutViewModel} from "./LogoutViewModel.js"; import {SessionPickerViewModel} from "./SessionPickerViewModel.js"; import {ViewModel} from "./ViewModel.js"; @@ -28,6 +29,7 @@ export class RootViewModel extends ViewModel { this._sessionPickerViewModel = null; this._sessionLoadViewModel = null; this._loginViewModel = null; + this._logoutViewModel = null; this._sessionViewModel = null; this._pendingClient = null; } @@ -40,13 +42,18 @@ export class RootViewModel extends ViewModel { } async _applyNavigation(shouldRestoreLastUrl) { - const isLogin = this.navigation.path.get("login") + const isLogin = this.navigation.path.get("login"); + const logoutSessionId = this.navigation.path.get("logout")?.value; const sessionId = this.navigation.path.get("session")?.value; const loginToken = this.navigation.path.get("sso")?.value; if (isLogin) { if (this.activeSection !== "login") { this._showLogin(); } + } else if (logoutSessionId) { + if (this.activeSection !== "logout") { + this._showLogout(logoutSessionId); + } } else if (sessionId === true) { if (this.activeSection !== "picker") { this._showPicker(); @@ -123,6 +130,12 @@ export class RootViewModel extends ViewModel { }); } + _showLogout(sessionId) { + this._setSection(() => { + this._logoutViewModel = new LogoutViewModel(this.childOptions({sessionId})); + }); + } + _showSession(client) { this._setSection(() => { this._sessionViewModel = new SessionViewModel(this.childOptions({client})); @@ -149,6 +162,8 @@ export class RootViewModel extends ViewModel { return "session"; } else if (this._loginViewModel) { return "login"; + } else if (this._logoutViewModel) { + return "logout"; } else if (this._sessionPickerViewModel) { return "picker"; } else if (this._sessionLoadViewModel) { @@ -164,12 +179,14 @@ export class RootViewModel extends ViewModel { this._sessionPickerViewModel = this.disposeTracked(this._sessionPickerViewModel); this._sessionLoadViewModel = this.disposeTracked(this._sessionLoadViewModel); this._loginViewModel = this.disposeTracked(this._loginViewModel); + this._logoutViewModel = this.disposeTracked(this._logoutViewModel); this._sessionViewModel = this.disposeTracked(this._sessionViewModel); // now set it again setter(); this._sessionPickerViewModel && this.track(this._sessionPickerViewModel); this._sessionLoadViewModel && this.track(this._sessionLoadViewModel); this._loginViewModel && this.track(this._loginViewModel); + this._logoutViewModel && this.track(this._logoutViewModel); this._sessionViewModel && this.track(this._sessionViewModel); this.emitChange("activeSection"); } @@ -177,6 +194,7 @@ export class RootViewModel extends ViewModel { get error() { return this._error; } get sessionViewModel() { return this._sessionViewModel; } get loginViewModel() { return this._loginViewModel; } + get logoutViewModel() { return this._logoutViewModel; } get sessionPickerViewModel() { return this._sessionPickerViewModel; } get sessionLoadViewModel() { return this._sessionLoadViewModel; } } diff --git a/src/domain/navigation/index.js b/src/domain/navigation/index.js index ffc5ee9b..e209f2e5 100644 --- a/src/domain/navigation/index.js +++ b/src/domain/navigation/index.js @@ -30,7 +30,7 @@ function allowsChild(parent, child) { switch (parent?.type) { case undefined: // allowed root segments - return type === "login" || type === "session" || type === "sso"; + return type === "login" || type === "session" || type === "sso" || type === "logout"; case "session": return type === "room" || type === "rooms" || type === "settings"; case "rooms": diff --git a/src/domain/session/settings/SettingsViewModel.js b/src/domain/session/settings/SettingsViewModel.js index 979409b3..70e507b8 100644 --- a/src/domain/session/settings/SettingsViewModel.js +++ b/src/domain/session/settings/SettingsViewModel.js @@ -50,7 +50,6 @@ export class SettingsViewModel extends ViewModel { this.minSentImageSizeLimit = 400; this.maxSentImageSizeLimit = 4000; this.pushNotifications = new PushNotificationStatus(); - this._isLoggingOut = false; } get _session() { @@ -58,14 +57,9 @@ export class SettingsViewModel extends ViewModel { } async logout() { - this._isLoggingOut = true; - await this._client.logout(); - this.emitChange("isLoggingOut"); - this.navigation.push("session", true); + this.navigation.push("logout", this._client.sessionId); } - get isLoggingOut() { return this._isLoggingOut; } - setSentImageSizeLimit(size) { if (size > this.maxSentImageSizeLimit || size < this.minSentImageSizeLimit) { this.sentImageSizeLimit = null;