From a9c54153eec696a86815ecb5a7047f30c72270f5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 May 2020 15:54:02 -0600 Subject: [PATCH] Update badge counts in new room list as needed --- src/components/views/rooms/RoomTile2.tsx | 21 +++++++++++++-- src/stores/room-list/RoomListStore2.ts | 14 ++++------ src/utils/read-receipts.ts | 34 ++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 11 deletions(-) create mode 100644 src/utils/read-receipts.ts diff --git a/src/components/views/rooms/RoomTile2.tsx b/src/components/views/rooms/RoomTile2.tsx index ae1802de49..d9d1d39142 100644 --- a/src/components/views/rooms/RoomTile2.tsx +++ b/src/components/views/rooms/RoomTile2.tsx @@ -30,6 +30,8 @@ import * as RoomNotifs from '../../../RoomNotifs'; import { EffectiveMembership, getEffectiveMembership } from "../../../stores/room-list/membership"; import * as Unread from '../../../Unread'; import * as FormattingUtils from "../../../utils/FormattingUtils"; +import { MatrixClientPeg } from "../../../MatrixClientPeg"; +import { MatrixEvent } from "matrix-js-sdk/src/models/event"; /******************************************************************* * CAUTION * @@ -86,10 +88,19 @@ export default class RoomTile2 extends React.Component { hover: false, notificationState: this.getNotificationState(), }; + + // TODO: We shouldn't have to listen to every room update + // We don't have a model which works in a better way though. + MatrixClientPeg.get().on("Room.receipt", this.tryUpdateIfRoomMatches); + MatrixClientPeg.get().on("Room.timeline", this.tryUpdateIfRoomMatches); + MatrixClientPeg.get().on("Event.decrypted", this.tryUpdateIfRoomMatches); + MatrixClientPeg.get().on("Room.redaction", this.tryUpdateIfRoomMatches); } public componentWillUnmount() { - // TODO: Listen for changes to the badge count and update as needed + if (MatrixClientPeg.get()) { + MatrixClientPeg.get().removeListener("Room.receipt", this.tryUpdateIfRoomMatches); + } } // XXX: This is a bit of an awful-looking hack. We should probably be using state for @@ -99,7 +110,13 @@ export default class RoomTile2 extends React.Component { return getEffectiveMembership(this.props.room.getMyMembership()) === EffectiveMembership.Invite; } - // TODO: Make use of this function when the notification state needs updating. + private tryUpdateIfRoomMatches = (event: MatrixEvent) => { + const roomId = event.getRoomId(); + if (roomId !== this.props.room.roomId) return; + + this.updateNotificationState(); + }; + private updateNotificationState() { this.setState({notificationState: this.getNotificationState()}); } diff --git a/src/stores/room-list/RoomListStore2.ts b/src/stores/room-list/RoomListStore2.ts index 881b8fd3cf..108922a598 100644 --- a/src/stores/room-list/RoomListStore2.ts +++ b/src/stores/room-list/RoomListStore2.ts @@ -26,6 +26,7 @@ import { ITagMap, ITagSortingMap, ListAlgorithm, SortAlgorithm } from "./algorit import { getListAlgorithmInstance } from "./algorithms/list-ordering"; import { ActionPayload } from "../../dispatcher/payloads"; import defaultDispatcher from "../../dispatcher/dispatcher"; +import { readReceiptChangeIsFor } from "../../utils/read-receipts"; interface IState { tagsEnabled?: boolean; @@ -135,15 +136,10 @@ class _RoomListStore extends AsyncStore { if (payload.action === 'MatrixActions.Room.receipt') { // First see if the receipt event is for our own user. If it was, trigger // a room update (we probably read the room on a different device). - // noinspection JSObjectNullOrUndefined - this.matrixClient can't be null by this point in the lifecycle - const myUserId = this.matrixClient.getUserId(); - for (const eventId of Object.keys(payload.event.getContent())) { - const receiptUsers = Object.keys(payload.event.getContent()[eventId]['m.read'] || {}); - if (receiptUsers.includes(myUserId)) { - // TODO: Update room now that it's been read - console.log(payload); - return; - } + if (readReceiptChangeIsFor(payload.event, this.matrixClient)) { + // TODO: Update room now that it's been read + console.log(payload); + return; } } else if (payload.action === 'MatrixActions.Room.tags') { // TODO: Update room from tags diff --git a/src/utils/read-receipts.ts b/src/utils/read-receipts.ts new file mode 100644 index 0000000000..f05c3cc5f2 --- /dev/null +++ b/src/utils/read-receipts.ts @@ -0,0 +1,34 @@ +/* +Copyright 2020 The Matrix.org Foundation C.I.C. + +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. +*/ + +import { MatrixEvent } from "matrix-js-sdk/src/models/event"; +import { MatrixClient } from "matrix-js-sdk/src/client"; + +/** + * Determines if a read receipt update event includes the client's own user. + * @param event The event to check. + * @param client The client to check against. + * @returns True if the read receipt update includes the client, false otherwise. + */ +export function readReceiptChangeIsFor(event: MatrixEvent, client: MatrixClient): boolean { + const myUserId = client.getUserId(); + for (const eventId of Object.keys(event.getContent())) { + const receiptUsers = Object.keys(event.getContent()[eventId]['m.read'] || {}); + if (receiptUsers.includes(myUserId)) { + return true; + } + } +}