From eba4d8a28b3e64c397ea83a7250e41faf308e70c Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 18 Mar 2021 12:43:00 +0100 Subject: [PATCH] improve ergonomics for sub-templates in TemplateView - renames if to ifView - adds map and if that immediately take a sub template render function rather than having to call createTemplate --- src/platform/web/ui/general/TemplateView.js | 27 +++++++++++++------ src/platform/web/ui/login/LoginView.js | 2 +- .../web/ui/login/SessionPickerView.js | 8 +++--- .../web/ui/session/SessionStatusView.js | 6 ++--- .../ui/session/room/timeline/BaseMediaView.js | 2 +- .../web/ui/session/room/timeline/GapView.js | 2 +- .../settings/SessionBackupSettingsView.js | 4 +-- 7 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/platform/web/ui/general/TemplateView.js b/src/platform/web/ui/general/TemplateView.js index 14cb53ac..6b016b9b 100644 --- a/src/platform/web/ui/general/TemplateView.js +++ b/src/platform/web/ui/general/TemplateView.js @@ -296,11 +296,6 @@ class TemplateBuilder { return root; } - // sugar - createTemplate(render) { - return vm => new TemplateView(vm, render); - } - // map a value to a view, every time the value changes mapView(mapFn, viewCreator) { return this._addReplaceNodeBinding(mapFn, (prevNode) => { @@ -321,13 +316,29 @@ class TemplateBuilder { }); } - // creates a conditional subtemplate - if(fn, viewCreator) { + // Special case of mapView for a TemplateView. + // Always creates a TemplateView, if this is optional depending + // on mappedValue, use `if` or `mapView` + map(mapFn, renderFn) { + return this.mapView(mapFn, mappedValue => { + return new TemplateView(this._value, (t, vm) => { + return renderFn(mappedValue, t, vm); + }); + }); + } + + ifView(predicate, viewCreator) { return this.mapView( - value => !!fn(value), + value => !!predicate(value), enabled => enabled ? viewCreator(this._value) : null ); } + + // creates a conditional subtemplate + // use mapView if you need to map to a different view class + if(predicate, renderFn) { + return this.ifView(predicate, vm => new TemplateView(vm, renderFn)); + } } diff --git a/src/platform/web/ui/login/LoginView.js b/src/platform/web/ui/login/LoginView.js index 48dbcdf1..0b15d42a 100644 --- a/src/platform/web/ui/login/LoginView.js +++ b/src/platform/web/ui/login/LoginView.js @@ -45,7 +45,7 @@ export class LoginView extends TemplateView { t.div({className: "logo"}), t.div({className: "LoginView form"}, [ t.h1([vm.i18n`Sign In`]), - t.if(vm => vm.error, t.createTemplate(t => t.div({className: "error"}, vm => vm.error))), + t.if(vm => vm.error, t => t.div({className: "error"}, vm => vm.error)), t.form({ onSubmit: evnt => { evnt.preventDefault(); diff --git a/src/platform/web/ui/login/SessionPickerView.js b/src/platform/web/ui/login/SessionPickerView.js index 279135ac..4bb69ee2 100644 --- a/src/platform/web/ui/login/SessionPickerView.js +++ b/src/platform/web/ui/login/SessionPickerView.js @@ -70,14 +70,14 @@ class SessionPickerItemView extends TemplateView { disabled: vm => vm.isClearing, onClick: () => vm.export(), }, "Export"); - const downloadExport = t.if(vm => vm.exportDataUrl, t.createTemplate((t, vm) => { + const downloadExport = t.if(vm => vm.exportDataUrl, (t, vm) => { return t.a({ href: vm.exportDataUrl, download: `brawl-session-${vm.id}.json`, onClick: () => setTimeout(() => vm.clearExport(), 100), }, "Download"); - })); - const errorMessage = t.if(vm => vm.error, t.createTemplate(t => t.p({className: "error"}, vm => vm.error))); + }); + const errorMessage = t.if(vm => vm.error, t => t.p({className: "error"}, vm => vm.error)); return t.li([ t.a({className: "session-info", href: vm.openUrl}, [ t.div({className: `avatar usercolor${vm.avatarColorNumber}`}, vm => vm.avatarInitials), @@ -118,7 +118,7 @@ export class SessionPickerView extends TemplateView { href: vm.cancelUrl }, vm.i18n`Sign In`) ]), - t.if(vm => vm.loadViewModel, vm => new SessionLoadStatusView(vm.loadViewModel)), + t.ifView(vm => vm.loadViewModel, () => new SessionLoadStatusView(vm.loadViewModel)), t.p(hydrogenGithubLink(t)) ]) ]); diff --git a/src/platform/web/ui/session/SessionStatusView.js b/src/platform/web/ui/session/SessionStatusView.js index 6a123ea9..fff25453 100644 --- a/src/platform/web/ui/session/SessionStatusView.js +++ b/src/platform/web/ui/session/SessionStatusView.js @@ -25,9 +25,9 @@ export class SessionStatusView extends TemplateView { }}, [ spinner(t, {hidden: vm => !vm.isWaiting}), t.p(vm => vm.statusLabel), - t.if(vm => vm.isConnectNowShown, t.createTemplate(t => t.button({className: "link", onClick: () => vm.connectNow()}, "Retry now"))), - t.if(vm => vm.isSecretStorageShown, t.createTemplate(t => t.a({href: vm.setupSessionBackupUrl}, "Go to settings"))), - t.if(vm => vm.canDismiss, t.createTemplate(t => t.div({className: "end"}, t.button({className: "dismiss", onClick: () => vm.dismiss()})))), + t.if(vm => vm.isConnectNowShown, t => t.button({className: "link", onClick: () => vm.connectNow()}, "Retry now")), + t.if(vm => vm.isSecretStorageShown, t => t.a({href: vm.setupSessionBackupUrl}, "Go to settings")), + t.if(vm => vm.canDismiss, t => t.div({className: "end"}, t.button({className: "dismiss", onClick: () => vm.dismiss()}))), ]); } } diff --git a/src/platform/web/ui/session/room/timeline/BaseMediaView.js b/src/platform/web/ui/session/room/timeline/BaseMediaView.js index 7dc538e6..b5b0ed4b 100644 --- a/src/platform/web/ui/session/room/timeline/BaseMediaView.js +++ b/src/platform/web/ui/session/room/timeline/BaseMediaView.js @@ -54,7 +54,7 @@ export class BaseMediaView extends TemplateView { } return renderMessage(t, vm, [ t.div({className: "media", style: `max-width: ${vm.width}px`}, children), - t.if(vm => vm.error, t.createTemplate((t, vm) => t.p({className: "error"}, vm.error))) + t.if(vm => vm.error, t => t.p({className: "error"}, vm.error)) ]); } } diff --git a/src/platform/web/ui/session/room/timeline/GapView.js b/src/platform/web/ui/session/room/timeline/GapView.js index 2b23ae3c..1e6e0af0 100644 --- a/src/platform/web/ui/session/room/timeline/GapView.js +++ b/src/platform/web/ui/session/room/timeline/GapView.js @@ -26,7 +26,7 @@ export class GapView extends TemplateView { return t.li({className}, [ spinner(t), t.div(vm.i18n`Loading more messages …`), - t.if(vm => vm.error, t.createTemplate(t => t.strong(vm => vm.error))) + t.if(vm => vm.error, t => t.strong(vm => vm.error)) ]); } } diff --git a/src/platform/web/ui/session/settings/SessionBackupSettingsView.js b/src/platform/web/ui/session/settings/SessionBackupSettingsView.js index c1c0e455..3c4f60ed 100644 --- a/src/platform/web/ui/session/settings/SessionBackupSettingsView.js +++ b/src/platform/web/ui/session/settings/SessionBackupSettingsView.js @@ -67,11 +67,11 @@ function renderEnableFieldRow(t, vm, label, callback) { } function renderError(t) { - return t.if(vm => vm.error, t.createTemplate((t, vm) => { + return t.if(vm => vm.error, (t, vm) => { return t.div([ t.p({className: "error"}, vm => vm.i18n`Could not enable session backup: ${vm.error}.`), t.p(vm.i18n`Try double checking that you did not mix up your security key, security phrase and login password as explained above.`) ]) - })); + }); }