Fix bug which stopped us scrolling down after we scrolled up

Make sure that, if we scroll up enough to move the timelinewindow away from the
end of the timeline, we reset the canForwardPaginate flag.
This commit is contained in:
Richard van der Hoff 2016-04-21 13:37:31 +01:00
parent 66966eecf8
commit 2f435f4836
3 changed files with 89 additions and 5 deletions

View file

@ -241,11 +241,25 @@ var TimelinePanel = React.createClass({
if (this.unmounted) { return; }
debuglog("TimelinePanel: paginate complete backwards:"+backwards+"; success:"+r);
this.setState({
var newState = {
[paginatingKey]: false,
[canPaginateKey]: r,
events: this._getEvents(),
});
};
// moving the window in this direction may mean that we can now
// paginate in the other where we previously could not.
var otherDirection = backwards ? EventTimeline.FORWARDS : EventTimeline.BACKWARDS;
var canPaginateOtherWayKey = backwards ? 'canForwardPaginate' : 'canBackPaginate';
if (!this.state[canPaginateOtherWayKey] &&
this._timelineWindow.canPaginate(otherDirection)) {
debuglog('TimelinePanel: can now', otherDirection, 'paginate again');
newState[canPaginateOtherWayKey] = true;
}
this.setState(newState);
return r;
});
},

View file

@ -204,4 +204,72 @@ describe('TimelinePanel', function() {
}, 0);
}, 0);
});
it("should let you scroll down again after you've scrolled up", function(done) {
var N_EVENTS = 600;
// sadly, loading all those events takes a while
this.timeout(N_EVENTS * 20);
// client.getRoom is called a /lot/ in this test, so replace
// sinon's spy with a fast noop.
client.getRoom = function(id) { return null; };
// fill the timeline with lots of events
for (var i = 0; i < N_EVENTS; i++) {
timeline.addEvent(mkMessage());
}
var scrollDefer;
var panel = ReactDOM.render(
<TimelinePanel room={room} onScroll={()=>{scrollDefer.resolve()}} />,
parentDiv
);
var messagePanel = ReactTestUtils.findRenderedComponentWithType(
panel, sdk.getComponent('structures.MessagePanel'));
var scrollingDiv = ReactTestUtils.findRenderedDOMComponentWithClass(
panel, "gm-scroll-view");
// helper function which will return a promise which resolves when
// the TimelinePanel fires a scroll event
var awaitScroll = function() {
scrollDefer = q.defer();
return scrollDefer.promise;
};
function backPaginate() {
scrollingDiv.scrollTop = 0;
return awaitScroll().then(() => {
if(scrollingDiv.scrollTop > 0) {
// need to go further
return backPaginate();
}
// hopefully, we got to the start of the timeline
expect(messagePanel.props.backPaginating).toBe(false);
});
}
// let the first round of pagination finish off
awaitScroll().then(() => {
// we should now have loaded the first few events
expect(messagePanel.props.backPaginating).toBe(false);
expect(messagePanel.props.suppressFirstDateSeparator).toBe(true);
// back-paginate until we hit the start
return backPaginate();
}).then(() => {
expect(messagePanel.props.suppressFirstDateSeparator).toBe(false);
var events = scryEventTiles(panel);
expect(events[0].props.mxEvent).toBe(timeline.getEvents()[0])
// we should now be able to scroll down, and paginate in the other
// direction.
scrollingDiv.scrollTop = scrollingDiv.scrollHeight;
return awaitScroll();
}).then(() => {
console.log("done");
}).done(done, done);
});
});

View file

@ -42,8 +42,8 @@ module.exports.stubClient = function() {
sendReadReceipt: sinon.stub().returns(q()),
};
// create the peg
// stub out the methods in MatrixClientPeg
//
// 'sandbox.restore()' doesn't work correctly on inherited methods,
// so we do this for each method
var methods = ['get', 'unset', 'replaceUsingUrls',
@ -51,7 +51,9 @@ module.exports.stubClient = function() {
for (var i = 0; i < methods.length; i++) {
sandbox.stub(peg, methods[i]);
}
peg.get.returns(client);
// MatrixClientPeg.get() is called a /lot/, so implement it with our own
// fast stub function rather than a sinon stub
peg.get = function() { return client; };
return sandbox;
}