Fix scroll on long discussions

- Anchor scroll when inserting post placeholders
- Indicate that pages are loading at start of `loadPage`, which allows `onscroll` to not request that multiple pages be loaded at the same time

These changes are particularly applicable to firefox, where previously, dozens of posts could be skipped at a time if scroll up was held while at the top of the viewport.
This commit is contained in:
Alexander Skvortsov 2020-12-14 14:06:32 -05:00
parent a6547f02b0
commit a7306addf1
2 changed files with 16 additions and 10 deletions

View File

@ -149,6 +149,11 @@ export default class PostStream extends Component {
*/ */
onscroll(top = window.pageYOffset) { onscroll(top = window.pageYOffset) {
if (this.stream.paused) return; if (this.stream.paused) return;
this.updateScrubber(top);
if (this.stream.pagesLoading) return;
const marginTop = this.getMarginTop(); const marginTop = this.getMarginTop();
const viewportHeight = $(window).height() - marginTop; const viewportHeight = $(window).height() - marginTop;
const viewportTop = top + marginTop; const viewportTop = top + marginTop;
@ -174,8 +179,6 @@ export default class PostStream extends Component {
// viewport) to 100ms. // viewport) to 100ms.
clearTimeout(this.calculatePositionTimeout); clearTimeout(this.calculatePositionTimeout);
this.calculatePositionTimeout = setTimeout(this.calculatePosition.bind(this, top), 100); this.calculatePositionTimeout = setTimeout(this.calculatePosition.bind(this, top), 100);
this.updateScrubber(top);
} }
updateScrubber(top = window.pageYOffset) { updateScrubber(top = window.pageYOffset) {

View File

@ -238,23 +238,26 @@ class PostStreamState {
* @param {Boolean} backwards * @param {Boolean} backwards
*/ */
loadPage(start, end, backwards = false) { loadPage(start, end, backwards = false) {
m.redraw(); this.pagesLoading++;
const redraw = () => {
if (start < this.visibleStart || end > this.visibleEnd) return;
const anchorIndex = backwards ? this.visibleEnd - 1 : this.visibleStart;
anchorScroll(`.PostStream-item[data-index="${anchorIndex}"]`, m.redraw.sync);
};
redraw();
this.loadPageTimeouts[start] = setTimeout( this.loadPageTimeouts[start] = setTimeout(
() => { () => {
this.loadRange(start, end).then(() => { this.loadRange(start, end).then(() => {
if (start >= this.visibleStart && end <= this.visibleEnd) { redraw();
const anchorIndex = backwards ? this.visibleEnd - 1 : this.visibleStart;
anchorScroll(`.PostStream-item[data-index="${anchorIndex}"]`, () => m.redraw.sync());
}
this.pagesLoading--; this.pagesLoading--;
}); });
this.loadPageTimeouts[start] = null; this.loadPageTimeouts[start] = null;
}, },
this.pagesLoading ? 1000 : 0 this.pagesLoading - 1 ? 1000 : 0
); );
this.pagesLoading++;
} }
/** /**