diff --git a/Session/Calls/Call Management/SessionCall.swift b/Session/Calls/Call Management/SessionCall.swift index f533291ea..8fdc34f97 100644 --- a/Session/Calls/Call Management/SessionCall.swift +++ b/Session/Calls/Call Management/SessionCall.swift @@ -66,6 +66,7 @@ public final class SessionCall: NSObject, WebRTCSessionDelegate { enum EndCallMode { case local case remote + case unanswered } // MARK: Call State Properties @@ -119,6 +120,8 @@ public final class SessionCall: NSObject, WebRTCSessionDelegate { get { return endDate != nil } set { endDate = newValue ? Date() : nil } } + + var didTimeout = false var duration: TimeInterval { guard let connectedDate = connectedDate else { @@ -226,10 +229,9 @@ public final class SessionCall: NSObject, WebRTCSessionDelegate { newMessageBody = self.isOutgoing ? NSLocalizedString("call_cancelled", comment: "") : NSLocalizedString("call_rejected", comment: "") shouldMarkAsRead = true case .remote: - if self.hasStartedConnecting { - - } newMessageBody = self.isOutgoing ? NSLocalizedString("call_rejected", comment: "") : NSLocalizedString("call_missing", comment: "") + case .unanswered: + newMessageBody = NSLocalizedString("call_timeout", comment: "") } } messageToUpdate.updateCall(withNewBody: newMessageBody, transaction: transaction) diff --git a/Session/Calls/Call Management/SessionCallManager+CXProvider.swift b/Session/Calls/Call Management/SessionCallManager+CXProvider.swift index ebfae6cd5..6ae6d8faf 100644 --- a/Session/Calls/Call Management/SessionCallManager+CXProvider.swift +++ b/Session/Calls/Call Management/SessionCallManager+CXProvider.swift @@ -42,7 +42,11 @@ extension SessionCallManager: CXProviderDelegate { AssertIsOnMainThread() guard let call = self.currentCall else { return action.fail() } call.endSessionCall() - reportCurrentCallEnded(reason: nil) + if call.didTimeout { + reportCurrentCallEnded(reason: .unanswered) + } else { + reportCurrentCallEnded(reason: nil) + } action.fulfill() } diff --git a/Session/Calls/Call Management/SessionCallManager.swift b/Session/Calls/Call Management/SessionCallManager.swift index 0d561748f..af6a19e3a 100644 --- a/Session/Calls/Call Management/SessionCallManager.swift +++ b/Session/Calls/Call Management/SessionCallManager.swift @@ -4,6 +4,7 @@ import SessionMessagingKit public final class SessionCallManager: NSObject { let provider: CXProvider let callController = CXCallController() + var callTimeOutTimer: Timer? = nil var currentCall: SessionCall? = nil { willSet { if (newValue != nil) { @@ -68,6 +69,13 @@ public final class SessionCallManager: NSObject { self.provider.reportOutgoingCall(with: call.uuid, connectedAt: call.connectedDate) } } + callTimeOutTimer = Timer.scheduledTimer(withTimeInterval: 60, repeats: false) { _ in + guard let currentCall = self.currentCall else { return } + currentCall.didTimeout = true + self.endCall(currentCall) { error in + self.callTimeOutTimer = nil + } + } } public func reportIncomingCall(_ call: SessionCall, callerName: String, completion: @escaping (Error?) -> Void) { @@ -100,7 +108,11 @@ public final class SessionCallManager: NSObject { guard let call = currentCall else { return } if let reason = reason { self.provider.reportCall(with: call.uuid, endedAt: nil, reason: reason) - call.updateCallMessage(mode: .remote) + if reason == .unanswered { + call.updateCallMessage(mode: .unanswered) + } else { + call.updateCallMessage(mode: .remote) + } } else { call.updateCallMessage(mode: .local) } @@ -134,5 +146,10 @@ public final class SessionCallManager: NSObject { tsMessage.updateCall(withNewBody: NSLocalizedString("call_missing", comment: ""), transaction: transaction) } } + + public func invalidateTimeoutTimer() { + callTimeOutTimer?.invalidate() + callTimeOutTimer = nil + } } diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index f7e64c8dc..972b5e5a9 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -66,6 +66,7 @@ extension AppDelegate { MessageReceiver.handleAnswerCallMessage = { message in DispatchQueue.main.async { guard let call = AppEnvironment.shared.callManager.currentCall, message.uuid == call.uuid.uuidString else { return } + AppEnvironment.shared.callManager.invalidateTimeoutTimer() call.hasStartedConnecting = true let sdp = RTCSessionDescription(type: .answer, sdp: message.sdps![0]) call.didReceiveRemoteSDP(sdp: sdp) diff --git a/Session/Meta/Translations/en.lproj/Localizable.strings b/Session/Meta/Translations/en.lproj/Localizable.strings index 4bbda8679..efd20b6af 100644 --- a/Session/Meta/Translations/en.lproj/Localizable.strings +++ b/Session/Meta/Translations/en.lproj/Localizable.strings @@ -586,6 +586,7 @@ "call_missing" = "Missing Call"; "call_rejected" = "Rejected Call"; "call_cancelled" = "Cancelled Call"; +"call_timeout" = "No answer"; "voice_call" = "Voice Call"; "video_call" = "Video Call"; "APN_Message" = "You've got a new message";