mirror of https://github.com/vector-im/riot-web
Merge pull request #283 from matrix-org/rav/issue_1427
Fix bug which stopped us scrolling down after we scrolled uppull/21833/head
commit
30f273c611
|
@ -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;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue