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;
|
this._boundUpdateFromValue = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get value() {
|
||||||
|
return this._value;
|
||||||
|
}
|
||||||
|
|
||||||
_subscribe() {
|
_subscribe() {
|
||||||
this._boundUpdateFromValue = this._updateFromValue.bind(this);
|
this._boundUpdateFromValue = this._updateFromValue.bind(this);
|
||||||
|
|
||||||
|
@ -94,8 +98,10 @@ export class TemplateView {
|
||||||
unmount() {
|
unmount() {
|
||||||
this._detach();
|
this._detach();
|
||||||
this._unsubscribe();
|
this._unsubscribe();
|
||||||
for (const v of this._subViews) {
|
if (this._subViews) {
|
||||||
v.unmount();
|
for (const v of this._subViews) {
|
||||||
|
v.unmount();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 = {};
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,6 @@ export class RoomTile extends TemplateView {
|
||||||
|
|
||||||
// called from ListView
|
// called from ListView
|
||||||
clicked() {
|
clicked() {
|
||||||
this.viewModel.open();
|
this.value.open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)))
|
||||||
|
|
Loading…
Reference in a new issue