mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-09-27 22:18:36 +00:00
The count is seeded by getUsersInfo, which counts RcvNew items where ntfsEnabled holds - every item for an unmuted chat, only mentions for a mentions-only one, none for a muted one. The deltas that maintain it afterwards did not follow that rule for the active profile: addChatItem incremented for every item regardless of the chat's notification setting, the mark-read helpers subtracted the full unread count, removeChat left a deleted chat's unread behind, and changing the setting moved a chat between rules without moving the count. Chat.userUnreadCount names what a chat contributes, and it is not a new rule: totalUnreadCountForAllUsers already computed exactly this inline for the app badge, and now calls it. Every site that changes a chat's stats, its settings or its presence reports the contribution before and after, and the count moves by the difference. For that to hold the stats it reads have to be maintained, so on Android and desktop decreaseCounterInPrimaryContext now decrements unreadMentions alongside unreadCount when the item was a mention. Without it a mentions-only chat's contribution never moved on any of that function's three paths - a deleted item, a moderated member item, or an item going from New to Read. iOS already passed the mention delta on its deletion paths. This is visible beyond the profile picker, which badges only other profiles: the desktop tray dot sums the count across profiles including the active one, and on iOS these same deltas drive the app icon badge. So on iOS, muting a chat with unread now drops the badge by its contribution, deleting a chat drops it, and a message in a muted chat no longer raises it - each of which now agrees with totalUnreadCountForAllUsers, which the badge is also set from. addChat is deliberately not the mirror of removeChat: adding a chat means it is being loaded into view, and its items were already counted by the seed, so counting them again on ChatItemsLoader's addChat would double them. The one place that removes and re-adds a chat while keeping its items - deleting a contact in "keep conversation" mode on iOS - now carries its stats across and restores the contribution explicitly, since the core keeps both the contact row and its items there and the seed still counts them. Wherever the chat list is re-read wholesale the counts are re-read with it: both resume paths, and setting a chat item TTL, which deletes items across every profile and so leaves every profile's count stale, not just the active one. They are assigned before the chats, which matters on iOS because updateChats recomputes the app badge from users there. Reading users is best effort on both platforms - losing them must not cost us the chats already fetched. This does not make the count exact. getUsersInfo has no group_scope_tag filter where the query behind chatStats.unreadCount does, so the seed counts support-scope items that no client-side rule can, and the count steps up by the outstanding support unread on each reseed. Two paths also install a whole chatStats without moving the count: processLoadedChat's updateChatStats on Android and desktop, and replaceChat on both - from a pre-call snapshot in the mark-read paths there, and from the server in iOS's contact-request handler.