2019-06-16 18:51:20 +05:30
|
|
|
import ListView from "../../general/ListView.js";
|
|
|
|
import GapView from "./timeline/GapView.js";
|
|
|
|
import TextMessageView from "./timeline/TextMessageView.js";
|
|
|
|
import AnnouncementView from "./timeline/AnnouncementView.js";
|
|
|
|
|
|
|
|
export default class TimelineList extends ListView {
|
|
|
|
constructor(options = {}) {
|
|
|
|
options.className = "Timeline";
|
|
|
|
super(options, entry => {
|
|
|
|
switch (entry.shape) {
|
|
|
|
case "gap": return new GapView(entry);
|
|
|
|
case "announcement": return new AnnouncementView(entry);
|
|
|
|
case "message":return new TextMessageView(entry);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
this._atBottom = false;
|
2019-06-16 20:59:33 +05:30
|
|
|
this._onScroll = this._onScroll.bind(this);
|
|
|
|
this._topLoadingPromise = null;
|
|
|
|
this._viewModel = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
async _onScroll() {
|
|
|
|
const root = this.root();
|
|
|
|
if (root.scrollTop === 0 && !this._topLoadingPromise && this._viewModel) {
|
|
|
|
const beforeFromBottom = this._distanceFromBottom();
|
|
|
|
this._topLoadingPromise = this._viewModel.loadAtTop();
|
|
|
|
await this._topLoadingPromise;
|
|
|
|
const fromBottom = this._distanceFromBottom();
|
|
|
|
const amountGrown = fromBottom - beforeFromBottom;
|
|
|
|
root.scrollTop = root.scrollTop + amountGrown;
|
|
|
|
this._topLoadingPromise = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
update(attributes) {
|
|
|
|
if(attributes.viewModel) {
|
|
|
|
this._viewModel = attributes.viewModel;
|
|
|
|
attributes.list = attributes.viewModel.tiles;
|
|
|
|
}
|
|
|
|
super.update(attributes);
|
|
|
|
}
|
|
|
|
|
|
|
|
mount() {
|
|
|
|
const root = super.mount();
|
|
|
|
root.addEventListener("scroll", this._onScroll);
|
|
|
|
return root;
|
|
|
|
}
|
|
|
|
|
|
|
|
unmount() {
|
|
|
|
this.root().removeEventListener("scroll", this._onScroll);
|
|
|
|
super.unmount();
|
2019-06-16 18:51:20 +05:30
|
|
|
}
|
|
|
|
|
2019-06-16 20:58:51 +05:30
|
|
|
loadList() {
|
|
|
|
super.loadList();
|
2019-06-16 20:09:20 +05:30
|
|
|
const root = this.root();
|
|
|
|
root.scrollTop = root.scrollHeight;
|
|
|
|
}
|
|
|
|
|
2019-06-16 18:51:20 +05:30
|
|
|
onBeforeListChanged() {
|
2019-06-16 20:59:33 +05:30
|
|
|
const fromBottom = this._distanceFromBottom();
|
2019-06-16 18:51:20 +05:30
|
|
|
this._atBottom = fromBottom < 1;
|
|
|
|
}
|
|
|
|
|
2019-06-16 20:59:33 +05:30
|
|
|
_distanceFromBottom() {
|
|
|
|
const root = this.root();
|
|
|
|
return root.scrollHeight - root.scrollTop - root.clientHeight;
|
|
|
|
}
|
|
|
|
|
2019-06-16 18:51:20 +05:30
|
|
|
onListChanged() {
|
|
|
|
if (this._atBottom) {
|
|
|
|
const root = this.root();
|
|
|
|
root.scrollTop = root.scrollHeight;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|