mirror of
https://github.com/vector-im/hydrogen-web.git
synced 2024-12-23 03:25:12 +01:00
Move homeserver input into LoginView
Signed-off-by: RMidhunSuresh <rmidhunsuresh@gmail.com>
This commit is contained in:
parent
13cb8979ac
commit
10a6aca477
@ -32,39 +32,51 @@ export class LoginViewModel extends ViewModel {
|
|||||||
this._passwordLoginViewModel = null;
|
this._passwordLoginViewModel = null;
|
||||||
this._startSSOLoginViewModel = null;
|
this._startSSOLoginViewModel = null;
|
||||||
this._completeSSOLoginViewModel = null;
|
this._completeSSOLoginViewModel = null;
|
||||||
this._start();
|
this._homeserver = null;
|
||||||
|
this._errorMessage = "";
|
||||||
|
this._start(this._defaultHomeServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
get passwordLoginViewModel() { return this._passwordLoginViewModel; }
|
get passwordLoginViewModel() { return this._passwordLoginViewModel; }
|
||||||
get startSSOLoginViewModel() { return this._startSSOLoginViewModel; }
|
get startSSOLoginViewModel() { return this._startSSOLoginViewModel; }
|
||||||
get completeSSOLoginViewModel(){ return this._completeSSOLoginViewModel; }
|
get completeSSOLoginViewModel(){ return this._completeSSOLoginViewModel; }
|
||||||
|
get defaultHomeServer() { return this._defaultHomeServer; }
|
||||||
|
get errorMessage() { return this._errorMessage; }
|
||||||
|
|
||||||
async _start() {
|
async _start(homeserver) {
|
||||||
if (this._loginToken) {
|
if (this._loginToken) {
|
||||||
this._completeSSOLoginViewModel = this.track(new CompleteSSOLoginViewModel(this.childOptions({loginToken: this._loginToken})));
|
this._completeSSOLoginViewModel = this.track(new CompleteSSOLoginViewModel(this.childOptions({loginToken: this._loginToken})));
|
||||||
this.emitChange("completeSSOLoginViewModel");
|
this.emitChange("completeSSOLoginViewModel");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
await this.queryLogin(this._defaultHomeServer);
|
this._errorMessage = "";
|
||||||
this._showPasswordLogin();
|
await this.queryLogin(homeserver);
|
||||||
this._showSSOLogin(this._defaultHomeServer);
|
if (this._loginOptions) {
|
||||||
|
if (this._loginOptions.sso) { this._showSSOLogin(); }
|
||||||
|
if (this._loginOptions.password) { this._showPasswordLogin(); }
|
||||||
|
if (!this._loginOptions.sso && !this._loginOptions.password) {
|
||||||
|
this._showError("This homeserver neither supports SSO nor Password based login flows");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._showError("Could not query login methods supported by the homeserver");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_showPasswordLogin() {
|
_showPasswordLogin() {
|
||||||
this._passwordLoginViewModel = new PasswordLoginViewModel(this.childOptions({defaultHomeServer: this._defaultHomeServer}));
|
this._passwordLoginViewModel = this.track(new PasswordLoginViewModel(this.childOptions()));
|
||||||
const observable = this._passwordLoginViewModel.homeserverObservable;
|
|
||||||
this.track(observable.subscribe(newHomeServer => this._onHomeServerChange(newHomeServer)));
|
|
||||||
this.emitChange("passwordLoginViewModel");
|
this.emitChange("passwordLoginViewModel");
|
||||||
}
|
}
|
||||||
|
|
||||||
_showSSOLogin(homeserver) {
|
_showSSOLogin() {
|
||||||
this._startSSOLoginViewModel = this.disposeTracked(this._ssoLoginViewModel);
|
this._startSSOLoginViewModel = this.track(new StartSSOLoginViewModel(this.childOptions()));
|
||||||
this.emitChange("startSSOLoginViewModel");
|
this.emitChange("startSSOLoginViewModel");
|
||||||
if (this._loginOptions?.sso && !this._loginToken) {
|
}
|
||||||
this._startSSOLoginViewModel = this.track(new StartSSOLoginViewModel(this.childOptions({homeserver})));
|
|
||||||
this.emitChange("startSSOLoginViewModel");
|
_showError(message) {
|
||||||
}
|
this._errorMessage = message;
|
||||||
|
this.emitChange("errorMessage");
|
||||||
}
|
}
|
||||||
|
|
||||||
async queryLogin(homeserver) {
|
async queryLogin(homeserver) {
|
||||||
@ -73,16 +85,22 @@ export class LoginViewModel extends ViewModel {
|
|||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
this._loginOptions = null;
|
this._loginOptions = null;
|
||||||
console.error("Could not query login methods supported by the homeserver");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onHomeServerChange(homeserver) {
|
_disposeViewModels() {
|
||||||
await this.queryLogin(homeserver);
|
this._startSSOLoginViewModel = this.disposeTracked(this._ssoLoginViewModel);
|
||||||
this._showSSOLogin(homeserver);
|
this._passwordLoginViewModel = this.disposeTracked(this._passwordLoginViewModel);
|
||||||
|
this.emitChange("disposeViewModels");
|
||||||
}
|
}
|
||||||
|
|
||||||
childOptions(options) {
|
updateHomeServer(newHomeserver) {
|
||||||
|
this._homeserver = newHomeserver;
|
||||||
|
this._disposeViewModels();
|
||||||
|
this._start(newHomeserver);
|
||||||
|
}
|
||||||
|
|
||||||
|
childOptions(options = {}) {
|
||||||
return {
|
return {
|
||||||
...super.childOptions(options),
|
...super.childOptions(options),
|
||||||
ready: sessionContainer => {
|
ready: sessionContainer => {
|
||||||
@ -91,7 +109,8 @@ export class LoginViewModel extends ViewModel {
|
|||||||
this._ready(sessionContainer);
|
this._ready(sessionContainer);
|
||||||
},
|
},
|
||||||
sessionContainer: this._sessionContainer,
|
sessionContainer: this._sessionContainer,
|
||||||
loginOptions: this._loginOptions
|
loginOptions: this._loginOptions,
|
||||||
|
homeserver: this._homeserver ?? this._defaultHomeServer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,30 +16,22 @@ limitations under the License.
|
|||||||
|
|
||||||
import {ViewModel} from "../ViewModel.js";
|
import {ViewModel} from "../ViewModel.js";
|
||||||
import {SessionLoadViewModel} from "../SessionLoadViewModel.js";
|
import {SessionLoadViewModel} from "../SessionLoadViewModel.js";
|
||||||
import {ObservableValue} from "../../observable/ObservableValue.js";
|
|
||||||
|
|
||||||
export class PasswordLoginViewModel extends ViewModel {
|
export class PasswordLoginViewModel extends ViewModel {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super(options);
|
super(options);
|
||||||
const {ready, defaultHomeServer, loginOptions, sessionContainer} = options;
|
const {ready, loginOptions, sessionContainer, homeserver} = options;
|
||||||
this._ready = ready;
|
this._ready = ready;
|
||||||
this._defaultHomeServer = defaultHomeServer;
|
|
||||||
this._sessionContainer = sessionContainer;
|
this._sessionContainer = sessionContainer;
|
||||||
this._loadViewModel = null;
|
this._loadViewModel = null;
|
||||||
this._loadViewModelSubscription = null;
|
this._loadViewModelSubscription = null;
|
||||||
this._loginOptions = loginOptions;
|
this._loginOptions = loginOptions;
|
||||||
this._homeserverObservable = new ObservableValue(this._defaultHomeServer);
|
this._homeserver = homeserver;
|
||||||
}
|
}
|
||||||
|
|
||||||
get defaultHomeServer() { return this._defaultHomeServer; }
|
|
||||||
get loadViewModel() {return this._loadViewModel; }
|
get loadViewModel() {return this._loadViewModel; }
|
||||||
get homeserverObservable() { return this._homeserverObservable; }
|
|
||||||
get cancelUrl() { return this.urlCreator.urlForSegment("session"); }
|
get cancelUrl() { return this.urlCreator.urlForSegment("session"); }
|
||||||
|
|
||||||
updateHomeServer(homeserver) {
|
|
||||||
this._homeserverObservable.set(homeserver);
|
|
||||||
}
|
|
||||||
|
|
||||||
get isBusy() {
|
get isBusy() {
|
||||||
if (!this._loadViewModel) {
|
if (!this._loadViewModel) {
|
||||||
return false;
|
return false;
|
||||||
@ -48,7 +40,8 @@ export class PasswordLoginViewModel extends ViewModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async login(username, password, homeserver) {
|
async login(username, password) {
|
||||||
|
const homeserver = this._homeserver;
|
||||||
if (!this._loginOptions.password) {
|
if (!this._loginOptions.password) {
|
||||||
const path = this.navigation.pathFrom([this.navigation.segment("session")]);
|
const path = this.navigation.pathFrom([this.navigation.segment("session")]);
|
||||||
this.navigation.applyPath(path);
|
this.navigation.applyPath(path);
|
||||||
|
@ -50,8 +50,8 @@ limitations under the License.
|
|||||||
margin: 0 20px;
|
margin: 0 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.LoginView {
|
.PasswordLoginView {
|
||||||
padding: 0.4em;
|
padding: 0 0.4em 0.4em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.SessionLoadStatusView {
|
.SessionLoadStatusView {
|
||||||
@ -81,7 +81,7 @@ limitations under the License.
|
|||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.StartSSOLoginView_separator {
|
.LoginView_separator {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
margin: 8px;
|
margin: 8px;
|
||||||
@ -91,3 +91,11 @@ limitations under the License.
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.LoginView_sso {
|
||||||
|
padding: 0.4em 0.4em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.LoginView_error {
|
||||||
|
padding: 0.4em
|
||||||
|
}
|
||||||
|
@ -228,7 +228,7 @@ a.button-action {
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.StartSSOLoginView_separator {
|
.LoginView_separator {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,25 @@ import {PasswordLoginView} from "./PasswordLoginView.js";
|
|||||||
import {CompleteSSOView} from "./CompleteSSOView.js";
|
import {CompleteSSOView} from "./CompleteSSOView.js";
|
||||||
|
|
||||||
export class LoginView extends TemplateView {
|
export class LoginView extends TemplateView {
|
||||||
render(t) {
|
render(t, vm) {
|
||||||
return t.div({ className: "PreSessionScreen" }, [
|
const homeserver = t.input({
|
||||||
t.div({ className: "logo" }),
|
id: "homeserver",
|
||||||
t.mapView(vm => vm.completeSSOLoginViewModel, vm => vm? new CompleteSSOView(vm): null),
|
type: "text",
|
||||||
t.mapView(vm => vm.passwordLoginViewModel, vm => vm? new PasswordLoginView(vm): null),
|
placeholder: vm.i18n`Your matrix homeserver`,
|
||||||
t.mapView(vm => vm.startSSOLoginViewModel, vm => vm? new StartSSOLoginView(vm): null),
|
value: vm.defaultHomeServer,
|
||||||
|
onChange: () => vm.updateHomeServer(homeserver.value),
|
||||||
|
});
|
||||||
|
|
||||||
|
return t.div({className: "PreSessionScreen"}, [
|
||||||
|
t.div({className: "logo"}),
|
||||||
|
t.h1([vm.i18n`Sign In`]),
|
||||||
|
t.mapView(vm => vm.completeSSOLoginViewModel, vm => vm ? new CompleteSSOView(vm) : null),
|
||||||
|
t.if(vm => !vm.completeSSOLoginViewModel,
|
||||||
|
(t, vm) => t.div({ className: "LoginView_sso form form-row" }, [t.label({ for: "homeserver" }, vm.i18n`Homeserver`), homeserver])),
|
||||||
|
t.mapView(vm => vm.passwordLoginViewModel, vm => vm ? new PasswordLoginView(vm): null),
|
||||||
|
t.if(vm => vm.passwordLoginViewModel && vm.startSSOLoginViewModel, t => t.p({className: "LoginView_separator"}, vm.i18n`or`)),
|
||||||
|
t.mapView(vm => vm.startSSOLoginViewModel, vm => vm ? new StartSSOLoginView(vm) : null),
|
||||||
|
t.if(vm => vm.errorMessage, (t, vm) => t.h5({className: "LoginView_error"}, vm.i18n(vm.errorMessage))),
|
||||||
// use t.mapView rather than t.if to create a new view when the view model changes too
|
// use t.mapView rather than t.if to create a new view when the view model changes too
|
||||||
t.p(hydrogenGithubLink(t))
|
t.p(hydrogenGithubLink(t))
|
||||||
]);
|
]);
|
||||||
@ -35,10 +48,11 @@ export class LoginView extends TemplateView {
|
|||||||
class StartSSOLoginView extends TemplateView {
|
class StartSSOLoginView extends TemplateView {
|
||||||
render(t, vm) {
|
render(t, vm) {
|
||||||
return t.div({ className: "StartSSOLoginView" },
|
return t.div({ className: "StartSSOLoginView" },
|
||||||
[
|
t.button({
|
||||||
t.p({ className: "StartSSOLoginView_separator" }, "or"),
|
className: "StartSSOLoginView_button button-action secondary",
|
||||||
t.button({ className: "StartSSOLoginView_button button-action secondary", type: "button", onClick: () => vm.startSSOLogin() }, "Log in with SSO")
|
type: "button",
|
||||||
]
|
onClick: () => vm.startSSOLogin()
|
||||||
|
}, vm.i18n`Log in with SSO`)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,27 +32,17 @@ export class PasswordLoginView extends TemplateView {
|
|||||||
placeholder: vm.i18n`Password`,
|
placeholder: vm.i18n`Password`,
|
||||||
disabled
|
disabled
|
||||||
});
|
});
|
||||||
const homeserver = t.input({
|
|
||||||
id: "homeserver",
|
|
||||||
type: "text",
|
|
||||||
placeholder: vm.i18n`Your matrix homeserver`,
|
|
||||||
value: vm.defaultHomeServer,
|
|
||||||
onChange: () => vm.updateHomeServer(homeserver.value),
|
|
||||||
disabled
|
|
||||||
});
|
|
||||||
|
|
||||||
return t.div({className: "LoginView form"}, [
|
return t.div({className: "PasswordLoginView form"}, [
|
||||||
t.h1([vm.i18n`Sign In`]),
|
|
||||||
t.if(vm => vm.error, t => t.div({ className: "error" }, vm => vm.error)),
|
t.if(vm => vm.error, t => t.div({ className: "error" }, vm => vm.error)),
|
||||||
t.form({
|
t.form({
|
||||||
onSubmit: evnt => {
|
onSubmit: evnt => {
|
||||||
evnt.preventDefault();
|
evnt.preventDefault();
|
||||||
vm.login(username.value, password.value, homeserver.value);
|
vm.login(username.value, password.value);
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
t.div({ className: "form-row" }, [t.label({ for: "username" }, vm.i18n`Username`), username]),
|
t.div({ className: "form-row" }, [t.label({ for: "username" }, vm.i18n`Username`), username]),
|
||||||
t.div({ className: "form-row" }, [t.label({ for: "password" }, vm.i18n`Password`), password]),
|
t.div({ className: "form-row" }, [t.label({ for: "password" }, vm.i18n`Password`), password]),
|
||||||
t.div({ className: "form-row" }, [t.label({ for: "homeserver" }, vm.i18n`Homeserver`), homeserver]),
|
|
||||||
t.mapView(vm => vm.loadViewModel, loadViewModel => loadViewModel ? new SessionLoadStatusView(loadViewModel) : null),
|
t.mapView(vm => vm.loadViewModel, loadViewModel => loadViewModel ? new SessionLoadStatusView(loadViewModel) : null),
|
||||||
t.div({ className: "button-row" }, [
|
t.div({ className: "button-row" }, [
|
||||||
t.a({
|
t.a({
|
||||||
|
Loading…
Reference in New Issue
Block a user