From 92523751412db247cc9fd77be577d0b04b221dd6 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Sun, 20 Oct 2024 17:13:05 +0200 Subject: [PATCH] notify reactions while app is running --- DcCore/DcCore/DC/events.swift | 10 ++++++ .../NotificationService.swift | 2 +- .../Helper/NotificationManager.swift | 35 +++++++++++++++++-- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/DcCore/DcCore/DC/events.swift b/DcCore/DcCore/DC/events.swift index a4c5247a2..3b24fc88d 100644 --- a/DcCore/DcCore/DC/events.swift +++ b/DcCore/DcCore/DC/events.swift @@ -7,6 +7,7 @@ public enum Event { public static let messageReadDeliveredFailedReaction = Notification.Name(rawValue: "messageReadDeliveredFailedReaction") public static let incomingMessage = Notification.Name(rawValue: "incomingMessage") public static let incomingMessageOnAnyAccount = Notification.Name(rawValue: "incomingMessageOnAnyAccount") + public static let incomingReaction = Notification.Name(rawValue: "incomingReaction") public static let messagesNoticed = Notification.Name(rawValue: "messagesNoticed") // Chats @@ -140,6 +141,15 @@ public class DcEventHandler { "chat_id": Int(data1), ]) + case DC_EVENT_INCOMING_REACTION: + logger.info("📡[\(accountId)] incoming reaction") + NotificationCenter.default.post(name: Event.incomingReaction, object: nil, userInfo: [ + "account_id": Int(accountId), + "contact_id": Int(data1), + "msg_id": Int(data2), + "reaction": event.data2String + ]) + case DC_EVENT_CONTACTS_CHANGED: if accountId != dcAccounts.getSelected().id { return diff --git a/DcNotificationService/NotificationService.swift b/DcNotificationService/NotificationService.swift index 76065bf06..c153a22f8 100644 --- a/DcNotificationService/NotificationService.swift +++ b/DcNotificationService/NotificationService.swift @@ -61,7 +61,7 @@ class NotificationService: UNNotificationServiceExtension { let msg = dcContext.getMessage(id: event.data2Int) let chat = dcContext.getChat(chatId: msg.chatId) if !chat.isMuted { - let sender = msg.getSenderName(dcContext.getContact(id: event.data1Int)) + let sender = dcContext.getContact(id: event.data1Int).displayName let summary = (msg.summary(chars: 80) ?? "") bestAttemptContent.title = chat.name bestAttemptContent.body = String.localized(stringID: "reaction_by_other", parameter: sender, event.data2String, summary) diff --git a/deltachat-ios/Helper/NotificationManager.swift b/deltachat-ios/Helper/NotificationManager.swift index c76e9d68b..1f6e260c0 100644 --- a/deltachat-ios/Helper/NotificationManager.swift +++ b/deltachat-ios/Helper/NotificationManager.swift @@ -14,6 +14,7 @@ public class NotificationManager { NotificationCenter.default.addObserver(self, selector: #selector(NotificationManager.handleIncomingMessageOnAnyAccount(_:)), name: Event.incomingMessageOnAnyAccount, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(NotificationManager.handleIncomingMessage(_:)), name: Event.incomingMessage, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(NotificationManager.handleIncomingReaction(_:)), name: Event.incomingReaction, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(NotificationManager.handleMessagesNoticed(_:)), name: Event.messagesNoticed, object: nil) } @@ -86,8 +87,6 @@ public class NotificationManager { } @objc private func handleIncomingMessage(_ notification: Notification) { - // TODO: handle DC_EVENT_INCOMING_REACTION - // make sure to balance each call to `beginBackgroundTask` with `endBackgroundTask` let backgroundTask = UIApplication.shared.beginBackgroundTask { // we cannot easily stop the task, @@ -127,4 +126,36 @@ public class NotificationManager { UIApplication.shared.endBackgroundTask(backgroundTask) } } + + @objc private func handleIncomingReaction(_ notification: Notification) { + let backgroundTask = UIApplication.shared.beginBackgroundTask { + logger.info("incoming-reaction-task will end soon") + } + + DispatchQueue.global().async { [weak self] in + guard let self, let ui = notification.userInfo else { return } + let eventContext = dcAccounts.get(id: ui["account_id"] as? Int ?? 0) + if !eventContext.isMuted() { + let msg = eventContext.getMessage(id: ui["msg_id"] as? Int ?? 0) + let chat = eventContext.getChat(chatId: msg.chatId) + if !chat.isMuted { + let contact = eventContext.getContact(id: ui["contact_id"] as? Int ?? 0) + let summary = (msg.summary(chars: 80) ?? "") + let reaction = ui["reaction"] as? String ?? "" + + let content = UNMutableNotificationContent() + content.title = chat.name + content.body = String.localized(stringID: "reaction_by_other", parameter: contact.displayName, reaction, summary) + content.userInfo["account_id"] = eventContext.id + content.userInfo["chat_id"] = chat.id + content.userInfo["message_id"] = msg.id + + let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil) + UNUserNotificationCenter.current().add(request, withCompletionHandler: nil) + } + } + + UIApplication.shared.endBackgroundTask(backgroundTask) // this line mist be reached to balance call to `beginBackgroundTask` above + } + } }