1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-25 05:23:13 +03:00

Fix notification counts for encrypted rooms with ignored event rules (#3130)

* Validate vars early

* Split out unread  counts for total and highlight to different logic blocks

* Add tests for ignoring non notifying events

* Fix possibly incorrect tests?

* lint fix

* Refactor currentTotalCount

* Track Total locally too

* Lots of total count assumptions and comments

* Adjust for threading too

* Fixup tests

* a word

* lint fix
This commit is contained in:
Will Hunt
2023-02-15 11:25:13 +00:00
committed by GitHub
parent db4bd907f8
commit 195d1730bd
3 changed files with 106 additions and 55 deletions

View File

@@ -9504,64 +9504,77 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* accurate notification_count
*/
export function fixNotificationCountOnDecryption(cli: MatrixClient, event: MatrixEvent): void {
const ourUserId = cli.getUserId();
const eventId = event.getId();
const room = cli.getRoom(event.getRoomId());
if (!room || !ourUserId || !eventId) return;
const oldActions = event.getPushActions();
const actions = cli.getPushActionsForEvent(event, true);
const room = cli.getRoom(event.getRoomId());
if (!room || !cli.getUserId()) return;
const isThreadEvent = !!event.threadRootId && !event.isThreadRoot;
const currentCount = room.getUnreadCountForEventContext(NotificationCountType.Highlight, event);
const currentHighlightCount = room.getUnreadCountForEventContext(NotificationCountType.Highlight, event);
// Ensure the unread counts are kept up to date if the event is encrypted
// We also want to make sure that the notification count goes up if we already
// have encrypted events to avoid other code from resetting 'highlight' to zero.
const oldHighlight = !!oldActions?.tweaks?.highlight;
const newHighlight = !!actions?.tweaks?.highlight;
if (oldHighlight !== newHighlight || currentCount > 0) {
let hasReadEvent;
if (isThreadEvent) {
const thread = room.getThread(event.threadRootId);
hasReadEvent = thread
? thread.hasUserReadEvent(ourUserId, eventId)
: // If the thread object does not exist in the room yet, we don't
// want to calculate notification for this event yet. We have not
// restored the read receipts yet and can't accurately calculate
// notifications at this stage.
//
// This issue can likely go away when MSC3874 is implemented
true;
} else {
hasReadEvent = room.hasUserReadEvent(ourUserId, eventId);
}
if (hasReadEvent) {
// If the event has been read, ignore it.
return;
}
if (oldHighlight !== newHighlight || currentHighlightCount > 0) {
// TODO: Handle mentions received while the client is offline
// See also https://github.com/vector-im/element-web/issues/9069
let hasReadEvent;
let newCount = currentHighlightCount;
if (newHighlight && !oldHighlight) newCount++;
if (!newHighlight && oldHighlight) newCount--;
if (isThreadEvent) {
const thread = room.getThread(event.threadRootId);
hasReadEvent = thread
? thread.hasUserReadEvent(cli.getUserId()!, event.getId()!)
: // If the thread object does not exist in the room yet, we don't
// want to calculate notification for this event yet. We have not
// restored the read receipts yet and can't accurately calculate
// highlight notifications at this stage.
//
// This issue can likely go away when MSC3874 is implemented
true;
room.setThreadUnreadNotificationCount(event.threadRootId, NotificationCountType.Highlight, newCount);
} else {
hasReadEvent = room.hasUserReadEvent(cli.getUserId()!, event.getId()!);
room.setUnreadNotificationCount(NotificationCountType.Highlight, newCount);
}
}
if (!hasReadEvent) {
let newCount = currentCount;
if (newHighlight && !oldHighlight) newCount++;
if (!newHighlight && oldHighlight) newCount--;
// Total count is used to typically increment a room notification counter, but not loudly highlight it.
const currentTotalCount = room.getUnreadCountForEventContext(NotificationCountType.Total, event);
if (isThreadEvent) {
room.setThreadUnreadNotificationCount(event.threadRootId, NotificationCountType.Highlight, newCount);
} else {
room.setUnreadNotificationCount(NotificationCountType.Highlight, newCount);
}
// `notify` is used in practice for incrementing the total count
const newNotify = !!actions?.notify;
// Fix 'Mentions Only' rooms from not having the right badge count
const totalCount =
(isThreadEvent
? room.getThreadUnreadNotificationCount(event.threadRootId, NotificationCountType.Total)
: room.getRoomUnreadNotificationCount(NotificationCountType.Total)) ?? 0;
if (totalCount < newCount) {
if (isThreadEvent) {
room.setThreadUnreadNotificationCount(event.threadRootId, NotificationCountType.Total, newCount);
} else {
room.setUnreadNotificationCount(NotificationCountType.Total, newCount);
}
}
// The room total count is NEVER incremented by the server for encrypted rooms. We basically ignore
// the server here as it's always going to tell us to increment for encrypted events.
if (newNotify) {
if (isThreadEvent) {
room.setThreadUnreadNotificationCount(
event.threadRootId,
NotificationCountType.Total,
currentTotalCount + 1,
);
} else {
room.setUnreadNotificationCount(NotificationCountType.Total, currentTotalCount + 1);
}
}
}