From 1e3040d19ae63695851237e120002f23277fd239 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 1 Mar 2016 10:41:56 +0000 Subject: [PATCH] Fix a race condition handling gappy syncs We had a problem handling gappy syncs: resetting the timeline would trigger a pagination request (which would return no results, because there are no events at this point); this would make the pagination requests which are spawned when we process the events in the sync get ignored - with the result that we get a blank window. The fix is to avoid the ScrollPanel when we are processing new live events and tell the TimelineWindow to paginate itself directly. --- src/components/structures/TimelinePanel.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index 886bd2b706..6d034721a5 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -229,6 +229,8 @@ var TimelinePanel = React.createClass({ if (!this.refs.messagePanel) return; + if (!this.refs.messagePanel.getScrollState().stuckAtBottom) return; + // when a new event arrives when the user is not watching the window, but the // window is in its auto-scroll mode, make sure the read marker is visible. // @@ -242,19 +244,21 @@ var TimelinePanel = React.createClass({ var myUserId = MatrixClientPeg.get().credentials.userId; var sender = ev.sender ? ev.sender.userId : null; var activity_age = Date.now() - this.user_last_active; - if (sender != myUserId && this.refs.messagePanel.getScrollState().stuckAtBottom - && activity_age > CONSIDER_USER_ACTIVE_FOR_MS) { + if (sender != myUserId && activity_age > CONSIDER_USER_ACTIVE_FOR_MS) { this.setState({readMarkerVisible: true}); } - // tell the messagepanel to go paginate itself. This in turn will cause - // onMessageListFillRequest to be called, which will call - // _onTimelineUpdated, which will update the state with the new event - - // so there is no need update the state here. + // tell the timeline window to try to advance itself, but not to make + // an http request to do so. // - if (this.refs.messagePanel) { - this.refs.messagePanel.checkFillState(); - } + // we deliberately avoid going via the ScrollPanel for this call - the + // ScrollPanel might already have an active pagination promise, which + // will fail, but would stop us passing the pagination request to the + // timeline window. + // + // see https://github.com/vector-im/vector-web/issues/1035 + this._timelineWindow.paginate(EventTimeline.FORWARDS, 1, false) + .done(this._onTimelineUpdated); }, onRoomTimelineReset: function(room) {