apply template view api changes

This commit is contained in:
Bruno Windels 2020-04-30 18:27:21 +02:00
parent cdf051f19b
commit ceec8937ef
9 changed files with 42 additions and 45 deletions

View file

@ -35,6 +35,10 @@ export class TemplateView {
this._boundUpdateFromValue = null; this._boundUpdateFromValue = null;
} }
get value() {
return this._value;
}
_subscribe() { _subscribe() {
this._boundUpdateFromValue = this._updateFromValue.bind(this); this._boundUpdateFromValue = this._updateFromValue.bind(this);
@ -94,10 +98,12 @@ export class TemplateView {
unmount() { unmount() {
this._detach(); this._detach();
this._unsubscribe(); this._unsubscribe();
if (this._subViews) {
for (const v of this._subViews) { for (const v of this._subViews) {
v.unmount(); v.unmount();
} }
} }
}
root() { root() {
return this._root; return this._root;

View file

@ -70,7 +70,7 @@ export function text(str) {
export const TAG_NAMES = [ export const TAG_NAMES = [
"a", "ol", "ul", "li", "div", "h1", "h2", "h3", "h4", "h5", "h6", "a", "ol", "ul", "li", "div", "h1", "h2", "h3", "h4", "h5", "h6",
"p", "strong", "em", "span", "img", "section", "main", "article", "aside", "p", "strong", "em", "span", "img", "section", "main", "article", "aside",
"pre", "button", "time", "input", "textarea"]; "pre", "button", "time", "input", "textarea", "svg", "circle"];
export const tag = {}; export const tag = {};

View file

@ -2,15 +2,11 @@ import {TemplateView} from "../general/TemplateView.js";
import {brawlGithubLink} from "./common.js"; import {brawlGithubLink} from "./common.js";
export class LoginView extends TemplateView { export class LoginView extends TemplateView {
constructor(vm) {
super(vm, true);
}
render(t, vm) { render(t, vm) {
const disabled = vm => vm.loading;
const username = t.input({type: "text", placeholder: vm.usernamePlaceholder, disabled}); const username = t.input({type: "text", placeholder: vm.usernamePlaceholder, disabled});
const password = t.input({type: "password", placeholder: vm.passwordPlaceholder, disabled}); const password = t.input({type: "password", placeholder: vm.passwordPlaceholder, disabled});
const homeserver = t.input({type: "text", placeholder: vm.hsPlaceholder, value: vm.defaultHomeServer, disabled}); const homeserver = t.input({type: "text", placeholder: vm.hsPlaceholder, value: vm.defaultHomeServer, disabled});
const disabled = vm => !!vm.loadViewModel;
return t.div({className: "LoginView form"}, [ return t.div({className: "LoginView form"}, [
t.h1(["Log in to your homeserver"]), t.h1(["Log in to your homeserver"]),
t.if(vm => vm.error, t.createTemplate(t => t.div({className: "error"}, vm => vm.error))), t.if(vm => vm.error, t.createTemplate(t => t.div({className: "error"}, vm => vm.error))),
@ -28,10 +24,17 @@ export class LoginView extends TemplateView {
} }
} }
function renderLoadProgress(t) { function spinner(t, extraClasses = undefined) {
return t.div({className: "loadProgress"}, [ return t.svg({className: Object.assign({"spinner": true}, extraClasses), viewBox:"0 0 100% 100%"},
t.div({className: "spinner"}), t.circle({cx:"50%", cy:"50%", r:"45%", pathLength:"100"})
t.p(vm => vm.loadLabel), );
t.if(vm => vm.loading, t.createTemplate(t => t.button({onClick: vm => vm.cancel()}, "Cancel login"))) }
class SessionLoadView extends TemplateView {
render(t) {
return t.div([
spinner(t, {hidden: vm => !vm.loading}),
t.p(vm => vm.loadLabel)
]); ]);
} }
}

View file

@ -29,28 +29,28 @@ function selectFileAsText(mimeType) {
class SessionPickerItemView extends TemplateView { class SessionPickerItemView extends TemplateView {
_onDeleteClick() { _onDeleteClick() {
if (confirm("Are you sure?")) { if (confirm("Are you sure?")) {
this.viewModel.delete(); this.value.delete();
} }
} }
render(t) { render(t, vm) {
const deleteButton = t.button({ const deleteButton = t.button({
disabled: vm => vm.isDeleting, disabled: vm => vm.isDeleting,
onClick: this._onDeleteClick.bind(this), onClick: this._onDeleteClick.bind(this),
}, "Delete"); }, "Delete");
const clearButton = t.button({ const clearButton = t.button({
disabled: vm => vm.isClearing, disabled: vm => vm.isClearing,
onClick: () => this.viewModel.clear(), onClick: () => vm.clear(),
}, "Clear"); }, "Clear");
const exportButton = t.button({ const exportButton = t.button({
disabled: vm => vm.isClearing, disabled: vm => vm.isClearing,
onClick: () => this.viewModel.export(), onClick: () => vm.export(),
}, "Export"); }, "Export");
const downloadExport = t.if(vm => vm.exportDataUrl, t.createTemplate((t, vm) => { const downloadExport = t.if(vm => vm.exportDataUrl, t.createTemplate((t, vm) => {
return t.a({ return t.a({
href: vm.exportDataUrl, href: vm.exportDataUrl,
download: `brawl-session-${this.viewModel.id}.json`, download: `brawl-session-${vm.id}.json`,
onClick: () => setTimeout(() => this.viewModel.clearExport(), 100), onClick: () => setTimeout(() => vm.clearExport(), 100),
}, "Download"); }, "Download");
})); }));
@ -68,32 +68,24 @@ class SessionPickerItemView extends TemplateView {
} }
export class SessionPickerView extends TemplateView { export class SessionPickerView extends TemplateView {
mount() { render(t, vm) {
this._sessionList = new ListView({ const sessionList = new ListView({
list: this.viewModel.sessions, list: vm.sessions,
onItemClick: (item, event) => { onItemClick: (item, event) => {
if (event.target.closest(".userId")) { if (event.target.closest(".userId")) {
this.viewModel.pick(item.viewModel.id); vm.pick(item.value.id);
} }
}, },
}, sessionInfo => { }, sessionInfo => {
return new SessionPickerItemView(sessionInfo); return new SessionPickerItemView(sessionInfo);
}); });
return super.mount();
}
render(t) {
return t.div({className: "SessionPickerView"}, [ return t.div({className: "SessionPickerView"}, [
t.h1(["Pick a session"]), t.h1(["Pick a session"]),
this._sessionList.mount(), t.view(sessionList),
t.p(t.button({onClick: () => this.viewModel.cancel()}, ["Log in to a new session instead"])), t.p(t.button({onClick: () => vm.cancel()}, ["Log in to a new session instead"])),
t.p(t.button({onClick: async () => this.viewModel.import(await selectFileAsText("application/json"))}, "Import")), t.p(t.button({onClick: async () => vm.import(await selectFileAsText("application/json"))}, "Import")),
t.p(brawlGithubLink(t)) t.p(brawlGithubLink(t))
]); ]);
} }
unmount() {
super.unmount();
this._sessionList.unmount();
}
} }

View file

@ -10,6 +10,6 @@ export class RoomTile extends TemplateView {
// called from ListView // called from ListView
clicked() { clicked() {
this.viewModel.open(); this.value.open();
} }
} }

View file

@ -1,10 +1,6 @@
import {TemplateView} from "../general/TemplateView.js"; import {TemplateView} from "../general/TemplateView.js";
export class SyncStatusBar extends TemplateView { export class SyncStatusBar extends TemplateView {
constructor(vm) {
super(vm, true);
}
render(t, vm) { render(t, vm) {
return t.div({className: { return t.div({className: {
"SyncStatusBar": true, "SyncStatusBar": true,

View file

@ -16,7 +16,7 @@ export class MessageComposer extends TemplateView {
_onKeyDown(event) { _onKeyDown(event) {
if (event.key === "Enter") { if (event.key === "Enter") {
if (this.viewModel.sendMessage(this._input.value)) { if (this.value.sendMessage(this._input.value)) {
this._input.value = ""; this._input.value = "";
} }
} }

View file

@ -4,7 +4,7 @@ import {MessageComposer} from "./MessageComposer.js";
export class RoomView extends TemplateView { export class RoomView extends TemplateView {
constructor(viewModel) { constructor(viewModel) {
super(viewModel, true); super(viewModel);
this._timelineList = null; this._timelineList = null;
} }
@ -26,7 +26,7 @@ export class RoomView extends TemplateView {
} }
mount() { mount() {
this._composer = new MessageComposer(this.viewModel); this._composer = new MessageComposer(this.value);
this._timelineList = new TimelineList(); this._timelineList = new TimelineList();
return super.mount(); return super.mount();
} }
@ -40,7 +40,7 @@ export class RoomView extends TemplateView {
update(value, prop) { update(value, prop) {
super.update(value, prop); super.update(value, prop);
if (prop === "timelineViewModel") { if (prop === "timelineViewModel") {
this._timelineList.update({viewModel: this.viewModel.timelineViewModel}); this._timelineList.update({viewModel: this.value.timelineViewModel});
} }
} }
} }

View file

@ -9,7 +9,7 @@ export class GapView extends TemplateView {
const label = (vm.isUp ? "🠝" : "🠟") + " fill gap"; //no binding const label = (vm.isUp ? "🠝" : "🠟") + " fill gap"; //no binding
return t.li({className}, [ return t.li({className}, [
t.button({ t.button({
onClick: () => this.viewModel.fill(), onClick: () => vm.fill(),
disabled: vm => vm.isLoading disabled: vm => vm.isLoading
}, label), }, label),
t.if(vm => vm.error, t.createTemplate(t => t.strong(vm => vm.error))) t.if(vm => vm.error, t.createTemplate(t => t.strong(vm => vm.error)))