From a92d626c1e13946553517c903bd176cce9558ab0 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 19 Apr 2022 16:36:40 +1000 Subject: [PATCH] fix open group notification spam in NSE --- .../NSENotificationPresenter.swift | 26 ++++++++++++++++--- .../NotificationServiceExtension.swift | 1 + 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/SessionNotificationServiceExtension/NSENotificationPresenter.swift b/SessionNotificationServiceExtension/NSENotificationPresenter.swift index 13b7727b5..c19184a5d 100644 --- a/SessionNotificationServiceExtension/NSENotificationPresenter.swift +++ b/SessionNotificationServiceExtension/NSENotificationPresenter.swift @@ -5,6 +5,8 @@ import UserNotifications public class NSENotificationPresenter: NSObject, NotificationsProtocol { + private var notifications: [String: UNNotificationRequest] = [:] + public func notifyUser(for incomingMessage: TSIncomingMessage, in thread: TSThread, transaction: YapDatabaseReadTransaction) { guard !thread.isMuted else { return } guard let threadID = thread.uniqueId else { return } @@ -36,6 +38,9 @@ public class NSENotificationPresenter: NSObject, NotificationsProtocol { return } + let identifier = incomingMessage.notificationIdentifier ?? UUID().uuidString + let isBackgroudPoll = identifier == threadID + let context = Contact.context(for: thread) let senderName = Storage.shared.getContact(with: senderPublicKey, using: transaction)?.displayName(for: context) ?? senderPublicKey @@ -50,7 +55,7 @@ public class NSENotificationPresenter: NSObject, NotificationsProtocol { if groupName.count < 1 { groupName = MessageStrings.newGroupDefaultTitle } - notificationTitle = String(format: NotificationStrings.incomingGroupMessageTitleFormat, senderName, groupName) + notificationTitle = isBackgroudPoll ? groupName : String(format: NotificationStrings.incomingGroupMessageTitleFormat, senderName, groupName) } let snippet = incomingMessage.previewText(with: transaction).filterForDisplay?.replacingMentions(for: threadID, using: transaction) @@ -91,14 +96,29 @@ public class NSENotificationPresenter: NSObject, NotificationsProtocol { } // Add request - let identifier = incomingMessage.notificationIdentifier ?? UUID().uuidString - let request = UNNotificationRequest(identifier: identifier, content: notificationContent, trigger: nil) + let trigger: UNNotificationTrigger? + if isBackgroudPoll { + trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false) + let numberOfNotifications: Int + if let lastRequest = notifications[identifier], let counter = lastRequest.content.userInfo[NotificationServiceExtension.threadNotificationCounter] as? Int { + numberOfNotifications = counter + 1 + notificationContent.body = String(format: NotificationStrings.incomingCollapsedMessagesBody, "\(numberOfNotifications)") + } else { + numberOfNotifications = 1 + } + notificationContent.userInfo[NotificationServiceExtension.threadNotificationCounter] = numberOfNotifications + } else { + trigger = nil + } + + let request = UNNotificationRequest(identifier: identifier, content: notificationContent, trigger: trigger) SNLog("Add remote notification request: \(notificationContent.body)") let semaphore = DispatchSemaphore(value: 0) UNUserNotificationCenter.current().add(request) { error in if let error = error { SNLog("Failed to add notification request due to error:\(error)") } + self.notifications[identifier] = request semaphore.signal() } semaphore.wait() diff --git a/SessionNotificationServiceExtension/NotificationServiceExtension.swift b/SessionNotificationServiceExtension/NotificationServiceExtension.swift index b492cf52f..aeec50602 100644 --- a/SessionNotificationServiceExtension/NotificationServiceExtension.swift +++ b/SessionNotificationServiceExtension/NotificationServiceExtension.swift @@ -13,6 +13,7 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension public static let isFromRemoteKey = "remote" public static let threadIdKey = "Signal.AppNotificationsUserInfoKey.threadId" + public static let threadNotificationCounter = "Session.AppNotificationsUserInfoKey.threadNotificationCounter" // MARK: Did receive a remote push notification request