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
|
// 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) {
|
||||||
|
|
|
@ -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
|
||||||
);
|
);
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue