diff --git a/wire-ios-sync-engine/Source/SessionManager/PresentationDelegate.swift b/wire-ios-sync-engine/Source/SessionManager/PresentationDelegate.swift index 6a5b044a89e..07b09ddf827 100644 --- a/wire-ios-sync-engine/Source/SessionManager/PresentationDelegate.swift +++ b/wire-ios-sync-engine/Source/SessionManager/PresentationDelegate.swift @@ -70,4 +70,8 @@ public protocol PresentationDelegate: AnyObject { // Called when showing the password prompt before joining a group conversation func showPasswordPrompt(for conversationName: String, completion: @escaping (String?) -> Void) + + /// Updates the calling UI state if there's an active call + func updateActiveCallPresentationStateIfNeeded() + } diff --git a/wire-ios-sync-engine/Source/SessionManager/SessionManager+Push.swift b/wire-ios-sync-engine/Source/SessionManager/SessionManager+Push.swift index ef5174be20b..dba5c1cfbaa 100644 --- a/wire-ios-sync-engine/Source/SessionManager/SessionManager+Push.swift +++ b/wire-ios-sync-engine/Source/SessionManager/SessionManager+Push.swift @@ -125,6 +125,23 @@ extension SessionManager: UNUserNotificationCenterDelegate { fatalError("User session \(session) is not present in backgroundSessions") } } + + /// Registers an observer to update active call presentation state when the conversation becomes visible. + fileprivate func observeConversationDidBecomeVisible() { + conversationVisibleObserver = NotificationCenter.default.addObserver( + forName: .conversationDidBecomeVisible, + object: nil, + queue: .main + ) { [weak self] _ in + guard let self else { return } + + if let observer = conversationVisibleObserver { + NotificationCenter.default.removeObserver(observer) + conversationVisibleObserver = nil + } + presentationDelegate?.updateActiveCallPresentationStateIfNeeded() + } + } } public extension SessionManager { @@ -138,6 +155,11 @@ public extension SessionManager { return } + // If switching accounts, observe when conversation becomes visible to update call UI + if session != activeUserSession { + observeConversationDidBecomeVisible() + } + activateAccount(for: session) { self.presentationDelegate?.showConversation(conversation, at: message) } @@ -153,3 +175,7 @@ public extension SessionManager { presentationDelegate?.showUserProfile(user: user) } } + +public extension Notification.Name { + static let conversationDidBecomeVisible = Notification.Name("ConversationDidBecomeVisible") +} diff --git a/wire-ios-sync-engine/Source/SessionManager/SessionManager.swift b/wire-ios-sync-engine/Source/SessionManager/SessionManager.swift index e2b0f296d36..b9048f03ba2 100644 --- a/wire-ios-sync-engine/Source/SessionManager/SessionManager.swift +++ b/wire-ios-sync-engine/Source/SessionManager/SessionManager.swift @@ -341,6 +341,7 @@ public final class SessionManager: NSObject, SessionManagerType { let jailbreakDetector: JailbreakDetectorProtocol? fileprivate var accountTokens: [UUID: [Any]] = [:] fileprivate var memoryWarningObserver: NSObjectProtocol? + var conversationVisibleObserver: NSObjectProtocol? fileprivate var isSelectingAccount: Bool = false var proxyCredentials: WireTransport.ProxyCredentials? diff --git a/wire-ios-sync-engine/Tests/Source/MockPresentationDelegate.swift b/wire-ios-sync-engine/Tests/Source/MockPresentationDelegate.swift index 13ddc265f2a..028465ccae6 100644 --- a/wire-ios-sync-engine/Tests/Source/MockPresentationDelegate.swift +++ b/wire-ios-sync-engine/Tests/Source/MockPresentationDelegate.swift @@ -74,4 +74,6 @@ class MockPresentationDelegate: PresentationDelegate { completion(mockPassword) } + func updateActiveCallPresentationStateIfNeeded() {} + } diff --git a/wire-ios/Wire-iOS/Sources/AppRootRouter.swift b/wire-ios/Wire-iOS/Sources/AppRootRouter.swift index 3f7f902b4ab..2c594d3686f 100644 --- a/wire-ios/Wire-iOS/Sources/AppRootRouter.swift +++ b/wire-ios/Wire-iOS/Sources/AppRootRouter.swift @@ -509,8 +509,6 @@ extension AppRootRouter { presentAlertForDeletedAccountIfNeeded(error) sessionManager.processPendingURLActionDoesNotRequireAuthentication() case .authenticated: - // This is needed to display an ongoing call when coming from the background. - authenticatedRouter?.updateActiveCallPresentationState() urlActionRouter.authenticatedRouter = authenticatedRouter ZClientViewController.shared?.legalHoldDisclosureController?.discloseCurrentState(cause: .appOpen) sessionManager.processPendingURLActionRequiresAuthentication() diff --git a/wire-ios/Wire-iOS/Sources/URLActionRouter.swift b/wire-ios/Wire-iOS/Sources/URLActionRouter.swift index b3e4564f2c6..967ed3e498b 100644 --- a/wire-ios/Wire-iOS/Sources/URLActionRouter.swift +++ b/wire-ios/Wire-iOS/Sources/URLActionRouter.swift @@ -143,6 +143,10 @@ class URLActionRouter: URLActionRouterProtocol { extension URLActionRouter: PresentationDelegate { + func updateActiveCallPresentationStateIfNeeded() { + authenticatedRouter?.updateActiveCallPresentationState() + } + func showPasswordPrompt(for conversationName: String, completion: @escaping (String?) -> Void) { typealias ConversationAlert = L10n.Localizable.Join.Group.Conversation.Alert diff --git a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/ConversationViewController+ViewLifeCycle.swift b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/ConversationViewController+ViewLifeCycle.swift index 38d583d1d9f..750fa0f000f 100644 --- a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/ConversationViewController+ViewLifeCycle.swift +++ b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/ConversationViewController+ViewLifeCycle.swift @@ -41,5 +41,15 @@ extension ConversationViewController { isAppearing = false syncCellsState() + notifyConversationDidBecomeVisible() + + } + + private func notifyConversationDidBecomeVisible() { + NotificationCenter.default.post( + name: .conversationDidBecomeVisible, + object: nil + ) } + }