From 00656fc1dcf81f09c9a5ac0d6ab38b624a444515 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 10 Dec 2015 16:26:36 +0000 Subject: [PATCH 1/8] Preserve scroll offset when switching rooms When we change rooms, save the scroll offset, and restore the scroll when we switch back. Hopefully this fixes https://github.com/vector-im/vector-web/issues/80. --- src/components/structures/MatrixChat.js | 81 +++++++++++++--------- src/components/structures/RoomView.js | 90 +++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 31 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 25f25e919e..1a522da361 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -80,6 +80,9 @@ module.exports = React.createClass({ this.startMatrixClient(); } this.focusComposer = false; + // scrollStateMap is a map from room id to the scroll state returned by + // RoomView.getScrollState() + this.scrollStateMap = {}; document.addEventListener("keydown", this.onKeyDown); window.addEventListener("focus", this.onFocus); if (this.state.logged_in) { @@ -202,27 +205,7 @@ module.exports = React.createClass({ break; case 'view_room': - this.focusComposer = true; - var newState = { - currentRoom: payload.room_id, - page_type: this.PageTypes.RoomView, - }; - if (this.sdkReady) { - // if the SDK is not ready yet, remember what room - // we're supposed to be on but don't notify about - // the new screen yet (we won't be showing it yet) - // The normal case where this happens is navigating - // to the room in the URL bar on page load. - var presentedId = payload.room_id; - var room = MatrixClientPeg.get().getRoom(payload.room_id); - if (room) { - var theAlias = MatrixTools.getCanonicalAliasForRoom(room); - if (theAlias) presentedId = theAlias; - } - this.notifyNewScreen('room/'+presentedId); - newState.ready = true; - } - this.setState(newState); + this._viewRoom(payload.room_id); break; case 'view_prev_room': roomIndexDelta = -1; @@ -239,11 +222,7 @@ module.exports = React.createClass({ } roomIndex = (roomIndex + roomIndexDelta) % allRooms.length; if (roomIndex < 0) roomIndex = allRooms.length - 1; - this.focusComposer = true; - this.setState({ - currentRoom: allRooms[roomIndex].roomId - }); - this.notifyNewScreen('room/'+allRooms[roomIndex].roomId); + this._viewRoom(allRooms[roomIndex].roomId); break; case 'view_indexed_room': var allRooms = RoomListSorter.mostRecentActivityFirst( @@ -251,11 +230,7 @@ module.exports = React.createClass({ ); var roomIndex = payload.roomIndex; if (allRooms[roomIndex]) { - this.focusComposer = true; - this.setState({ - currentRoom: allRooms[roomIndex].roomId - }); - this.notifyNewScreen('room/'+allRooms[roomIndex].roomId); + this._viewRoom(allRooms[roomIndex].roomId); } break; case 'view_room_alias': @@ -322,6 +297,49 @@ module.exports = React.createClass({ } }, + _viewRoom: function(roomId) { + // before we switch room, record the scroll state of the current room + this._updateScrollMap(); + + this.focusComposer = true; + var newState = { + currentRoom: roomId, + page_type: this.PageTypes.RoomView, + }; + if (this.sdkReady) { + // if the SDK is not ready yet, remember what room + // we're supposed to be on but don't notify about + // the new screen yet (we won't be showing it yet) + // The normal case where this happens is navigating + // to the room in the URL bar on page load. + var presentedId = roomId; + var room = MatrixClientPeg.get().getRoom(roomId); + if (room) { + var theAlias = MatrixTools.getCanonicalAliasForRoom(room); + if (theAlias) presentedId = theAlias; + } + this.notifyNewScreen('room/'+presentedId); + newState.ready = true; + } + this.setState(newState); + if (this.scrollStateMap[roomId]) { + var scrollState = this.scrollStateMap[roomId]; + this.refs.roomview.restoreScrollState(scrollState); + } + }, + + // update scrollStateMap according to the current scroll state of the + // room view. + _updateScrollMap: function() { + if (!this.refs.roomview) { + return; + } + + var roomview = this.refs.roomview; + var state = roomview.getScrollState(); + this.scrollStateMap[roomview.props.roomId] = state; + }, + onLoggedIn: function(credentials) { console.log("onLoggedIn => %s", credentials.userId); MatrixClientPeg.replaceUsingAccessToken( @@ -590,6 +608,7 @@ module.exports = React.createClass({ case this.PageTypes.RoomView: page_element = ( diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 176d61b42e..46258f9580 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -803,6 +803,96 @@ module.exports = React.createClass({ scrollNode.scrollTop = scrollNode.scrollHeight; }, + // scroll the event view to put the given event at the bottom. + // + // pixel_offset gives the number of pixels between the bottom of the event + // and the bottom of the container. + scrollToEvent: function(event_id, pixel_offset) { + var scrollNode = this._getScrollNode(); + if (!scrollNode) return; + + var messageWrapper = this.refs.messagePanel; + if (messageWrapper === undefined) return; + + var idx = this._indexForEventId(event_id); + if (idx === null) { + // we don't seem to have this event in our timeline. Presumably + // it's fallen out of scrollback. We ought to backfill until we + // find it, but we'd have to be careful we didn't backfill forever + // looking for a non-existent event. + // + // for now, just scroll to the top of the buffer. + console.log("Refusing to scroll to unknown event "+event_id); + scrollNode.scrollTop = 0; + return; + } + + // we might need to roll back the messagecap (to generate tiles for + // older messages). Don't roll it back past the timeline we have, though. + var minCap = this.state.room.timeline.length - Math.min(idx - INITIAL_SIZE, 0); + if (minCap > this.state.messageCap) { + this.setState({messageCap: minCap}); + } + + var node = this.eventNodes[event_id]; + if (node === null) { + // getEventTiles should have sorted this out when we set the + // messageCap, so this is weird. + console.error("No node for event, even after rolling back messageCap"); + return; + } + + var wrapperRect = ReactDOM.findDOMNode(messageWrapper).getBoundingClientRect(); + var boundingRect = node.getBoundingClientRect(); + scrollNode.scrollTop += boundingRect.bottom + pixel_offset - wrapperRect.bottom; + }, + + // get the current scroll position of the room, so that it can be + // restored when we switch back to it + getScrollState: function() { + // we don't save the absolute scroll offset, because that + // would be affected by window width, zoom level, amount of scrollback, + // etc. + // + // instead we save the id of the last fully-visible event, and the + // number of pixels the window was scrolled below it - which will + // hopefully be near enough. + // + if (this.eventNodes === undefined) return null; + + var messageWrapper = this.refs.messagePanel; + if (messageWrapper === undefined) return null; + var wrapperRect = ReactDOM.findDOMNode(messageWrapper).getBoundingClientRect(); + + for (var i = this.state.room.timeline.length-1; i >= 0; --i) { + var ev = this.state.room.timeline[i]; + var node = this.eventNodes[ev.getId()]; + if (!node) continue; + + var boundingRect = node.getBoundingClientRect(); + if (boundingRect.bottom < wrapperRect.bottom) { + return { + atBottom: this.atBottom, + lastDisplayedEvent: ev.getId(), + pixelOffset: wrapperRect.bottom - boundingRect.bottom, + } + } + } + + // apparently the entire timeline is below the viewport. Give up. + return null; + }, + + restoreScrollState: function(scrollState) { + if(scrollState.atBottom) { + // we were at the bottom before. Ideally we'd scroll to the + // 'read-up-to' mark here. + } else if (scrollState.lastDisplayed) { + this.scrollToEvent(scrollState.lastDisplayedEvent, + scrollState.pixelOffset); + } + }, + render: function() { var RoomHeader = sdk.getComponent('rooms.RoomHeader'); var MessageComposer = sdk.getComponent('rooms.MessageComposer'); From a1d88722aa061a4c8683a37f4eec32dc5430eb37 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 10 Dec 2015 20:53:21 +0000 Subject: [PATCH 2/8] Avoid kicking off two pagination requests at once Make sure that we don't end up with two concurrent pagination requests by firing off the second from the completion handler of the first. This ends up making the code a bit simpler. --- src/components/structures/RoomView.js | 41 +++++++++++++++------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 46258f9580..d438e0cbbe 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -288,9 +288,6 @@ module.exports = React.createClass({ var heightGained = messageWrapperScroll.scrollHeight - this.oldScrollHeight; messageWrapperScroll.scrollTop += heightGained; this.oldScrollHeight = undefined; - if (!this.fillSpace()) { - this.setState({paginating: false}); - } } else if (this.atBottom) { messageWrapperScroll.scrollTop = messageWrapperScroll.scrollHeight; if (this.state.numUnreadMessages !== 0) { @@ -299,36 +296,44 @@ module.exports = React.createClass({ } }, + _paginateCompleted: function() { + this.waiting_for_paginate = false; + this.setState({ + room: MatrixClientPeg.get().getRoom(this.props.roomId) + }); + + // we might not have got enough results from the pagination + // request, so give fillSpace() a chance to set off another. + if (!this.fillSpace()) { + this.setState({paginating: false}); + } + }, + + // check the scroll position, and if we need to, set off a pagination + // request. + // + // returns true if a pagination request was started (or is still in progress) fillSpace: function() { if (!this.refs.messagePanel) return; if (this.state.searchResults) return; // TODO: paginate search results var messageWrapperScroll = this._getScrollNode(); if (messageWrapperScroll.scrollTop < messageWrapperScroll.clientHeight && this.state.room.oldState.paginationToken) { - this.setState({paginating: true}); + // there's less than a screenful of messages left. Either wind back + // the message cap (if there are enough events in the timeline to + // do so), or fire off a pagination request. this.oldScrollHeight = messageWrapperScroll.scrollHeight; if (this.state.messageCap < this.state.room.timeline.length) { - this.waiting_for_paginate = false; var cap = Math.min(this.state.messageCap + PAGINATE_SIZE, this.state.room.timeline.length); - this.setState({messageCap: cap, paginating: true}); + this.setState({messageCap: cap}); } else { this.waiting_for_paginate = true; var cap = this.state.messageCap + PAGINATE_SIZE; this.setState({messageCap: cap, paginating: true}); - var self = this; - MatrixClientPeg.get().scrollback(this.state.room, PAGINATE_SIZE).finally(function() { - self.waiting_for_paginate = false; - if (self.isMounted()) { - self.setState({ - room: MatrixClientPeg.get().getRoom(self.props.roomId) - }); - } - // wait and set paginating to false when the component updates - }); + MatrixClientPeg.get().scrollback(this.state.room, PAGINATE_SIZE).finally(this._paginateCompleted).done(); + return true; } - - return true; } return false; }, From 1a3fb9aca908712dbf20e20af67489d9604c9e35 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 10 Dec 2015 21:34:10 +0000 Subject: [PATCH 3/8] Preserve scroll position when backfilling Save the scroll state whenever the user does a scroll operation, and use that to update the scroll after a backfill completes. --- src/components/structures/RoomView.js | 52 +++++++++++++-------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index d438e0cbbe..a7a01ff207 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -70,7 +70,7 @@ module.exports = React.createClass({ MatrixClientPeg.get().on("RoomMember.typing", this.onRoomMemberTyping); MatrixClientPeg.get().on("RoomState.members", this.onRoomStateMember); MatrixClientPeg.get().on("sync", this.onSyncStateChange); - this.atBottom = true; + this.savedScrollState = {atBottom: true}; }, componentWillUnmount: function() { @@ -173,7 +173,7 @@ module.exports = React.createClass({ if (!toStartOfTimeline && (ev.getSender() !== MatrixClientPeg.get().credentials.userId)) { // update unread count when scrolled up - if (this.atBottom) { + if (this.savedScrollState.atBottom) { currentUnread = 0; } else { @@ -181,15 +181,10 @@ module.exports = React.createClass({ } } - this.setState({ room: MatrixClientPeg.get().getRoom(this.props.roomId), numUnreadMessages: currentUnread }); - - if (toStartOfTimeline && !this.state.paginating) { - this.fillSpace(); - } }, onRoomName: function(room) { @@ -282,17 +277,15 @@ module.exports = React.createClass({ componentDidUpdate: function() { if (!this.refs.messagePanel) return; - var messageWrapperScroll = this._getScrollNode(); - - if (this.state.paginating && !this.waiting_for_paginate) { - var heightGained = messageWrapperScroll.scrollHeight - this.oldScrollHeight; - messageWrapperScroll.scrollTop += heightGained; - this.oldScrollHeight = undefined; - } else if (this.atBottom) { - messageWrapperScroll.scrollTop = messageWrapperScroll.scrollHeight; + var scrollState = this.savedScrollState; + if (scrollState.atBottom) { + this.scrollToBottom(); if (this.state.numUnreadMessages !== 0) { this.setState({numUnreadMessages: 0}); } + } else if (scrollState.lastDisplayedEvent) { + this.scrollToEvent(scrollState.lastDisplayedEvent, + scrollState.pixelOffset); } }, @@ -365,12 +358,9 @@ module.exports = React.createClass({ onMessageListScroll: function(ev) { if (this.refs.messagePanel) { - var messageWrapperScroll = this._getScrollNode(); - var wasAtBottom = this.atBottom; - // + 1 here to avoid fractional pixel rounding errors - this.atBottom = messageWrapperScroll.scrollHeight - messageWrapperScroll.scrollTop <= messageWrapperScroll.clientHeight + 1; - if (this.atBottom && !wasAtBottom) { - this.forceUpdate(); // remove unread msg count + this.savedScrollState = this._calculateScrollState(); + if (this.savedScrollState.atBottom && this.state.numUnreadMessages != 0) { + this.setState({numUnreadMessages: 0}); } } if (!this.state.paginating) this.fillSpace(); @@ -852,9 +842,7 @@ module.exports = React.createClass({ scrollNode.scrollTop += boundingRect.bottom + pixel_offset - wrapperRect.bottom; }, - // get the current scroll position of the room, so that it can be - // restored when we switch back to it - getScrollState: function() { + _calculateScrollState: function() { // we don't save the absolute scroll offset, because that // would be affected by window width, zoom level, amount of scrollback, // etc. @@ -869,6 +857,10 @@ module.exports = React.createClass({ if (messageWrapper === undefined) return null; var wrapperRect = ReactDOM.findDOMNode(messageWrapper).getBoundingClientRect(); + var messageWrapperScroll = this._getScrollNode(); + // + 1 here to avoid fractional pixel rounding errors + var atBottom = messageWrapperScroll.scrollHeight - messageWrapperScroll.scrollTop <= messageWrapperScroll.clientHeight + 1; + for (var i = this.state.room.timeline.length-1; i >= 0; --i) { var ev = this.state.room.timeline[i]; var node = this.eventNodes[ev.getId()]; @@ -877,7 +869,7 @@ module.exports = React.createClass({ var boundingRect = node.getBoundingClientRect(); if (boundingRect.bottom < wrapperRect.bottom) { return { - atBottom: this.atBottom, + atBottom: atBottom, lastDisplayedEvent: ev.getId(), pixelOffset: wrapperRect.bottom - boundingRect.bottom, } @@ -885,14 +877,20 @@ module.exports = React.createClass({ } // apparently the entire timeline is below the viewport. Give up. - return null; + return { atBottom: true }; + }, + + // get the current scroll position of the room, so that it can be + // restored when we switch back to it + getScrollState: function() { + return this.savedScrollState; }, restoreScrollState: function(scrollState) { if(scrollState.atBottom) { // we were at the bottom before. Ideally we'd scroll to the // 'read-up-to' mark here. - } else if (scrollState.lastDisplayed) { + } else if (scrollState.lastDisplayedEvent) { this.scrollToEvent(scrollState.lastDisplayedEvent, scrollState.pixelOffset); } From d9782b35e1740295462bb8c31b70163e81067933 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 10 Dec 2015 21:44:30 +0000 Subject: [PATCH 4/8] Fix review comments camelcasing and comments --- src/components/structures/MatrixChat.js | 8 ++++---- src/components/structures/RoomView.js | 19 +++++++++++++------ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 1a522da361..f8f7252822 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -324,18 +324,18 @@ module.exports = React.createClass({ this.setState(newState); if (this.scrollStateMap[roomId]) { var scrollState = this.scrollStateMap[roomId]; - this.refs.roomview.restoreScrollState(scrollState); + this.refs.roomView.restoreScrollState(scrollState); } }, // update scrollStateMap according to the current scroll state of the // room view. _updateScrollMap: function() { - if (!this.refs.roomview) { + if (!this.refs.roomView) { return; } - var roomview = this.refs.roomview; + var roomview = this.refs.roomView; var state = roomview.getScrollState(); this.scrollStateMap[roomview.props.roomId] = state; }, @@ -608,7 +608,7 @@ module.exports = React.createClass({ case this.PageTypes.RoomView: page_element = ( diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index a7a01ff207..05bf8e53cb 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -802,14 +802,14 @@ module.exports = React.createClass({ // // pixel_offset gives the number of pixels between the bottom of the event // and the bottom of the container. - scrollToEvent: function(event_id, pixel_offset) { + scrollToEvent: function(eventId, pixelOffset) { var scrollNode = this._getScrollNode(); if (!scrollNode) return; var messageWrapper = this.refs.messagePanel; if (messageWrapper === undefined) return; - var idx = this._indexForEventId(event_id); + var idx = this._indexForEventId(eventId); if (idx === null) { // we don't seem to have this event in our timeline. Presumably // it's fallen out of scrollback. We ought to backfill until we @@ -817,19 +817,26 @@ module.exports = React.createClass({ // looking for a non-existent event. // // for now, just scroll to the top of the buffer. - console.log("Refusing to scroll to unknown event "+event_id); + console.log("Refusing to scroll to unknown event "+eventId); scrollNode.scrollTop = 0; return; } // we might need to roll back the messagecap (to generate tiles for - // older messages). Don't roll it back past the timeline we have, though. + // older messages). This just means telling getEventTiles to create + // tiles for events we already have in our timeline (we already know + // the event in question is in our timeline, so we shouldn't need to + // backfill). + // + // we actually wind back slightly further than the event in question, + // because we want the event to be at the *bottom* of the container. + // Don't roll it back past the timeline we have, though. var minCap = this.state.room.timeline.length - Math.min(idx - INITIAL_SIZE, 0); if (minCap > this.state.messageCap) { this.setState({messageCap: minCap}); } - var node = this.eventNodes[event_id]; + var node = this.eventNodes[eventId]; if (node === null) { // getEventTiles should have sorted this out when we set the // messageCap, so this is weird. @@ -839,7 +846,7 @@ module.exports = React.createClass({ var wrapperRect = ReactDOM.findDOMNode(messageWrapper).getBoundingClientRect(); var boundingRect = node.getBoundingClientRect(); - scrollNode.scrollTop += boundingRect.bottom + pixel_offset - wrapperRect.bottom; + scrollNode.scrollTop += boundingRect.bottom + pixelOffset - wrapperRect.bottom; }, _calculateScrollState: function() { From b7699c0544f7bff4e1834733bf70011e80193e3a Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 10 Dec 2015 21:53:14 +0000 Subject: [PATCH 5/8] Save scroll state when swapping to non-room pages too --- src/components/structures/MatrixChat.js | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index f8f7252822..e290843ed4 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -254,21 +254,15 @@ module.exports = React.createClass({ }); break; case 'view_user_settings': - this.setState({ - page_type: this.PageTypes.UserSettings, - }); + this._setPage(this.PageTypes.UserSettings); this.notifyNewScreen('settings'); break; case 'view_create_room': - this.setState({ - page_type: this.PageTypes.CreateRoom, - }); + this._setPage(this.PageTypes.CreateRoom); this.notifyNewScreen('new'); break; case 'view_room_directory': - this.setState({ - page_type: this.PageTypes.RoomDirectory, - }); + this._setPage(this.PageTypes.RoomDirectory); this.notifyNewScreen('directory'); break; case 'notifier_enabled': @@ -297,6 +291,15 @@ module.exports = React.createClass({ } }, + _setPage: function(pageType) { + // record the scroll state if we're in a room view. + this._updateScrollMap(); + + this.setState({ + page_type: this.PageTypes.RoomDirectory, + }); + }, + _viewRoom: function(roomId) { // before we switch room, record the scroll state of the current room this._updateScrollMap(); From a8638390630ccfe679f550189612184c97ad3e2a Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 10 Dec 2015 22:04:52 +0000 Subject: [PATCH 6/8] Don't try to fiddle with the scroll state in search mode --- src/components/structures/RoomView.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 6ceaba3821..3695859ed1 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -275,8 +275,13 @@ module.exports = React.createClass({ }, componentDidUpdate: function() { + // after adding event tiles, we may need to tweak the scroll (either to + // keep at the bottom of the timeline, or to maintain the view after + // adding events to the top). + if (!this.refs.messagePanel) return; + if (this.state.searchResults) return; var scrollState = this.savedScrollState; if (scrollState.atBottom) { this.scrollToBottom(); @@ -357,7 +362,7 @@ module.exports = React.createClass({ }, onMessageListScroll: function(ev) { - if (this.refs.messagePanel) { + if (this.refs.messagePanel && !this.state.searchResults) { this.savedScrollState = this._calculateScrollState(); if (this.savedScrollState.atBottom && this.state.numUnreadMessages != 0) { this.setState({numUnreadMessages: 0}); From ee0f0e332a705773d0776192fdf051b56bf37f07 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 10 Dec 2015 22:08:35 +0000 Subject: [PATCH 7/8] Remove redundant 'waiting_for_paginate' --- src/components/structures/RoomView.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 3695859ed1..ea489b326a 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -295,7 +295,6 @@ module.exports = React.createClass({ }, _paginateCompleted: function() { - this.waiting_for_paginate = false; this.setState({ room: MatrixClientPeg.get().getRoom(this.props.roomId) }); @@ -326,7 +325,6 @@ module.exports = React.createClass({ var cap = Math.min(this.state.messageCap + PAGINATE_SIZE, this.state.room.timeline.length); this.setState({messageCap: cap}); } else { - this.waiting_for_paginate = true; var cap = this.state.messageCap + PAGINATE_SIZE; this.setState({messageCap: cap, paginating: true}); MatrixClientPeg.get().scrollback(this.state.room, PAGINATE_SIZE).finally(this._paginateCompleted).done(); From 0d47495e04e6410f77be2ba79d629841fc047378 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 11 Dec 2015 11:04:12 +0000 Subject: [PATCH 8/8] RoomView: Remove another redundant unreadMessageCount reset There's never any need to reset the unreadMessageCount in ComponentDidUpdate, as an update can never cause there to be *fewer* unread messages. Instead we rely on the reset in onMessageListScroll. --- src/components/structures/RoomView.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index ea489b326a..872640f52e 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -285,9 +285,6 @@ module.exports = React.createClass({ var scrollState = this.savedScrollState; if (scrollState.atBottom) { this.scrollToBottom(); - if (this.state.numUnreadMessages !== 0) { - this.setState({numUnreadMessages: 0}); - } } else if (scrollState.lastDisplayedEvent) { this.scrollToEvent(scrollState.lastDisplayedEvent, scrollState.pixelOffset);