forked from mystiq/hydrogen-web
load more events when scrolled to top
This commit is contained in:
parent
c12300bfa5
commit
9cd5257959
4 changed files with 47 additions and 14 deletions
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue