From 4cebded04f159c154d526a81cdf70b30593f3b95 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Wed, 22 Mar 2017 15:06:52 +0000 Subject: [PATCH] Add canResetTimeline callback and thread it through to TimelinePanel --- src/components/structures/LoggedInView.js | 7 +++++++ src/components/structures/MatrixChat.js | 24 +++++++++++++++++++++- src/components/structures/RoomView.js | 7 +++++++ src/components/structures/TimelinePanel.js | 4 ++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index c2243820cd..6e2f0a3a5b 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -81,6 +81,13 @@ export default React.createClass({ return this._scrollStateMap[roomId]; }, + canResetTimelineInRoom: function(roomId) { + if (!this.refs.roomView) { + return true; + } + return this.refs.roomView.canResetTimeline(); + }, + _onKeyDown: function(ev) { /* // Remove this for now as ctrl+alt = alt-gr so this breaks keyboards which rely on alt-gr for numbers diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 2337d62fd8..9b51e7f3fb 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -806,9 +806,31 @@ module.exports = React.createClass({ * (useful for setting listeners) */ _onWillStartClient() { + var self = this; var cli = MatrixClientPeg.get(); - var self = this; + // Allow the JS SDK to reap timeline events. This reduces the amount of + // memory consumed as the JS SDK stores multiple distinct copies of room + // state (each of which can be 10s of MBs) for each DISJOINT timeline. This is + // particularly noticeable when there are lots of 'limited' /sync responses + // such as when laptops unsleep. + // https://github.com/vector-im/riot-web/issues/3307#issuecomment-282895568 + cli.setCanResetTimelineCallback(function(roomId) { + console.log("Request to reset timeline in room ", roomId, " viewing:", self.state.currentRoomId); + if (roomId !== self.state.currentRoomId) { + // It is safe to remove events from rooms we are not viewing. + return true; + } + // We are viewing the room which we want to reset. It is only safe to do + // this if we are not scrolled up in the view. To find out, delegate to + // the timeline panel. If the timeline panel doesn't exist, then we assume + // it is safe to reset the timeline. + if (!self.refs.loggedInView) { + return true; + } + return self.refs.loggedInView.canResetTimelineInRoom(roomId); + }); + cli.on('sync', function(state, prevState) { self.updateStatusIndicator(state, prevState); if (state === "SYNCING" && prevState === "SYNCING") { diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 345d0f6b80..b22d867acf 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -490,6 +490,13 @@ module.exports = React.createClass({ } }, + canResetTimeline: function() { + if (!this.refs.messagePanel) { + return true; + } + return this.refs.messagePanel.canResetTimeline(); + }, + // called when state.room is first initialised (either at initial load, // after a successful peek, or after we join the room). _onRoomLoaded: function(room) { diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index cb42f701a3..8ef0e7631f 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -431,6 +431,10 @@ var TimelinePanel = React.createClass({ } }, + canResetTimeline: function() { + return this.refs.messagePanel && this.refs.messagePanel.isAtBottom(); + }, + onRoomRedaction: function(ev, room) { if (this.unmounted) return;