Reimplement _saveScrollState
The actual fix to https://github.com/vector-im/riot-web/issues/3175 is this change to `_saveScrollState`, which is to pick the trackedScrollToken based on which node is intersected by the bottom of the scroll panel. This is opposed to the previous logic that picked based on which node was the first from the bottom to be above the bottom of the viewport. In the case where the viewport bottom does not intersect any events, the topmost event is used.
This commit is contained in:
parent
8e5a83a056
commit
94fe9999db
2 changed files with 22 additions and 11 deletions
|
@ -589,24 +589,35 @@ module.exports = React.createClass({
|
|||
var itemlist = this.refs.itemlist;
|
||||
var wrapperRect = ReactDOM.findDOMNode(this).getBoundingClientRect();
|
||||
var messages = itemlist.children;
|
||||
let newScrollState = null;
|
||||
|
||||
for (var i = messages.length-1; i >= 0; --i) {
|
||||
var node = messages[i];
|
||||
if (!node.dataset.scrollToken) continue;
|
||||
|
||||
var boundingRect = node.getBoundingClientRect();
|
||||
if (boundingRect.bottom < wrapperRect.bottom) {
|
||||
this.scrollState = {
|
||||
stuckAtBottom: false,
|
||||
trackedScrollToken: node.dataset.scrollToken,
|
||||
pixelOffset: wrapperRect.bottom - boundingRect.bottom,
|
||||
};
|
||||
debuglog("ScrollPanel: saved scroll state", this.scrollState);
|
||||
return;
|
||||
newScrollState = {
|
||||
stuckAtBottom: false,
|
||||
trackedScrollToken: node.dataset.scrollToken,
|
||||
pixelOffset: wrapperRect.bottom - boundingRect.bottom,
|
||||
};
|
||||
// If the bottom of the panel intersects the ClientRect of node, use this node
|
||||
// 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 (boundingRect.top < wrapperRect.bottom &&
|
||||
wrapperRect.bottom < boundingRect.bottom) {
|
||||
// Use this node as the scrollToken
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
debuglog("ScrollPanel: unable to save scroll state: found no children in the viewport");
|
||||
// This is only false if there were no nodes with `node.dataset.scrollToken` set.
|
||||
if (newScrollState) {
|
||||
this.scrollState = newScrollState;
|
||||
debuglog("ScrollPanel: saved scroll state", this.scrollState);
|
||||
} else {
|
||||
debuglog("ScrollPanel: unable to save scroll state: found no children in the viewport");
|
||||
}
|
||||
},
|
||||
|
||||
_restoreSavedScrollState: function() {
|
||||
|
|
|
@ -263,7 +263,7 @@ var TimelinePanel = React.createClass({
|
|||
}
|
||||
);
|
||||
|
||||
let count = backwards ? marker : this.state.events.length - marker;
|
||||
let count = backwards ? marker + 1 : this.state.events.length - marker;
|
||||
|
||||
if (count > 0) {
|
||||
debuglog("TimelinePanel: Unpaginating", count, "in direction", dir);
|
||||
|
|
Loading…
Reference in a new issue