diff --git a/apps/ios/Shared/ContentView.swift b/apps/ios/Shared/ContentView.swift index 2bfec8368d..aeccaf9346 100644 --- a/apps/ios/Shared/ContentView.swift +++ b/apps/ios/Shared/ContentView.swift @@ -103,26 +103,33 @@ struct ContentView: View { } IncomingCallView() } -// .onContinueUserActivity("INStartCallIntent", perform: processUserActivity) -// .onContinueUserActivity("INStartAudioCallIntent", perform: processUserActivity) -// .onContinueUserActivity("INStartVideoCallIntent", perform: processUserActivity) + .onContinueUserActivity("INStartCallIntent", perform: processUserActivity) + .onContinueUserActivity("INStartAudioCallIntent", perform: processUserActivity) + .onContinueUserActivity("INStartVideoCallIntent", perform: processUserActivity) } -// private func processUserActivity(_ activity: NSUserActivity) { -// let callToContact = { (contactId: ChatId?, mediaType: CallMediaType) in -// if let chatInfo = chatModel.chats.first(where: { $0.id == contactId })?.chatInfo, -// case let .direct(contact) = chatInfo { -// CallController.shared.startCall(contact, mediaType) -// } -// } -// if let intent = activity.interaction?.intent as? INStartCallIntent { -// callToContact(intent.contacts?.first?.personHandle?.value, .audio) -// } else if let intent = activity.interaction?.intent as? INStartAudioCallIntent { -// callToContact(intent.contacts?.first?.personHandle?.value, .audio) -// } else if let intent = activity.interaction?.intent as? INStartVideoCallIntent { -// callToContact(intent.contacts?.first?.personHandle?.value, .video) -// } -// } + private func processUserActivity(_ activity: NSUserActivity) { + let intent = activity.interaction?.intent + if let intent = intent as? INStartCallIntent { + callToRecentContact(intent.contacts, intent.callCapability == .videoCall ? .video : .audio) + } else if let intent = intent as? INStartAudioCallIntent { + callToRecentContact(intent.contacts, .audio) + } else if let intent = intent as? INStartVideoCallIntent { + callToRecentContact(intent.contacts, .video) + } + } + + private func callToRecentContact(_ contacts: [INPerson]?, _ mediaType: CallMediaType) { + logger.debug("callToRecentContact") + if let contactId = contacts?.first?.personHandle?.value, + let chat = chatModel.getChat(contactId), + case let .direct(contact) = chat.chatInfo { + logger.debug("callToRecentContact: schedule call") + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { + CallController.shared.startCall(contact, mediaType) + } + } + } private func initAuthenticate() { if CallController.useCallKit() && chatModel.showCallView && chatModel.activeCall != nil { diff --git a/apps/ios/Shared/Views/Call/CallController.swift b/apps/ios/Shared/Views/Call/CallController.swift index 83338804c1..3f338d771d 100644 --- a/apps/ios/Shared/Views/Call/CallController.swift +++ b/apps/ios/Shared/Views/Call/CallController.swift @@ -23,7 +23,7 @@ class CallController: NSObject, CXProviderDelegate, PKPushRegistryDelegate, Obse let configuration = CXProviderConfiguration() configuration.supportsVideo = true configuration.supportedHandleTypes = [.generic] - configuration.includesCallsInRecents = false // UserDefaults.standard.bool(forKey: DEFAULT_CALL_KIT_CALLS_IN_RECENTS) + configuration.includesCallsInRecents = UserDefaults.standard.bool(forKey: DEFAULT_CALL_KIT_CALLS_IN_RECENTS) configuration.maximumCallGroups = 1 configuration.maximumCallsPerCallGroup = 1 configuration.iconTemplateImageData = UIImage(named: "icon-transparent")?.pngData() diff --git a/apps/ios/Shared/Views/UserSettings/CallSettings.swift b/apps/ios/Shared/Views/UserSettings/CallSettings.swift index 9d3f56c710..ca43faab03 100644 --- a/apps/ios/Shared/Views/UserSettings/CallSettings.swift +++ b/apps/ios/Shared/Views/UserSettings/CallSettings.swift @@ -20,26 +20,13 @@ struct CallSettings: View { VStack { List { Section { - Toggle("Connect via relay", isOn: $webrtcPolicyRelay) - - if !CallController.isInChina { - Toggle("Use CallKit", isOn: $callKitEnabled) - -// if allowChangingCallsHistory { -// Toggle("Show calls in phone history", isOn: $callKitCallsInRecents) -// .disabled(!callKitEnabled) -// .onChange(of: callKitCallsInRecents) { value in -// CallController.shared.showInRecents(value) -// } -// } - } - NavigationLink { RTCServers() .navigationTitle("Your ICE servers") } label: { Text("WebRTC ICE servers") } + Toggle("Always use relay", isOn: $webrtcPolicyRelay) } header: { Text("Settings") } footer: { @@ -50,10 +37,29 @@ struct CallSettings: View { } } + if !CallController.isInChina { + Section { + Toggle("Use iOS call interface", isOn: $callKitEnabled) + Toggle("Show calls in phone history", isOn: $callKitCallsInRecents) + .disabled(!callKitEnabled) + .onChange(of: callKitCallsInRecents) { value in + CallController.shared.showInRecents(value) + } + } header: { + Text("Interface") + } footer: { + if callKitEnabled { + Text("You can accept calls from lock screen, without device and app authentication.") + } else { + Text("Authentication is required before the call is connected, but you may miss calls.") + } + } + } + Section("Limitations") { VStack(alignment: .leading, spacing: 8) { textListItem("1.", "Do NOT use SimpleX for emergency calls.") - textListItem("2.", "To prevent the call interruption, enable Do Not Disturb mode.") + textListItem("2.", "Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.") } .font(.callout) .padding(.vertical, 8)