diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index 2d080c6d2..44c32742c 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -154,7 +154,6 @@ final class BuildSettings: NSObject { } static let stunServerFallbackUrlString: String? = "stun:turn.matrix.org" - // MARK: - Public rooms Directory #warning("Unused build setting: should this be implemented in ShowDirectory?") static let publicRoomsAllowServerChange: Bool = true diff --git a/RiotNSE/NotificationService.swift b/RiotNSE/NotificationService.swift index 0b2ff4758..99a9bba12 100644 --- a/RiotNSE/NotificationService.swift +++ b/RiotNSE/NotificationService.swift @@ -53,6 +53,12 @@ class NotificationService: UNNotificationServiceExtension { private lazy var configuration: Configurable = { return CommonConfiguration() }() + private lazy var mxRestClient: MXRestClient? = { + guard let userAccount = userAccount else { + return nil + } + return MXRestClient(credentials: userAccount.mxCredentials, unrecognizedCertificateHandler: nil) + }() private static var isLoggerInitialized: Bool = false private lazy var pushGatewayRestClient: MXPushGatewayRestClient = { let url = URL(string: BuildSettings.serverConfigSygnalAPIUrlString)! @@ -222,7 +228,7 @@ class NotificationService: UNNotificationServiceExtension { return } - self.notificationContent(forEvent: event, forAccount: userAccount) { (notificationContent) in + self.notificationContent(forEvent: event, forAccount: userAccount) { (notificationContent, ignoreBadgeUpdate) in var isUnwantedNotification = false // Modify the notification content here... @@ -240,6 +246,10 @@ class NotificationService: UNNotificationServiceExtension { isUnwantedNotification = true } + if ignoreBadgeUpdate { + content.badge = nil + } + if self.ongoingVoIPPushRequests[event.eventId] == true { // modify the best attempt content, to be able to use in the future self.bestAttemptContents[event.eventId] = content @@ -279,10 +289,10 @@ class NotificationService: UNNotificationServiceExtension { MXLog.debug("--------------------------------------------------------------------------------") } - private func notificationContent(forEvent event: MXEvent, forAccount account: MXKAccount, onComplete: @escaping (UNNotificationContent?) -> Void) { + private func notificationContent(forEvent event: MXEvent, forAccount account: MXKAccount, onComplete: @escaping (UNNotificationContent?, Bool) -> Void) { guard let content = event.content, content.count > 0 else { MXLog.debug("[NotificationService] notificationContentForEvent: empty event content") - onComplete(nil) + onComplete(nil, false) return } @@ -298,7 +308,7 @@ class NotificationService: UNNotificationServiceExtension { var notificationTitle: String? var notificationBody: String? var additionalUserInfo: [AnyHashable: Any]? - + var ignoreBadgeUpdate = false var threadIdentifier: String? = roomId let currentUserId = account.mxCredentials.userId let roomDisplayName = roomSummary?.displayname @@ -322,7 +332,25 @@ class NotificationService: UNNotificationServiceExtension { if let callInviteContent = MXCallInviteEventContent(fromJSON: event.content), callInviteContent.lifetime > event.age, (callInviteContent.lifetime - event.age) > UInt(NSE.Constants.timeNeededToSendVoIPPushes * MSEC_PER_SEC) { + NotificationService.backgroundSyncService.roomAccountData(forRoomId: roomId) { response in + if let accountData = response.value, accountData.virtualRoomInfo.isVirtual { + self.sendReadReceipt(forEvent: event) + ignoreBadgeUpdate = true + } + self.validateNotificationContentAndComplete( + notificationTitle: notificationTitle, + notificationBody: notificationBody, + additionalUserInfo: additionalUserInfo, + ignoreBadgeUpdate: ignoreBadgeUpdate, + threadIdentifier: threadIdentifier, + currentUserId: currentUserId, + event: event, + pushRule: pushRule, + onComplete: onComplete + ) + } self.sendVoipPush(forEvent: event) + return } else { MXLog.debug("[NotificationService] notificationContent: Do not attempt to send a VoIP push, there is not enough time to process it.") } @@ -351,7 +379,7 @@ class NotificationService: UNNotificationServiceExtension { #warning("In practice, this only hides the notification's content. An empty notification may be less useful in this instance?") // Ignore this notif. MXLog.debug("[NotificationService] notificationContentForEvent: Ignore non highlighted notif in mentions only room") - onComplete(nil) + onComplete(nil, false) return } } @@ -475,35 +503,63 @@ class NotificationService: UNNotificationServiceExtension { break } - if self.localAuthenticationService.isProtectionSet { - MXLog.debug("[NotificationService] notificationContentForEvent: Resetting title and body because app protection is set") - notificationBody = NSString.localizedUserNotificationString(forKey: "MESSAGE_PROTECTED", arguments: []) - notificationTitle = nil - } - guard notificationBody != nil else { - MXLog.debug("[NotificationService] notificationContentForEvent: notificationBody is nil") - onComplete(nil) - return - } - - let notificationContent = self.notificationContent(withTitle: notificationTitle, - body: notificationBody, - threadIdentifier: threadIdentifier, - userId: currentUserId, - event: event, - pushRule: pushRule, - additionalInfo: additionalUserInfo) - - MXLog.debug("[NotificationService] notificationContentForEvent: Calling onComplete.") - onComplete(notificationContent) + self.validateNotificationContentAndComplete( + notificationTitle: notificationTitle, + notificationBody: notificationBody, + additionalUserInfo: additionalUserInfo, + ignoreBadgeUpdate: ignoreBadgeUpdate, + threadIdentifier: threadIdentifier, + currentUserId: currentUserId, + event: event, + pushRule: pushRule, + onComplete: onComplete + ) case .failure(let error): MXLog.debug("[NotificationService] notificationContentForEvent: error: \(error)") - onComplete(nil) + onComplete(nil, false) } }) } + private func validateNotificationContentAndComplete( + notificationTitle: String?, + notificationBody: String?, + additionalUserInfo: [AnyHashable: Any]?, + ignoreBadgeUpdate: Bool, + threadIdentifier: String?, + currentUserId: String?, + event: MXEvent, + pushRule: MXPushRule?, + onComplete: @escaping (UNNotificationContent?, Bool) -> Void + ) { + + var validatedNotificationBody: String? = notificationBody + var validatedNotificationTitle: String? = notificationTitle + if self.localAuthenticationService.isProtectionSet { + MXLog.debug("[NotificationService] validateNotificationContentAndComplete: Resetting title and body because app protection is set") + validatedNotificationBody = NSString.localizedUserNotificationString(forKey: "MESSAGE_PROTECTED", arguments: []) + validatedNotificationTitle = nil + } + + guard validatedNotificationBody != nil else { + MXLog.debug("[NotificationService] validateNotificationContentAndComplete: notificationBody is nil") + onComplete(nil, false) + return + } + + let notificationContent = self.notificationContent(withTitle: validatedNotificationTitle, + body: validatedNotificationBody, + threadIdentifier: threadIdentifier, + userId: currentUserId, + event: event, + pushRule: pushRule, + additionalInfo: additionalUserInfo) + + MXLog.debug("[NotificationService] validateNotificationContentAndComplete: Calling onComplete.") + onComplete(notificationContent, ignoreBadgeUpdate) + } + /// Returns the default title for message notifications. /// - Parameters: /// - eventSenderName: The displayname of the sender. @@ -710,4 +766,23 @@ class NotificationService: UNNotificationServiceExtension { } } + private func sendReadReceipt(forEvent event: MXEvent) { + guard let mxRestClient = mxRestClient else { + MXLog.error("[NotificationService] sendReadReceipt: Missing mxRestClient for read receipt request.") + return + } + guard let eventId = event.eventId, + let roomId = event.roomId else { + MXLog.error("[NotificationService] sendReadReceipt: Event information missing for read receipt request.") + return + } + + mxRestClient.sendReadReceipt(toRoom: roomId, forEvent: eventId) { response in + if response.isSuccess { + MXLog.debug("[NotificationService] sendReadReceipt: Read receipt send successfully.") + } else if let error = response.error { + MXLog.error("[NotificationService] sendReadReceipt: Read receipt send failed with error \(error).") + } + } + } } diff --git a/changelog.d/5155.bugfix b/changelog.d/5155.bugfix new file mode 100644 index 000000000..1e21bfc43 --- /dev/null +++ b/changelog.d/5155.bugfix @@ -0,0 +1 @@ +Ignore badge updates from virtual rooms.