check top of node instead of bottom, since coming in from last

as we're approaching from the last node, if we're scrolled up,
the first node we encounter would be below the bottom of the viewport

change the logic to stop at the first node that has its top
above the viewport bottom.

When completely scrolled up, this was causing nodes way below
the viewport to be selected as the reference for the pixelOffset,
and when pagination came in, it would immediately try to apply
the big negative pixelOffset, scrolling to a negative scrollTop,
thus going to the top again, and triggering another pagination,
entering in an infinite pagination loop until you scrolled down.
pull/21833/head
Bruno Windels 2019-02-26 16:26:24 +01:00
parent 42030796c7
commit c920dd2e8a
1 changed files with 5 additions and 8 deletions

View File

@ -609,20 +609,16 @@ module.exports = React.createClass({
const itemlist = this.refs.itemlist; const itemlist = this.refs.itemlist;
const messages = itemlist.children; const messages = itemlist.children;
let node = null; let node = null;
let nodeBottom;
// loop backwards, from bottom-most message (as that is the most common case)
for (let i = messages.length-1; i >= 0; --i) { for (let i = messages.length-1; i >= 0; --i) {
if (!messages[i].dataset.scrollTokens) { if (!messages[i].dataset.scrollTokens) {
continue; continue;
} }
node = messages[i]; node = messages[i];
// break at the first message (coming from the bottom)
nodeBottom = node.offsetTop + node.clientHeight; // that has it's offsetTop above the bottom of the viewport.
// If the bottom of the panel intersects the ClientRect of node, use this node if (node.offsetTop < scrollBottom) {
// as the scrollToken.
// If this is false for the entire for-loop, we default to the last node
// (which is why newScrollState is set on every iteration).
if (nodeBottom >= scrollBottom) {
// Use this node as the scrollToken // Use this node as the scrollToken
break; break;
} }
@ -633,6 +629,7 @@ module.exports = React.createClass({
return; return;
} }
const nodeBottom = node.offsetTop + node.clientHeight;
debuglog("ScrollPanel: saved scroll state", this.scrollState); debuglog("ScrollPanel: saved scroll state", this.scrollState);
this.scrollState = { this.scrollState = {
stuckAtBottom: false, stuckAtBottom: false,