organize view code in directory like viewmodels

This commit is contained in:
Bruno Windels 2019-06-16 10:52:02 +02:00
parent 95e1d55b97
commit a5a333b71a
18 changed files with 129 additions and 22 deletions

View file

@ -6,7 +6,7 @@ export default class RoomNameTile extends SimpleTile {
return "announcement";
}
get label() {
get announcement() {
const event = this._entry.event;
const content = event.content;
return `${event.sender} changed membership to ${content.membership}`;

View file

@ -6,9 +6,9 @@ export default class RoomNameTile extends SimpleTile {
return "announcement";
}
get label() {
get announcement() {
const event = this._entry.event;
const content = event.content;
return `${event.sender} changed the room name to "${content.name}"`
return `${event.sender} named the room "${content.name}"`
}
}

View file

@ -22,7 +22,8 @@ export default function ({timeline}) {
case "m.emote":
return new TextTile(options);
case "m.image":
return new ImageTile(options);
return null; // not supported yet
// return new ImageTile(options);
case "m.location":
return new LocationTile(options);
default:

View file

@ -1,8 +1,9 @@
import Template from "./Template.js";
export default class TemplateView {
constructor(value) {
this.viewModel = value;
constructor(vm, bindToChangeEvent) {
this.viewModel = vm;
this._changeEventHandler = bindToChangeEvent ? this.update.bind(this, this.viewModel) : null;
this._template = null;
}
@ -11,6 +12,9 @@ export default class TemplateView {
}
mount() {
if (this._changeEventHandler) {
this.viewModel.on("change", this._changeEventHandler);
}
this._template = new Template(this.viewModel, (t, value) => this.render(t, value));
return this.root();
}
@ -20,6 +24,9 @@ export default class TemplateView {
}
unmount() {
if (this._changeEventHandler) {
this.viewModel.off("change", this._changeEventHandler);
}
this._template.dispose();
this._template = null;
}

View file

@ -1,6 +1,7 @@
// DOM helper functions
export function isChildren(children) {
// children should be an not-object (that's the attributes), or a domnode, or an array
return typeof children !== "object" || !!children.nodeType || Array.isArray(children);
}

View file

@ -0,0 +1,19 @@
import TemplateView from "./general/TemplateView.js";
export default class LoginView extends TemplateView {
render(t, vm) {
const username = t.input({type: "text", placeholder: vm.usernamePlaceholder});
const password = t.input({type: "password", placeholder: vm.usernamePlaceholder});
const homeserver = t.input({type: "text", placeholder: vm.hsPlaceholder, value: vm.defaultHS});
return t.div({className: "login form"}, [
t.if(vm => vm.error, t => t.div({className: "error"}, vm => vm.error)),
t.div(username),
t.div(password),
t.div(homeserver),
t.div(t.button({
onClick: () => vm.login(username.value, password.value, homeserver.value),
disabled: vm => vm.isBusy
}, "Log In"))
]);
}
}

View file

@ -1,4 +1,4 @@
import {tag} from "./html.js";
import {tag} from "../general/html.js";
export default class RoomPlaceholderView {
constructor() {

View file

@ -1,4 +1,4 @@
import TemplateView from "./TemplateView.js";
import TemplateView from "../general/TemplateView.js";
export default class RoomTile extends TemplateView {
render(t) {

View file

@ -1,9 +1,10 @@
import ListView from "./ListView.js";
import ListView from "../general/ListView.js";
import RoomTile from "./RoomTile.js";
import RoomView from "./RoomView.js";
import SwitchView from "./SwitchView.js";
import RoomView from "./room/RoomView.js";
import SwitchView from "../general/SwitchView.js";
import RoomPlaceholderView from "./RoomPlaceholderView.js";
import {tag} from "./html.js";
import SyncStatusBar from "./SyncStatusBar.js";
import {tag} from "../general/html.js";
export default class SessionView {
constructor(viewModel) {
@ -21,8 +22,7 @@ export default class SessionView {
mount() {
this._viewModel.on("change", this._onViewModelChange);
this._root = tag.div({className: "SessionView"});
this._syncStatusBar = new SyncStatusBar(this._viewModel.syncStatusViewModel);
this._roomList = new ListView(
{
list: this._viewModel.roomList,
@ -30,9 +30,16 @@ export default class SessionView {
},
(room) => new RoomTile(room)
);
this._root.appendChild(this._roomList.mount());
this._middleSwitcher = new SwitchView(new RoomPlaceholderView());
this._root.appendChild(this._middleSwitcher.mount());
this._root = tag.div({className: "SessionView"}, [
this._syncStatusBar.mount(),
tag.div({className: "main"}, [
this._roomList.mount(),
this._middleSwitcher.mount()
])
]);
return this._root;
}

View file

@ -0,0 +1,16 @@
import TemplateView from "../general/TemplateView.js";
export default class SyncStatusBar extends TemplateView {
constructor(vm) {
super(vm, true);
}
render(t, vm) {
return t.div({className: {
"SyncStatusBar": true,
}}, [
vm => vm.status,
t.if(vm => !vm.isSyncing, t => t.button({onClick: () => vm.trySync()}, "Try syncing"))
]);
}
}

View file

@ -1,6 +1,6 @@
import TimelineTile from "./TimelineTile.js";
import ListView from "./ListView.js";
import {tag} from "./html.js";
import TimelineTile from "./timeline/TimelineTile.js";
import ListView from "../../general/ListView.js";
import {tag} from "../../general/html.js";
import GapView from "./timeline/GapView.js";
export default class RoomView {

View file

@ -0,0 +1,7 @@
import TemplateView from "../../../general/TemplateView.js";
export default class AnnouncementView extends TemplateView {
render(t) {
return t.li({className: "AnnouncementView"}, vm => vm.announcement);
}
}

View file

@ -1,14 +1,17 @@
import TemplateView from "../TemplateView.js";
import TemplateView from "../../../general/TemplateView.js";
export default class GapView extends TemplateView {
render(t, vm) {
const className = {
gap: true,
GapView: true,
isLoading: vm => vm.isLoading
};
const label = (vm.isUp ? "🠝" : "🠟") + " fill gap"; //no binding
return t.li({className}, [
t.button({onClick: () => this.viewModel.fill(), disabled: vm => vm.isLoading}, label),
t.button({
onClick: () => this.viewModel.fill(),
disabled: vm => vm.isLoading
}, label),
t.if(vm => vm.error, t => t.strong(vm => vm.error))
]);
}

View file

@ -0,0 +1,13 @@
import TemplateView from "../../../general/TemplateView.js";
export default class TextMessageView extends TemplateView {
render(t, vm) {
return t.li(
{className: {"TextMessageView": true, own: vm.isOwn}},
t.div({className: "message-container"}, [
t.div({className: "sender"}, vm.sender),
t.p([vm.text, t.time(vm.time)]),
])
);
}
}

View file

@ -0,0 +1,33 @@
import {tag} from "../../../general/html.js";
export default class TimelineTile {
constructor(tileVM) {
this._tileVM = tileVM;
this._root = null;
}
root() {
return this._root;
}
mount() {
this._root = renderTile(this._tileVM);
return this._root;
}
unmount() {}
update(vm, paramName) {
}
}
function renderTile(tile) {
switch (tile.shape) {
case "message":
return tag.li([tag.strong(tile.internalId+" "), tile.label]);
case "announcement":
return tag.li([tag.strong(tile.internalId+" "), tile.announcement]);
default:
return tag.li([tag.strong(tile.internalId+" "), "unknown tile shape: " + tile.shape]);
}
}