forked from mystiq/hydrogen-web
WIP
This commit is contained in:
parent
98cc1e2715
commit
9411e6f065
4 changed files with 19 additions and 18 deletions
|
@ -34,8 +34,6 @@ when loading, it just reads events from a sortkey backwards or forwards...
|
||||||
import {TilesCollection} from "./TilesCollection.js";
|
import {TilesCollection} from "./TilesCollection.js";
|
||||||
import {ViewModel} from "../../../ViewModel.js";
|
import {ViewModel} from "../../../ViewModel.js";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export class TimelineViewModel extends ViewModel {
|
export class TimelineViewModel extends ViewModel {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super(options);
|
super(options);
|
||||||
|
@ -45,7 +43,6 @@ export class TimelineViewModel extends ViewModel {
|
||||||
this._startTile = null;
|
this._startTile = null;
|
||||||
this._endTile = null;
|
this._endTile = null;
|
||||||
this._topLoadingPromise = null;
|
this._topLoadingPromise = null;
|
||||||
this._bottomLoadingPromise = null;
|
|
||||||
this._requestedStartTile = null;
|
this._requestedStartTile = null;
|
||||||
this._requestedEndTile = null;
|
this._requestedEndTile = null;
|
||||||
this._requestScheduled = false;
|
this._requestScheduled = false;
|
||||||
|
@ -56,7 +53,7 @@ export class TimelineViewModel extends ViewModel {
|
||||||
this._requestedStartTile = startTile;
|
this._requestedStartTile = startTile;
|
||||||
this._requestedEndTile = endTile;
|
this._requestedEndTile = endTile;
|
||||||
if (!this._requestScheduled) {
|
if (!this._requestScheduled) {
|
||||||
Promise.resolve().then(() => {
|
requestIdleCallback(() => {
|
||||||
this._setVisibleTileRange(this._requestedStartTile, this._requestedEndTile);
|
this._setVisibleTileRange(this._requestedStartTile, this._requestedEndTile);
|
||||||
this._requestScheduled = false;
|
this._requestScheduled = false;
|
||||||
});
|
});
|
||||||
|
@ -72,14 +69,15 @@ export class TimelineViewModel extends ViewModel {
|
||||||
this._endTile = endTile;
|
this._endTile = endTile;
|
||||||
const startIndex = this._tiles.getTileIndex(this._startTile);
|
const startIndex = this._tiles.getTileIndex(this._startTile);
|
||||||
const endIndex = this._tiles.getTileIndex(this._endTile);
|
const endIndex = this._tiles.getTileIndex(this._endTile);
|
||||||
for (const tile of this._tiles.sliceIterator(startIndex, endIndex)) {
|
for (const tile of this._tiles.sliceIterator(startIndex, endIndex + 1)) {
|
||||||
tile.notifyVisible();
|
tile.notifyVisible();
|
||||||
}
|
}
|
||||||
loadTop = startIndex < 5;
|
loadTop = startIndex < 10;
|
||||||
console.log("got tiles", startIndex, endIndex, loadTop);
|
// console.log("got tiles", startIndex, endIndex, loadTop);
|
||||||
} else {
|
} else {
|
||||||
|
// tiles collection is empty, load more at top
|
||||||
loadTop = true;
|
loadTop = true;
|
||||||
console.log("no tiles, load more at top");
|
// console.log("no tiles, load more at top");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadTop && !this._topLoadingPromise) {
|
if (loadTop && !this._topLoadingPromise) {
|
||||||
|
@ -91,7 +89,7 @@ export class TimelineViewModel extends ViewModel {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (loadTop) {
|
} else if (loadTop) {
|
||||||
console.log("loadTop is true but already loading");
|
// console.log("loadTop is true but already loading");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,8 +72,10 @@ export class Timeline {
|
||||||
// as they should only populate once the view subscribes to it
|
// as they should only populate once the view subscribes to it
|
||||||
// if they are populated already, the sender profile would be empty
|
// if they are populated already, the sender profile would be empty
|
||||||
|
|
||||||
// 30 seems to be a good amount to fill the entire screen
|
// choose good amount here between showing messages initially and
|
||||||
const readerRequest = this._disposables.track(this._timelineReader.readFromEnd(30, txn, log));
|
// not spending too much time decrypting messages before showing the timeline.
|
||||||
|
// more messages should be loaded automatically until the viewport is full by the view if needed.
|
||||||
|
const readerRequest = this._disposables.track(this._timelineReader.readFromEnd(5, txn, log));
|
||||||
try {
|
try {
|
||||||
const entries = await readerRequest.complete();
|
const entries = await readerRequest.complete();
|
||||||
this._setupEntries(entries);
|
this._setupEntries(entries);
|
||||||
|
|
|
@ -20,6 +20,8 @@ limitations under the License.
|
||||||
overscroll-behavior: contain;
|
overscroll-behavior: contain;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
/* need to read the offsetTop of tiles relative to this element in TimelineView */
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.RoomView_body > .Timeline > ul {
|
.RoomView_body > .Timeline > ul {
|
||||||
|
|
|
@ -91,7 +91,7 @@ export class TimelineView extends TemplateView<TimelineViewModel> {
|
||||||
tiles.style.setProperty("margin-top", `${missingTilesHeight}px`);
|
tiles.style.setProperty("margin-top", `${missingTilesHeight}px`);
|
||||||
// we don't have enough tiles to fill the viewport, so set all as visible
|
// we don't have enough tiles to fill the viewport, so set all as visible
|
||||||
const len = this.value.tiles.length;
|
const len = this.value.tiles.length;
|
||||||
this.updateVisibleRange(0, len - 1, false);
|
this.updateVisibleRange(0, len - 1);
|
||||||
} else {
|
} else {
|
||||||
tiles.style.removeProperty("margin-top");
|
tiles.style.removeProperty("margin-top");
|
||||||
if (this.stickToBottom) {
|
if (this.stickToBottom) {
|
||||||
|
@ -104,7 +104,7 @@ export class TimelineView extends TemplateView<TimelineViewModel> {
|
||||||
timeline.scrollBy(0, bottomDiff);
|
timeline.scrollBy(0, bottomDiff);
|
||||||
this.anchoredBottom = newAnchoredBottom;
|
this.anchoredBottom = newAnchoredBottom;
|
||||||
} else {
|
} else {
|
||||||
console.log("restore: bottom didn't change, must be below viewport");
|
// console.log("restore: bottom didn't change, must be below viewport");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,22 +122,21 @@ export class TimelineView extends TemplateView<TimelineViewModel> {
|
||||||
bottomNodeIndex = len - 1;
|
bottomNodeIndex = len - 1;
|
||||||
} else {
|
} else {
|
||||||
const viewportBottom = scrollTop + clientHeight;
|
const viewportBottom = scrollTop + clientHeight;
|
||||||
|
// console.log(`viewportBottom: ${viewportBottom} (${scrollTop} + ${clientHeight})`);
|
||||||
const anchoredNodeIndex = findFirstNodeIndexAtOrBelow(tiles, viewportBottom);
|
const anchoredNodeIndex = findFirstNodeIndexAtOrBelow(tiles, viewportBottom);
|
||||||
this.anchoredNode = tiles.childNodes[anchoredNodeIndex] as HTMLElement;
|
this.anchoredNode = tiles.childNodes[anchoredNodeIndex] as HTMLElement;
|
||||||
this.anchoredBottom = bottom(this.anchoredNode!);
|
this.anchoredBottom = bottom(this.anchoredNode!);
|
||||||
bottomNodeIndex = anchoredNodeIndex;
|
bottomNodeIndex = anchoredNodeIndex;
|
||||||
}
|
}
|
||||||
let topNodeIndex = findFirstNodeIndexAtOrBelow(tiles, scrollTop, bottomNodeIndex);
|
let topNodeIndex = findFirstNodeIndexAtOrBelow(tiles, scrollTop, bottomNodeIndex);
|
||||||
this.updateVisibleRange(topNodeIndex, bottomNodeIndex, true);
|
this.updateVisibleRange(topNodeIndex, bottomNodeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateVisibleRange(startIndex: number, endIndex: number, isViewportFilled: boolean) {
|
private updateVisibleRange(startIndex: number, endIndex: number) {
|
||||||
// can be undefined, meaning the tiles collection is still empty
|
// can be undefined, meaning the tiles collection is still empty
|
||||||
const firstVisibleChild = this.tilesView!.getChildInstanceByIndex(startIndex);
|
const firstVisibleChild = this.tilesView!.getChildInstanceByIndex(startIndex);
|
||||||
const lastVisibleChild = this.tilesView!.getChildInstanceByIndex(endIndex);
|
const lastVisibleChild = this.tilesView!.getChildInstanceByIndex(endIndex);
|
||||||
//if (firstVisibleChild && lastVisibleChild) {
|
this.value.setVisibleTileRange(firstVisibleChild?.value, lastVisibleChild?.value);
|
||||||
this.value.setVisibleTileRange(firstVisibleChild?.value, lastVisibleChild?.value, isViewportFilled);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue