Fix: Grey dot appears when you have unread messages that do not trigger a notification (#2371)

This commit is contained in:
Mauro
2024-01-23 16:14:53 +01:00
committed by GitHub
parent 680c6ef3aa
commit 550db5e377
11 changed files with 85 additions and 88 deletions
@@ -145,9 +145,11 @@ struct HomeScreenRoom: Identifiable, Equatable {
var name = "" var name = ""
var hasUnreads = false var hasUnreadMessages = false
var hasMentions = false var hasUnreadMentions = false
var hasUnreadNotifications = false
var hasOngoingCall = false var hasOngoingCall = false
@@ -165,8 +167,9 @@ struct HomeScreenRoom: Identifiable, Equatable {
HomeScreenRoom(id: UUID().uuidString, HomeScreenRoom(id: UUID().uuidString,
roomId: nil, roomId: nil,
name: "Placeholder room name", name: "Placeholder room name",
hasUnreads: false, hasUnreadMessages: false,
hasMentions: false, hasUnreadMentions: false,
hasUnreadNotifications: false,
timestamp: "Now", timestamp: "Now",
lastMessage: placeholderLastMessage, lastMessage: placeholderLastMessage,
isPlaceholder: true) isPlaceholder: true)
@@ -287,13 +287,13 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
private func buildRoom(with details: RoomSummaryDetails, invalidated: Bool) -> HomeScreenRoom { private func buildRoom(with details: RoomSummaryDetails, invalidated: Bool) -> HomeScreenRoom {
let identifier = invalidated ? "invalidated-" + details.id : details.id let identifier = invalidated ? "invalidated-" + details.id : details.id
let hasMentions = appSettings.mentionsBadgeEnabled ? details.unreadMentionsCount > 0 : false
return HomeScreenRoom(id: identifier, return HomeScreenRoom(id: identifier,
roomId: details.id, roomId: details.id,
name: details.name, name: details.name,
hasUnreads: details.unreadNotificationsCount > 0, hasUnreadMessages: details.unreadMessagesCount > 0,
hasMentions: hasMentions, hasUnreadMentions: details.unreadMentionsCount > 0,
hasUnreadNotifications: details.unreadNotificationsCount > 0,
hasOngoingCall: details.hasOngoingCall, hasOngoingCall: details.hasOngoingCall,
timestamp: details.lastMessageFormattedTimestamp, timestamp: details.lastMessageFormattedTimestamp,
lastMessage: details.lastMessage, lastMessage: details.lastMessage,
@@ -128,7 +128,7 @@ struct HomeScreenRoomCell: View {
.foregroundColor(.compound.iconQuaternary) .foregroundColor(.compound.iconQuaternary)
} }
if room.hasMentions, room.notificationMode != .mute { if room.hasUnreadMentions, room.notificationMode != .mute {
mentionIcon mentionIcon
.foregroundColor(.compound.iconAccentTertiary) .foregroundColor(.compound.iconAccentTertiary)
} }
@@ -143,19 +143,17 @@ struct HomeScreenRoomCell: View {
} }
private var hasNewContent: Bool { private var hasNewContent: Bool {
room.hasUnreads || room.hasMentions room.hasUnreadMessages ||
room.hasUnreadMentions ||
room.hasUnreadNotifications
} }
private var isHighlighted: Bool { private var isHighlighted: Bool {
guard !room.isPlaceholder else { guard !room.isPlaceholder &&
room.notificationMode != .mute else {
return false return false
} }
return (isNotificationModeUnrestricted && hasNewContent) || return room.hasUnreadNotifications || room.hasUnreadMentions
(room.notificationMode == .mentionsAndKeywordsOnly && room.hasMentions)
}
private var isNotificationModeUnrestricted: Bool {
room.notificationMode == nil || room.notificationMode == .allMessages
} }
private var mentionIcon: some View { private var mentionIcon: some View {
@@ -225,7 +223,9 @@ struct HomeScreenRoomCell_Previews: PreviewProvider, TestablePreview {
return HomeScreenRoom(id: UUID().uuidString, return HomeScreenRoom(id: UUID().uuidString,
roomId: details.id, roomId: details.id,
name: details.name, 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, hasOngoingCall: details.hasOngoingCall,
timestamp: Date(timeIntervalSinceReferenceDate: 0).formattedMinimal(), timestamp: Date(timeIntervalSinceReferenceDate: 0).formattedMinimal(),
lastMessage: details.lastMessage, lastMessage: details.lastMessage,
@@ -186,8 +186,9 @@ private extension InvitesScreenRoomDetails {
avatarURL: nil, avatarURL: nil,
lastMessage: nil, lastMessage: nil,
lastMessageFormattedTimestamp: nil, lastMessageFormattedTimestamp: nil,
unreadNotificationsCount: 0, unreadMessagesCount: 0,
unreadMentionsCount: 0, unreadMentionsCount: 0,
unreadNotificationsCount: 0,
notificationMode: nil, notificationMode: nil,
canonicalAlias: "#footest:somewhere.org", canonicalAlias: "#footest:somewhere.org",
inviter: inviter, inviter: inviter,
@@ -207,8 +208,9 @@ private extension InvitesScreenRoomDetails {
avatarURL: avatarURL, avatarURL: avatarURL,
lastMessage: nil, lastMessage: nil,
lastMessageFormattedTimestamp: nil, lastMessageFormattedTimestamp: nil,
unreadNotificationsCount: 0, unreadMessagesCount: 0,
unreadMentionsCount: 0, unreadMentionsCount: 0,
unreadNotificationsCount: 0,
notificationMode: nil, notificationMode: nil,
canonicalAlias: alias, canonicalAlias: alias,
inviter: inviter, inviter: inviter,
@@ -17,7 +17,7 @@
import Foundation import Foundation
import MatrixRustSDK import MatrixRustSDK
enum RoomNotificationModeProxy: String { enum RoomNotificationModeProxy: String, CaseIterable {
case allMessages case allMessages
case mentionsAndKeywordsOnly case mentionsAndKeywordsOnly
case mute case mute
@@ -83,8 +83,9 @@ extension Array where Element == RoomSummary {
avatarURL: nil, avatarURL: nil,
lastMessage: AttributedString("I do not wish to take the trouble to understand mysticism"), lastMessage: AttributedString("I do not wish to take the trouble to understand mysticism"),
lastMessageFormattedTimestamp: "14:56", lastMessageFormattedTimestamp: "14:56",
unreadNotificationsCount: 0, unreadMessagesCount: 0,
unreadMentionsCount: 0, unreadMentionsCount: 0,
unreadNotificationsCount: 0,
notificationMode: .allMessages, notificationMode: .allMessages,
canonicalAlias: nil, canonicalAlias: nil,
inviter: nil, inviter: nil,
@@ -95,8 +96,9 @@ extension Array where Element == RoomSummary {
avatarURL: URL.picturesDirectory, avatarURL: URL.picturesDirectory,
lastMessage: AttributedString("How do you see the Emperor then? You think he keeps office hours?"), lastMessage: AttributedString("How do you see the Emperor then? You think he keeps office hours?"),
lastMessageFormattedTimestamp: "2:56 PM", lastMessageFormattedTimestamp: "2:56 PM",
unreadNotificationsCount: 2, unreadMessagesCount: 2,
unreadMentionsCount: 0, unreadMentionsCount: 0,
unreadNotificationsCount: 2,
notificationMode: .mute, notificationMode: .mute,
canonicalAlias: nil, canonicalAlias: nil,
inviter: nil, inviter: nil,
@@ -107,8 +109,9 @@ extension Array where Element == RoomSummary {
avatarURL: nil, avatarURL: nil,
lastMessage: try? AttributedString(markdown: "He certainly seemed no *mental genius* to me"), lastMessage: try? AttributedString(markdown: "He certainly seemed no *mental genius* to me"),
lastMessageFormattedTimestamp: "Some time ago", lastMessageFormattedTimestamp: "Some time ago",
unreadNotificationsCount: 3, unreadMessagesCount: 3,
unreadMentionsCount: 0, unreadMentionsCount: 0,
unreadNotificationsCount: 0,
notificationMode: .mentionsAndKeywordsOnly, notificationMode: .mentionsAndKeywordsOnly,
canonicalAlias: nil, canonicalAlias: nil,
inviter: nil, inviter: nil,
@@ -119,8 +122,9 @@ extension Array where Element == RoomSummary {
avatarURL: nil, avatarURL: nil,
lastMessage: AttributedString("There's an archaic measure of time that's called the month"), lastMessage: AttributedString("There's an archaic measure of time that's called the month"),
lastMessageFormattedTimestamp: "Just now", lastMessageFormattedTimestamp: "Just now",
unreadNotificationsCount: 2, unreadMessagesCount: 2,
unreadMentionsCount: 2, unreadMentionsCount: 2,
unreadNotificationsCount: 2,
notificationMode: .allMessages, notificationMode: .allMessages,
canonicalAlias: nil, canonicalAlias: nil,
inviter: nil, inviter: nil,
@@ -131,8 +135,9 @@ extension Array where Element == RoomSummary {
avatarURL: nil, 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"), 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", lastMessageFormattedTimestamp: "1986",
unreadNotificationsCount: 1, unreadMessagesCount: 1,
unreadMentionsCount: 1, unreadMentionsCount: 1,
unreadNotificationsCount: 1,
notificationMode: .allMessages, notificationMode: .allMessages,
canonicalAlias: nil, canonicalAlias: nil,
inviter: nil, inviter: nil,
@@ -143,8 +148,9 @@ extension Array where Element == RoomSummary {
avatarURL: nil, avatarURL: nil,
lastMessage: AttributedString("Are you groping for the word 'paranoia'?"), lastMessage: AttributedString("Are you groping for the word 'paranoia'?"),
lastMessageFormattedTimestamp: "きょうはじゅういちがつじゅういちにちです", lastMessageFormattedTimestamp: "きょうはじゅういちがつじゅういちにちです",
unreadNotificationsCount: 6, unreadMessagesCount: 6,
unreadMentionsCount: 0, unreadMentionsCount: 0,
unreadNotificationsCount: 0,
notificationMode: .mute, notificationMode: .mute,
canonicalAlias: nil, canonicalAlias: nil,
inviter: nil, inviter: nil,
@@ -155,8 +161,9 @@ extension Array where Element == RoomSummary {
avatarURL: nil, avatarURL: nil,
lastMessage: nil, lastMessage: nil,
lastMessageFormattedTimestamp: nil, lastMessageFormattedTimestamp: nil,
unreadNotificationsCount: 0, unreadMessagesCount: 0,
unreadMentionsCount: 0, unreadMentionsCount: 0,
unreadNotificationsCount: 0,
notificationMode: nil, notificationMode: nil,
canonicalAlias: nil, canonicalAlias: nil,
inviter: nil, inviter: nil,
@@ -164,56 +171,34 @@ extension Array where Element == RoomSummary {
.empty .empty
] ]
static let mockRoomsWithNotificationsState: [Element] = [ static let mockRoomsWithNotificationsState: [Element] = {
.filled(details: RoomSummaryDetails(id: "1", var result: [Element] = []
settingsMode: .allMessages,
hasUnreadNotifications: false, // Iterate over settings modes
hasUnreadMentions: false)), for mode in RoomNotificationModeProxy.allCases {
.filled(details: RoomSummaryDetails(id: "2", // Iterate over unread messages states
settingsMode: .allMessages, for hasUnreadMessages in [false, true] {
hasUnreadNotifications: true, // Iterate over unread mentions states
hasUnreadMentions: false)), for hasUnreadMentions in [false, true] {
.filled(details: RoomSummaryDetails(id: "3", // Iterate over unread notifications states
settingsMode: .allMessages, for hasUnreadNotifications in [false, true] {
hasUnreadNotifications: true, // Incrementing id value for each combination
hasUnreadMentions: true)), let id = result.count + 1
.filled(details: RoomSummaryDetails(id: "4",
settingsMode: .allMessages, let room = RoomSummary.filled(details: RoomSummaryDetails(id: "\(id)",
hasUnreadNotifications: false, settingsMode: mode,
hasUnreadMentions: true)), hasUnreadMessages: hasUnreadMessages,
.filled(details: RoomSummaryDetails(id: "5", hasUnreadMentions: hasUnreadMentions,
settingsMode: .mentionsAndKeywordsOnly, hasUnreadNotifications: hasUnreadNotifications))
hasUnreadNotifications: false,
hasUnreadMentions: false)), result.append(room)
.filled(details: RoomSummaryDetails(id: "6", }
settingsMode: .mentionsAndKeywordsOnly, }
hasUnreadNotifications: true, }
hasUnreadMentions: false)), }
.filled(details: RoomSummaryDetails(id: "7",
settingsMode: .mentionsAndKeywordsOnly, return result
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 mockInvites: [Element] = [ static let mockInvites: [Element] = [
.filled(details: RoomSummaryDetails(id: "someAwesomeRoomId1", name: "First room", .filled(details: RoomSummaryDetails(id: "someAwesomeRoomId1", name: "First room",
@@ -221,8 +206,9 @@ extension Array where Element == RoomSummary {
avatarURL: URL.picturesDirectory, avatarURL: URL.picturesDirectory,
lastMessage: nil, lastMessage: nil,
lastMessageFormattedTimestamp: nil, lastMessageFormattedTimestamp: nil,
unreadNotificationsCount: 0, unreadMessagesCount: 0,
unreadMentionsCount: 0, unreadMentionsCount: 0,
unreadNotificationsCount: 0,
notificationMode: nil, notificationMode: nil,
canonicalAlias: "#footest:somewhere.org", canonicalAlias: "#footest:somewhere.org",
inviter: RoomMemberProxyMock.mockCharlie, inviter: RoomMemberProxyMock.mockCharlie,
@@ -233,8 +219,9 @@ extension Array where Element == RoomSummary {
avatarURL: nil, avatarURL: nil,
lastMessage: nil, lastMessage: nil,
lastMessageFormattedTimestamp: nil, lastMessageFormattedTimestamp: nil,
unreadNotificationsCount: 0, unreadMessagesCount: 0,
unreadMentionsCount: 0, unreadMentionsCount: 0,
unreadNotificationsCount: 0,
notificationMode: nil, notificationMode: nil,
canonicalAlias: nil, canonicalAlias: nil,
inviter: RoomMemberProxyMock.mockCharlie, inviter: RoomMemberProxyMock.mockCharlie,
@@ -24,8 +24,9 @@ struct RoomSummaryDetails {
let avatarURL: URL? let avatarURL: URL?
let lastMessage: AttributedString? let lastMessage: AttributedString?
let lastMessageFormattedTimestamp: String? let lastMessageFormattedTimestamp: String?
let unreadNotificationsCount: UInt let unreadMessagesCount: UInt
let unreadMentionsCount: UInt let unreadMentionsCount: UInt
let unreadNotificationsCount: UInt
let notificationMode: RoomNotificationModeProxy? let notificationMode: RoomNotificationModeProxy?
let canonicalAlias: String? let canonicalAlias: String?
let inviter: RoomMemberProxyProtocol? let inviter: RoomMemberProxyProtocol?
@@ -34,21 +35,22 @@ struct RoomSummaryDetails {
extension RoomSummaryDetails: CustomStringConvertible { extension RoomSummaryDetails: CustomStringConvertible {
var description: String { 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 { 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 self.id = id
let string = "\(settingsMode) - hasUnreadNotifications: \(hasUnreadNotifications) - hasUnreadMentions: \(hasUnreadMentions)" let string = "\(settingsMode) - messages: \(hasUnreadMessages) - mentions: \(hasUnreadMentions) - notifications: \(hasUnreadNotifications)"
name = string name = string
isDirect = true isDirect = true
avatarURL = nil avatarURL = nil
lastMessage = AttributedString(string) lastMessage = AttributedString(string)
lastMessageFormattedTimestamp = "Now" lastMessageFormattedTimestamp = "Now"
unreadNotificationsCount = hasUnreadNotifications ? 1 : 0 unreadMessagesCount = hasUnreadMessages ? 1 : 0
unreadMentionsCount = hasUnreadMentions ? 1 : 0 unreadMentionsCount = hasUnreadMentions ? 1 : 0
unreadNotificationsCount = hasUnreadNotifications ? 1 : 0
notificationMode = settingsMode notificationMode = settingsMode
canonicalAlias = nil canonicalAlias = nil
inviter = nil inviter = nil
@@ -248,8 +248,9 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
avatarURL: roomInfo.avatarUrl.flatMap(URL.init(string:)), avatarURL: roomInfo.avatarUrl.flatMap(URL.init(string:)),
lastMessage: attributedLastMessage, lastMessage: attributedLastMessage,
lastMessageFormattedTimestamp: lastMessageFormattedTimestamp, 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), unreadNotificationsCount: appSettings.mentionsBadgeEnabled ? UInt(roomInfo.numUnreadNotifications) : UInt(roomInfo.notificationCount),
unreadMentionsCount: UInt(roomInfo.numUnreadMentions),
notificationMode: notificationMode, notificationMode: notificationMode,
canonicalAlias: roomInfo.canonicalAlias, canonicalAlias: roomInfo.canonicalAlias,
inviter: inviterProxy, inviter: inviterProxy,
+2 -1
View File
@@ -229,8 +229,9 @@ class LoggingTests: XCTestCase {
avatarURL: nil, avatarURL: nil,
lastMessage: AttributedString(lastMessage), lastMessage: AttributedString(lastMessage),
lastMessageFormattedTimestamp: "Now", lastMessageFormattedTimestamp: "Now",
unreadNotificationsCount: 0, unreadMessagesCount: 0,
unreadMentionsCount: 0, unreadMentionsCount: 0,
unreadNotificationsCount: 0,
notificationMode: nil, notificationMode: nil,
canonicalAlias: nil, canonicalAlias: nil,
inviter: nil, inviter: nil,
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:0701f80353a05af1c99196feb5480525dd9106052bb5c0b096d581344b8ba6af oid sha256:15801a4cca3898a59aaa7607710b7193323ae25df590a1857d009d97afc45955
size 427934 size 804308
+1
View File
@@ -0,0 +1 @@
Unread messages that do not trigger notifications, will show a grey dot in the room list.