load more events when scrolled to top

This commit is contained in:
Bruno Windels 2019-06-16 17:29:33 +02:00
parent c12300bfa5
commit 9cd5257959
4 changed files with 47 additions and 14 deletions

View file

@ -28,8 +28,7 @@ export default class TimelineViewModel {
// doesn't fill gaps, only loads stored entries/tiles
loadAtTop() {
// load 100 entries, which may result in 0..100 tiles
return this._timeline.loadAtTop(100);
return this._timeline.loadAtTop(50);
}
unloadAtTop(tileAmount) {

View file

@ -20,7 +20,7 @@ export default class Timeline {
/** @package */
async load() {
const entries = await this._timelineReader.readFromEnd(100);
const entries = await this._timelineReader.readFromEnd(50);
this._entriesList.setManySorted(entries);
}
@ -47,12 +47,12 @@ export default class Timeline {
// tries to prepend `amount` entries to the `entries` list.
async loadAtTop(amount) {
if (this._entriesList.length() === 0) {
const firstEventEntry = this._entriesList.array.find(e => !!e.event);
if (!firstEventEntry) {
return;
}
const firstEntry = this._entriesList.array()[0];
const entries = await this._timelineReader.readFrom(
firstEntry.asEventKey(),
firstEventEntry.asEventKey(),
Direction.Backward,
amount
);

View file

@ -5,7 +5,6 @@ export default class RoomView extends TemplateView {
constructor(viewModel) {
super(viewModel, true);
this._timelineList = null;
this._checkScroll = this._checkScroll.bind(this);
}
render(t) {
@ -37,11 +36,7 @@ export default class RoomView extends TemplateView {
update(value, prop) {
super.update(value, prop);
if (prop === "timelineViewModel") {
this._timelineList.update({list: this.viewModel.timelineViewModel.tiles});
this._timelineList.update({viewModel: this.viewModel.timelineViewModel});
}
}
_checkScroll() {
// const list = this._timelineList.root();
}
}

View file

@ -14,6 +14,41 @@ export default class TimelineList extends ListView {
}
});
this._atBottom = false;
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();
}
loadList() {
@ -23,11 +58,15 @@ export default class TimelineList extends ListView {
}
onBeforeListChanged() {
const root = this.root();
const fromBottom = root.scrollHeight - root.scrollTop - root.clientHeight;
const fromBottom = this._distanceFromBottom();
this._atBottom = fromBottom < 1;
}
_distanceFromBottom() {
const root = this.root();
return root.scrollHeight - root.scrollTop - root.clientHeight;
}
onListChanged() {
if (this._atBottom) {
const root = this.root();