diff --git a/src/domain/login/SSOLoginViewModel.js b/src/domain/login/CompleteSSOLoginViewModel.js similarity index 81% rename from src/domain/login/SSOLoginViewModel.js rename to src/domain/login/CompleteSSOLoginViewModel.js index baa478f1..f64c5b94 100644 --- a/src/domain/login/SSOLoginViewModel.js +++ b/src/domain/login/CompleteSSOLoginViewModel.js @@ -17,29 +17,23 @@ limitations under the License. import {ViewModel} from "../ViewModel.js"; import {SessionLoadViewModel} from "../SessionLoadViewModel.js"; -export class SSOLoginViewModel extends ViewModel{ +export class CompleteSSOLoginViewModel extends ViewModel { constructor(options) { super(options); const { loginToken, sessionContainer, - loginOptions, ready, - homeserver } = options; this._loginToken = loginToken; this._ready = ready; this._sessionContainer = sessionContainer; - this._homeserver = homeserver; this._loadViewModelSubscription = null; this._loadViewModel = null; - this._loginOptions = loginOptions; this.performSSOLoginCompletion(); } get loadViewModel() { return this._loadViewModel; } - get supportsSSOLogin() { return this._supportsSSOLogin; } - get isSSOCompletion() { return !!this._loginToken; } async performSSOLoginCompletion() { if (!this._loginToken) { @@ -70,10 +64,4 @@ export class SSOLoginViewModel extends ViewModel{ this.emitChange("isBusy"); })); } - - async startSSOLogin() { - await this.platform.settingsStorage.setString("sso_ongoing_login_homeserver", this._homeserver); - const link = this._loginOptions.sso.ssoEndpointLink(this.urlCreator.createSSOCallbackURL()); - this.platform.openUrl(link); - } } diff --git a/src/domain/login/LoginViewModel.js b/src/domain/login/LoginViewModel.js index 3d747024..ba86baf5 100644 --- a/src/domain/login/LoginViewModel.js +++ b/src/domain/login/LoginViewModel.js @@ -16,8 +16,9 @@ limitations under the License. import {ViewModel} from "../ViewModel.js"; import {PasswordLoginViewModel} from "./PasswordLoginViewModel.js"; -import {SSOLoginViewModel} from "./SSOLoginViewModel.js"; +import {StartSSOLoginViewModel} from "./StartSSOLoginViewModel.js"; import {normalizeHomeserver} from "./common.js"; +import {CompleteSSOLoginViewModel} from "./CompleteSSOLoginViewModel.js"; export class LoginViewModel extends ViewModel { constructor(options) { @@ -29,17 +30,20 @@ export class LoginViewModel extends ViewModel { this._loginToken = loginToken; this._sessionContainer = this._createSessionContainer(); this._loginOptions = null; + this._passwordLoginViewModel = null; + this._startSSOLoginViewModel = null; + this._completeSSOLoginViewModel = null; this._start(); } get passwordLoginViewModel() { return this._passwordLoginViewModel; } - get ssoLoginViewModel() { return this._ssoLoginViewModel; } - get loadViewModel() {return this._loadViewModel; } + get startSSOLoginViewModel() { return this._startSSOLoginViewModel; } + get completeSSOLoginViewModel(){ return this._completeSSOLoginViewModel; } async _start() { if (this._loginToken) { - this._ssoLoginViewModel = this.track(new SSOLoginViewModel(this.childOptions({loginToken: this._loginToken}))); - this.emitChange("ssoLoginViewModel"); + this._completeSSOLoginViewModel = this.track(new CompleteSSOLoginViewModel(this.childOptions({loginToken: this._loginToken}))); + this.emitChange("completeSSOLoginViewModel"); } else { const defaultHomeServer = normalizeHomeserver(this._defaultHomeServer); @@ -57,11 +61,11 @@ export class LoginViewModel extends ViewModel { } _showSSOLogin(homeserver) { - this._ssoLoginViewModel = this.disposeTracked(this._ssoLoginViewModel); - this.emitChange("ssoLoginViewModel"); + this._startSSOLoginViewModel = this.disposeTracked(this._ssoLoginViewModel); + this.emitChange("startSSOLoginViewModel"); if (this._loginOptions?.sso && !this._loginToken) { - this._ssoLoginViewModel = this.track(new SSOLoginViewModel(this.childOptions({homeserver}))); - this.emitChange("ssoLoginViewModel"); + this._startSSOLoginViewModel = this.track(new StartSSOLoginViewModel(this.childOptions({homeserver}))); + this.emitChange("startSSOLoginViewModel"); } } diff --git a/src/domain/login/StartSSOLoginViewModel.js b/src/domain/login/StartSSOLoginViewModel.js new file mode 100644 index 00000000..315106ce --- /dev/null +++ b/src/domain/login/StartSSOLoginViewModel.js @@ -0,0 +1,32 @@ +/* +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"; + +export class StartSSOLoginViewModel extends ViewModel{ + constructor(options) { + super(options); + const {loginOptions, homeserver} = options; + this._sso = loginOptions.sso; + this._homeserver = homeserver; + } + + async startSSOLogin() { + await this.platform.settingsStorage.setString("sso_ongoing_login_homeserver", this._homeserver); + const link = this._sso.ssoEndpointLink(this.urlCreator.createSSOCallbackURL()); + this.platform.openUrl(link); + } +} diff --git a/src/platform/web/ui/css/login.css b/src/platform/web/ui/css/login.css index 9a979024..b6f474dd 100644 --- a/src/platform/web/ui/css/login.css +++ b/src/platform/web/ui/css/login.css @@ -71,17 +71,17 @@ limitations under the License. --size: 20px; } -.SSOLoginView { +.StartSSOLoginView { display: flex; flex-direction: column; } -.SSOLoginView_button { +.StartSSOLoginView_button { flex: 1; margin-top: 10px; } -.SSOLoginView_separator { +.StartSSOLoginView_separator { justify-content: center; display: flex; margin: 8px; diff --git a/src/platform/web/ui/css/themes/element/theme.css b/src/platform/web/ui/css/themes/element/theme.css index 121f5e51..74a1f5f8 100644 --- a/src/platform/web/ui/css/themes/element/theme.css +++ b/src/platform/web/ui/css/themes/element/theme.css @@ -223,12 +223,12 @@ a.button-action { padding-top: 16px; } -.SSOLoginView_button { +.StartSSOLoginView_button { border: 1px solid #03B381; border-radius: 8px; } -.SSOLoginView_separator { +.StartSSOLoginView_separator { font-weight: 500; font-size: 1.5rem; } diff --git a/src/platform/web/ui/login/LoginView.js b/src/platform/web/ui/login/LoginView.js index 34187154..45c773bd 100644 --- a/src/platform/web/ui/login/LoginView.js +++ b/src/platform/web/ui/login/LoginView.js @@ -23,28 +23,21 @@ export class LoginView extends TemplateView { render(t) { return t.div({ className: "PreSessionScreen" }, [ t.div({ className: "logo" }), + t.mapView(vm => vm.completeSSOLoginViewModel, vm => vm? new CompleteSSOView(vm): null), t.mapView(vm => vm.passwordLoginViewModel, vm => vm? new PasswordLoginView(vm): null), - t.mapView(vm => vm.ssoLoginViewModel, vm => { - if (vm?.isSSOCompletion) { - return new CompleteSSOView(vm); - } - else if (vm) { - return new SSOLoginView(vm); - } - return null; - } ), + t.mapView(vm => vm.startSSOLoginViewModel, vm => vm? new StartSSOLoginView(vm): null), // use t.mapView rather than t.if to create a new view when the view model changes too t.p(hydrogenGithubLink(t)) ]); } } -class SSOLoginView extends TemplateView { +class StartSSOLoginView extends TemplateView { render(t, vm) { - return t.div({ className: "SSOLoginView" }, + return t.div({ className: "StartSSOLoginView" }, [ - t.p({ className: "SSOLoginView_separator" }, "or"), - t.button({ className: "SSOLoginView_button button-action secondary", type: "button", onClick: () => vm.startSSOLogin() }, "Log in with SSO") + t.p({ className: "StartSSOLoginView_separator" }, "or"), + t.button({ className: "StartSSOLoginView_button button-action secondary", type: "button", onClick: () => vm.startSSOLogin() }, "Log in with SSO") ] ); }