mirror of
https://github.com/vector-im/hydrogen-web.git
synced 2024-12-23 03:25:12 +01:00
render date separator in base class for all tiles
apart from gap, which doesn't have date since we add a container when the date separator needs to be shown, and we don't want to rerender the whole tile, we always render timeline tiles with a DIV rather than an LI (same for the UL).
This commit is contained in:
parent
90d0fd1f89
commit
4406d7917e
@ -55,7 +55,7 @@ export class MessageComposer extends TemplateView {
|
|||||||
className: "cancel",
|
className: "cancel",
|
||||||
onClick: () => this._clearReplyingTo()
|
onClick: () => this._clearReplyingTo()
|
||||||
}, "Close"),
|
}, "Close"),
|
||||||
t.view(new TileView(rvm, this._viewClassForTile, { interactive: false }, "div"))
|
t.view(new TileView(rvm, this._viewClassForTile, { interactive: false }))
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
const input = t.div({className: "MessageComposer_input"}, [
|
const input = t.div({className: "MessageComposer_input"}, [
|
||||||
|
@ -192,6 +192,7 @@ class TilesListView extends ListView<SimpleTile, TileView> {
|
|||||||
super({
|
super({
|
||||||
list: tiles,
|
list: tiles,
|
||||||
onItemClick: (tileView, evt) => tileView.onClick(evt),
|
onItemClick: (tileView, evt) => tileView.onClick(evt),
|
||||||
|
tagName: "div"
|
||||||
}, tile => {
|
}, tile => {
|
||||||
const TileView = viewClassForTile(tile);
|
const TileView = viewClassForTile(tile);
|
||||||
return new TileView(tile, viewClassForTile);
|
return new TileView(tile, viewClassForTile);
|
||||||
|
@ -14,21 +14,13 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {TemplateView} from "../../../general/TemplateView";
|
import {BaseTileView} from "./BaseTileView";
|
||||||
|
|
||||||
export class AnnouncementView extends TemplateView {
|
export class AnnouncementView extends BaseTileView {
|
||||||
// ignore other arguments
|
renderTile(t, vm) {
|
||||||
constructor(vm) {
|
return t.div({
|
||||||
super(vm);
|
|
||||||
}
|
|
||||||
|
|
||||||
render(t, vm) {
|
|
||||||
return t.li({
|
|
||||||
className: "AnnouncementView",
|
className: "AnnouncementView",
|
||||||
'data-event-id': vm.eventId
|
'data-event-id': vm.eventId
|
||||||
}, t.div(vm => vm.announcement));
|
}, t.div(vm => vm.announcement));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is called by the parent ListView, which just has 1 listener for the whole list */
|
|
||||||
onClick() {}
|
|
||||||
}
|
}
|
||||||
|
@ -18,17 +18,15 @@ limitations under the License.
|
|||||||
import {renderStaticAvatar} from "../../../avatar";
|
import {renderStaticAvatar} from "../../../avatar";
|
||||||
import {tag} from "../../../general/html";
|
import {tag} from "../../../general/html";
|
||||||
import {mountView} from "../../../general/utils";
|
import {mountView} from "../../../general/utils";
|
||||||
import {TemplateView} from "../../../general/TemplateView";
|
import {BaseTileView} from "./BaseTileView";
|
||||||
import {Popup} from "../../../general/Popup.js";
|
import {Popup} from "../../../general/Popup.js";
|
||||||
import {Menu} from "../../../general/Menu.js";
|
import {Menu} from "../../../general/Menu.js";
|
||||||
import {ReactionsView} from "./ReactionsView.js";
|
import {ReactionsView} from "./ReactionsView.js";
|
||||||
|
|
||||||
export class BaseMessageView extends TemplateView {
|
export class BaseMessageView extends BaseTileView {
|
||||||
constructor(value, viewClassForTile, renderFlags, tagName = "li") {
|
constructor(value, viewClassForTile, renderFlags) {
|
||||||
super(value);
|
super(value, viewClassForTile);
|
||||||
this._menuPopup = null;
|
this._menuPopup = null;
|
||||||
this._tagName = tagName;
|
|
||||||
this._viewClassForTile = viewClassForTile;
|
|
||||||
// TODO An enum could be nice to make code easier to read at call sites.
|
// TODO An enum could be nice to make code easier to read at call sites.
|
||||||
this._renderFlags = renderFlags;
|
this._renderFlags = renderFlags;
|
||||||
}
|
}
|
||||||
@ -36,12 +34,12 @@ export class BaseMessageView extends TemplateView {
|
|||||||
get _interactive() { return this._renderFlags?.interactive ?? true; }
|
get _interactive() { return this._renderFlags?.interactive ?? true; }
|
||||||
get _isReplyPreview() { return this._renderFlags?.reply; }
|
get _isReplyPreview() { return this._renderFlags?.reply; }
|
||||||
|
|
||||||
render(t, vm) {
|
renderTile(t, vm) {
|
||||||
const children = [this.renderMessageBody(t, vm)];
|
const children = [this.renderMessageBody(t, vm)];
|
||||||
if (this._interactive) {
|
if (this._interactive) {
|
||||||
children.push(t.button({className: "Timeline_messageOptions"}, "⋯"));
|
children.push(t.button({className: "Timeline_messageOptions"}, "⋯"));
|
||||||
}
|
}
|
||||||
const li = t.el(this._tagName, {
|
const tile = t.div({
|
||||||
className: {
|
className: {
|
||||||
"Timeline_message": true,
|
"Timeline_message": true,
|
||||||
own: vm.isOwn,
|
own: vm.isOwn,
|
||||||
@ -59,13 +57,13 @@ export class BaseMessageView extends TemplateView {
|
|||||||
// don't use `t` from within the side-effect callback
|
// don't use `t` from within the side-effect callback
|
||||||
t.mapSideEffect(vm => vm.isContinuation, (isContinuation, wasContinuation) => {
|
t.mapSideEffect(vm => vm.isContinuation, (isContinuation, wasContinuation) => {
|
||||||
if (isContinuation && wasContinuation === false) {
|
if (isContinuation && wasContinuation === false) {
|
||||||
li.removeChild(li.querySelector(".Timeline_messageAvatar"));
|
tile.removeChild(tile.querySelector(".Timeline_messageAvatar"));
|
||||||
li.removeChild(li.querySelector(".Timeline_messageSender"));
|
tile.removeChild(tile.querySelector(".Timeline_messageSender"));
|
||||||
} else if (!isContinuation && !this._isReplyPreview) {
|
} else if (!isContinuation && !this._isReplyPreview) {
|
||||||
const avatar = tag.a({href: vm.memberPanelLink, className: "Timeline_messageAvatar"}, [renderStaticAvatar(vm, 30)]);
|
const avatar = tag.a({href: vm.memberPanelLink, className: "Timeline_messageAvatar"}, [renderStaticAvatar(vm, 30)]);
|
||||||
const sender = tag.div({className: `Timeline_messageSender usercolor${vm.avatarColorNumber}`}, vm.displayName);
|
const sender = tag.div({className: `Timeline_messageSender usercolor${vm.avatarColorNumber}`}, vm.displayName);
|
||||||
li.insertBefore(avatar, li.firstChild);
|
tile.insertBefore(avatar, tile.firstChild);
|
||||||
li.insertBefore(sender, li.firstChild);
|
tile.insertBefore(sender, tile.firstChild);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// similarly, we could do this with a simple ifView,
|
// similarly, we could do this with a simple ifView,
|
||||||
@ -75,15 +73,15 @@ export class BaseMessageView extends TemplateView {
|
|||||||
if (reactions && this._interactive && !reactionsView) {
|
if (reactions && this._interactive && !reactionsView) {
|
||||||
reactionsView = new ReactionsView(reactions);
|
reactionsView = new ReactionsView(reactions);
|
||||||
this.addSubView(reactionsView);
|
this.addSubView(reactionsView);
|
||||||
li.appendChild(mountView(reactionsView));
|
tile.appendChild(mountView(reactionsView));
|
||||||
} else if (!reactions && reactionsView) {
|
} else if (!reactions && reactionsView) {
|
||||||
li.removeChild(reactionsView.root());
|
tile.removeChild(reactionsView.root());
|
||||||
reactionsView.unmount();
|
reactionsView.unmount();
|
||||||
this.removeSubView(reactionsView);
|
this.removeSubView(reactionsView);
|
||||||
reactionsView = null;
|
reactionsView = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return li;
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is called by the parent ListView, which just has 1 listener for the whole list */
|
/* This is called by the parent ListView, which just has 1 listener for the whole list */
|
||||||
|
56
src/platform/web/ui/session/room/timeline/BaseTileView.js
Normal file
56
src/platform/web/ui/session/room/timeline/BaseTileView.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2020 Bruno Windels <bruno@windels.cloud>
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {TemplateView} from "../../../general/TemplateView";
|
||||||
|
|
||||||
|
export class BaseTileView extends TemplateView {
|
||||||
|
// ignore other arguments
|
||||||
|
constructor(vm, viewClassForTile) {
|
||||||
|
super(vm);
|
||||||
|
this._viewClassForTile = viewClassForTile;
|
||||||
|
this._root = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
root() {
|
||||||
|
return this._root;
|
||||||
|
}
|
||||||
|
|
||||||
|
render(t, vm) {
|
||||||
|
const tile = this.renderTile(t, vm);
|
||||||
|
const swapRoot = newRoot => {
|
||||||
|
this._root?.replaceWith(newRoot);
|
||||||
|
this._root = newRoot;
|
||||||
|
}
|
||||||
|
t.mapSideEffect(vm => vm.hasDateSeparator, hasDateSeparator => {
|
||||||
|
if (hasDateSeparator) {
|
||||||
|
const container = t.div([this._renderDateSeparator(t, vm)]);
|
||||||
|
swapRoot(container);
|
||||||
|
container.appendChild(tile);
|
||||||
|
} else {
|
||||||
|
swapRoot(tile);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return this._root;
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderDateSeparator(t, vm) {
|
||||||
|
// if this needs any bindings, we need to use a subview
|
||||||
|
return t.div({className: "DateSeparator"}, t.time(vm.date));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is called by the parent ListView, which just has 1 listener for the whole list */
|
||||||
|
onClick() {}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user