mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Remove delivered notifications for rooms that have meantime become fully read and have messages newer than what's delivered
- this is a best effort solution to cleanup outdated notifications when using multiple clients and reading them elsewhere
This commit is contained in:
committed by
Stefan Ceriu
parent
e14672e1f6
commit
899c33a5ad
@@ -387,36 +387,19 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
userSession.clientProxy.actionsPublisher
|
userSession.clientProxy.actionsPublisher
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
.sink { [weak self] action in
|
.sink { [weak self] action in
|
||||||
guard let self, case let .receivedDecryptionError(info) = action else {
|
guard let self else { return }
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let timeToDecryptMs: Int
|
switch action {
|
||||||
if let unsignedTimeToDecryptMs = info.timeToDecryptMs {
|
case .receivedDecryptionError(let info):
|
||||||
timeToDecryptMs = Int(unsignedTimeToDecryptMs)
|
processDecryptionError(info)
|
||||||
} else {
|
case .receivedSyncUpdate:
|
||||||
timeToDecryptMs = -1
|
Task {
|
||||||
|
let roomSummaries = self.userSession.clientProxy.staticRoomSummaryProvider.roomListPublisher.value
|
||||||
|
await self.notificationManager.removeDeliveredNotificationsForFullyReadRooms(roomSummaries)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
let errorName: AnalyticsEvent.Error.Name = switch info.cause {
|
|
||||||
case .unknown: .OlmKeysNotSentError
|
|
||||||
case .unknownDevice, .unsignedDevice: .ExpectedSentByInsecureDevice
|
|
||||||
case .verificationViolation: .ExpectedVerificationViolation
|
|
||||||
case .sentBeforeWeJoined: .ExpectedDueToMembership
|
|
||||||
case .historicalMessageAndBackupIsDisabled, .historicalMessageAndDeviceIsUnverified: .HistoricalMessage
|
|
||||||
case .withheldForUnverifiedOrInsecureDevice: .RoomKeysWithheldForUnverifiedDevice
|
|
||||||
case .withheldBySender: .OlmKeysNotSentError
|
|
||||||
}
|
|
||||||
|
|
||||||
analytics.trackError(context: nil,
|
|
||||||
domain: .E2EE,
|
|
||||||
name: errorName,
|
|
||||||
timeToDecryptMillis: timeToDecryptMs,
|
|
||||||
eventLocalAgeMillis: Int(truncatingIfNeeded: info.eventLocalAgeMillis),
|
|
||||||
isFederated: info.ownHomeserver != info.senderHomeserver,
|
|
||||||
isMatrixDotOrg: info.ownHomeserver == "matrix.org",
|
|
||||||
userTrustsOwnIdentity: info.userTrustsOwnIdentity,
|
|
||||||
wasVisibleToUser: nil)
|
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
@@ -444,6 +427,35 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func processDecryptionError(_ info: UnableToDecryptInfo) {
|
||||||
|
let timeToDecryptMs: Int
|
||||||
|
if let unsignedTimeToDecryptMs = info.timeToDecryptMs {
|
||||||
|
timeToDecryptMs = Int(unsignedTimeToDecryptMs)
|
||||||
|
} else {
|
||||||
|
timeToDecryptMs = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
let errorName: AnalyticsEvent.Error.Name = switch info.cause {
|
||||||
|
case .unknown: .OlmKeysNotSentError
|
||||||
|
case .unknownDevice, .unsignedDevice: .ExpectedSentByInsecureDevice
|
||||||
|
case .verificationViolation: .ExpectedVerificationViolation
|
||||||
|
case .sentBeforeWeJoined: .ExpectedDueToMembership
|
||||||
|
case .historicalMessageAndBackupIsDisabled, .historicalMessageAndDeviceIsUnverified: .HistoricalMessage
|
||||||
|
case .withheldForUnverifiedOrInsecureDevice: .RoomKeysWithheldForUnverifiedDevice
|
||||||
|
case .withheldBySender: .OlmKeysNotSentError
|
||||||
|
}
|
||||||
|
|
||||||
|
analytics.trackError(context: nil,
|
||||||
|
domain: .E2EE,
|
||||||
|
name: errorName,
|
||||||
|
timeToDecryptMillis: timeToDecryptMs,
|
||||||
|
eventLocalAgeMillis: Int(truncatingIfNeeded: info.eventLocalAgeMillis),
|
||||||
|
isFederated: info.ownHomeserver != info.senderHomeserver,
|
||||||
|
isMatrixDotOrg: info.ownHomeserver == "matrix.org",
|
||||||
|
userTrustsOwnIdentity: info.userTrustsOwnIdentity,
|
||||||
|
wasVisibleToUser: nil)
|
||||||
|
}
|
||||||
|
|
||||||
private func setupSessionVerificationRequestsObserver() {
|
private func setupSessionVerificationRequestsObserver() {
|
||||||
userSession.clientProxy.sessionVerificationController?.actions
|
userSession.clientProxy.sessionVerificationController?.actions
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
|
|||||||
@@ -12026,6 +12026,47 @@ class NotificationManagerMock: NotificationManagerProtocol, @unchecked Sendable
|
|||||||
}
|
}
|
||||||
await removeDeliveredMessageNotificationsForClosure?(roomID)
|
await removeDeliveredMessageNotificationsForClosure?(roomID)
|
||||||
}
|
}
|
||||||
|
//MARK: - removeDeliveredNotificationsForFullyReadRooms
|
||||||
|
|
||||||
|
var removeDeliveredNotificationsForFullyReadRoomsUnderlyingCallsCount = 0
|
||||||
|
var removeDeliveredNotificationsForFullyReadRoomsCallsCount: Int {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return removeDeliveredNotificationsForFullyReadRoomsUnderlyingCallsCount
|
||||||
|
} else {
|
||||||
|
var returnValue: Int? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = removeDeliveredNotificationsForFullyReadRoomsUnderlyingCallsCount
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
removeDeliveredNotificationsForFullyReadRoomsUnderlyingCallsCount = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
removeDeliveredNotificationsForFullyReadRoomsUnderlyingCallsCount = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var removeDeliveredNotificationsForFullyReadRoomsCalled: Bool {
|
||||||
|
return removeDeliveredNotificationsForFullyReadRoomsCallsCount > 0
|
||||||
|
}
|
||||||
|
var removeDeliveredNotificationsForFullyReadRoomsReceivedRooms: [RoomSummary]?
|
||||||
|
var removeDeliveredNotificationsForFullyReadRoomsReceivedInvocations: [[RoomSummary]] = []
|
||||||
|
var removeDeliveredNotificationsForFullyReadRoomsClosure: (([RoomSummary]) async -> Void)?
|
||||||
|
|
||||||
|
func removeDeliveredNotificationsForFullyReadRooms(_ rooms: [RoomSummary]) async {
|
||||||
|
removeDeliveredNotificationsForFullyReadRoomsCallsCount += 1
|
||||||
|
removeDeliveredNotificationsForFullyReadRoomsReceivedRooms = rooms
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.removeDeliveredNotificationsForFullyReadRoomsReceivedInvocations.append(rooms)
|
||||||
|
}
|
||||||
|
await removeDeliveredNotificationsForFullyReadRoomsClosure?(rooms)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
class NotificationSettingsProxyMock: NotificationSettingsProxyProtocol, @unchecked Sendable {
|
class NotificationSettingsProxyMock: NotificationSettingsProxyProtocol, @unchecked Sendable {
|
||||||
var callbacks: PassthroughSubject<NotificationSettingsProxyCallback, Never> {
|
var callbacks: PassthroughSubject<NotificationSettingsProxyCallback, Never> {
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ extension RoomSummary {
|
|||||||
avatarURL: nil,
|
avatarURL: nil,
|
||||||
heroes: [],
|
heroes: [],
|
||||||
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"),
|
||||||
|
lastMessageDate: nil,
|
||||||
lastMessageFormattedTimestamp: "14:56",
|
lastMessageFormattedTimestamp: "14:56",
|
||||||
unreadMessagesCount: 0,
|
unreadMessagesCount: 0,
|
||||||
unreadMentionsCount: 0,
|
unreadMentionsCount: 0,
|
||||||
@@ -102,6 +103,7 @@ extension Array where Element == RoomSummary {
|
|||||||
avatarURL: nil,
|
avatarURL: nil,
|
||||||
heroes: [],
|
heroes: [],
|
||||||
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"),
|
||||||
|
lastMessageDate: nil,
|
||||||
lastMessageFormattedTimestamp: "14:56",
|
lastMessageFormattedTimestamp: "14:56",
|
||||||
unreadMessagesCount: 0,
|
unreadMessagesCount: 0,
|
||||||
unreadMentionsCount: 0,
|
unreadMentionsCount: 0,
|
||||||
@@ -120,6 +122,7 @@ extension Array where Element == RoomSummary {
|
|||||||
avatarURL: .mockMXCAvatar,
|
avatarURL: .mockMXCAvatar,
|
||||||
heroes: [],
|
heroes: [],
|
||||||
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?"),
|
||||||
|
lastMessageDate: nil,
|
||||||
lastMessageFormattedTimestamp: "2:56 PM",
|
lastMessageFormattedTimestamp: "2:56 PM",
|
||||||
unreadMessagesCount: 2,
|
unreadMessagesCount: 2,
|
||||||
unreadMentionsCount: 0,
|
unreadMentionsCount: 0,
|
||||||
@@ -138,6 +141,7 @@ extension Array where Element == RoomSummary {
|
|||||||
avatarURL: nil,
|
avatarURL: nil,
|
||||||
heroes: [],
|
heroes: [],
|
||||||
lastMessage: try? AttributedString(markdown: "He certainly seemed no *mental genius* to me"),
|
lastMessage: try? AttributedString(markdown: "He certainly seemed no *mental genius* to me"),
|
||||||
|
lastMessageDate: nil,
|
||||||
lastMessageFormattedTimestamp: "Some time ago",
|
lastMessageFormattedTimestamp: "Some time ago",
|
||||||
unreadMessagesCount: 3,
|
unreadMessagesCount: 3,
|
||||||
unreadMentionsCount: 0,
|
unreadMentionsCount: 0,
|
||||||
@@ -156,6 +160,7 @@ extension Array where Element == RoomSummary {
|
|||||||
avatarURL: nil,
|
avatarURL: nil,
|
||||||
heroes: [],
|
heroes: [],
|
||||||
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"),
|
||||||
|
lastMessageDate: nil,
|
||||||
lastMessageFormattedTimestamp: "Just now",
|
lastMessageFormattedTimestamp: "Just now",
|
||||||
unreadMessagesCount: 2,
|
unreadMessagesCount: 2,
|
||||||
unreadMentionsCount: 2,
|
unreadMentionsCount: 2,
|
||||||
@@ -174,6 +179,7 @@ extension Array where Element == RoomSummary {
|
|||||||
avatarURL: nil,
|
avatarURL: nil,
|
||||||
heroes: [],
|
heroes: [],
|
||||||
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"),
|
||||||
|
lastMessageDate: nil,
|
||||||
lastMessageFormattedTimestamp: "1986",
|
lastMessageFormattedTimestamp: "1986",
|
||||||
unreadMessagesCount: 1,
|
unreadMessagesCount: 1,
|
||||||
unreadMentionsCount: 1,
|
unreadMentionsCount: 1,
|
||||||
@@ -192,6 +198,7 @@ extension Array where Element == RoomSummary {
|
|||||||
avatarURL: nil,
|
avatarURL: nil,
|
||||||
heroes: [],
|
heroes: [],
|
||||||
lastMessage: AttributedString("Are you groping for the word 'paranoia'?"),
|
lastMessage: AttributedString("Are you groping for the word 'paranoia'?"),
|
||||||
|
lastMessageDate: nil,
|
||||||
lastMessageFormattedTimestamp: "きょうはじゅういちがつじゅういちにちです",
|
lastMessageFormattedTimestamp: "きょうはじゅういちがつじゅういちにちです",
|
||||||
unreadMessagesCount: 6,
|
unreadMessagesCount: 6,
|
||||||
unreadMentionsCount: 0,
|
unreadMentionsCount: 0,
|
||||||
@@ -210,6 +217,7 @@ extension Array where Element == RoomSummary {
|
|||||||
avatarURL: nil,
|
avatarURL: nil,
|
||||||
heroes: [],
|
heroes: [],
|
||||||
lastMessage: nil,
|
lastMessage: nil,
|
||||||
|
lastMessageDate: nil,
|
||||||
lastMessageFormattedTimestamp: nil,
|
lastMessageFormattedTimestamp: nil,
|
||||||
unreadMessagesCount: 0,
|
unreadMessagesCount: 0,
|
||||||
unreadMentionsCount: 0,
|
unreadMentionsCount: 0,
|
||||||
@@ -261,6 +269,7 @@ extension Array where Element == RoomSummary {
|
|||||||
avatarURL: .mockMXCAvatar,
|
avatarURL: .mockMXCAvatar,
|
||||||
heroes: [],
|
heroes: [],
|
||||||
lastMessage: nil,
|
lastMessage: nil,
|
||||||
|
lastMessageDate: nil,
|
||||||
lastMessageFormattedTimestamp: nil,
|
lastMessageFormattedTimestamp: nil,
|
||||||
unreadMessagesCount: 0,
|
unreadMessagesCount: 0,
|
||||||
unreadMentionsCount: 0,
|
unreadMentionsCount: 0,
|
||||||
@@ -279,6 +288,7 @@ extension Array where Element == RoomSummary {
|
|||||||
avatarURL: nil,
|
avatarURL: nil,
|
||||||
heroes: [],
|
heroes: [],
|
||||||
lastMessage: nil,
|
lastMessage: nil,
|
||||||
|
lastMessageDate: nil,
|
||||||
lastMessageFormattedTimestamp: nil,
|
lastMessageFormattedTimestamp: nil,
|
||||||
unreadMessagesCount: 0,
|
unreadMessagesCount: 0,
|
||||||
unreadMentionsCount: 0,
|
unreadMentionsCount: 0,
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ private extension HomeScreenRoom {
|
|||||||
avatarURL: nil,
|
avatarURL: nil,
|
||||||
heroes: [.init(userID: "@someone:somewhere.com")],
|
heroes: [.init(userID: "@someone:somewhere.com")],
|
||||||
lastMessage: nil,
|
lastMessage: nil,
|
||||||
|
lastMessageDate: nil,
|
||||||
lastMessageFormattedTimestamp: nil,
|
lastMessageFormattedTimestamp: nil,
|
||||||
unreadMessagesCount: 0,
|
unreadMessagesCount: 0,
|
||||||
unreadMentionsCount: 0,
|
unreadMentionsCount: 0,
|
||||||
@@ -235,6 +236,7 @@ private extension HomeScreenRoom {
|
|||||||
avatarURL: avatarURL,
|
avatarURL: avatarURL,
|
||||||
heroes: [.init(userID: "@someone:somewhere.com")],
|
heroes: [.init(userID: "@someone:somewhere.com")],
|
||||||
lastMessage: nil,
|
lastMessage: nil,
|
||||||
|
lastMessageDate: nil,
|
||||||
lastMessageFormattedTimestamp: nil,
|
lastMessageFormattedTimestamp: nil,
|
||||||
unreadMessagesCount: 0,
|
unreadMessagesCount: 0,
|
||||||
unreadMentionsCount: 0,
|
unreadMentionsCount: 0,
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ private extension HomeScreenRoom {
|
|||||||
avatarURL: nil,
|
avatarURL: nil,
|
||||||
heroes: [.init(userID: "@someone:somewhere.com")],
|
heroes: [.init(userID: "@someone:somewhere.com")],
|
||||||
lastMessage: nil,
|
lastMessage: nil,
|
||||||
|
lastMessageDate: nil,
|
||||||
lastMessageFormattedTimestamp: nil,
|
lastMessageFormattedTimestamp: nil,
|
||||||
unreadMessagesCount: 0,
|
unreadMessagesCount: 0,
|
||||||
unreadMentionsCount: 0,
|
unreadMentionsCount: 0,
|
||||||
@@ -180,6 +181,7 @@ private extension HomeScreenRoom {
|
|||||||
avatarURL: avatarURL,
|
avatarURL: avatarURL,
|
||||||
heroes: [.init(userID: "@someone:somewhere.com")],
|
heroes: [.init(userID: "@someone:somewhere.com")],
|
||||||
lastMessage: nil,
|
lastMessage: nil,
|
||||||
|
lastMessageDate: nil,
|
||||||
lastMessageFormattedTimestamp: nil,
|
lastMessageFormattedTimestamp: nil,
|
||||||
unreadMessagesCount: 0,
|
unreadMessagesCount: 0,
|
||||||
unreadMentionsCount: 0,
|
unreadMentionsCount: 0,
|
||||||
|
|||||||
@@ -129,6 +129,28 @@ final class NotificationManager: NSObject, NotificationManagerProtocol {
|
|||||||
notificationCenter.removeDeliveredNotifications(withIdentifiers: notificationsIdentifiers)
|
notificationCenter.removeDeliveredNotifications(withIdentifiers: notificationsIdentifiers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func removeDeliveredNotificationsForFullyReadRooms(_ rooms: [RoomSummary]) async {
|
||||||
|
let roomsToLastMessageDates = rooms
|
||||||
|
.filter { $0.hasUnreadMessages == false }
|
||||||
|
.reduce(into: [:]) { partialResult, roomSummary in
|
||||||
|
partialResult[roomSummary.id] = roomSummary.lastMessageDate
|
||||||
|
}
|
||||||
|
|
||||||
|
let notificationsIdentifiers = await notificationCenter
|
||||||
|
.deliveredNotifications()
|
||||||
|
.filter { notification in
|
||||||
|
guard let roomID = notification.request.content.roomID,
|
||||||
|
let lastMessageDate = roomsToLastMessageDates[roomID] else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return notification.date <= lastMessageDate
|
||||||
|
}
|
||||||
|
.map(\.request.identifier)
|
||||||
|
|
||||||
|
notificationCenter.removeDeliveredNotifications(withIdentifiers: notificationsIdentifiers)
|
||||||
|
}
|
||||||
|
|
||||||
private func setPusher(with deviceToken: Data, clientProxy: ClientProxyProtocol) async -> Bool {
|
private func setPusher(with deviceToken: Data, clientProxy: ClientProxyProtocol) async -> Bool {
|
||||||
do {
|
do {
|
||||||
let defaultPayload = APNSPayload(aps: APSInfo(mutableContent: 1,
|
let defaultPayload = APNSPayload(aps: APSInfo(mutableContent: 1,
|
||||||
|
|||||||
@@ -33,4 +33,6 @@ protocol NotificationManagerProtocol: AnyObject {
|
|||||||
func requestAuthorization()
|
func requestAuthorization()
|
||||||
|
|
||||||
func removeDeliveredMessageNotifications(for roomID: String) async
|
func removeDeliveredMessageNotifications(for roomID: String) async
|
||||||
|
|
||||||
|
func removeDeliveredNotificationsForFullyReadRooms(_ rooms: [RoomSummary]) async
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ struct RoomSummary {
|
|||||||
let avatarURL: URL?
|
let avatarURL: URL?
|
||||||
let heroes: [UserProfileProxy]
|
let heroes: [UserProfileProxy]
|
||||||
let lastMessage: AttributedString?
|
let lastMessage: AttributedString?
|
||||||
|
let lastMessageDate: Date?
|
||||||
let lastMessageFormattedTimestamp: String?
|
let lastMessageFormattedTimestamp: String?
|
||||||
let unreadMessagesCount: UInt
|
let unreadMessagesCount: UInt
|
||||||
let unreadMentionsCount: UInt
|
let unreadMentionsCount: UInt
|
||||||
@@ -95,6 +96,7 @@ extension RoomSummary {
|
|||||||
avatarURL = nil
|
avatarURL = nil
|
||||||
heroes = []
|
heroes = []
|
||||||
lastMessage = AttributedString(string)
|
lastMessage = AttributedString(string)
|
||||||
|
lastMessageDate = .now
|
||||||
lastMessageFormattedTimestamp = "Now"
|
lastMessageFormattedTimestamp = "Now"
|
||||||
unreadMessagesCount = hasUnreadMessages ? 1 : 0
|
unreadMessagesCount = hasUnreadMessages ? 1 : 0
|
||||||
unreadMentionsCount = hasUnreadMentions ? 1 : 0
|
unreadMentionsCount = hasUnreadMentions ? 1 : 0
|
||||||
|
|||||||
@@ -242,10 +242,12 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var attributedLastMessage: AttributedString?
|
var attributedLastMessage: AttributedString?
|
||||||
|
var lastMessageDate: Date?
|
||||||
var lastMessageFormattedTimestamp: String?
|
var lastMessageFormattedTimestamp: String?
|
||||||
|
|
||||||
if let latestRoomMessage = roomDetails.latestEvent {
|
if let latestRoomMessage = roomDetails.latestEvent {
|
||||||
let lastMessage = EventTimelineItemProxy(item: latestRoomMessage, uniqueID: .init("0"))
|
let lastMessage = EventTimelineItemProxy(item: latestRoomMessage, uniqueID: .init("0"))
|
||||||
|
lastMessageDate = lastMessage.timestamp
|
||||||
lastMessageFormattedTimestamp = lastMessage.timestamp.formattedMinimal()
|
lastMessageFormattedTimestamp = lastMessage.timestamp.formattedMinimal()
|
||||||
attributedLastMessage = eventStringBuilder.buildAttributedString(for: lastMessage)
|
attributedLastMessage = eventStringBuilder.buildAttributedString(for: lastMessage)
|
||||||
}
|
}
|
||||||
@@ -271,6 +273,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
|||||||
avatarURL: roomInfo.avatarUrl.flatMap(URL.init(string:)),
|
avatarURL: roomInfo.avatarUrl.flatMap(URL.init(string:)),
|
||||||
heroes: roomInfo.heroes.map(UserProfileProxy.init),
|
heroes: roomInfo.heroes.map(UserProfileProxy.init),
|
||||||
lastMessage: attributedLastMessage,
|
lastMessage: attributedLastMessage,
|
||||||
|
lastMessageDate: lastMessageDate,
|
||||||
lastMessageFormattedTimestamp: lastMessageFormattedTimestamp,
|
lastMessageFormattedTimestamp: lastMessageFormattedTimestamp,
|
||||||
unreadMessagesCount: UInt(roomInfo.numUnreadMessages),
|
unreadMessagesCount: UInt(roomInfo.numUnreadMessages),
|
||||||
unreadMentionsCount: UInt(roomInfo.numUnreadMentions),
|
unreadMentionsCount: UInt(roomInfo.numUnreadMentions),
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class HomeScreenRoomTests: XCTestCase {
|
|||||||
avatarURL: nil,
|
avatarURL: nil,
|
||||||
heroes: [],
|
heroes: [],
|
||||||
lastMessage: nil,
|
lastMessage: nil,
|
||||||
|
lastMessageDate: nil,
|
||||||
lastMessageFormattedTimestamp: nil,
|
lastMessageFormattedTimestamp: nil,
|
||||||
unreadMessagesCount: unreadMessagesCount,
|
unreadMessagesCount: unreadMessagesCount,
|
||||||
unreadMentionsCount: unreadMentionsCount,
|
unreadMentionsCount: unreadMentionsCount,
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ class LoggingTests: XCTestCase {
|
|||||||
avatarURL: nil,
|
avatarURL: nil,
|
||||||
heroes: [.init(userID: "", displayName: heroName)],
|
heroes: [.init(userID: "", displayName: heroName)],
|
||||||
lastMessage: AttributedString(lastMessage),
|
lastMessage: AttributedString(lastMessage),
|
||||||
|
lastMessageDate: nil,
|
||||||
lastMessageFormattedTimestamp: "Now",
|
lastMessageFormattedTimestamp: "Now",
|
||||||
unreadMessagesCount: 0,
|
unreadMessagesCount: 0,
|
||||||
unreadMentionsCount: 0,
|
unreadMentionsCount: 0,
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ class RoomSummaryTests: XCTestCase {
|
|||||||
avatarURL: hasRoomAvatar ? roomDetails.avatarURL : nil,
|
avatarURL: hasRoomAvatar ? roomDetails.avatarURL : nil,
|
||||||
heroes: heroes,
|
heroes: heroes,
|
||||||
lastMessage: nil,
|
lastMessage: nil,
|
||||||
|
lastMessageDate: nil,
|
||||||
lastMessageFormattedTimestamp: nil,
|
lastMessageFormattedTimestamp: nil,
|
||||||
unreadMessagesCount: 0,
|
unreadMessagesCount: 0,
|
||||||
unreadMentionsCount: 0,
|
unreadMentionsCount: 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user