Merge pull request #283 from matrix-org/rav/issue_1427

Fix bug which stopped us scrolling down after we scrolled up
pull/21833/head
Richard van der Hoff 2016-04-21 14:26:42 +01:00
commit 30f273c611
3 changed files with 89 additions and 5 deletions

View File

@ -241,11 +241,25 @@ var TimelinePanel = React.createClass({
if (this.unmounted) { return; } if (this.unmounted) { return; }
debuglog("TimelinePanel: paginate complete backwards:"+backwards+"; success:"+r); debuglog("TimelinePanel: paginate complete backwards:"+backwards+"; success:"+r);
this.setState({
var newState = {
[paginatingKey]: false, [paginatingKey]: false,
[canPaginateKey]: r, [canPaginateKey]: r,
events: this._getEvents(), 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; return r;
}); });
}, },

View File

@ -205,4 +205,72 @@ describe('TimelinePanel', function() {
}, 0); }, 0);
}, 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

@ -43,8 +43,8 @@ module.exports.stubClient = function() {
sendReadReceipt: sinon.stub().returns(q()), sendReadReceipt: sinon.stub().returns(q()),
}; };
// create the peg // stub out the methods in MatrixClientPeg
//
// 'sandbox.restore()' doesn't work correctly on inherited methods, // 'sandbox.restore()' doesn't work correctly on inherited methods,
// so we do this for each method // so we do this for each method
var methods = ['get', 'unset', 'replaceUsingUrls', var methods = ['get', 'unset', 'replaceUsingUrls',
@ -52,7 +52,9 @@ module.exports.stubClient = function() {
for (var i = 0; i < methods.length; i++) { for (var i = 0; i < methods.length; i++) {
sandbox.stub(peg, methods[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; return sandbox;
} }