Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

notify reactions #2331

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions DcCore/DcCore/DC/events.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
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
Expand Down Expand Up @@ -140,6 +141,15 @@
"chat_id": Int(data1),
])

case DC_EVENT_INCOMING_REACTION:

Check failure on line 144 in DcCore/DcCore/DC/events.swift

View workflow job for this annotation

GitHub Actions / build

cannot find 'DC_EVENT_INCOMING_REACTION' in scope
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
Expand Down
36 changes: 31 additions & 5 deletions DcNotificationService/NotificationService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class NotificationService: UNNotificationServiceExtension {
UserDefaults.setNseFetching(false)

var messageCount = 0
var reactionCount = 0
var uniqueChats: [String: String] = [:]
while true {
guard let event = eventEmitter.getNextEvent() else { break }
Expand All @@ -55,24 +56,49 @@ class NotificationService: UNNotificationServiceExtension {
uniqueChats["\(dcContext.id)-\(chat.id)"] = bestAttemptContent.title
messageCount += 1
}
} else if event.id == DC_EVENT_INCOMING_REACTION {
let dcContext = dcAccounts.get(id: event.accountId)
if !dcContext.isMuted() {
let msg = dcContext.getMessage(id: event.data2Int)
let chat = dcContext.getChat(chatId: msg.chatId)
if !chat.isMuted {
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)
bestAttemptContent.userInfo["account_id"] = dcContext.id
bestAttemptContent.userInfo["chat_id"] = chat.id
bestAttemptContent.userInfo["message_id"] = msg.id

uniqueChats["\(dcContext.id)-\(chat.id)"] = bestAttemptContent.title
reactionCount += 1
}
}
}
}

if messageCount == 0 {
if (messageCount + reactionCount) == 0 {
dcAccounts.closeDatabase()
UserDefaults.pushToDebugArray(String(format: "OK0 %.3fs", Double(Date().timeIntervalSince1970) - nowTimestamp))
contentHandler(silenceNotification())
} else {
bestAttemptContent.badge = dcAccounts.getFreshMessageCount() as NSNumber
dcAccounts.closeDatabase()
if messageCount > 1 {
if (messageCount + reactionCount) > 1 {
bestAttemptContent.userInfo["message_id"] = nil
if uniqueChats.count == 1 {

if messageCount > 0 && reactionCount > 0 {
bestAttemptContent.body = String.localized(stringID: "n_messages", parameter: messageCount)
+ ", " + String.localized(stringID: "n_reactions", parameter: reactionCount)
} else if messageCount > 0 {
bestAttemptContent.body = String.localized(stringID: "n_messages", parameter: messageCount)
} else {
bestAttemptContent.userInfo["open_as_overview"] = true // leaving chat_id as is removes the notification when one of the chats is opened (does not matter which)
bestAttemptContent.body = String.localized(stringID: "n_reactions", parameter: reactionCount)
}

if uniqueChats.count > 1 {
bestAttemptContent.userInfo["open_as_overview"] = true // leaving chat_id removes the notification when one of the chats is opened
bestAttemptContent.title = uniqueChats.values.joined(separator: ", ")
bestAttemptContent.body = String.localized(stringID: "n_messages_in_m_chats", parameter: messageCount, uniqueChats.count)
}
}
if #available(iOS 15.0, *) {
Expand Down
33 changes: 33 additions & 0 deletions deltachat-ios/Helper/NotificationManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down Expand Up @@ -125,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
}
}
}
Loading