only clear min-height on scroll & adding items (componentDidUpdate)

before we would clear it as soon as you were 1px away from
the bottom of the timeline, which would still create jumping as
the whitespace would around 36px. To play it safe, we only clear it
after moving 200px from the bottom.

Also include "local echo" scroll events, caused by setting scrollTop
This commit is contained in:
Bruno Windels 2019-02-22 13:12:52 +01:00
parent 03784e586c
commit 41ae618d0e

View file

@ -176,10 +176,6 @@ module.exports = React.createClass({
// //
// This will also re-check the fill state, in case the paginate was inadequate // This will also re-check the fill state, in case the paginate was inadequate
this.checkScroll(); this.checkScroll();
if (!this.isAtBottom()) {
this.clearBlockShrinking();
}
}, },
componentWillUnmount: function() { componentWillUnmount: function() {
@ -204,23 +200,16 @@ module.exports = React.createClass({
// forget what we wanted, so don't overwrite the saved state unless // forget what we wanted, so don't overwrite the saved state unless
// this appears to be a user-initiated scroll. // this appears to be a user-initiated scroll.
if (sn.scrollTop != this._lastSetScroll) { if (sn.scrollTop != this._lastSetScroll) {
// when scrolling, we don't care about disappearing typing notifs shrinking the timeline
// this might cause the scrollbar to resize in case the max-height was not correct
// but that's better than ending up with a lot of whitespace at the bottom of the timeline.
// we need to above check because when showing the typing notifs, an onScroll event is also triggered
if (!this.isAtBottom()) {
this.clearBlockShrinking();
}
this._saveScrollState(); this._saveScrollState();
} else { } else {
debuglog("Ignoring scroll echo"); debuglog("Ignoring scroll echo");
// only ignore the echo once, otherwise we'll get confused when the // only ignore the echo once, otherwise we'll get confused when the
// user scrolls away from, and back to, the autoscroll point. // user scrolls away from, and back to, the autoscroll point.
this._lastSetScroll = undefined; this._lastSetScroll = undefined;
} }
this._checkBlockShrinking();
this.props.onScroll(ev); this.props.onScroll(ev);
this.checkFillState(); this.checkFillState();
@ -228,8 +217,6 @@ module.exports = React.createClass({
onResize: function() { onResize: function() {
this.props.onResize(); this.props.onResize();
// clear min-height as the height might have changed
this.clearBlockShrinking();
this.checkScroll(); this.checkScroll();
if (this._gemScroll) this._gemScroll.forceUpdate(); if (this._gemScroll) this._gemScroll.forceUpdate();
}, },
@ -238,6 +225,7 @@ module.exports = React.createClass({
// where it ought to be, and set off pagination requests if necessary. // where it ought to be, and set off pagination requests if necessary.
checkScroll: function() { checkScroll: function() {
this._restoreSavedScrollState(); this._restoreSavedScrollState();
this._checkBlockShrinking();
this.checkFillState(); this.checkFillState();
}, },
@ -379,8 +367,6 @@ module.exports = React.createClass({
} }
this._unfillDebouncer = setTimeout(() => { this._unfillDebouncer = setTimeout(() => {
this._unfillDebouncer = null; this._unfillDebouncer = null;
// if timeline shrinks, min-height should be cleared
this.clearBlockShrinking();
this.props.onUnfillRequest(backwards, markerScrollToken); this.props.onUnfillRequest(backwards, markerScrollToken);
}, UNFILL_REQUEST_DEBOUNCE_MS); }, UNFILL_REQUEST_DEBOUNCE_MS);
} }
@ -717,6 +703,21 @@ module.exports = React.createClass({
} }
}, },
_checkBlockShrinking: function() {
const sn = this._getScrollNode();
const scrollState = this.scrollState;
if (!scrollState.stuckAtBottom) {
const spaceBelowViewport = sn.scrollHeight - (sn.scrollTop + sn.clientHeight);
// only if we've scrolled up 200px from the bottom
// should we clear the min-height used by the typing notifications,
// otherwise we might still see it jump as the whitespace disappears
// when scrolling up from the bottom
if (spaceBelowViewport >= 200) {
this.clearBlockShrinking();
}
}
},
render: function() { render: function() {
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper"); const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
// TODO: the classnames on the div and ol could do with being updated to // TODO: the classnames on the div and ol could do with being updated to