forked from mystiq/hydrogen-web
apply template view api changes
This commit is contained in:
parent
cdf051f19b
commit
ceec8937ef
9 changed files with 42 additions and 45 deletions
|
@ -35,6 +35,10 @@ export class TemplateView {
|
|||
this._boundUpdateFromValue = null;
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
_subscribe() {
|
||||
this._boundUpdateFromValue = this._updateFromValue.bind(this);
|
||||
|
||||
|
@ -94,10 +98,12 @@ export class TemplateView {
|
|||
unmount() {
|
||||
this._detach();
|
||||
this._unsubscribe();
|
||||
if (this._subViews) {
|
||||
for (const v of this._subViews) {
|
||||
v.unmount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
root() {
|
||||
return this._root;
|
||||
|
|
|
@ -70,7 +70,7 @@ export function text(str) {
|
|||
export const TAG_NAMES = [
|
||||
"a", "ol", "ul", "li", "div", "h1", "h2", "h3", "h4", "h5", "h6",
|
||||
"p", "strong", "em", "span", "img", "section", "main", "article", "aside",
|
||||
"pre", "button", "time", "input", "textarea"];
|
||||
"pre", "button", "time", "input", "textarea", "svg", "circle"];
|
||||
|
||||
export const tag = {};
|
||||
|
||||
|
|
|
@ -2,15 +2,11 @@ import {TemplateView} from "../general/TemplateView.js";
|
|||
import {brawlGithubLink} from "./common.js";
|
||||
|
||||
export class LoginView extends TemplateView {
|
||||
constructor(vm) {
|
||||
super(vm, true);
|
||||
}
|
||||
|
||||
render(t, vm) {
|
||||
const disabled = vm => vm.loading;
|
||||
const username = t.input({type: "text", placeholder: vm.usernamePlaceholder, 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 disabled = vm => !!vm.loadViewModel;
|
||||
return t.div({className: "LoginView form"}, [
|
||||
t.h1(["Log in to your homeserver"]),
|
||||
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) {
|
||||
return t.div({className: "loadProgress"}, [
|
||||
t.div({className: "spinner"}),
|
||||
t.p(vm => vm.loadLabel),
|
||||
t.if(vm => vm.loading, t.createTemplate(t => t.button({onClick: vm => vm.cancel()}, "Cancel login")))
|
||||
]);
|
||||
function spinner(t, extraClasses = undefined) {
|
||||
return t.svg({className: Object.assign({"spinner": true}, extraClasses), viewBox:"0 0 100% 100%"},
|
||||
t.circle({cx:"50%", cy:"50%", r:"45%", pathLength:"100"})
|
||||
);
|
||||
}
|
||||
|
||||
class SessionLoadView extends TemplateView {
|
||||
render(t) {
|
||||
return t.div([
|
||||
spinner(t, {hidden: vm => !vm.loading}),
|
||||
t.p(vm => vm.loadLabel)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,28 +29,28 @@ function selectFileAsText(mimeType) {
|
|||
class SessionPickerItemView extends TemplateView {
|
||||
_onDeleteClick() {
|
||||
if (confirm("Are you sure?")) {
|
||||
this.viewModel.delete();
|
||||
this.value.delete();
|
||||
}
|
||||
}
|
||||
|
||||
render(t) {
|
||||
render(t, vm) {
|
||||
const deleteButton = t.button({
|
||||
disabled: vm => vm.isDeleting,
|
||||
onClick: this._onDeleteClick.bind(this),
|
||||
}, "Delete");
|
||||
const clearButton = t.button({
|
||||
disabled: vm => vm.isClearing,
|
||||
onClick: () => this.viewModel.clear(),
|
||||
onClick: () => vm.clear(),
|
||||
}, "Clear");
|
||||
const exportButton = t.button({
|
||||
disabled: vm => vm.isClearing,
|
||||
onClick: () => this.viewModel.export(),
|
||||
onClick: () => vm.export(),
|
||||
}, "Export");
|
||||
const downloadExport = t.if(vm => vm.exportDataUrl, t.createTemplate((t, vm) => {
|
||||
return t.a({
|
||||
href: vm.exportDataUrl,
|
||||
download: `brawl-session-${this.viewModel.id}.json`,
|
||||
onClick: () => setTimeout(() => this.viewModel.clearExport(), 100),
|
||||
download: `brawl-session-${vm.id}.json`,
|
||||
onClick: () => setTimeout(() => vm.clearExport(), 100),
|
||||
}, "Download");
|
||||
}));
|
||||
|
||||
|
@ -68,32 +68,24 @@ class SessionPickerItemView extends TemplateView {
|
|||
}
|
||||
|
||||
export class SessionPickerView extends TemplateView {
|
||||
mount() {
|
||||
this._sessionList = new ListView({
|
||||
list: this.viewModel.sessions,
|
||||
render(t, vm) {
|
||||
const sessionList = new ListView({
|
||||
list: vm.sessions,
|
||||
onItemClick: (item, event) => {
|
||||
if (event.target.closest(".userId")) {
|
||||
this.viewModel.pick(item.viewModel.id);
|
||||
vm.pick(item.value.id);
|
||||
}
|
||||
},
|
||||
}, sessionInfo => {
|
||||
return new SessionPickerItemView(sessionInfo);
|
||||
});
|
||||
return super.mount();
|
||||
}
|
||||
|
||||
render(t) {
|
||||
return t.div({className: "SessionPickerView"}, [
|
||||
t.h1(["Pick a session"]),
|
||||
this._sessionList.mount(),
|
||||
t.p(t.button({onClick: () => this.viewModel.cancel()}, ["Log in to a new session instead"])),
|
||||
t.p(t.button({onClick: async () => this.viewModel.import(await selectFileAsText("application/json"))}, "Import")),
|
||||
t.view(sessionList),
|
||||
t.p(t.button({onClick: () => vm.cancel()}, ["Log in to a new session instead"])),
|
||||
t.p(t.button({onClick: async () => vm.import(await selectFileAsText("application/json"))}, "Import")),
|
||||
t.p(brawlGithubLink(t))
|
||||
]);
|
||||
}
|
||||
|
||||
unmount() {
|
||||
super.unmount();
|
||||
this._sessionList.unmount();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@ export class RoomTile extends TemplateView {
|
|||
|
||||
// called from ListView
|
||||
clicked() {
|
||||
this.viewModel.open();
|
||||
this.value.open();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
import {TemplateView} from "../general/TemplateView.js";
|
||||
|
||||
export class SyncStatusBar extends TemplateView {
|
||||
constructor(vm) {
|
||||
super(vm, true);
|
||||
}
|
||||
|
||||
render(t, vm) {
|
||||
return t.div({className: {
|
||||
"SyncStatusBar": true,
|
||||
|
|
|
@ -16,7 +16,7 @@ export class MessageComposer extends TemplateView {
|
|||
|
||||
_onKeyDown(event) {
|
||||
if (event.key === "Enter") {
|
||||
if (this.viewModel.sendMessage(this._input.value)) {
|
||||
if (this.value.sendMessage(this._input.value)) {
|
||||
this._input.value = "";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import {MessageComposer} from "./MessageComposer.js";
|
|||
|
||||
export class RoomView extends TemplateView {
|
||||
constructor(viewModel) {
|
||||
super(viewModel, true);
|
||||
super(viewModel);
|
||||
this._timelineList = null;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ export class RoomView extends TemplateView {
|
|||
}
|
||||
|
||||
mount() {
|
||||
this._composer = new MessageComposer(this.viewModel);
|
||||
this._composer = new MessageComposer(this.value);
|
||||
this._timelineList = new TimelineList();
|
||||
return super.mount();
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ export class RoomView extends TemplateView {
|
|||
update(value, prop) {
|
||||
super.update(value, prop);
|
||||
if (prop === "timelineViewModel") {
|
||||
this._timelineList.update({viewModel: this.viewModel.timelineViewModel});
|
||||
this._timelineList.update({viewModel: this.value.timelineViewModel});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ export class GapView extends TemplateView {
|
|||
const label = (vm.isUp ? "🠝" : "🠟") + " fill gap"; //no binding
|
||||
return t.li({className}, [
|
||||
t.button({
|
||||
onClick: () => this.viewModel.fill(),
|
||||
onClick: () => vm.fill(),
|
||||
disabled: vm => vm.isLoading
|
||||
}, label),
|
||||
t.if(vm => vm.error, t.createTemplate(t => t.strong(vm => vm.error)))
|
||||
|
|
Loading…
Reference in a new issue