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 // doesn't fill gaps, only loads stored entries/tiles
loadAtTop() { loadAtTop() {
// load 100 entries, which may result in 0..100 tiles return this._timeline.loadAtTop(50);
return this._timeline.loadAtTop(100);
} }
unloadAtTop(tileAmount) { unloadAtTop(tileAmount) {

View File

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

View File

@ -5,7 +5,6 @@ export default class RoomView extends TemplateView {
constructor(viewModel) { constructor(viewModel) {
super(viewModel, true); super(viewModel, true);
this._timelineList = null; this._timelineList = null;
this._checkScroll = this._checkScroll.bind(this);
} }
render(t) { render(t) {
@ -37,11 +36,7 @@ export default class RoomView extends TemplateView {
update(value, prop) { update(value, prop) {
super.update(value, prop); super.update(value, prop);
if (prop === "timelineViewModel") { 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._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() { loadList() {
@ -23,11 +58,15 @@ export default class TimelineList extends ListView {
} }
onBeforeListChanged() { onBeforeListChanged() {
const root = this.root(); const fromBottom = this._distanceFromBottom();
const fromBottom = root.scrollHeight - root.scrollTop - root.clientHeight;
this._atBottom = fromBottom < 1; this._atBottom = fromBottom < 1;
} }
_distanceFromBottom() {
const root = this.root();
return root.scrollHeight - root.scrollTop - root.clientHeight;
}
onListChanged() { onListChanged() {
if (this._atBottom) { if (this._atBottom) {
const root = this.root(); const root = this.root();