diff --git a/src/domain/session/room/timeline/tiles/GapTile.js b/src/domain/session/room/timeline/tiles/GapTile.js index cebffe24..240c071c 100644 --- a/src/domain/session/room/timeline/tiles/GapTile.js +++ b/src/domain/session/room/timeline/tiles/GapTile.js @@ -24,12 +24,20 @@ export default class GapTile extends SimpleTile { } } + get shape() { + return "gap"; + } + get isLoading() { return this._loading; } - get direction() { - return this._entry.direction; + get isUp() { + return this._entry.direction.isBackward; + } + + get isDown() { + return this._entry.direction.isForward; } get error() { diff --git a/src/domain/session/room/timeline/tiles/ImageTile.js b/src/domain/session/room/timeline/tiles/ImageTile.js index 8c18491e..ebe8d022 100644 --- a/src/domain/session/room/timeline/tiles/ImageTile.js +++ b/src/domain/session/room/timeline/tiles/ImageTile.js @@ -19,4 +19,8 @@ export default class ImageTile extends MessageTile { get height() { return 200; } + + get label() { + return "this is an image"; + } } diff --git a/src/domain/session/room/timeline/tiles/MessageTile.js b/src/domain/session/room/timeline/tiles/MessageTile.js index f57f8379..8ada2310 100644 --- a/src/domain/session/room/timeline/tiles/MessageTile.js +++ b/src/domain/session/room/timeline/tiles/MessageTile.js @@ -7,6 +7,10 @@ export default class MessageTile extends SimpleTile { this._date = new Date(this._entry.event.origin_server_ts); } + get shape() { + return "message"; + } + get sender() { return this._entry.event.sender; } diff --git a/src/domain/session/room/timeline/tiles/RoomMemberTile.js b/src/domain/session/room/timeline/tiles/RoomMemberTile.js index df31945c..cc9796e9 100644 --- a/src/domain/session/room/timeline/tiles/RoomMemberTile.js +++ b/src/domain/session/room/timeline/tiles/RoomMemberTile.js @@ -1,6 +1,11 @@ import SimpleTile from "./SimpleTile.js"; export default class RoomNameTile extends SimpleTile { + + get shape() { + return "announcement"; + } + get label() { const event = this._entry.event; const content = event.content; diff --git a/src/domain/session/room/timeline/tiles/RoomNameTile.js b/src/domain/session/room/timeline/tiles/RoomNameTile.js index e352b168..756d8d97 100644 --- a/src/domain/session/room/timeline/tiles/RoomNameTile.js +++ b/src/domain/session/room/timeline/tiles/RoomNameTile.js @@ -1,6 +1,11 @@ import SimpleTile from "./SimpleTile.js"; export default class RoomNameTile extends SimpleTile { + + get shape() { + return "annoucement"; + } + get label() { const event = this._entry.event; const content = event.content; diff --git a/src/domain/session/room/timeline/tiles/TextTile.js b/src/domain/session/room/timeline/tiles/TextTile.js index 092ff889..08c330f5 100644 --- a/src/domain/session/room/timeline/tiles/TextTile.js +++ b/src/domain/session/room/timeline/tiles/TextTile.js @@ -1,7 +1,7 @@ import MessageTile from "./MessageTile.js"; export default class TextTile extends MessageTile { - get text() { + get label() { const content = this._getContent(); const body = content && content.body; if (this._entry.type() === "m.emote") { diff --git a/src/ui/web/RoomView.js b/src/ui/web/RoomView.js index 987bdeeb..fd18ba6f 100644 --- a/src/ui/web/RoomView.js +++ b/src/ui/web/RoomView.js @@ -14,9 +14,7 @@ export default class RoomView { mount() { this._viewModel.on("change", this._onViewModelUpdate); this._nameLabel = html.h2(null, this._viewModel.name); - this._timelineList = new ListView({ - list: this._viewModel.timelineEntries - }, entry => new TimelineTile(entry)); + this._timelineList = new ListView({}, entry => new TimelineTile(entry)); this._timelineList.mount(); this._root = html.div({className: "RoomView"}, [ @@ -40,8 +38,8 @@ export default class RoomView { if (prop === "name") { this._nameLabel.innerText = this._viewModel.name; } - else if (prop === "timelineEntries") { - this._timelineList.update({list: this._viewModel.timelineEntries}); + else if (prop === "timelineViewModel") { + this._timelineList.update({list: this._viewModel.timelineViewModel.tiles}); } } diff --git a/src/ui/web/TimelineTile.js b/src/ui/web/TimelineTile.js index 7c362d78..a8d7e481 100644 --- a/src/ui/web/TimelineTile.js +++ b/src/ui/web/TimelineTile.js @@ -1,29 +1,8 @@ import * as html from "./html.js"; -function tileText(event) { - const content = event.content; - switch (event.type) { - case "m.room.message": { - const msgtype = content.msgtype; - switch (msgtype) { - case "m.text": - return content.body; - default: - return `unsupported msgtype: ${msgtype}`; - } - } - case "m.room.name": - return `changed the room name to "${content.name}"`; - case "m.room.member": - return `changed membership to ${content.membership}`; - default: - return `unsupported event type: ${event.type}`; - } -} - export default class TimelineTile { - constructor(entry) { - this._entry = entry; + constructor(tileVM) { + this._tileVM = tileVM; this._root = null; } @@ -32,21 +11,7 @@ export default class TimelineTile { } mount() { - let children; - if (this._entry.gap) { - children = [ - html.strong(null, "Gap"), - " with prev_batch ", - html.strong(null, this._entry.gap.prev_batch) - ]; - } else if (this._entry.event) { - const event = this._entry.event; - children = [ - html.strong(null, event.sender), - `: ${tileText(event)}`, - ]; - } - this._root = html.li(null, children); + this._root = renderTile(this._tileVM); return this._root; } @@ -54,3 +19,23 @@ export default class TimelineTile { update() {} } + +function renderTile(tile) { + switch (tile.shape) { + case "message": + return html.li(null, [html.strong(tile.sender), `: ${tile.label}`]); + case "gap": { + const button = html.button(null, (tile.isUp ? "🠝" : "🠟") + " fill gap"); + const handler = () => { + tile.fill(); + button.removeEventListener("click", handler); + }; + button.addEventListener("click", handler); + return html.li(null, button); + } + case "announcement": + return html.li(null, tile.label); + default: + return html.li(null, "unknown tile shape: " + tile.shape); + } +}