diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 9fbdb51f11..3d0bcf7445 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -273,6 +273,9 @@ module.exports = React.createClass({ window.removeEventListener('resize', this.onResize); + // cancel any pending calls to the rate_limited_funcs + this._updateRoomMembers.cancelPendingCall(); + // no need to do this as Dir & Settings are now overlays. It just burnt CPU. // console.log("Tinter.tint from RoomView.unmount"); // Tinter.tint(); // reset colourscheme diff --git a/src/components/views/rooms/InviteMemberList.js b/src/components/views/rooms/InviteMemberList.js index c088822324..1e5b19fdf1 100644 --- a/src/components/views/rooms/InviteMemberList.js +++ b/src/components/views/rooms/InviteMemberList.js @@ -58,6 +58,8 @@ module.exports = React.createClass({ if (cli) { cli.removeListener("RoomState.members", this.onRoomStateMember); } + // cancel any pending calls to the rate_limited_funcs + this._updateList.cancelPendingCall(); }, _updateList: new rate_limited_func(function() { @@ -100,7 +102,7 @@ module.exports = React.createClass({ } className="mx_EntityTile_invitePlaceholder" - presenceState="online" onClick={this.onThirdPartyInvite} name={"Invite by email"} + presenceState="online" onClick={this.onThirdPartyInvite} name={"Invite by email"} />, function(query) { return true; // always show this diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index 5536aeddd6..4f2a51e8cd 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -81,6 +81,9 @@ module.exports = React.createClass({ cli.removeListener("User.lastPresenceTs", this.onUserLastPresenceTs); // cli.removeListener("Room.timeline", this.onRoomTimeline); } + + // cancel any pending calls to the rate_limited_funcs + this._updateList.cancelPendingCall(); }, /* diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 8967bdeafb..52e0ffb083 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -101,6 +101,8 @@ module.exports = React.createClass({ MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvents); MatrixClientPeg.get().removeListener("RoomMember.name", this.onRoomMemberName); } + // cancel any pending calls to the rate_limited_funcs + this._delayedRefreshRoomList.cancelPendingCall(); }, onRoom: function(room) { diff --git a/src/ratelimitedfunc.js b/src/ratelimitedfunc.js index ed892f4eac..a9e8a4cab2 100644 --- a/src/ratelimitedfunc.js +++ b/src/ratelimitedfunc.js @@ -21,13 +21,16 @@ limitations under the License. * * Note that the function must not take arguments, since the args * could be different for each invocarion of the function. + * + * The returned function has a 'cancelPendingCall' property which can be called + * on unmount or similar to cancel any pending update. */ module.exports = function(f, minIntervalMs) { this.lastCall = 0; this.scheduledCall = undefined; var self = this; - return function() { + var wrapper = function() { var now = Date.now(); if (self.lastCall < now - minIntervalMs) { @@ -44,5 +47,23 @@ module.exports = function(f, minIntervalMs) { ); } }; -}; + // add the cancelPendingCall property + wrapper.cancelPendingCall = function() { + if (self.scheduledCall) { + clearTimeout(self.scheduledCall); + self.scheduledCall = undefined; + } + }; + + // make sure that cancelPendingCall is copied when react rebinds the + // wrapper + var _bind = wrapper.bind; + wrapper.bind = function() { + var rebound = _bind.apply(this, arguments); + rebound.cancelPendingCall = wrapper.cancelPendingCall; + return rebound; + }; + + return wrapper; +};