);
@@ -1888,8 +1904,10 @@ module.exports = React.createClass({
// just show a spinner while the timeline loads.
//
- // put it in a div of the right class so that the order in the
- // roomview flexbox is correct.
+ // put it in a div of the right class (mx_RoomView_messagePanel) so
+ // that the order in the roomview flexbox is correct, and
+ // mx_RoomView_messageListWrapper to position the inner div in the
+ // right place.
//
// Note that the click-on-search-result functionality relies on the
// fact that the messagePanel is hidden while the timeline reloads,
@@ -1897,7 +1915,7 @@ module.exports = React.createClass({
// exist.
if (this.state.timelineLoading) {
messagePanel = (
-
+
);
diff --git a/src/components/structures/ScrollPanel.js b/src/components/structures/ScrollPanel.js
index a577be2e52..514937f877 100644
--- a/src/components/structures/ScrollPanel.js
+++ b/src/components/structures/ScrollPanel.js
@@ -38,16 +38,17 @@ if (DEBUG_SCROLL) {
* when we get close to the start or end of the list.
*
* Each child element should have a 'data-scroll-token'. This token is used to
- * serialise the scroll state, and returned as the 'lastDisplayedScrollToken'
+ * serialise the scroll state, and returned as the 'trackedScrollToken'
* attribute by getScrollState().
*
* Some notes about the implementation:
*
* The saved 'scrollState' can exist in one of two states:
*
- * - atBottom: (the default, and restored by resetScrollState): the viewport
- * is scrolled down as far as it can be. When the children are updated, the
- * scroll position will be updated to ensure it is still at the bottom.
+ * - stuckAtBottom: (the default, and restored by resetScrollState): the
+ * viewport is scrolled down as far as it can be. When the children are
+ * updated, the scroll position will be updated to ensure it is still at
+ * the bottom.
*
* - fixed, in which the viewport is conceptually tied at a specific scroll
* offset. We don't save the absolute scroll offset, because that would be
@@ -59,9 +60,9 @@ if (DEBUG_SCROLL) {
* The 'stickyBottom' property controls the behaviour when we reach the bottom
* of the window (either through a user-initiated scroll, or by calling
* scrollToBottom). If stickyBottom is enabled, the scrollState will enter
- * 'atBottom' state - ensuring that new additions cause the window to scroll
- * down further. If stickyBottom is disabled, we just save the scroll offset as
- * normal.
+ * 'stuckAtBottom' state - ensuring that new additions cause the window to
+ * scroll down further. If stickyBottom is disabled, we just save the scroll
+ * offset as normal.
*/
module.exports = React.createClass({
displayName: 'ScrollPanel',
@@ -178,6 +179,10 @@ module.exports = React.createClass({
},
// return true if the content is fully scrolled down right now; else false.
+ //
+ // note that this is independent of the 'stuckAtBottom' state - it is simply
+ // about whether the the content is scrolled down right now, irrespective of
+ // whether it will stay that way when the children update.
isAtBottom: function() {
var sn = this._getScrollNode();
@@ -268,8 +273,19 @@ module.exports = React.createClass({
}).done();
},
- // get the current scroll position of the room, so that it can be
- // restored later
+ /* get the current scroll state. This returns an object with the following
+ * properties:
+ *
+ * boolean stuckAtBottom: true if we are tracking the bottom of the
+ * scroll. false if we are tracking a particular child.
+ *
+ * string trackedScrollToken: undefined if stuckAtBottom is true; if it is
+ * false, the data-scroll-token of the child which we are tracking.
+ *
+ * number pixelOffset: undefined if stuckAtBottom is true; if it is false,
+ * the number of pixels the bottom of the tracked child is above the
+ * bottom of the scroll panel.
+ */
getScrollState: function() {
return this.scrollState;
},
@@ -287,7 +303,7 @@ module.exports = React.createClass({
* child list.)
*/
resetScrollState: function() {
- this.scrollState = {atBottom: true};
+ this.scrollState = {stuckAtBottom: true};
},
scrollToBottom: function() {
@@ -322,8 +338,8 @@ module.exports = React.createClass({
// timeline and need to do more pagination); we want to save the
// *desired* scroll state rather than what we end up achieving.
this.scrollState = {
- atBottom: false,
- lastDisplayedScrollToken: scrollToken,
+ stuckAtBottom: false,
+ trackedScrollToken: scrollToken,
pixelOffset: pixelOffset
};
@@ -370,7 +386,7 @@ module.exports = React.createClass({
_saveScrollState: function() {
if (this.props.stickyBottom && this.isAtBottom()) {
- this.scrollState = { atBottom: true };
+ this.scrollState = { stuckAtBottom: true };
debuglog("Saved scroll state", this.scrollState);
return;
}
@@ -386,8 +402,8 @@ module.exports = React.createClass({
var boundingRect = node.getBoundingClientRect();
if (boundingRect.bottom < wrapperRect.bottom) {
this.scrollState = {
- atBottom: false,
- lastDisplayedScrollToken: node.dataset.scrollToken,
+ stuckAtBottom: false,
+ trackedScrollToken: node.dataset.scrollToken,
pixelOffset: wrapperRect.bottom - boundingRect.bottom,
}
debuglog("Saved scroll state", this.scrollState);
@@ -402,11 +418,11 @@ module.exports = React.createClass({
var scrollState = this.scrollState;
var scrollNode = this._getScrollNode();
- if (scrollState.atBottom) {
+ if (scrollState.stuckAtBottom) {
scrollNode.scrollTop = scrollNode.scrollHeight;
debuglog("Scrolled to bottom; offset now", scrollNode.scrollTop);
- } else if (scrollState.lastDisplayedScrollToken) {
- this._scrollToToken(scrollState.lastDisplayedScrollToken,
+ } else if (scrollState.trackedScrollToken) {
+ this._scrollToToken(scrollState.trackedScrollToken,
scrollState.pixelOffset);
}
this._lastSetScroll = scrollNode.scrollTop;
diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js
index 6d786294ad..f580686128 100644
--- a/src/components/views/rooms/EventTile.js
+++ b/src/components/views/rooms/EventTile.js
@@ -100,7 +100,7 @@ module.exports = React.createClass({
onHighlightClick: React.PropTypes.func,
/* is this the focussed event */
- selectedEvent: React.PropTypes.bool,
+ isSelectedEvent: React.PropTypes.bool,
},
getInitialState: function() {
@@ -276,7 +276,7 @@ module.exports = React.createClass({
) !== -1,
mx_EventTile_notSent: this.props.mxEvent.status == 'not_sent',
mx_EventTile_highlight: this.shouldHighlight(),
- mx_EventTile_selected: this.props.selectedEvent,
+ mx_EventTile_selected: this.props.isSelectedEvent,
mx_EventTile_continuation: this.props.continuation,
mx_EventTile_last: this.props.last,
mx_EventTile_contextual: this.props.contextual,