mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
Remove delivered notifications if their event gets redacted. (#3191)
This commit is contained in:
parent
a1cb6bd376
commit
d54e08e815
@ -44,6 +44,10 @@ extension UNNotificationContent {
|
|||||||
@objc var roomID: String? {
|
@objc var roomID: String? {
|
||||||
userInfo[NotificationConstants.UserInfoKey.roomIdentifier] as? String
|
userInfo[NotificationConstants.UserInfoKey.roomIdentifier] as? String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc var eventID: String? {
|
||||||
|
userInfo[NotificationConstants.UserInfoKey.eventIdentifier] as? String
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension UNMutableNotificationContent {
|
extension UNMutableNotificationContent {
|
||||||
@ -65,6 +69,15 @@ extension UNMutableNotificationContent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override var eventID: String? {
|
||||||
|
get {
|
||||||
|
userInfo[NotificationConstants.UserInfoKey.eventIdentifier] as? String
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
userInfo[NotificationConstants.UserInfoKey.eventIdentifier] = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func addMediaAttachment(using mediaProvider: MediaProviderProtocol?,
|
func addMediaAttachment(using mediaProvider: MediaProviderProtocol?,
|
||||||
mediaSource: MediaSourceProxy) async -> UNMutableNotificationContent {
|
mediaSource: MediaSourceProxy) async -> UNMutableNotificationContent {
|
||||||
guard let mediaProvider else {
|
guard let mediaProvider else {
|
||||||
|
@ -63,6 +63,10 @@ struct NotificationContentBuilder {
|
|||||||
let notification = UNMutableNotificationContent()
|
let notification = UNMutableNotificationContent()
|
||||||
notification.receiverID = notificationItem.receiverID
|
notification.receiverID = notificationItem.receiverID
|
||||||
notification.roomID = notificationItem.roomID
|
notification.roomID = notificationItem.roomID
|
||||||
|
notification.eventID = switch notificationItem.event {
|
||||||
|
case .timeline(let event): event.eventId()
|
||||||
|
case .invite, .none: nil
|
||||||
|
}
|
||||||
notification.sound = notificationItem.isNoisy ? UNNotificationSound(named: UNNotificationSoundName(rawValue: "message.caf")) : nil
|
notification.sound = notificationItem.isNoisy ? UNNotificationSound(named: UNNotificationSoundName(rawValue: "message.caf")) : nil
|
||||||
// So that the UI groups notification that are received for the same room but also for the same user
|
// So that the UI groups notification that are received for the same room but also for the same user
|
||||||
// Removing the @ fixes an iOS bug where the notification crashes if the mute button is tapped
|
// Removing the @ fixes an iOS bug where the notification crashes if the mute button is tapped
|
||||||
|
@ -59,8 +59,8 @@ class NotificationServiceExtension: UNNotificationServiceExtension {
|
|||||||
override func didReceive(_ request: UNNotificationRequest,
|
override func didReceive(_ request: UNNotificationRequest,
|
||||||
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
|
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
|
||||||
guard !DataProtectionManager.isDeviceLockedAfterReboot(containerURL: URL.appGroupContainerDirectory),
|
guard !DataProtectionManager.isDeviceLockedAfterReboot(containerURL: URL.appGroupContainerDirectory),
|
||||||
let roomId = request.roomId,
|
let roomID = request.roomID,
|
||||||
let eventId = request.eventId,
|
let eventID = request.eventID,
|
||||||
let clientID = request.pusherNotificationClientIdentifier,
|
let clientID = request.pusherNotificationClientIdentifier,
|
||||||
let credentials = keychainController.restorationTokens().first(where: { $0.restorationToken.pusherNotificationClientIdentifier == clientID }) else {
|
let credentials = keychainController.restorationTokens().first(where: { $0.restorationToken.pusherNotificationClientIdentifier == clientID }) else {
|
||||||
// We cannot process this notification, it might be due to one of these:
|
// We cannot process this notification, it might be due to one of these:
|
||||||
@ -103,8 +103,8 @@ class NotificationServiceExtension: UNNotificationServiceExtension {
|
|||||||
|
|
||||||
Task {
|
Task {
|
||||||
await run(with: credentials,
|
await run(with: credentials,
|
||||||
roomId: roomId,
|
roomID: roomID,
|
||||||
eventId: eventId,
|
eventID: eventID,
|
||||||
unreadCount: request.unreadCount)
|
unreadCount: request.unreadCount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,10 +117,10 @@ class NotificationServiceExtension: UNNotificationServiceExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func run(with credentials: KeychainCredentials,
|
private func run(with credentials: KeychainCredentials,
|
||||||
roomId: String,
|
roomID: String,
|
||||||
eventId: String,
|
eventID: String,
|
||||||
unreadCount: Int?) async {
|
unreadCount: Int?) async {
|
||||||
MXLog.info("\(tag) run with roomId: \(roomId), eventId: \(eventId)")
|
MXLog.info("\(tag) run with roomId: \(roomID), eventId: \(eventID)")
|
||||||
|
|
||||||
guard let userSession = Self.userSession else {
|
guard let userSession = Self.userSession else {
|
||||||
MXLog.error("Invalid NSE User Session, discarding.")
|
MXLog.error("Invalid NSE User Session, discarding.")
|
||||||
@ -128,7 +128,7 @@ class NotificationServiceExtension: UNNotificationServiceExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
guard let itemProxy = await userSession.notificationItemProxy(roomID: roomId, eventID: eventId) else {
|
guard let itemProxy = await userSession.notificationItemProxy(roomID: roomID, eventID: eventID) else {
|
||||||
MXLog.info("\(tag) no notification for the event, discard")
|
MXLog.info("\(tag) no notification for the event, discard")
|
||||||
return discard(unreadCount: unreadCount)
|
return discard(unreadCount: unreadCount)
|
||||||
}
|
}
|
||||||
@ -137,6 +137,10 @@ class NotificationServiceExtension: UNNotificationServiceExtension {
|
|||||||
return discard(unreadCount: unreadCount)
|
return discard(unreadCount: unreadCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if await handleRedactionNotification(itemProxy) {
|
||||||
|
return discard(unreadCount: unreadCount)
|
||||||
|
}
|
||||||
|
|
||||||
// After the first processing, update the modified content
|
// After the first processing, update the modified content
|
||||||
modifiedContent = try await notificationContentBuilder.content(for: itemProxy, mediaProvider: nil)
|
modifiedContent = try await notificationContentBuilder.content(for: itemProxy, mediaProvider: nil)
|
||||||
|
|
||||||
@ -246,6 +250,29 @@ class NotificationServiceExtension: UNNotificationServiceExtension {
|
|||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handles a notification for an `m.room.redaction` event.
|
||||||
|
/// - Returns: A boolean indicating whether the notification was handled.
|
||||||
|
private func handleRedactionNotification(_ itemProxy: NotificationItemProxyProtocol) async -> Bool {
|
||||||
|
guard case let .timeline(event) = itemProxy.event,
|
||||||
|
case let .messageLike(content) = try? event.eventType(),
|
||||||
|
case let .roomRedaction(redactedEventID, _) = content else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let redactedEventID else {
|
||||||
|
MXLog.error("Unable to redact notification due to missing event ID.")
|
||||||
|
return true // Return true as there's no point showing this notification.
|
||||||
|
}
|
||||||
|
|
||||||
|
let deliveredNotifications = await UNUserNotificationCenter.current().deliveredNotifications()
|
||||||
|
|
||||||
|
if let targetNotification = deliveredNotifications.first(where: { $0.request.content.eventID == redactedEventID }) {
|
||||||
|
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [targetNotification.request.identifier])
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/a/77300959/730924
|
// https://stackoverflow.com/a/77300959/730924
|
||||||
|
@ -18,11 +18,11 @@ import Foundation
|
|||||||
import UserNotifications
|
import UserNotifications
|
||||||
|
|
||||||
extension UNNotificationRequest {
|
extension UNNotificationRequest {
|
||||||
var roomId: String? {
|
var roomID: String? {
|
||||||
content.userInfo[NotificationConstants.UserInfoKey.roomIdentifier] as? String
|
content.userInfo[NotificationConstants.UserInfoKey.roomIdentifier] as? String
|
||||||
}
|
}
|
||||||
|
|
||||||
var eventId: String? {
|
var eventID: String? {
|
||||||
content.userInfo[NotificationConstants.UserInfoKey.eventIdentifier] as? String
|
content.userInfo[NotificationConstants.UserInfoKey.eventIdentifier] as? String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user