Browse Source

add missed call notification

pull/615/head
ryanzhao 4 months ago
parent
commit
f1445a2191
  1. 4
      Session/Meta/AppDelegate.swift
  2. 33
      Session/Notifications/AppNotifications.swift
  3. 5
      SessionMessagingKit/Sending & Receiving/Notifications/NotificationsProtocol.h
  4. 39
      SessionNotificationServiceExtension/NSENotificationPresenter.swift
  5. 2
      SessionNotificationServiceExtension/NotificationServiceExtension.swift
  6. 4
      SignalUtilitiesKit/Utilities/NoopNotificationsManager.swift

4
Session/Meta/AppDelegate.swift

@ -77,11 +77,15 @@ extension AppDelegate {
// Add missed call message for call offer messages from more than one minute
let infoMessage = self.insertCallInfoMessage(for: message, using: transaction)
infoMessage.updateCallInfoMessage(.missed, using: transaction)
let thread = TSContactThread.getOrCreateThread(withContactSessionID: message.sender!, transaction: transaction)
SSKEnvironment.shared.notificationsManager?.notifyUser(forIncomingCall: infoMessage, in: thread, transaction: transaction)
return
}
guard SSKPreferences.areCallsEnabled else {
let infoMessage = self.insertCallInfoMessage(for: message, using: transaction)
infoMessage.updateCallInfoMessage(.permissionDenied, using: transaction)
let thread = TSContactThread.getOrCreateThread(withContactSessionID: message.sender!, transaction: transaction)
SSKEnvironment.shared.notificationsManager?.notifyUser(forIncomingCall: infoMessage, in: thread, transaction: transaction)
let contactName = Storage.shared.getContact(with: message.sender!, using: transaction)?.displayName(for: Contact.Context.regular) ?? message.sender!
DispatchQueue.main.async {
self.showMissedCallTipsIfNeeded(caller: contactName)

33
Session/Notifications/AppNotifications.swift

@ -269,6 +269,39 @@ public class NotificationPresenter: NSObject, NotificationsProtocol {
)
}
}
public func notifyUser(forIncomingCall callInfoMessage: TSInfoMessage, in thread: TSThread, transaction: YapDatabaseReadTransaction) {
guard !thread.isMuted else { return }
guard !thread.isGroupThread() else { return } // Calls shouldn't happen in groups
guard let threadId = thread.uniqueId else { return }
guard [ .missed, .permissionDenied ].contains(callInfoMessage.callState) else { return } // Only notify missed call
let category = AppNotificationCategory.errorMessage
let userInfo = [
AppNotificationUserInfoKey.threadId: threadId
]
let notificationTitle = callInfoMessage.previewText(with: transaction)
var notificationBody: String?
if callInfoMessage.callState == .permissionDenied {
notificationBody = String(format: "modal_call_missed_tips_explanation".localized(), thread.name(with: transaction))
}
DispatchQueue.main.async {
let sound = self.requestSound(thread: thread)
self.adaptee.notify(
category: category,
title: notificationTitle,
body: notificationBody ?? "",
userInfo: userInfo,
sound: sound,
replacingIdentifier: UUID().uuidString
)
}
}
public func notifyForFailedSend(inThread thread: TSThread) {
let notificationTitle: String?

5
SessionMessagingKit/Sending & Receiving/Notifications/NotificationsProtocol.h

@ -8,6 +8,7 @@ NS_ASSUME_NONNULL_BEGIN
@class TSErrorMessage;
@class TSIncomingMessage;
@class TSInfoMessage;
@class TSThread;
@class YapDatabaseReadTransaction;
@class YapDatabaseReadWriteTransaction;
@ -20,6 +21,10 @@ NS_ASSUME_NONNULL_BEGIN
inThread:(TSThread *)thread
transaction:(YapDatabaseReadTransaction *)transaction;
- (void)notifyUserForIncomingCall:(TSInfoMessage *)callInfoMessage
inThread:(TSThread *)thread
transaction:(YapDatabaseReadTransaction *)transaction;
- (void)cancelNotification:(NSString *)identifier;
- (void)clearAllNotifications;

39
SessionNotificationServiceExtension/NSENotificationPresenter.swift

@ -105,6 +105,45 @@ public class NSENotificationPresenter: NSObject, NotificationsProtocol {
SNLog("Finish adding remote notification request")
}
public func notifyUser(forIncomingCall callInfoMessage: TSInfoMessage, in thread: TSThread, transaction: YapDatabaseReadTransaction) {
guard !thread.isMuted else { return }
guard !thread.isGroupThread() else { return } // Calls shouldn't happen in groups
guard let threadID = thread.uniqueId else { return }
guard [ .missed, .permissionDenied ].contains(callInfoMessage.callState) else { return } // Only notify missed call
var userInfo: [String:Any] = [ NotificationServiceExtension.isFromRemoteKey : true ]
userInfo[NotificationServiceExtension.threadIdKey] = threadID
let notificationContent = UNMutableNotificationContent()
notificationContent.userInfo = userInfo
notificationContent.sound = OWSSounds.notificationSound(for: thread).notificationSound(isQuiet: false)
// Badge Number
let newBadgeNumber = CurrentAppContext().appUserDefaults().integer(forKey: "currentBadgeNumber") + 1
notificationContent.badge = NSNumber(value: newBadgeNumber)
CurrentAppContext().appUserDefaults().set(newBadgeNumber, forKey: "currentBadgeNumber")
notificationContent.title = callInfoMessage.previewText(with: transaction)
notificationContent.body = ""
if callInfoMessage.callState == .permissionDenied {
notificationContent.body = String(format: "modal_call_missed_tips_explanation".localized(), thread.name(with: transaction))
}
// Add request
let identifier = UUID().uuidString
let request = UNNotificationRequest(identifier: identifier, content: notificationContent, trigger: nil)
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)")
}
semaphore.signal()
}
semaphore.wait()
SNLog("Finish adding remote notification request")
}
public func cancelNotification(_ identifier: String) {
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.removePendingNotificationRequests(withIdentifiers: [ identifier ])

2
SessionNotificationServiceExtension/NotificationServiceExtension.swift

@ -79,6 +79,7 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension
if let sender = callMessage.sender, let thread = TSContactThread.fetch(for: sender, using: transaction), !thread.isMessageRequest(using: transaction) {
let infoMessage = TSInfoMessage.from(callMessage, associatedWith: thread)
infoMessage.updateCallInfoMessage(.permissionDenied, using: transaction)
SSKEnvironment.shared.notificationsManager?.notifyUser(forIncomingCall: infoMessage, in: thread, transaction: transaction)
}
break
}
@ -92,6 +93,7 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension
MessageSender.sendNonDurably(message, in: thread, using: transaction).retainUntilComplete()
let infoMessage = TSInfoMessage.from(callMessage, associatedWith: thread)
infoMessage.updateCallInfoMessage(.missed, using: transaction)
SSKEnvironment.shared.notificationsManager?.notifyUser(forIncomingCall: infoMessage, in: thread, transaction: transaction)
}
break
}

4
SignalUtilitiesKit/Utilities/NoopNotificationsManager.swift

@ -9,6 +9,10 @@ public class NoopNotificationsManager: NSObject, NotificationsProtocol {
owsFailDebug("")
}
public func notifyUser(forIncomingCall callInfoMessage: TSInfoMessage, in thread: TSThread, transaction: YapDatabaseReadTransaction) {
owsFailDebug("")
}
public func cancelNotification(_ identifier: String) {
owsFailDebug("")
}

Loading…
Cancel
Save