mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +00:00
Rely on the room's info to decide whether a call ringing notification is outdated and should be ignored as opposed to a time based approach.
This commit is contained in:
committed by
Stefan Ceriu
parent
6c8cb2bbe5
commit
690ff3caa6
@@ -10,6 +10,7 @@ import MatrixRustSDK
|
||||
import UserNotifications
|
||||
|
||||
class NotificationHandler {
|
||||
private let userSession: NSEUserSession
|
||||
private let settings: CommonSettingsProtocol
|
||||
private let contentHandler: (UNNotificationContent) -> Void
|
||||
private var notificationContent: UNMutableNotificationContent
|
||||
@@ -17,10 +18,15 @@ class NotificationHandler {
|
||||
|
||||
private let notificationContentBuilder: NotificationContentBuilder
|
||||
|
||||
init(settings: CommonSettingsProtocol,
|
||||
// periphery:ignore - required for instance retention in the rust codebase
|
||||
private var roomInfoObservationToken: TaskHandle?
|
||||
|
||||
init(userSession: NSEUserSession,
|
||||
settings: CommonSettingsProtocol,
|
||||
contentHandler: @escaping (UNNotificationContent) -> Void,
|
||||
notificationContent: UNMutableNotificationContent,
|
||||
tag: String) {
|
||||
self.userSession = userSession
|
||||
self.settings = settings
|
||||
self.contentHandler = contentHandler
|
||||
self.notificationContent = notificationContent
|
||||
@@ -33,9 +39,7 @@ class NotificationHandler {
|
||||
settings: settings)
|
||||
}
|
||||
|
||||
func processEvent(_ eventID: String,
|
||||
roomID: String,
|
||||
userSession: NSEUserSession) async {
|
||||
func processEvent(_ eventID: String, roomID: String) async {
|
||||
MXLog.info("\(tag) Processing event: \(eventID) in room: \(roomID)")
|
||||
|
||||
guard let notificationItemProxy = await userSession.notificationItemProxy(roomID: roomID, eventID: eventID) else {
|
||||
@@ -163,10 +167,31 @@ class NotificationHandler {
|
||||
return .shouldDisplay
|
||||
}
|
||||
|
||||
let timestamp = Date(timeIntervalSince1970: TimeInterval(timestamp / 1000))
|
||||
guard abs(timestamp.timeIntervalSinceNow) < ElementCallServiceNotificationDiscardDelta else {
|
||||
MXLog.info("Call notification is too old, handling as push notification")
|
||||
return .shouldDisplay
|
||||
// Check to see if a call is still ongoing
|
||||
if let room = userSession.roomForIdentifier(roomID) { // Try to get call details from the room info
|
||||
if !room.hasActiveRoomCall() { // If I don't have an active call wait a bit and make sure
|
||||
let runner = ExpiringTaskRunner {
|
||||
await withCheckedContinuation { [weak self] continuation in
|
||||
self?.roomInfoObservationToken = room.subscribeToRoomInfoUpdates(listener: RoomInfoUpdateListener { _ in
|
||||
MXLog.info("Received room info update")
|
||||
continuation.resume()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
try? await runner.run(timeout: .seconds(5)) // Wait 5 seconds or just use whatever is available
|
||||
|
||||
guard room.hasActiveRoomCall() else {
|
||||
return .shouldDisplay
|
||||
}
|
||||
}
|
||||
} else { // Otherwise fallback to the old timeout mechanism
|
||||
let timestamp = Date(timeIntervalSince1970: TimeInterval(timestamp / 1000))
|
||||
|
||||
guard abs(timestamp.timeIntervalSinceNow) < ElementCallServiceNotificationDiscardDelta else {
|
||||
MXLog.info("Call notification is too old, handling as push notification")
|
||||
return .shouldDisplay
|
||||
}
|
||||
}
|
||||
|
||||
let payload = [ElementCallServiceNotificationKey.roomID.rawValue: roomID,
|
||||
@@ -189,3 +214,15 @@ class NotificationHandler {
|
||||
case unsupportedShouldDiscard
|
||||
}
|
||||
}
|
||||
|
||||
private final class RoomInfoUpdateListener: RoomInfoListener {
|
||||
private let onUpdateClosure: (RoomInfo) -> Void
|
||||
|
||||
init(_ onUpdateClosure: @escaping (RoomInfo) -> Void) {
|
||||
self.onUpdateClosure = onUpdateClosure
|
||||
}
|
||||
|
||||
func call(roomInfo: RoomInfo) {
|
||||
onUpdateClosure(roomInfo)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,11 +63,6 @@ class NotificationServiceExtension: UNNotificationServiceExtension {
|
||||
|
||||
Target.nse.configure(logLevel: settings.logLevel, traceLogPacks: settings.traceLogPacks)
|
||||
|
||||
notificationHandler = NotificationHandler(settings: settings,
|
||||
contentHandler: contentHandler,
|
||||
notificationContent: mutableContent,
|
||||
tag: tag)
|
||||
|
||||
MXLog.info("\(tag) #########################################")
|
||||
|
||||
ExtensionLogger.logMemory(with: tag)
|
||||
@@ -82,12 +77,16 @@ class NotificationServiceExtension: UNNotificationServiceExtension {
|
||||
appHooks: appHooks,
|
||||
appSettings: settings)
|
||||
|
||||
notificationHandler = NotificationHandler(userSession: userSession,
|
||||
settings: settings,
|
||||
contentHandler: contentHandler,
|
||||
notificationContent: mutableContent,
|
||||
tag: tag)
|
||||
|
||||
ExtensionLogger.logMemory(with: tag)
|
||||
MXLog.info("\(tag) Configured user session")
|
||||
|
||||
await notificationHandler?.processEvent(eventID,
|
||||
roomID: roomID,
|
||||
userSession: userSession)
|
||||
await notificationHandler?.processEvent(eventID, roomID: roomID)
|
||||
} catch {
|
||||
MXLog.error("Failed creating user session with error: \(error)")
|
||||
}
|
||||
|
||||
@@ -68,11 +68,20 @@ final class NSEUserSession {
|
||||
receiverID: userID,
|
||||
roomID: roomID)
|
||||
} catch {
|
||||
MXLog.error("NSE: Could not get notification's content creating an empty notification instead, error: \(error)")
|
||||
MXLog.error("Could not get notification's content creating an empty notification instead, error: \(error)")
|
||||
return EmptyNotificationItemProxy(eventID: eventID, roomID: roomID, receiverID: userID)
|
||||
}
|
||||
}
|
||||
|
||||
func roomForIdentifier(_ roomID: String) -> Room? {
|
||||
do {
|
||||
return try baseClient.getRoom(roomId: roomID)
|
||||
} catch {
|
||||
MXLog.error("Failed retrieving room with error: \(error)")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
delegateHandle?.cancel()
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ targets:
|
||||
- path: ../../ElementX/Sources/Generated/Strings.swift
|
||||
- path: ../../ElementX/Sources/Other/Avatars.swift
|
||||
- path: ../../ElementX/Sources/Other/CurrentValuePublisher.swift
|
||||
- path: ../../ElementX/Sources/Other/ExpiringTaskRunner.swift
|
||||
- path: ../../ElementX/Sources/Other/Extensions/AttributedString.swift
|
||||
- path: ../../ElementX/Sources/Other/Extensions/Bundle.swift
|
||||
- path: ../../ElementX/Sources/Other/Extensions/ClientBuilder.swift
|
||||
|
||||
Reference in New Issue
Block a user