diff --git a/src/actions/MatrixActionCreators.js b/src/actions/MatrixActionCreators.js index dbfe910533..a307af6f57 100644 --- a/src/actions/MatrixActionCreators.js +++ b/src/actions/MatrixActionCreators.js @@ -66,6 +66,16 @@ function createRoomTagsAction(matrixClient, roomTagsEvent, room) { return { action: 'MatrixActions.Room.tags', room }; } +function createRoomTimelineAction(matrixClient, timelineEvent, room, toStartOfTimeline, removed, data) { + return { + action: 'MatrixActions.Room.timeline', + event: timelineEvent, + isLiveEvent: data.liveEvent, + isLiveUnfilteredRoomTimelineEvent: + room && data.timeline.getTimelineSet() === room.getUnfilteredTimelineSet(), + }; +} + function createRoomMembershipAction(matrixClient, membershipEvent, member, oldMembership) { return { action: 'MatrixActions.RoomMember.membership', member }; } @@ -87,6 +97,7 @@ export default { this._addMatrixClientListener(matrixClient, 'sync', createSyncAction); this._addMatrixClientListener(matrixClient, 'accountData', createAccountDataAction); this._addMatrixClientListener(matrixClient, 'Room.tags', createRoomTagsAction); + this._addMatrixClientListener(matrixClient, 'Room.timeline', createRoomTimelineAction); this._addMatrixClientListener(matrixClient, 'RoomMember.membership', createRoomMembershipAction); }, diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 68b171b0ee..4305835dbd 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -77,7 +77,6 @@ module.exports = React.createClass({ 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); @@ -178,7 +177,6 @@ module.exports = React.createClass({ if (MatrixClientPeg.get()) { MatrixClientPeg.get().removeListener("Room", this.onRoom); MatrixClientPeg.get().removeListener("deleteRoom", this.onDeleteRoom); - MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline); MatrixClientPeg.get().removeListener("Room.name", this.onRoomName); MatrixClientPeg.get().removeListener("Room.receipt", this.onRoomReceipt); MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvents); @@ -237,13 +235,6 @@ module.exports = React.createClass({ this._updateStickyHeaders(true, scrollToPosition); }, - onRoomTimeline: function(ev, room, toStartOfTimeline, removed, data) { - if (toStartOfTimeline) return; - if (!room) return; - if (data.timeline.getTimelineSet() !== room.getUnfilteredTimelineSet()) return; - this._delayedRefreshRoomList(); - }, - 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 diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index fdd9ca6692..8a3af309fc 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -23,6 +23,16 @@ import Unread from '../Unread'; * the RoomList. */ class RoomListStore extends Store { + + static _listOrders = { + "m.favourite": "manual", + "im.vector.fake.invite": "recent", + "im.vector.fake.recent": "recent", + "im.vector.fake.direct": "recent", + "m.lowpriority": "recent", + "im.vector.fake.archived": "recent", + }; + constructor() { super(dis); @@ -68,6 +78,15 @@ class RoomListStore extends Store { this._generateRoomLists(); } break; + case 'MatrixActions.Room.timeline': { + if (!this._state.ready || + !payload.isLiveEvent || + !payload.isLiveUnfilteredRoomTimelineEvent || + !this._eventTriggersRecentReorder(payload.event) + ) break; + this._generateRoomLists(); + } + break; case 'MatrixActions.accountData': { if (payload.event_type !== 'm.direct') break; this._generateRoomLists(); @@ -159,18 +178,9 @@ class RoomListStore extends Store { } }); - const listOrders = { - "m.favourite": "manual", - "im.vector.fake.invite": "recent", - "im.vector.fake.recent": "recent", - "im.vector.fake.direct": "recent", - "m.lowpriority": "recent", - "im.vector.fake.archived": "recent", - }; - Object.keys(lists).forEach((listKey) => { let comparator; - switch (listOrders[listKey]) { + switch (RoomListStore._listOrders[listKey]) { case "recent": comparator = this._recentsComparator; break; @@ -188,13 +198,17 @@ class RoomListStore extends Store { }); } + _eventTriggersRecentReorder(ev) { + return ev.getTs() && ( + Unread.eventTriggersUnreadCount(ev) || + ev.getSender() === this._matrixClient.credentials.userId + ); + } + _tsOfNewestEvent(room) { for (let i = room.timeline.length - 1; i >= 0; --i) { const ev = room.timeline[i]; - if (ev.getTs() && - (Unread.eventTriggersUnreadCount(ev) || - (ev.getSender() === this._matrixClient.credentials.userId)) - ) { + if (this._eventTriggersRecentReorder(ev)) { return ev.getTs(); } } @@ -210,6 +224,8 @@ class RoomListStore extends Store { } _recentsComparator(roomA, roomB) { + // XXX: We could use a cache here and update it when we see new + // events that trigger a reorder return this._tsOfNewestEvent(roomB) - this._tsOfNewestEvent(roomA); }