Throttle notification state calculation (#31922)

Because every room in a space will emit a notification state change
when push rules change so we would otherwise recalculate the space
notification state for every room in the space, On^2 style.
This commit is contained in:
David Baker 2026-01-30 17:09:02 +00:00 committed by GitHub
parent 25d24d478f
commit 7dbffb348d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
Please see LICENSE files in the repository root for full details.
*/
import { throttle } from "lodash";
import { type Room } from "matrix-js-sdk/src/matrix";
import { NotificationLevel } from "./NotificationLevel";
@ -63,23 +64,27 @@ export class SpaceNotificationState extends NotificationState {
this.calculateTotalState();
};
private calculateTotalState(): void {
const snapshot = this.snapshot();
private calculateTotalState = throttle(
(): void => {
const snapshot = this.snapshot();
this._count = 0;
this._level = NotificationLevel.None;
for (const [roomId, state] of Object.entries(this.states)) {
const room = this.rooms.find((r) => r.roomId === roomId);
const roomTags = room ? RoomListStore.instance.getTagsForRoom(room) : [];
this._count = 0;
this._level = NotificationLevel.None;
for (const [roomId, state] of Object.entries(this.states)) {
const room = this.rooms.find((r) => r.roomId === roomId);
const roomTags = room ? RoomListStore.instance.getTagsForRoom(room) : [];
// We ignore unreads in LowPriority rooms, see https://github.com/vector-im/element-web/issues/16836
if (roomTags.includes(DefaultTagID.LowPriority) && state.level === NotificationLevel.Activity) continue;
// We ignore unreads in LowPriority rooms, see https://github.com/vector-im/element-web/issues/16836
if (roomTags.includes(DefaultTagID.LowPriority) && state.level === NotificationLevel.Activity) continue;
this._count += state.count;
this._level = Math.max(this.level, state.level);
}
this._count += state.count;
this._level = Math.max(this.level, state.level);
}
// finally, publish an update if needed
this.emitIfUpdated(snapshot);
}
// finally, publish an update if needed
this.emitIfUpdated(snapshot);
},
100,
{ leading: false, trailing: true },
);
}