From 45e40f26c7274d1694bd624bb02aaea67cddb4c6 Mon Sep 17 00:00:00 2001 From: Mauro <34335419+Velin92@users.noreply.github.com> Date: Tue, 23 Jan 2024 16:14:53 +0100 Subject: [PATCH] Fix: Grey dot appears when you have unread messages that do not trigger a notification (#2371) --- .../Screens/HomeScreen/HomeScreenModels.swift | 11 +- .../HomeScreen/HomeScreenViewModel.swift | 6 +- .../HomeScreen/View/HomeScreenRoomCell.swift | 20 ++-- .../View/InvitesScreenCell.swift | 6 +- .../RoomNotificationModeProxy.swift | 2 +- .../RoomSummary/MockRoomSummaryProvider.swift | 105 ++++++++---------- .../Room/RoomSummary/RoomSummaryDetails.swift | 12 +- .../RoomSummary/RoomSummaryProvider.swift | 3 +- UnitTests/Sources/LoggingTests.swift | 3 +- ...homeScreenRoomCell.Notifications-State.png | 4 +- changelog.d/pr-2371.change | 1 + 11 files changed, 85 insertions(+), 88 deletions(-) create mode 100644 changelog.d/pr-2371.change diff --git a/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift b/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift index 9dea90a92..13d930781 100644 --- a/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift +++ b/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift @@ -145,9 +145,11 @@ struct HomeScreenRoom: Identifiable, Equatable { var name = "" - var hasUnreads = false + var hasUnreadMessages = false - var hasMentions = false + var hasUnreadMentions = false + + var hasUnreadNotifications = false var hasOngoingCall = false @@ -165,8 +167,9 @@ struct HomeScreenRoom: Identifiable, Equatable { HomeScreenRoom(id: UUID().uuidString, roomId: nil, name: "Placeholder room name", - hasUnreads: false, - hasMentions: false, + hasUnreadMessages: false, + hasUnreadMentions: false, + hasUnreadNotifications: false, timestamp: "Now", lastMessage: placeholderLastMessage, isPlaceholder: true) diff --git a/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift b/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift index d0ad99ce9..8f792e5b4 100644 --- a/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift +++ b/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift @@ -287,13 +287,13 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol private func buildRoom(with details: RoomSummaryDetails, invalidated: Bool) -> HomeScreenRoom { let identifier = invalidated ? "invalidated-" + details.id : details.id - let hasMentions = appSettings.mentionsBadgeEnabled ? details.unreadMentionsCount > 0 : false return HomeScreenRoom(id: identifier, roomId: details.id, name: details.name, - hasUnreads: details.unreadNotificationsCount > 0, - hasMentions: hasMentions, + hasUnreadMessages: details.unreadMessagesCount > 0, + hasUnreadMentions: details.unreadMentionsCount > 0, + hasUnreadNotifications: details.unreadNotificationsCount > 0, hasOngoingCall: details.hasOngoingCall, timestamp: details.lastMessageFormattedTimestamp, lastMessage: details.lastMessage, diff --git a/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift b/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift index 1dcf2bc26..3420d6af7 100644 --- a/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift +++ b/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift @@ -128,7 +128,7 @@ struct HomeScreenRoomCell: View { .foregroundColor(.compound.iconQuaternary) } - if room.hasMentions, room.notificationMode != .mute { + if room.hasUnreadMentions, room.notificationMode != .mute { mentionIcon .foregroundColor(.compound.iconAccentTertiary) } @@ -143,19 +143,17 @@ struct HomeScreenRoomCell: View { } private var hasNewContent: Bool { - room.hasUnreads || room.hasMentions + room.hasUnreadMessages || + room.hasUnreadMentions || + room.hasUnreadNotifications } private var isHighlighted: Bool { - guard !room.isPlaceholder else { + guard !room.isPlaceholder && + room.notificationMode != .mute else { return false } - return (isNotificationModeUnrestricted && hasNewContent) || - (room.notificationMode == .mentionsAndKeywordsOnly && room.hasMentions) - } - - private var isNotificationModeUnrestricted: Bool { - room.notificationMode == nil || room.notificationMode == .allMessages + return room.hasUnreadNotifications || room.hasUnreadMentions } private var mentionIcon: some View { @@ -225,7 +223,9 @@ struct HomeScreenRoomCell_Previews: PreviewProvider, TestablePreview { return HomeScreenRoom(id: UUID().uuidString, roomId: details.id, name: details.name, - hasUnreads: details.unreadNotificationsCount > 0, hasMentions: details.unreadMentionsCount > 0, + hasUnreadMessages: details.unreadMessagesCount > 0, + hasUnreadMentions: details.unreadMentionsCount > 0, + hasUnreadNotifications: details.unreadNotificationsCount > 0, hasOngoingCall: details.hasOngoingCall, timestamp: Date(timeIntervalSinceReferenceDate: 0).formattedMinimal(), lastMessage: details.lastMessage, diff --git a/ElementX/Sources/Screens/InvitesScreen/View/InvitesScreenCell.swift b/ElementX/Sources/Screens/InvitesScreen/View/InvitesScreenCell.swift index bb1103541..cc140e7d0 100644 --- a/ElementX/Sources/Screens/InvitesScreen/View/InvitesScreenCell.swift +++ b/ElementX/Sources/Screens/InvitesScreen/View/InvitesScreenCell.swift @@ -186,8 +186,9 @@ private extension InvitesScreenRoomDetails { avatarURL: nil, lastMessage: nil, lastMessageFormattedTimestamp: nil, - unreadNotificationsCount: 0, + unreadMessagesCount: 0, unreadMentionsCount: 0, + unreadNotificationsCount: 0, notificationMode: nil, canonicalAlias: "#footest:somewhere.org", inviter: inviter, @@ -207,8 +208,9 @@ private extension InvitesScreenRoomDetails { avatarURL: avatarURL, lastMessage: nil, lastMessageFormattedTimestamp: nil, - unreadNotificationsCount: 0, + unreadMessagesCount: 0, unreadMentionsCount: 0, + unreadNotificationsCount: 0, notificationMode: nil, canonicalAlias: alias, inviter: inviter, diff --git a/ElementX/Sources/Services/NotificationSettings/RoomNotificationModeProxy.swift b/ElementX/Sources/Services/NotificationSettings/RoomNotificationModeProxy.swift index 158705858..6b3c0267c 100644 --- a/ElementX/Sources/Services/NotificationSettings/RoomNotificationModeProxy.swift +++ b/ElementX/Sources/Services/NotificationSettings/RoomNotificationModeProxy.swift @@ -17,7 +17,7 @@ import Foundation import MatrixRustSDK -enum RoomNotificationModeProxy: String { +enum RoomNotificationModeProxy: String, CaseIterable { case allMessages case mentionsAndKeywordsOnly case mute diff --git a/ElementX/Sources/Services/Room/RoomSummary/MockRoomSummaryProvider.swift b/ElementX/Sources/Services/Room/RoomSummary/MockRoomSummaryProvider.swift index 59c1dd4e6..3ab1d5ad4 100644 --- a/ElementX/Sources/Services/Room/RoomSummary/MockRoomSummaryProvider.swift +++ b/ElementX/Sources/Services/Room/RoomSummary/MockRoomSummaryProvider.swift @@ -83,8 +83,9 @@ extension Array where Element == RoomSummary { avatarURL: nil, lastMessage: AttributedString("I do not wish to take the trouble to understand mysticism"), lastMessageFormattedTimestamp: "14:56", - unreadNotificationsCount: 0, + unreadMessagesCount: 0, unreadMentionsCount: 0, + unreadNotificationsCount: 0, notificationMode: .allMessages, canonicalAlias: nil, inviter: nil, @@ -95,8 +96,9 @@ extension Array where Element == RoomSummary { avatarURL: URL.picturesDirectory, lastMessage: AttributedString("How do you see the Emperor then? You think he keeps office hours?"), lastMessageFormattedTimestamp: "2:56 PM", - unreadNotificationsCount: 2, + unreadMessagesCount: 2, unreadMentionsCount: 0, + unreadNotificationsCount: 2, notificationMode: .mute, canonicalAlias: nil, inviter: nil, @@ -107,8 +109,9 @@ extension Array where Element == RoomSummary { avatarURL: nil, lastMessage: try? AttributedString(markdown: "He certainly seemed no *mental genius* to me"), lastMessageFormattedTimestamp: "Some time ago", - unreadNotificationsCount: 3, + unreadMessagesCount: 3, unreadMentionsCount: 0, + unreadNotificationsCount: 0, notificationMode: .mentionsAndKeywordsOnly, canonicalAlias: nil, inviter: nil, @@ -119,8 +122,9 @@ extension Array where Element == RoomSummary { avatarURL: nil, lastMessage: AttributedString("There's an archaic measure of time that's called the month"), lastMessageFormattedTimestamp: "Just now", - unreadNotificationsCount: 2, + unreadMessagesCount: 2, unreadMentionsCount: 2, + unreadNotificationsCount: 2, notificationMode: .allMessages, canonicalAlias: nil, inviter: nil, @@ -131,8 +135,9 @@ extension Array where Element == RoomSummary { avatarURL: nil, lastMessage: AttributedString("Clearly, if Earth is powerful enough to do that, it might also be capable of adjusting minds in order to force belief in its radioactivity"), lastMessageFormattedTimestamp: "1986", - unreadNotificationsCount: 1, + unreadMessagesCount: 1, unreadMentionsCount: 1, + unreadNotificationsCount: 1, notificationMode: .allMessages, canonicalAlias: nil, inviter: nil, @@ -143,8 +148,9 @@ extension Array where Element == RoomSummary { avatarURL: nil, lastMessage: AttributedString("Are you groping for the word 'paranoia'?"), lastMessageFormattedTimestamp: "きょうはじゅういちがつじゅういちにちです", - unreadNotificationsCount: 6, + unreadMessagesCount: 6, unreadMentionsCount: 0, + unreadNotificationsCount: 0, notificationMode: .mute, canonicalAlias: nil, inviter: nil, @@ -155,8 +161,9 @@ extension Array where Element == RoomSummary { avatarURL: nil, lastMessage: nil, lastMessageFormattedTimestamp: nil, - unreadNotificationsCount: 0, + unreadMessagesCount: 0, unreadMentionsCount: 0, + unreadNotificationsCount: 0, notificationMode: nil, canonicalAlias: nil, inviter: nil, @@ -164,56 +171,34 @@ extension Array where Element == RoomSummary { .empty ] - static let mockRoomsWithNotificationsState: [Element] = [ - .filled(details: RoomSummaryDetails(id: "1", - settingsMode: .allMessages, - hasUnreadNotifications: false, - hasUnreadMentions: false)), - .filled(details: RoomSummaryDetails(id: "2", - settingsMode: .allMessages, - hasUnreadNotifications: true, - hasUnreadMentions: false)), - .filled(details: RoomSummaryDetails(id: "3", - settingsMode: .allMessages, - hasUnreadNotifications: true, - hasUnreadMentions: true)), - .filled(details: RoomSummaryDetails(id: "4", - settingsMode: .allMessages, - hasUnreadNotifications: false, - hasUnreadMentions: true)), - .filled(details: RoomSummaryDetails(id: "5", - settingsMode: .mentionsAndKeywordsOnly, - hasUnreadNotifications: false, - hasUnreadMentions: false)), - .filled(details: RoomSummaryDetails(id: "6", - settingsMode: .mentionsAndKeywordsOnly, - hasUnreadNotifications: true, - hasUnreadMentions: false)), - .filled(details: RoomSummaryDetails(id: "7", - settingsMode: .mentionsAndKeywordsOnly, - hasUnreadNotifications: true, - hasUnreadMentions: true)), - .filled(details: RoomSummaryDetails(id: "8", - settingsMode: .mentionsAndKeywordsOnly, - hasUnreadNotifications: false, - hasUnreadMentions: true)), - .filled(details: RoomSummaryDetails(id: "9", - settingsMode: .mute, - hasUnreadNotifications: false, - hasUnreadMentions: false)), - .filled(details: RoomSummaryDetails(id: "10", - settingsMode: .mute, - hasUnreadNotifications: true, - hasUnreadMentions: false)), - .filled(details: RoomSummaryDetails(id: "11", - settingsMode: .mute, - hasUnreadNotifications: true, - hasUnreadMentions: true)), - .filled(details: RoomSummaryDetails(id: "12", - settingsMode: .mute, - hasUnreadNotifications: false, - hasUnreadMentions: true)) - ] + static let mockRoomsWithNotificationsState: [Element] = { + var result: [Element] = [] + + // Iterate over settings modes + for mode in RoomNotificationModeProxy.allCases { + // Iterate over unread messages states + for hasUnreadMessages in [false, true] { + // Iterate over unread mentions states + for hasUnreadMentions in [false, true] { + // Iterate over unread notifications states + for hasUnreadNotifications in [false, true] { + // Incrementing id value for each combination + let id = result.count + 1 + + let room = RoomSummary.filled(details: RoomSummaryDetails(id: "\(id)", + settingsMode: mode, + hasUnreadMessages: hasUnreadMessages, + hasUnreadMentions: hasUnreadMentions, + hasUnreadNotifications: hasUnreadNotifications)) + + result.append(room) + } + } + } + } + + return result + }() static let mockInvites: [Element] = [ .filled(details: RoomSummaryDetails(id: "someAwesomeRoomId1", name: "First room", @@ -221,8 +206,9 @@ extension Array where Element == RoomSummary { avatarURL: URL.picturesDirectory, lastMessage: nil, lastMessageFormattedTimestamp: nil, - unreadNotificationsCount: 0, + unreadMessagesCount: 0, unreadMentionsCount: 0, + unreadNotificationsCount: 0, notificationMode: nil, canonicalAlias: "#footest:somewhere.org", inviter: RoomMemberProxyMock.mockCharlie, @@ -233,8 +219,9 @@ extension Array where Element == RoomSummary { avatarURL: nil, lastMessage: nil, lastMessageFormattedTimestamp: nil, - unreadNotificationsCount: 0, + unreadMessagesCount: 0, unreadMentionsCount: 0, + unreadNotificationsCount: 0, notificationMode: nil, canonicalAlias: nil, inviter: RoomMemberProxyMock.mockCharlie, diff --git a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryDetails.swift b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryDetails.swift index f566a4bbb..7832f9fbf 100644 --- a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryDetails.swift +++ b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryDetails.swift @@ -24,8 +24,9 @@ struct RoomSummaryDetails { let avatarURL: URL? let lastMessage: AttributedString? let lastMessageFormattedTimestamp: String? - let unreadNotificationsCount: UInt + let unreadMessagesCount: UInt let unreadMentionsCount: UInt + let unreadNotificationsCount: UInt let notificationMode: RoomNotificationModeProxy? let canonicalAlias: String? let inviter: RoomMemberProxyProtocol? @@ -34,21 +35,22 @@ struct RoomSummaryDetails { extension RoomSummaryDetails: CustomStringConvertible { var description: String { - "RoomSummaryDetails: - id: \(id) - isDirect: \(isDirect) - unreadNotificationsCount: \(unreadNotificationsCount) - unreadMentionsCount: \(unreadMentionsCount) - notificationMode: \(notificationMode?.rawValue ?? "nil")" + "RoomSummaryDetails: - id: \(id) - isDirect: \(isDirect) - unreadMessagesCount: \(unreadMessagesCount) - unreadMentionsCount: \(unreadMentionsCount) - unreadNotificationsCount: \(unreadNotificationsCount) - notificationMode: \(notificationMode?.rawValue ?? "nil")" } } extension RoomSummaryDetails { - init(id: String, settingsMode: RoomNotificationModeProxy, hasUnreadNotifications: Bool, hasUnreadMentions: Bool) { + init(id: String, settingsMode: RoomNotificationModeProxy, hasUnreadMessages: Bool, hasUnreadMentions: Bool, hasUnreadNotifications: Bool) { self.id = id - let string = "\(settingsMode) - hasUnreadNotifications: \(hasUnreadNotifications) - hasUnreadMentions: \(hasUnreadMentions)" + let string = "\(settingsMode) - messages: \(hasUnreadMessages) - mentions: \(hasUnreadMentions) - notifications: \(hasUnreadNotifications)" name = string isDirect = true avatarURL = nil lastMessage = AttributedString(string) lastMessageFormattedTimestamp = "Now" - unreadNotificationsCount = hasUnreadNotifications ? 1 : 0 + unreadMessagesCount = hasUnreadMessages ? 1 : 0 unreadMentionsCount = hasUnreadMentions ? 1 : 0 + unreadNotificationsCount = hasUnreadNotifications ? 1 : 0 notificationMode = settingsMode canonicalAlias = nil inviter = nil diff --git a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift index 1547fffd3..215b5b98c 100644 --- a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift +++ b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift @@ -248,8 +248,9 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol { avatarURL: roomInfo.avatarUrl.flatMap(URL.init(string:)), lastMessage: attributedLastMessage, lastMessageFormattedTimestamp: lastMessageFormattedTimestamp, + unreadMessagesCount: appSettings.mentionsBadgeEnabled ? UInt(roomInfo.numUnreadMessages) : 0, + unreadMentionsCount: appSettings.mentionsBadgeEnabled ? UInt(roomInfo.numUnreadMentions) : 0, unreadNotificationsCount: appSettings.mentionsBadgeEnabled ? UInt(roomInfo.numUnreadNotifications) : UInt(roomInfo.notificationCount), - unreadMentionsCount: UInt(roomInfo.numUnreadMentions), notificationMode: notificationMode, canonicalAlias: roomInfo.canonicalAlias, inviter: inviterProxy, diff --git a/UnitTests/Sources/LoggingTests.swift b/UnitTests/Sources/LoggingTests.swift index 93024897d..8fd73d535 100644 --- a/UnitTests/Sources/LoggingTests.swift +++ b/UnitTests/Sources/LoggingTests.swift @@ -229,8 +229,9 @@ class LoggingTests: XCTestCase { avatarURL: nil, lastMessage: AttributedString(lastMessage), lastMessageFormattedTimestamp: "Now", - unreadNotificationsCount: 0, + unreadMessagesCount: 0, unreadMentionsCount: 0, + unreadNotificationsCount: 0, notificationMode: nil, canonicalAlias: nil, inviter: nil, diff --git a/UnitTests/__Snapshots__/PreviewTests/test_homeScreenRoomCell.Notifications-State.png b/UnitTests/__Snapshots__/PreviewTests/test_homeScreenRoomCell.Notifications-State.png index 01a5bdadb..4e2645469 100644 --- a/UnitTests/__Snapshots__/PreviewTests/test_homeScreenRoomCell.Notifications-State.png +++ b/UnitTests/__Snapshots__/PreviewTests/test_homeScreenRoomCell.Notifications-State.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0701f80353a05af1c99196feb5480525dd9106052bb5c0b096d581344b8ba6af -size 427934 +oid sha256:15801a4cca3898a59aaa7607710b7193323ae25df590a1857d009d97afc45955 +size 804308 diff --git a/changelog.d/pr-2371.change b/changelog.d/pr-2371.change new file mode 100644 index 000000000..513ee1aa7 --- /dev/null +++ b/changelog.d/pr-2371.change @@ -0,0 +1 @@ +Unread messages that do not trigger notifications, will show a grey dot in the room list. \ No newline at end of file