try filling async instead of sync in scroll handler
see if that avoids jumpspull/21833/head
							parent
							
								
									8f7170a4a1
								
							
						
					
					
						commit
						18b5041ed2
					
				| 
						 | 
				
			
			@ -21,7 +21,7 @@ import { KeyCode } from '../../Keyboard';
 | 
			
		|||
import Timer from '../../utils/Timer';
 | 
			
		||||
import AutoHideScrollbar from "./AutoHideScrollbar";
 | 
			
		||||
 | 
			
		||||
const DEBUG_SCROLL = false;
 | 
			
		||||
const DEBUG_SCROLL = true;
 | 
			
		||||
 | 
			
		||||
// The amount of extra scroll distance to allow prior to unfilling.
 | 
			
		||||
// See _getExcessHeight.
 | 
			
		||||
| 
						 | 
				
			
			@ -193,10 +193,10 @@ module.exports = React.createClass({
 | 
			
		|||
        debuglog("onScroll", this._getScrollNode().scrollTop);
 | 
			
		||||
        this._scrollTimeout.restart();
 | 
			
		||||
        this._saveScrollState();
 | 
			
		||||
        this.checkFillState();
 | 
			
		||||
        this.updatePreventShrinking();
 | 
			
		||||
        console.timeStamp("onScroll:" + JSON.stringify({st: this._getScrollNode().scrollTop, mh: this._getMessagesHeight(), lh: this._getListHeight()}));
 | 
			
		||||
        this.props.onScroll(ev);
 | 
			
		||||
        this.checkFillState();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    onResize: function() {
 | 
			
		||||
| 
						 | 
				
			
			@ -270,11 +270,12 @@ module.exports = React.createClass({
 | 
			
		|||
    },
 | 
			
		||||
 | 
			
		||||
    // check the scroll state and send out backfill requests if necessary.
 | 
			
		||||
    checkFillState: function() {
 | 
			
		||||
    checkFillState: async function(depth=0) {
 | 
			
		||||
        if (this.unmounted) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const isFirstCall = depth === 0;
 | 
			
		||||
        const sn = this._getScrollNode();
 | 
			
		||||
 | 
			
		||||
        // if there is less than a screenful of messages above or below the
 | 
			
		||||
| 
						 | 
				
			
			@ -301,16 +302,46 @@ module.exports = React.createClass({
 | 
			
		|||
        //   `---------'                            -
 | 
			
		||||
        //
 | 
			
		||||
 | 
			
		||||
        if (isFirstCall) {
 | 
			
		||||
            if (this._isFilling) {
 | 
			
		||||
                debuglog("_isFilling: not entering while request is ongoing, marking for a subsequent request");
 | 
			
		||||
                this._fillRequestWhileRunning = true;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            debuglog("_isFilling: setting");
 | 
			
		||||
            this._isFilling = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        const contentHeight = this._getMessagesHeight();
 | 
			
		||||
        const contentTop = contentHeight - this._getListHeight();
 | 
			
		||||
        const contentScrollTop = sn.scrollTop + contentTop;
 | 
			
		||||
        const fillPromises = [];
 | 
			
		||||
 | 
			
		||||
        if (contentScrollTop < sn.clientHeight) {
 | 
			
		||||
            // need to back-fill
 | 
			
		||||
            this._maybeFill(true);
 | 
			
		||||
            fillPromises.push(this._maybeFill(depth, true));
 | 
			
		||||
        }
 | 
			
		||||
        if (contentScrollTop > contentHeight - sn.clientHeight * 2) {
 | 
			
		||||
            // need to forward-fill
 | 
			
		||||
            this._maybeFill(false);
 | 
			
		||||
            fillPromises.push(this._maybeFill(depth, false));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (fillPromises.length) {
 | 
			
		||||
            try {
 | 
			
		||||
                await Promise.all(fillPromises);
 | 
			
		||||
            } catch (err) {
 | 
			
		||||
                console.error(err);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (isFirstCall) {
 | 
			
		||||
            debuglog("_isFilling: clearing");
 | 
			
		||||
            this._isFilling = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._fillRequestWhileRunning) {
 | 
			
		||||
            this._fillRequestWhileRunning = false;
 | 
			
		||||
            this.checkFillState();
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -364,7 +395,7 @@ module.exports = React.createClass({
 | 
			
		|||
    },
 | 
			
		||||
 | 
			
		||||
    // check if there is already a pending fill request. If not, set one off.
 | 
			
		||||
    _maybeFill: function(backwards) {
 | 
			
		||||
    _maybeFill: function(depth, backwards) {
 | 
			
		||||
        const dir = backwards ? 'b' : 'f';
 | 
			
		||||
        if (this._pendingFillRequests[dir]) {
 | 
			
		||||
            debuglog("Already a "+dir+" fill in progress - not starting another");
 | 
			
		||||
| 
						 | 
				
			
			@ -377,7 +408,7 @@ module.exports = React.createClass({
 | 
			
		|||
        // events) so make sure we set this before firing off the call.
 | 
			
		||||
        this._pendingFillRequests[dir] = true;
 | 
			
		||||
 | 
			
		||||
        Promise.try(() => {
 | 
			
		||||
        return new Promise(resolve => setTimeout(resolve, 1)).then(() => {
 | 
			
		||||
            return this.props.onFillRequest(backwards);
 | 
			
		||||
        }).finally(() => {
 | 
			
		||||
            this._pendingFillRequests[dir] = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -393,9 +424,9 @@ module.exports = React.createClass({
 | 
			
		|||
                // further pagination requests have been disabled until now, so
 | 
			
		||||
                // it's time to check the fill state again in case the pagination
 | 
			
		||||
                // was insufficient.
 | 
			
		||||
                this.checkFillState();
 | 
			
		||||
                return this.checkFillState(depth + 1);
 | 
			
		||||
            }
 | 
			
		||||
        }).done();
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /* get the current scroll state. This returns an object with the following
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue