From 6f2e0a4cdf7aa4d6e409e69e9704e6f7ec3f4e24 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 9 Sep 2016 16:59:59 +0100 Subject: [PATCH] Make rooms in MemberInfo update when necessary Factor out the chunk of code that looks through a read receipt event to see if it contain a read receipt from a given user, now we use it in 2 places. --- src/components/views/rooms/MemberInfo.js | 60 +++++++++++++++++++++++- src/components/views/rooms/RoomList.js | 10 ++-- src/utils/Receipt.js | 32 +++++++++++++ 3 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 src/utils/Receipt.js diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 4310c56363..b6944a3d4e 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -35,6 +35,7 @@ var UserSettingsStore = require('../../../UserSettingsStore'); var createRoom = require('../../../createRoom'); var DMRoomMap = require('../../../utils/DMRoomMap'); var Unread = require('../../../Unread'); +var Receipt = require('../../../utils/Receipt'); module.exports = React.createClass({ displayName: 'MemberInfo', @@ -73,11 +74,21 @@ module.exports = React.createClass({ // feature is enabled in the user settings this._enableDevices = MatrixClientPeg.get().isCryptoEnabled() && UserSettingsStore.isFeatureEnabled("e2e_encryption"); + + const cli = MatrixClientPeg.get(); + cli.on("deviceVerificationChanged", this.onDeviceVerificationChanged); + cli.on("Room", this.onRoom); + cli.on("deleteRoom", this.onDeleteRoom); + cli.on("Room.timeline", this.onRoomTimeline); + cli.on("Room.name", this.onRoomName); + cli.on("Room.receipt", this.onRoomReceipt); + cli.on("RoomState.events", this.onRoomStateEvents); + cli.on("RoomMember.name", this.onRoomMemberName); + cli.on("accountData", this.onAccountData); }, componentDidMount: function() { this._updateStateForNewMember(this.props.member); - MatrixClientPeg.get().on("deviceVerificationChanged", this.onDeviceVerificationChanged); }, componentWillReceiveProps: function(newProps) { @@ -90,6 +101,14 @@ module.exports = React.createClass({ var client = MatrixClientPeg.get(); if (client) { client.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged); + client.removeListener("Room", this.onRoom); + client.removeListener("deleteRoom", this.onDeleteRoom); + client.removeListener("Room.timeline", this.onRoomTimeline); + client.removeListener("Room.name", this.onRoomName); + client.removeListener("Room.receipt", this.onRoomReceipt); + client.removeListener("RoomState.events", this.onRoomStateEvents); + client.removeListener("RoomMember.name", this.onRoomMemberName); + client.removeListener("accountData", this.onAccountData); } if (this._cancelDeviceList) { this._cancelDeviceList(); @@ -109,6 +128,45 @@ module.exports = React.createClass({ } }, + onRoom: function(room) { + this.forceUpdate(); + }, + + onDeleteRoom: function(roomId) { + this.forceUpdate(); + }, + + onRoomTimeline: function(ev, room, toStartOfTimeline) { + if (toStartOfTimeline) return; + this.forceUpdate(); + }, + + onRoomName: function(room) { + this.forceUpdate(); + }, + + onRoomReceipt: function(receiptEvent, room) { + // because if we read a notification, it will affect notification count + // only bother updating if there's a receipt from us + if (Receipt.findReadReceiptFromUserId(receiptEvent, MatrixClientPeg.get().credentials.userId)) { + this.forceUpdate(); + } + }, + + onRoomStateEvents: function(ev, state) { + this.forceUpdate(); + }, + + onRoomMemberName: function(ev, member) { + this.forceUpdate(); + }, + + onAccountData: function(ev) { + if (ev.getType() == 'm.direct') { + this.forceUpdate(); + } + }, + _updateStateForNewMember: function(member) { var newState = this._calculateOpsPermissions(member); newState.devicesLoading = true; diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 1265fc1af0..98ec789a7c 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -27,6 +27,7 @@ var sdk = require('../../../index'); var rate_limited_func = require('../../../ratelimitedfunc'); var Rooms = require('../../../Rooms'); var DMRoomMap = require('../../../utils/DMRoomMap'); +var Receipt = require('../../../utils/Receipt'); var HIDE_CONFERENCE_CHANS = true; @@ -154,13 +155,8 @@ module.exports = React.createClass({ onRoomReceipt: function(receiptEvent, room) { // because if we read a notification, it will affect notification count // only bother updating if there's a receipt from us - var receiptKeys = Object.keys(receiptEvent.getContent()); - for (var i = 0; i < receiptKeys.length; ++i) { - var rcpt = receiptEvent.getContent()[receiptKeys[i]]; - if (rcpt['m.read'] && rcpt['m.read'][MatrixClientPeg.get().credentials.userId]) { - this._delayedRefreshRoomList(); - break; - } + if (Receipt.findReadReceiptFromUserId(receiptEvent, MatrixClientPeg.get().credentials.userId)) { + this._delayedRefreshRoomList(); } }, diff --git a/src/utils/Receipt.js b/src/utils/Receipt.js new file mode 100644 index 0000000000..549a0fd8b3 --- /dev/null +++ b/src/utils/Receipt.js @@ -0,0 +1,32 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** + * Given MatrixEvent containing receipts, return the first + * read receipt from the given user ID, or null if no such + * receipt exists. + */ +export function findReadReceiptFromUserId(receiptEvent, userId) { + var receiptKeys = Object.keys(receiptEvent.getContent()); + for (var i = 0; i < receiptKeys.length; ++i) { + var rcpt = receiptEvent.getContent()[receiptKeys[i]]; + if (rcpt['m.read'] && rcpt['m.read'][userId]) { + return rcpt; + } + } + + return null; +}