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.
This commit is contained in:
Richard van der Hoff 2016-03-01 10:41:56 +00:00
parent dc9a7e5e28
commit 1e3040d19a

View file

@ -229,6 +229,8 @@ var TimelinePanel = React.createClass({
if (!this.refs.messagePanel) return; 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 // 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. // 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 myUserId = MatrixClientPeg.get().credentials.userId;
var sender = ev.sender ? ev.sender.userId : null; var sender = ev.sender ? ev.sender.userId : null;
var activity_age = Date.now() - this.user_last_active; var activity_age = Date.now() - this.user_last_active;
if (sender != myUserId && this.refs.messagePanel.getScrollState().stuckAtBottom if (sender != myUserId && activity_age > CONSIDER_USER_ACTIVE_FOR_MS) {
&& activity_age > CONSIDER_USER_ACTIVE_FOR_MS) {
this.setState({readMarkerVisible: true}); this.setState({readMarkerVisible: true});
} }
// tell the messagepanel to go paginate itself. This in turn will cause // tell the timeline window to try to advance itself, but not to make
// onMessageListFillRequest to be called, which will call // an http request to do so.
// _onTimelineUpdated, which will update the state with the new event -
// so there is no need update the state here.
// //
if (this.refs.messagePanel) { // we deliberately avoid going via the ScrollPanel for this call - the
this.refs.messagePanel.checkFillState(); // 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) { onRoomTimelineReset: function(room) {