From 06fc3101e8135e128fec245be3cd73663a4641f7 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 6 May 2020 23:44:52 +0200 Subject: [PATCH] make login view enabled again if load view is not busy anymore --- src/domain/LoginViewModel.js | 21 ++++++++++++++++++++- src/ui/web/general/TemplateView.js | 21 ++++++++++++++------- src/ui/web/login/LoginView.js | 6 +++--- src/utils/EventEmitter.js | 7 +++++++ 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/src/domain/LoginViewModel.js b/src/domain/LoginViewModel.js index 3f70108f..64558295 100644 --- a/src/domain/LoginViewModel.js +++ b/src/domain/LoginViewModel.js @@ -8,13 +8,26 @@ export class LoginViewModel extends ViewModel { this._sessionCallback = sessionCallback; this._defaultHomeServer = defaultHomeServer; this._loadViewModel = null; + this._loadViewModelSubscription = null; } get defaultHomeServer() { return this._defaultHomeServer; } get loadViewModel() {return this._loadViewModel; } + get isBusy() { + if (!this._loadViewModel) { + return false; + } else { + return this._loadViewModel.loading; + } + } + async login(username, password, homeserver) { + this._loadViewModelSubscription = this.disposeTracked(this._loadViewModelSubscription); + if (this._loadViewModel) { + this._loadViewModel.cancel(); + } this._loadViewModel = new SessionLoadViewModel({ createAndStartSessionContainer: () => { const sessionContainer = this._createSessionContainer(); @@ -36,10 +49,16 @@ export class LoginViewModel extends ViewModel { }); this._loadViewModel.start(); this.emitChange("loadViewModel"); + this._loadViewModelSubscription = this.track(this._loadViewModel.disposableOn("change", () => { + if (!this._loadViewModel.loading) { + this._loadViewModelSubscription = this.disposeTracked(this._loadViewModelSubscription); + } + this.emitChange("isBusy"); + })); } cancel() { - if (!this._loadViewModel) { + if (!this.isBusy) { this._sessionCallback(); } } diff --git a/src/ui/web/general/TemplateView.js b/src/ui/web/general/TemplateView.js index ae75abc7..8cdccdf1 100644 --- a/src/ui/web/general/TemplateView.js +++ b/src/ui/web/general/TemplateView.js @@ -276,10 +276,9 @@ class TemplateBuilder { return vm => new TemplateView(vm, render); } - // creates a conditional subtemplate - if(fn, viewCreator) { - const boolFn = value => !!fn(value); - return this._addReplaceNodeBinding(boolFn, (prevNode) => { + // map a value to a view, every time the value changes + mapView(mapFn, viewCreator) { + return this._addReplaceNodeBinding(mapFn, (prevNode) => { if (prevNode && prevNode.nodeType !== Node.COMMENT_NODE) { const subViews = this._templateView._subViews; const viewIdx = subViews.findIndex(v => v.root() === prevNode); @@ -288,14 +287,22 @@ class TemplateBuilder { view.unmount(); } } - if (boolFn(this._value)) { - const view = viewCreator(this._value); + const view = viewCreator(mapFn(this._value)); + if (view) { return this.view(view); } else { - return document.createComment("if placeholder"); + return document.createComment("node binding placeholder"); } }); } + + // creates a conditional subtemplate + if(fn, viewCreator) { + return this.mapView( + value => !!fn(value), + enabled => enabled ? viewCreator(this._value) : null + ); + } } diff --git a/src/ui/web/login/LoginView.js b/src/ui/web/login/LoginView.js index e361f1a6..18d99f65 100644 --- a/src/ui/web/login/LoginView.js +++ b/src/ui/web/login/LoginView.js @@ -4,7 +4,7 @@ import {SessionLoadView} from "./SessionLoadView.js"; export class LoginView extends TemplateView { render(t, vm) { - const disabled = vm => !!vm.loadViewModel; + const disabled = vm => !!vm.isBusy; const username = t.input({type: "text", placeholder: vm.i18n`Username`, disabled}); const password = t.input({type: "password", placeholder: vm.i18n`Password`, disabled}); const homeserver = t.input({type: "text", placeholder: vm.i18n`Your matrix homeserver`, value: vm.defaultHomeServer, disabled}); @@ -18,8 +18,8 @@ export class LoginView extends TemplateView { onClick: () => vm.login(username.value, password.value, homeserver.value), disabled }, vm.i18n`Log In`)), - t.div(t.button({onClick: () => vm.goBack(), disabled}, [vm.i18n`Pick an existing session`])), - t.if(vm => vm.loadViewModel, vm => new SessionLoadView(vm.loadViewModel)), + t.div(t.button({onClick: () => vm.cancel(), disabled}, [vm.i18n`Pick an existing session`])), + t.mapView(vm => vm.loadViewModel, loadViewModel => loadViewModel ? new SessionLoadView(loadViewModel) : null), t.p(brawlGithubLink(t)) ]); } diff --git a/src/utils/EventEmitter.js b/src/utils/EventEmitter.js index 94da0cde..04944bc8 100644 --- a/src/utils/EventEmitter.js +++ b/src/utils/EventEmitter.js @@ -12,6 +12,13 @@ export class EventEmitter { } } + disposableOn(name, callback) { + this.on(name, callback); + return () => { + this.off(name, callback); + } + } + on(name, callback) { let handlers = this._handlersByName[name]; if (!handlers) {