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
This commit is contained in:
Bruno Windels 2021-03-18 12:43:00 +01:00
parent 25cf72a9b6
commit eba4d8a28b
7 changed files with 31 additions and 20 deletions

View File

@ -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));
}
}

View File

@ -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();

View File

@ -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))
])
]);

View File

@ -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()}))),
]);
}
}

View File

@ -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))
]);
}
}

View File

@ -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))
]);
}
}

View File

@ -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.`)
])
}));
});
}