diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 63277f90..c800247d 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -60,6 +60,34 @@ import flutter_foreground_task ) } + private func conversationUuid(fromActionUrl actionUrl: String?) -> String? { + guard + let actionUrl = actionUrl, + let components = URLComponents(string: actionUrl) + else { + return nil + } + + let queryItems = components.queryItems ?? [] + for key in ["uuid", "conversationUuid", "conversation_uuid"] { + if let value = queryItems.first(where: { $0.name == key })?.value, + !value.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty + { + return value.trimmingCharacters(in: .whitespacesAndNewlines) + } + } + + let segments = components.path.split(separator: "/").map(String.init) + for index in segments.indices where segments[index] == "video-call" { + let nextIndex = segments.index(after: index) + if segments.indices.contains(nextIndex), !segments[nextIndex].isEmpty { + return segments[nextIndex] + } + } + + return nil + } + func pushRegistry( _ registry: PKPushRegistry, @@ -86,32 +114,42 @@ import flutter_foreground_task } let dict = payload.dictionaryPayload - if let pushType = ( - dict["type"] as? String - ?? dict["notification_type"] as? String - ?? dict["event"] as? String - ?? dict["action"] as? String - )?.lowercased().replacingOccurrences(of: "-", with: "_"), - pushType.contains("video_call"), - pushType.contains("end") || pushType.contains("cancel") - { + let pushMarkers = [ + dict["type"] as? String, + dict["notification_type"] as? String, + dict["event"] as? String, + dict["action"] as? String, + dict["push_type"] as? String, + dict["call_type"] as? String, + ] + .compactMap { $0?.lowercased().replacingOccurrences(of: "-", with: "_") } + + if pushMarkers.contains(where: { $0.contains("video_call") }) + && pushMarkers.contains(where: { $0.contains("end") || $0.contains("cancel") }) { SwiftFlutterCallkitIncomingPlugin.sharedInstance?.endAllCalls() completion() return } let nameCaller = (dict["nameCaller"] as? String) + ?? (dict["counterpartName"] as? String) + ?? (dict["counterpart_name"] as? String) ?? (dict["caller_name"] as? String) ?? (dict["callerName"] as? String) + ?? (dict["caller"] as? String) ?? "" let conversationUuid = (dict["conversation_uuid"] as? String) ?? (dict["conversationUuid"] as? String) + ?? (dict["conversation_id"] as? String) + ?? (dict["chat_uuid"] as? String) + ?? (dict["uuid"] as? String) + ?? conversationUuid(fromActionUrl: dict["action_url"] as? String) ?? (dict["handle"] as? String) ?? "" let id = [ - dict["id"] as? String, - dict["call_id"] as? String, conversationUuid, + dict["call_id"] as? String, + dict["id"] as? String, dict["message_id"] as? String, ] .compactMap { $0?.trimmingCharacters(in: .whitespacesAndNewlines) } @@ -127,6 +165,9 @@ import flutter_foreground_task } if let avatar = dict["caller_avatar"] as? String ?? dict["avatar"] as? String ?? dict["avatarUrl"] as? String + ?? dict["avatar_url"] as? String + ?? dict["counterpartAvatarUrl"] as? String + ?? dict["counterpart_avatar_url"] as? String { extra["counterpartAvatarUrl"] = avatar } @@ -143,6 +184,8 @@ import flutter_foreground_task } if let counterpartName = dict["counterpartName"] as? String { extra["counterpartName"] = counterpartName + } else if let counterpartName = dict["counterpart_name"] as? String { + extra["counterpartName"] = counterpartName } else if !nameCaller.isEmpty { extra["counterpartName"] = nameCaller } @@ -151,8 +194,15 @@ import flutter_foreground_task id: id, nameCaller: nameCaller, handle: conversationUuid.isEmpty ? nameCaller : conversationUuid, - type: isVideo ? 1 : 0 + type: 0 ) + data.appName = "Итвио" + data.duration = 45000 + data.handleType = "generic" + data.supportsVideo = isVideo + data.ringtonePath = "system_ringtone_default" + data.configureAudioSession = false + data.includesCallsInRecents = false data.extra = extra as NSDictionary SwiftFlutterCallkitIncomingPlugin.sharedInstance?.showCallkitIncoming( diff --git a/lib/features/video_calls/services/video_call_callkit_coordinator.dart b/lib/features/video_calls/services/video_call_callkit_coordinator.dart index 8b4f63cf..860525b3 100644 --- a/lib/features/video_calls/services/video_call_callkit_coordinator.dart +++ b/lib/features/video_calls/services/video_call_callkit_coordinator.dart @@ -112,6 +112,18 @@ class VideoCallCallKitCoordinator { CallKitParams? _paramsForCallId(String id) => _callKitParamsById[id]; + Future _paramsForCallIdOrActiveCall(String id) async { + final cached = _paramsForCallId(id); + if (cached != null || !Platform.isIOS) return cached; + + final activeCalls = await FlutterCallkitIncoming.activeCalls(); + for (final params in activeCalls) { + _cacheCallKitParams(params); + } + + return _paramsForCallId(id); + } + Future _openActiveCallKitCallIfNeeded() async { if (!Platform.isIOS) return; if (_cubit.state.connectPhase != VideoCallConnectPhase.idle) return; @@ -121,6 +133,7 @@ class VideoCallCallKitCoordinator { for (final params in activeCalls) { _cacheCallKitParams(params); + if (!params.isAccepted) continue; final extra = params.extra ?? {}; final conversationUuid = _parseConversationUuid( extra, @@ -191,12 +204,12 @@ class VideoCallCallKitCoordinator { if (_acceptHandledCallKitIds.contains(callKitId)) return; _activeCallKitId = callKitId; - final params = _paramsForCallId(callKitId); + final params = await _paramsForCallIdOrActiveCall(callKitId); final extra = params?.extra ?? {}; final conversationUuid = _parseConversationUuid( extra, - handle: params?.handle, + handle: params?.handle ?? callKitId, ); if (conversationUuid.isEmpty) { log( diff --git a/pubspec.yaml b/pubspec.yaml index 7a6062eb..cbc66a07 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: eatvio_app description: A new Flutter project. -version: 1.3.27+109 +version: 1.3.27+110 publish_to: 'none' environment: