From 8572150b70b3d1e5b5858e3a8d683eaf877a7c17 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 23 Sep 2026 10:00:18 +0300 Subject: [PATCH] Remove the room list notification count feature flag. The room list now always shows the unread notification count for highlighted rooms and the app icon badge always uses the SDK's own unread notification count, both in the app and in the NSE. The push payload's unread count is no longer used, so its UNNotificationContent helper and user info key have been removed along with the setting, its developer options toggle and the feature-disabled unit test. --- .../Application/Settings/AppSettings.swift | 4 --- .../Extensions/UNNotificationContent.swift | 4 --- .../Screens/HomeScreen/HomeScreenModels.swift | 2 -- .../HomeScreen/HomeScreenViewModel.swift | 4 --- .../HomeScreen/View/HomeScreenRoomCell.swift | 5 ++-- .../HomeScreen/View/HomeScreenRoomList.swift | 1 - .../DeveloperOptionsScreenModels.swift | 1 - .../View/DeveloperOptionsScreen.swift | 5 ---- .../Manager/NotificationManager.swift | 2 +- .../Notification/NotificationConstants.swift | 1 - NSE/Sources/NotificationHandler.swift | 26 ++++--------------- .../NotificationServiceExtension.swift | 3 --- .../homeScreen.Loaded-iPad-en-GB.png | 4 +-- .../homeScreen.Loaded-iPad-pseudo.png | 4 +-- .../homeScreen.Loaded-iPhone-en-GB.png | 4 +-- .../homeScreen.Loaded-iPhone-pseudo.png | 4 +-- .../homeScreenRoomCell.Generic-iPad-en-GB.png | 4 +-- ...homeScreenRoomCell.Generic-iPad-pseudo.png | 4 +-- ...omeScreenRoomCell.Generic-iPhone-en-GB.png | 4 +-- ...meScreenRoomCell.Generic-iPhone-pseudo.png | 4 +-- .../NotificationManagerTests.swift | 12 --------- 21 files changed, 24 insertions(+), 78 deletions(-) diff --git a/ElementX/Sources/Application/Settings/AppSettings.swift b/ElementX/Sources/Application/Settings/AppSettings.swift index e06f48c67..62b9cdfad 100644 --- a/ElementX/Sources/Application/Settings/AppSettings.swift +++ b/ElementX/Sources/Application/Settings/AppSettings.swift @@ -31,7 +31,6 @@ nonisolated protocol CommonSettingsProtocol: AnyObject, Sendable { var enableOnlySignedDeviceIsolationMode: Bool { get } var threadsEnabled: Bool { get } var hideQuietNotificationAlerts: Bool { get } - var roomListNotificationCountEnabled: Bool { get } } nonisolated enum AppBuildType { @@ -358,9 +357,6 @@ final nonisolated class AppSettings: @unchecked Sendable { @UserPreference(defaultValue: RoomListActivityVisibility.current) var roomListActivityVisibility: RoomListActivityVisibility - @UserPreference(defaultValue: false) - var roomListNotificationCountEnabled: Bool - // MARK: - Search Screen /// The queries the user searched for and the rooms they opened from the results, most recent first. diff --git a/ElementX/Sources/Other/Extensions/UNNotificationContent.swift b/ElementX/Sources/Other/Extensions/UNNotificationContent.swift index fbeb407fc..a458e2740 100644 --- a/ElementX/Sources/Other/Extensions/UNNotificationContent.swift +++ b/ElementX/Sources/Other/Extensions/UNNotificationContent.swift @@ -29,10 +29,6 @@ nonisolated extension UNNotificationContent { @objc var threadRootEventID: String? { userInfo[NotificationConstants.UserInfoKey.threadRootEventIdentifier] as? String } - - var unreadCount: Int? { - userInfo[NotificationConstants.UserInfoKey.unreadCount] as? Int - } } nonisolated extension UNMutableNotificationContent { diff --git a/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift b/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift index 8c6bf9408..374a5b49c 100644 --- a/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift +++ b/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift @@ -106,8 +106,6 @@ struct HomeScreenViewState: BindableState { var roomListActivityVisibility: RoomListActivityVisibility = .current - var roomListNotificationCountEnabled = false - var reportRoomEnabled = false var shouldShowSpaceFilters = false diff --git a/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift b/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift index 6e4e79855..d4e323aff 100644 --- a/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift +++ b/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift @@ -120,10 +120,6 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol } .store(in: &cancellables) - appSettings.roomListNotificationCountEnabledPublisher - .weakAssign(to: \.state.roomListNotificationCountEnabled, on: self) - .store(in: &cancellables) - appSettings.seenInvitesPublisher .removeDuplicates() .sink { [weak self] _ in diff --git a/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift b/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift index 62431afe3..77126a5bd 100644 --- a/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift +++ b/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift @@ -16,7 +16,6 @@ struct HomeScreenRoomCell: View { let room: HomeScreenRoom var roomListActivityVisibility: RoomListActivityVisibility = .current - var roomListNotificationCountEnabled = false let isSelected: Bool let mediaProvider: MediaProviderProtocol! let action: (HomeScreenViewAction) -> Void @@ -158,7 +157,7 @@ struct HomeScreenRoomCell: View { } if room.badges.isDotShown { - if roomListNotificationCountEnabled, room.isHighlighted, room.badges.notificationCount > 0 { + if room.isHighlighted, room.badges.notificationCount > 0 { Text(formattedNotificationCount) .font(.compound.bodySMSemibold) .foregroundColor(.compound.textOnSolidPrimary) @@ -255,7 +254,7 @@ struct HomeScreenRoomCell_Previews: PreviewProvider, TestablePreview { VStack(spacing: 0) { ForEach(notificationsStateRooms) { room in - HomeScreenRoomCell(room: room, roomListNotificationCountEnabled: true, isSelected: false, mediaProvider: MediaProviderMock(.init())) { _ in } + HomeScreenRoomCell(room: room, isSelected: false, mediaProvider: MediaProviderMock(.init())) { _ in } } } .previewLayout(.sizeThatFits) diff --git a/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomList.swift b/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomList.swift index 334beb012..e95e97b1b 100644 --- a/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomList.swift +++ b/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomList.swift @@ -37,7 +37,6 @@ struct HomeScreenRoomList: View { HomeScreenRoomCell(room: room, roomListActivityVisibility: context.viewState.roomListActivityVisibility, - roomListNotificationCountEnabled: context.viewState.roomListNotificationCountEnabled, isSelected: isSelected, mediaProvider: context.mediaProvider, action: context.send) diff --git a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenModels.swift b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenModels.swift index 203c842e6..90750f8fe 100644 --- a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenModels.swift +++ b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenModels.swift @@ -58,7 +58,6 @@ protocol DeveloperOptionsProtocol: AnyObject { var focusEventOnNotificationTap: Bool { get set } var roomListActivityVisibility: RoomListActivityVisibility { get set } - var roomListNotificationCountEnabled: Bool { get set } var elementCallBaseURLOverride: URL? { get set } var fuzzyRoomListSearchEnabled: Bool { get set } diff --git a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift index 6291176f7..a1d2ec538 100644 --- a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift +++ b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift @@ -67,11 +67,6 @@ struct DeveloperOptionsScreen: View { } } - Toggle(isOn: $context.roomListNotificationCountEnabled) { - Text("Show unread notification count") - Text("Also makes the app icon badge use the SDK's own unread notification count") - } - Toggle(isOn: $context.fuzzyRoomListSearchEnabled) { Text("Fuzzy searching") } diff --git a/ElementX/Sources/Services/Notification/Manager/NotificationManager.swift b/ElementX/Sources/Services/Notification/Manager/NotificationManager.swift index bf5489eb4..9b8bf8188 100644 --- a/ElementX/Sources/Services/Notification/Manager/NotificationManager.swift +++ b/ElementX/Sources/Services/Notification/Manager/NotificationManager.swift @@ -159,7 +159,7 @@ final class NotificationManager: NSObject, NotificationManagerProtocol { } func updateAppBadgeCount() async { - guard let userSession, appSettings.roomListNotificationCountEnabled else { return } + guard let userSession else { return } let badgeCount = Int(userSession.clientProxy.totalUnreadNotifications) diff --git a/ElementX/Sources/Services/Notification/NotificationConstants.swift b/ElementX/Sources/Services/Notification/NotificationConstants.swift index 71972daf5..8b083fb82 100644 --- a/ElementX/Sources/Services/Notification/NotificationConstants.swift +++ b/ElementX/Sources/Services/Notification/NotificationConstants.swift @@ -13,7 +13,6 @@ nonisolated enum NotificationConstants { static let roomIdentifier = "room_id" static let eventIdentifier = "event_id" static let threadRootEventIdentifier = "thread_root_event_id" - static let unreadCount = "unread_count" static let pusherNotificationClientIdentifier = "pusher_notification_client_identifier" static let receiverIdentifier = "receiver_id" } diff --git a/NSE/Sources/NotificationHandler.swift b/NSE/Sources/NotificationHandler.swift index a0a04bc14..5473a1009 100644 --- a/NSE/Sources/NotificationHandler.swift +++ b/NSE/Sources/NotificationHandler.swift @@ -45,12 +45,6 @@ nonisolated class NotificationHandler { func processEvent(_ eventID: String, roomID: String) async { MXLog.info("\(tag) Processing event: \(eventID) in room: \(roomID)") - if !settings.roomListNotificationCountEnabled { - // Copy over the unread information provided by the push payload to the notification badge. - notificationContent.badge = notificationContent.unreadCount as NSNumber? - MXLog.info("\(tag) New badge value: \(notificationContent.badge?.stringValue ?? "nil")") - } - guard let notificationItemProxy = await userSession.notificationItemProxy(roomID: roomID, eventID: eventID) else { MXLog.error("\(tag) Failed retrieving notification item") discardNotification() @@ -84,12 +78,8 @@ nonisolated class NotificationHandler { // MARK: - Private private func deliverNotification() { - if settings.roomListNotificationCountEnabled { - notificationContent.badge = NSNumber(value: incrementBadgeCount()) - MXLog.info("\(tag) Delivering notification, new badge value: \(settings.lastKnownBadgeCount)") - } else { - MXLog.info("\(tag) Delivering notification") - } + notificationContent.badge = NSNumber(value: incrementBadgeCount()) + MXLog.info("\(tag) Delivering notification, new badge value: \(settings.lastKnownBadgeCount)") contentHandler(notificationContent) } @@ -109,12 +99,8 @@ nonisolated class NotificationHandler { MXLog.info("\(tag) Discarding notification") let content = UNMutableNotificationContent() - if settings.roomListNotificationCountEnabled { - // Nothing new is shown to the user, so leave the badge where the app last put it. - content.badge = NSNumber(value: settings.lastKnownBadgeCount) - } else { - content.badge = notificationContent.unreadCount as NSNumber? - } + // Nothing new is shown to the user, so leave the badge where the app last put it. + content.badge = NSNumber(value: settings.lastKnownBadgeCount) MXLog.info("\(tag) New badge value: \(content.badge?.stringValue ?? "nil")") contentHandler(content) @@ -149,9 +135,7 @@ nonisolated class NotificationHandler { if let targetNotification = deliveredNotifications.first(where: { $0.request.content.eventID == redactedEventID }) { UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [targetNotification.request.identifier]) - if settings.roomListNotificationCountEnabled { - settings.lastKnownBadgeCount = max(0, settings.lastKnownBadgeCount - 1) - } + settings.lastKnownBadgeCount = max(0, settings.lastKnownBadgeCount - 1) } return .processedShouldDiscard diff --git a/NSE/Sources/NotificationServiceExtension.swift b/NSE/Sources/NotificationServiceExtension.swift index ac4a1088f..ec9febe9f 100644 --- a/NSE/Sources/NotificationServiceExtension.swift +++ b/NSE/Sources/NotificationServiceExtension.swift @@ -258,9 +258,6 @@ actor NotificationServiceExtensionActor { let content = UNMutableNotificationContent() content.body = L10n.notificationReceivedWhileOfflineIos - if !settings.roomListNotificationCountEnabled { - content.badge = originalRequest.content.unreadCount as NSNumber? - } content.sound = settings.notificationSound let request = UNNotificationRequest(identifier: Self.receivedWhileOfflineNotificationID, content: content, trigger: nil) diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPad-en-GB.png index 5dbccec65..a7e6a9120 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c02bce898b1b152d033925056fbc6988aa26586e51c72a197f451a8fee6d6165 -size 287212 +oid sha256:15fb653a9ebbf242796ea7f0642f593a97319565b2229b453f770c17955f4000 +size 288822 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPad-pseudo.png index dafc3afb3..c4525b9ef 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d6d245a8f330678b0cce10db60408839e0f6a7bbf3e8d0f1e4c4413311485b79 -size 297921 +oid sha256:995e5af4bcddb8930735d9e309f128ac0d39bea8fbff7f1113848071cbc6defe +size 299527 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPhone-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPhone-en-GB.png index 0730416ab..4e5d552d5 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPhone-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPhone-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:21900e354eb87dacdb3eb86c8ea6cc89ca3ca5440360d72857027d3a42f75b7d -size 203557 +oid sha256:29555629f6c361e8e83c0db0d3ef1dfd63db303ce0078da41f3244969902cc9a +size 204586 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPhone-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPhone-pseudo.png index 44da87703..ae432017b 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPhone-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPhone-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9618c5743c9f49ea3f59238f9a8aef209275461954be2ab7faa8d6caadf4da3f -size 209937 +oid sha256:7577f36308b256e7748f2e322a20e9b1152b70a6c3ffb02abf2a7d69af5dc432 +size 210956 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPad-en-GB.png index 4f1ebe5af..8f2c5935f 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28e5f6a36ceb714001a8dfc51197bad50537e2d1be2a273485964db6d6133fa5 -size 242420 +oid sha256:b84d846ceee7c653ae220d774cec99ae83fa5ff2ee116ffcb3d8d706a59ef26c +size 244002 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPad-pseudo.png index 3e836fd3c..4d7bcdcf1 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:99d7a5ca6e985e9b3ce8954428db7f4d1d7f312112e26c2837976edb921c33d3 -size 248146 +oid sha256:ac03aa9dc61d69183dc984c4469d1b53d312c3eba30bb28cb72db072446862cb +size 249780 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPhone-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPhone-en-GB.png index c6b14dd68..cee45cdd9 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPhone-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPhone-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7ad39875aa0432eee1f1518b6dcf42b8283ea4cbc8b2b4249d22e455932f27be -size 180646 +oid sha256:02f165e945006870b6b483a9ab8539c044813397f036773a3ed87451d41e4843 +size 181783 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPhone-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPhone-pseudo.png index dcc6ba441..4cffac6f3 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPhone-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPhone-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eb914d10c111af3dbd32174ea39fef5efd4d419d94af122c531e58f6acffc327 -size 184978 +oid sha256:529579d75acd5f8cde370ddfcaef7a45102904031d28674fcf7fb2471403b7a9 +size 186112 diff --git a/UnitTests/Sources/NotificationManager/NotificationManagerTests.swift b/UnitTests/Sources/NotificationManager/NotificationManagerTests.swift index a47796e1a..c2247acdf 100644 --- a/UnitTests/Sources/NotificationManager/NotificationManagerTests.swift +++ b/UnitTests/Sources/NotificationManager/NotificationManagerTests.swift @@ -240,7 +240,6 @@ final class NotificationManagerTests { @Test func updatingAppBadgeCountUsesTheClientSideCount() async { - appSettings.roomListNotificationCountEnabled = true clientProxy.totalUnreadNotifications = 7 await notificationManager.updateAppBadgeCount() @@ -251,23 +250,12 @@ final class NotificationManagerTests { @Test func updatingAppBadgeCountWithoutASessionDoesNothing() async { - appSettings.roomListNotificationCountEnabled = true notificationManager.setUserSession(nil) await notificationManager.updateAppBadgeCount() #expect(!notificationCenter.setBadgeCountCalled) } - - @Test - func updatingAppBadgeCountWithFeatureDisabledDoesNothing() async { - appSettings.roomListNotificationCountEnabled = false - clientProxy.totalUnreadNotifications = 7 - - await notificationManager.updateAppBadgeCount() - - #expect(!notificationCenter.setBadgeCountCalled) - } } extension NotificationManagerTests: @MainActor NotificationManagerDelegate {