{"id":"cce2bada-357f-4b55-9d50-48d31283ed08","shortId":"xUdumn","kind":"skill","title":"cometchat-flutter-v5-calls","tagline":"CometChat Calls integration for Flutter UIKit v5 (GetX-based, cometchat_calls_uikit separate package). Covers package wiring (cometchat_calls_uikit ^5.0.15 alongside cometchat_chat_uikit ^5.2), CometChatCallingExtension via UIKitSettingsBuilder, CallNavigationContext.navigatorKey","description":"## Purpose\n\nProduction-grade voice + video calling for Flutter UIKit v5 (GetX-based). Loaded by `cometchat-calls` when `framework === \"flutter\"` and `flutter_version === \"v5\"`. Operates in two modes:\n\n- **Standalone** — calls is the product. `cometchat_chat_sdk` (signaling) + `cometchat_calls_sdk` (WebRTC) without the `cometchat_chat_uikit` UI Kit. Custom call screens (or hand-roll the kit's call widgets without the conversation kit). **VoIP push is mandatory** — same rule as native iOS / Android.\n- **Additive** — calls layered onto an existing v5 chat integration. Adds `cometchat_calls_uikit` package, configures the calling extension via `UIKitSettingsBuilder.callingExtension`, sets `CallNavigationContext.navigatorKey` on `MaterialApp`, mounts the global incoming-call listener at the app shell.\n\n**Read these other skills first:**\n- `cometchat-calls` — dispatcher (modes, hard rules, anti-patterns)\n- `cometchat-flutter-v5-core` — UIKitSettingsBuilder, init/login order, GetX scope rules, app entry conventions\n- `cometchat-flutter-v5-events` — CometChatMessageEvents / CometChatCallEvents subscription patterns\n\n**Ground truth:**\n- SDK source — `~/Downloads/calls-sdk/calls-sdk-flutter-5/sdk/`\n- Sample app — `~/Downloads/calls-sdk/calls-sdk-flutter-5/sample-apps/`\n- Public docs — https://www.cometchat.com/docs/calls/flutter/overview\n\n---\n\n## 1. The seven hard rules — Flutter v5 specialization\n\n### 1.0 Calls SDK login is its own step (v5+)\n\nThe v5 Calls SDK has its own auth state, separate from the Chat SDK. After `CometChat.login` succeeds, you MUST also call `CometChatCalls.login` — without it, the FIRST calls API call throws **\"auth token cannot be null\"**.\n\n```dart\nimport 'package:cometchat_sdk/cometchat_sdk.dart';\nimport 'package:cometchat_calls_sdk/cometchat_calls_sdk.dart';\n\nCometChat.login(uid, AUTH_KEY,\n  onSuccess: (User user) {\n    // Chat SDK ready — now login Calls SDK\n    CometChatCalls.login(\n      uid: uid,\n      authKey: AUTH_KEY,\n      onSuccess: (User? callUser) {\n        // both ready\n      },\n      onError: (CometChatException e) {\n        // surface to user\n      },\n    );\n  },\n  onError: (CometChatException e) {\n    // chat login failed\n  },\n);\n```\n\nFor production with server-minted tokens:\n\n```dart\nCometChatCalls.loginWithAuthToken(\n  authToken: tokenFromBackend,\n  onSuccess: (User? user) { /* … */ },\n  onError: (CometChatException e) { /* … */ },\n);\n```\n\n**Surprises:**\n- Chat SDK persists login via shared preferences across launches. The **Calls SDK does NOT** — always check `CometChatCalls.getLoggedInUser()` on app start and re-login if it returns null.\n- The Calls SDK's onSuccess hands back `User?` (nullable) — guard before using.\n\n### 1.1 Dual-SDK contract — `CometChatCallingExtension` hides it (additive); standalone code sees both\n\nIn additive mode, the `CometChatCallingExtension` registered via `UIKitSettingsBuilder.callingExtension` wires both SDKs internally — your code rarely touches `CometChatUIKitCalls` directly. In standalone mode (no UI Kit), you call both SDKs explicitly:\n\n```dart\n// ✓ RIGHT — additive mode (calling extension owns the dual-SDK split)\nfinal settings = (UIKitSettingsBuilder()\n      ..appId = 'APP_ID'\n      ..region = 'us'\n      ..authKey = 'AUTH_KEY'\n      ..subscriptionType = CometChatSubscriptionType.allUsers\n      ..callingExtension = CometChatCallingExtension())\n    .build();\nCometChatUIKit.init(uiKitSettings: settings);\n```\n\n```dart\n// ✓ RIGHT — standalone mode (explicit dual-SDK)\nimport 'package:cometchat_chat_sdk/cometchat_chat_sdk.dart';\nimport 'package:cometchat_calls_sdk/cometchat_calls_sdk.dart';\n\n// Chat SDK — initiate ringing\nfinal outgoing = Call(receiverUid, CometChatReceiverType.user, CometChatCallType.video);\nfinal initiated = await CometChat.initiateCall(call: outgoing);\n\n// Calls SDK — join WebRTC session after acceptance.\n// Use SessionSettingsBuilder + callback shape — matches the upstream sample\n// at calls-sdk-flutter-5/sample-apps/cometchat-calls-sample-app-flutter/.\n// CallSettingsBuilder is the chat-side type; SessionSettingsBuilder is what\n// session/joinSession accepts.\nfinal sessionSettings = (SessionSettingsBuilder()\n      .setTitle('CometChat Call')\n      .startVideoPaused(false)\n      .startAudioMuted(false))\n    .build();\n\nCometChatCalls.joinSession(\n  sessionId: sessionId,\n  sessionSettings: sessionSettings,\n  onSuccess: (Widget? widget) {\n    // render widget via SizedBox.expand; register SessionStatusListeners\n  },\n  onError: (CometChatCallsException err) {\n    debugPrint('joinSession failed: ${err.message}');\n  },\n);\n```\n\n### 1.2 VoIP push — `flutter_callkit_incoming` + `firebase_messaging` + platform-channel bridges\n\nStandalone mode requires working VoIP push end-to-end. The Flutter stack:\n\n- **`flutter_callkit_incoming`** — bridges CallKit (iOS) and a custom heads-up notification (Android). Single Dart API for \"ring this device\".\n- **`firebase_messaging`** — FCM data messages on Android (priority `high`, `data` payload — NOT `notification`).\n- **iOS PushKit** — Flutter doesn't have a first-party PushKit plugin; the skill ships a tiny platform-channel bridge in `ios/Runner/AppDelegate.swift` registering `PKPushRegistry.voIP` and forwarding payloads through a `MethodChannel` to Dart.\n- **Server side** — same split as native: PushKit (VoIP cert) for iOS, FCM data-message for Android.\n\nIn additive mode, this is opt-in but recommended.\n\n### 1.3 Foreground service — Android 14+ rules apply unchanged\n\n**⚠️ Android build prerequisite — Jetifier is mandatory.** One of the `cometchat_calls_uikit` transitive deps pulls in the legacy `com.android.support:support-compat:26.1.0` AAR. Without Jetifier, AGP fails the assembleDebug step with dozens of `Duplicate class android.support.v4.*` errors against `androidx.core`. Set in `android/gradle.properties`:\n\n```properties\nandroid.useAndroidX=true\nandroid.enableJetifier=true\n```\n\nFlutter 3.x scaffolds omit `enableJetifier=true` by default — the build blows up on the first `flutter build apk` if you skip this. The error is loud but the fix is one line.\n\nThe `cometchat_calls_uikit` registers `CometChatOngoingCallService` via manifest merge, but the host app's `android/app/src/main/AndroidManifest.xml` must declare the four FOREGROUND_SERVICE permissions plus MANAGE_OWN_CALLS / BIND_TELECOM_CONNECTION_SERVICE — the same rule as native Android (cf. `cometchat-android-v5-calls` rule 1.3).\n\n```xml\n<uses-permission android:name=\"android.permission.FOREGROUND_SERVICE\" />\n<uses-permission android:name=\"android.permission.FOREGROUND_SERVICE_PHONE_CALL\" />\n<uses-permission android:name=\"android.permission.FOREGROUND_SERVICE_MICROPHONE\" />\n<uses-permission android:name=\"android.permission.FOREGROUND_SERVICE_CAMERA\" />\n<uses-permission android:name=\"android.permission.MANAGE_OWN_CALLS\" />\n<uses-permission android:name=\"android.permission.BIND_TELECOM_CONNECTION_SERVICE\"\n    tools:ignore=\"ProtectedPermissions\" />\n```\n\nSilent crash on Android 14+ if `FOREGROUND_SERVICE_PHONE_CALL` is missing. The `tools` namespace must be declared on the `<manifest>` element.\n\n### 1.4 Server-minted auth tokens\n\n`cometchat-flutter-v5-production` covers the token-endpoint pattern. Production calls path uses `CometChatUIKit.loginWithAuthToken(token)`, not `loginWithAuthKey(uid, authKey)`. The Calls SDK piggybacks on the Chat SDK auth context — there is no separate calls-only token.\n\n### 1.5 Hangup cleanup — Dart + native + system call UI\n\n```dart\nFuture<void> endCall(String sessionId) async {\n  // 1. End the Calls SDK session — releases WebRTC tracks.\n  // CometChatCalls.endSession() does NOT exist on Flutter — use the\n  // CallSession singleton's leaveSession().\n  await CallSession.getInstance().leaveSession();\n  await CometChatOngoingCallService.abort();\n\n  // 2. Tell the OS-level call UI the call ended\n  await FlutterCallkitIncoming.endAllCalls();\n\n  // 3. Pop the call screen\n  if (mounted) {\n    Navigator.of(context, rootNavigator: true).popUntil((r) => r.isFirst);\n  }\n\n  // 4. After logout flows: reset ServiceLocator if it was used directly\n  // (UIKit handles this for additive mode)\n}\n```\n\nSkipping `FlutterCallkitIncoming.endAllCalls` leaves the lock-screen/heads-up call UI stuck. Skipping the `Navigator.popUntil` strands the Dart-side call screen with WebRTC views still in the tree.\n\n### 1.6 Permissions — `permission_handler` + Info.plist + AndroidManifest\n\n```dart\nimport 'package:permission_handler/permission_handler.dart';\n\nawait [Permission.camera, Permission.microphone, Permission.notification].request();\n```\n\niOS — `ios/Runner/Info.plist`:\n```xml\n<key>NSCameraUsageDescription</key>\n<string>So you can be seen during video calls.</string>\n<key>NSMicrophoneUsageDescription</key>\n<string>So you can talk during voice and video calls.</string>\n<key>UIBackgroundModes</key>\n<array>\n  <string>audio</string>\n  <string>voip</string>\n  <string>remote-notification</string>\n</array>\n```\n\nAndroid — manifest as above (rule 1.3) plus runtime requests via `permission_handler`.\n\n### 1.7 IncomingCall mounted at app root + `CallNavigationContext.navigatorKey`\n\nV5 uses GetX's navigator key pattern. `CallNavigationContext.navigatorKey` MUST be set on `MaterialApp.navigatorKey` so call overlays can navigate even when a call is initiated from a sub-route:\n\n```dart\n// ✓ RIGHT\nMaterialApp(\n  navigatorKey: CallNavigationContext.navigatorKey,\n  // ...\n);\n```\n\nGlobal call listener registration (incoming calls fire app-wide) belongs in the app shell's State, not in a feature screen:\n\n```dart\nclass AppShellState extends State<AppShell>\n    with CallListener, CometChatCallEventListener {\n  static const _listenerId = 'app-shell-call-listener';\n\n  @override\n  void initState() {\n    super.initState();\n    CometChat.addCallListener(_listenerId, this);\n    CometChatCallEvents.addCallEventsListener(_listenerId, this);\n  }\n\n  @override\n  void dispose() {\n    CometChat.removeCallListener(_listenerId);\n    CometChatCallEvents.removeCallEventsListener(_listenerId);\n    super.dispose();\n  }\n\n  @override\n  void onIncomingCallReceived(Call call) {\n    // Route through CallNavigationContext or flutter_callkit_incoming\n  }\n}\n```\n\nUse a stable string ID for the listener — duplicate IDs overwrite, distinct IDs fire both (double-ring bug).\n\n---\n\n## 2. Setup\n\n```yaml\n# pubspec.yaml\ndependencies:\n  flutter:\n    sdk: flutter\n  cometchat_chat_uikit: ^5.2.14         # additive mode — already there\n  cometchat_calls_uikit: ^5.0.15        # adds the calling extension + widgets\n  permission_handler: ^11.0.0           # rule 1.6\n  flutter_callkit_incoming: ^2.0.0      # standalone — VoIP UI bridge\n  firebase_messaging: ^14.0.0           # standalone — Android FCM\n  firebase_core: ^2.0.0                 # firebase_messaging peer\n```\n\nHosted source if pub.dev resolution lags:\n\n```yaml\n  cometchat_calls_uikit:\n    hosted: https://dart.cloudsmith.io/cometchat/cometchat/\n    version: ^5.0.15\n```\n\nInit order — calling extension flows the dual-SDK init internally:\n\n```dart\nfinal settings = (UIKitSettingsBuilder()\n      ..appId = CometChatConfig.appId\n      ..region = CometChatConfig.region\n      ..authKey = CometChatConfig.authKey\n      ..subscriptionType = CometChatSubscriptionType.allUsers\n      ..callingExtension = CometChatCallingExtension())  // ← rule 1.1 (additive)\n    .build();\n\nawait CometChatUIKit.init(uiKitSettings: settings);\n```\n\nIn standalone mode (no UI Kit), use the SDKs directly:\n\n```dart\nawait CometChat.init(CometChatConfig.appId, AppSettings.builder\n  ..setRegion(CometChatConfig.region)\n  ..subscribePresenceForAllUsers());\n\nawait CometChatCalls.init(CallAppSettings.builder\n  ..setAppId(CometChatConfig.appId)\n  ..setRegion(CometChatConfig.region));\n```\n\n---\n\n## 3. Components catalog (UI Kit widgets)\n\nImports (additive mode — barrel re-exports `cometchat_uikit_shared`, `cometchat_sdk`, `cometchat_calls_sdk`):\n\n```dart\nimport 'package:cometchat_calls_uikit/cometchat_calls_uikit.dart';\n```\n\n| Widget | Purpose |\n|---|---|\n| `CometChatCallButtons(user: ..., group: ...)` | Voice + video buttons. Drop into `CometChatMessageHeader` trailing slot or anywhere in the tree. Mutually exclusive `user` / `group`. |\n| `CometChatIncomingCall(call:, onAccept:, onDecline:)` | Foreground in-app ring UI (additive mode). **Callbacks take `(BuildContext, Call)`, NOT `(Call)` alone** — common mistake. |\n| `CometChatOutgoingCall(call:, user: OR group:, onCancelled:)` | Dialing UI. `call:` is the result of `CometChatUIKitCalls.initiateCall(...)`. Callbacks `(BuildContext, Call)?`. |\n| `CometChatOngoingCall(callSettingsBuilder:, sessionId:)` | Active call view, hosts WebRTC. |\n| `CometChatCallLogs(onItemClick:, callLogsRequestBuilder:)` | Paginated history. **`CometChatCallLogDetails` is NOT a UIKit export** — copy the sample-app pattern from `~/Downloads/calls-sdk/calls-sdk-flutter-5/sample-apps/.../call_log_details/` for the detail screen. |\n\n`CometChatUIKitCalls` API:\n\n| Method | Purpose |\n|---|---|\n| `CometChatUIKitCalls.initiateCall(call)` | Start a call (wraps Chat SDK `initiateCall` + Calls SDK preflight) |\n| `CometChatUIKitCalls.acceptCall(sessionId)` | Accept incoming |\n| `CometChatUIKitCalls.rejectCall(sessionId, status)` | Reject / cancel |\n| `CometChatUIKitCalls.generateToken(sessionId)` | Mint session-scoped RTC token |\n| `CometChatUIKitCalls.startSession(sessionId, settings)` | Start WebRTC |\n| `CometChatUIKitCalls.endSession()` | End and cleanup |\n\n---\n\n## 4. Standalone integration\n\nWhen `product === \"voice-video\"` and there is no v5 chat integration.\n\n**Split by calling mode:**\n\n### 4a. Standalone — Session mode (meeting-room UX, no ringing)\n\nCalls SDK ONLY. NO Chat SDK. Matches `~/Downloads/calls-sdk/calls-sdk-flutter-5/sample-apps/cometchat-calls-sample-app-flutter/`. Scaffold:\n\n1. **`pubspec.yaml`** — `cometchat_calls_sdk: ^5.0.0` ONLY. No `cometchat_chat_sdk` / `cometchat_uikit_chat`.\n2. **`lib/main.dart`** — `CometChatCalls.init(appId, region, authKey)` + `permission_handler` flow.\n3. **`lib/screens/call_screen.dart`** — `StatefulWidget implements SessionStatusListeners, ButtonClickListeners`. `CometChatCalls.joinSession(sessionId:, sessionSettings: SessionSettingsBuilder().build(), onSuccess:, onError:)`. `CometChatOngoingCallService.launch/abort`. See `references/call-session.md`.\n4. **Native config** — Camera + microphone permissions only (no PushKit, no FCM for VoIP).\n\n**Why no Chat SDK / no VoIP push:** session mode never touches a Chat SDK call entity. No ringing.\n\n### 4b. Standalone — Ringing mode (CallKit + FCM + UIKit-driven UI)\n\nDual-SDK: Chat SDK signaling + Calls SDK media. Scaffold:\n\n1. **`lib/main.dart`** — Chat SDK + Calls SDK init (no UIKit). Permission_handler request flow. PushKit + FCM listener registration.\n2. **`lib/services/voip_service.dart`** — Combines `flutter_callkit_incoming` events + `firebase_messaging` + iOS platform-channel PushKit. On payload → `FlutterCallkitIncoming.showCallkitIncoming(...)`. On accept → navigate to ongoing-call screen.\n3. **`lib/widgets/call_button.dart`** — Voice + video icon buttons rendered next to a user / contact.\n4. **`lib/screens/ongoing_call_screen.dart`** — `CometChatCalls.joinSession(sessionId:, sessionSettings:, onSuccess:, onError:)` with the returned Widget rendered via `SizedBox.expand`. Implements rule 1.5 cleanup. Sets `resizeToAvoidBottomInset: false`.\n5. **`lib/screens/call_logs_screen.dart`** — `/calls` route. Paginated via `CallLogsRequestBuilder`.\n6. **`MaterialApp.navigatorKey: CallNavigationContext.navigatorKey`** — rule 1.7.\n7. **Native config** — `Info.plist` (rule 1.6), `AndroidManifest.xml` (rule 1.3 + FCM service registration), Firebase config (`google-services.json` in `android/app/`, `GoogleService-Info.plist` in `ios/Runner/`).\n\n## 5. Additive integration\n\nWhen chat is already integrated. The skill:\n\n1. Adds `cometchat_calls_uikit` to `pubspec.yaml`.\n2. Patches the existing `UIKitSettingsBuilder` to add `..callingExtension = CometChatCallingExtension()`.\n3. Sets `CallNavigationContext.navigatorKey` on `MaterialApp.navigatorKey` (rule 1.7).\n4. Mounts the global call listener in the app-shell `State` (rule 1.7).\n5. Confirms `CometChatMessageHeader` already shows call buttons (auto-rendered when `user` / `group` is passed).\n6. Optionally adds `CometChatCallLogs` as a tab/screen if user picked dedicated history.\n7. VoIP push: opt-in (substantial native config).\n\n## 6. Anti-patterns\n\n1. **`MaterialApp` without `CallNavigationContext.navigatorKey`.** Call overlays can't navigate; in-app ring works but accept-into-ongoing breaks. Rule 1.7.\n2. **Forgetting `..callingExtension = CometChatCallingExtension()`** on `UIKitSettingsBuilder`. Calls compile but `CometChatMessageHeader` doesn't show call icons; nothing rings. Most common additive-mode mistake.\n3. **`onAccept` / `onDecline` typed as `Function(Call)`** instead of `Function(BuildContext, Call)`. Compile errors are obvious; the dangerous case is when an agent wraps an existing chat screen's accept handler and silently mismatches signatures.\n4. **Per-screen incoming-call handling.** Calls only ring on the screen where the listener is attached. Listener belongs in the app shell (rule 1.7).\n5. **Skipping `resizeToAvoidBottomInset: false`** on Scaffolds with call UI. Keyboard-show during a call resizes WebRTC views and breaks layout.\n6. **Mixing `cometchat_chat_uikit ^5.x` with `cometchat_calls_uikit ^4.x`** (or vice versa). Internal SDK pin clash. Both UI Kit packages must be on matching majors.\n7. **Sending Android push as `notification`** instead of `data`. ConnectionService can't intercept `notification` payloads. Server must send `data: { type: \"incoming_call\", sessionId: ... }` with `priority: \"high\"`.\n\n## 7. Verification checklist\n\n**Static:**\n\n- [ ] `cometchat_calls_uikit ^5.0.15` in `pubspec.yaml` (additive) OR `cometchat_calls_sdk ^4.2.2` + `cometchat_sdk ^4.1.2` (standalone)\n- [ ] `..callingExtension = CometChatCallingExtension()` on `UIKitSettingsBuilder` (additive)\n- [ ] `MaterialApp.navigatorKey` is `CallNavigationContext.navigatorKey`\n- [ ] Global call listener attached in app-shell State, removed in `dispose`\n- [ ] Listener uses a stable string ID\n- [ ] Camera + microphone + notification permissions requested via `permission_handler`\n- [ ] iOS `Info.plist`: NSCameraUsageDescription + NSMicrophoneUsageDescription + UIBackgroundModes (audio + voip + remote-notification)\n- [ ] Android manifest: four FOREGROUND_SERVICE_* permissions + MANAGE_OWN_CALLS + BIND_TELECOM_CONNECTION_SERVICE\n- [ ] Hangup path: `endSession()` + `FlutterCallkitIncoming.endAllCalls()` + `Navigator.popUntil` (rule 1.5)\n- [ ] **Standalone only:** Firebase configured (`google-services.json` + `GoogleService-Info.plist`)\n- [ ] **Standalone only:** `flutter_callkit_incoming` + `firebase_messaging` + iOS PushKit platform-channel bridge\n\n**Runtime (real devices, both platforms):**\n\n- [ ] iOS — terminated app, lock-screen rings on incoming call\n- [ ] iOS — answer from lock screen → opens app, joins ongoing call\n- [ ] Android — terminated app, heads-up notification rings on incoming call\n- [ ] Android — answer from heads-up → opens app, joins ongoing call\n- [ ] Both — outgoing call connects, two-way audio + video\n- [ ] Both — hangup releases camera + mic, no system call UI stuck\n- [ ] Android 14+: ongoing-call notification visible, swipe-up doesn't kill the call\n- [ ] Keyboard-show during call doesn't break WebRTC view (rule from anti-pattern 5)\n\n## 8. Pointers\n\n- `cometchat-calls` — dispatcher\n- `cometchat-flutter-v5-core` — UIKitSettingsBuilder, init/login order, GetX scope\n- `cometchat-flutter-v5-events` — CometChatCallEvents subscription patterns\n- `cometchat-flutter-v5-push` — FCM/APNs for chat (overlap with VoIP push but distinct paths)\n- `cometchat-flutter-v5-production` — server-minted tokens, ProGuard, environment config\n- `cometchat-flutter-v5-troubleshooting` — pubspec conflicts, GetX issues, Pod errors, runtime crashes\n- `cometchat-flutter-v6-calls` + `cometchat-flutter-v6-migration` — when migrating to V6 (calls fold into the unified package, Bloc replaces GetX)","tags":["cometchat","flutter","calls","skills","agent-skills","ai-agent","chat","claude-code","cursor","messaging","nextjs","react"],"capabilities":["skill","source-cometchat","skill-cometchat-flutter-v5-calls","topic-agent-skills","topic-ai-agent","topic-chat","topic-claude-code","topic-cometchat","topic-cursor","topic-messaging","topic-nextjs","topic-react","topic-react-native","topic-ui-kit"],"categories":["cometchat-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/cometchat/cometchat-skills/cometchat-flutter-v5-calls","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add cometchat/cometchat-skills","source_repo":"https://github.com/cometchat/cometchat-skills","install_from":"skills.sh"}},"qualityScore":"0.463","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 27 github stars · SKILL.md body (20,102 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:04:49.698Z","embedding":null,"createdAt":"2026-05-07T13:05:08.987Z","updatedAt":"2026-05-18T19:04:49.698Z","lastSeenAt":"2026-05-18T19:04:49.698Z","tsv":"'/abort':1505 '/call_log_details':1382 '/calls':1636 '/cometchat/cometchat/':1207 '/docs/calls/flutter/overview':198 '/downloads/calls-sdk/calls-sdk-flutter-5/sample-apps':193,1381 '/downloads/calls-sdk/calls-sdk-flutter-5/sample-apps/cometchat-calls-sample-app-flutter':1465 '/downloads/calls-sdk/calls-sdk-flutter-5/sdk':190 '/heads-up':939 '1':199,862,1467,1559,1676,1753 '1.0':207 '1.1':356,1236 '1.2':528 '1.3':647,780,1009,1654 '1.4':803 '1.5':848,1629,2019 '1.6':960,1173,1651 '1.7':1016,1645,1698,1712,1774,1859 '11.0.0':1171 '14':651,786,2106 '14.0.0':1184 '2':888,1144,1481,1576,1683,1775 '2.0.0':1177,1190 '26.1.0':677 '3':705,901,1268,1490,1601,1692,1798 '4':915,1429,1508,1613,1699,1833,1892 '4.1.2':1954 '4.2.2':1951 '4a':1448 '4b':1539 '5':1634,1666,1713,1860,1886,2135 '5.0.0':1472 '5.0.15':27,1163,1209,1943 '5.2':32 '5.2.14':1155 '5/sample-apps/cometchat-calls-sample-app-flutter':483 '6':1641,1728,1749,1881 '7':1646,1740,1910,1936 '8':2136 'aar':678 'accept':469,495,1405,1594,1769,1827 'accept-into-ongo':1768 'across':323 'activ':1358 'add':122,1164,1677,1689,1730 'addit':113,364,370,400,638,930,1156,1237,1275,1327,1667,1795,1946,1960 'additive-mod':1794 'agent':1820 'agp':681 'alon':1335 'alongsid':28 'alreadi':1158,1672,1716 'also':235 'alway':330 'android':112,566,580,636,650,655,772,776,785,1004,1186,1912,2000,2064,2075,2105 'android.enablejetifier':702 'android.support':691 'android.useandroidx':700 'android/app':1662 'android/app/src/main/androidmanifest.xml':751 'android/gradle.properties':698 'androidmanifest':965 'androidmanifest.xml':1652 'androidx.core':695 'answer':2055,2076 'anti':161,1751,2133 'anti-pattern':160,1750,2132 'anywher':1309 'api':243,569,1388 'apk':722 'app':146,174,192,334,414,749,1020,1065,1070,1091,1324,1378,1708,1764,1856,1970,2046,2060,2066,2082 'app-shel':1707,1969 'app-shell-call-listen':1090 'app-wid':1064 'appid':413,1225,1484 'appli':653 'appsettings.builder':1257 'appshellst':1081 'assembledebug':684 'async':861 'attach':1851,1967 'audio':999,1995,2093 'auth':223,246,263,279,419,807,838 'authkey':278,418,829,1229,1486 'authtoken':307 'auto':1721 'auto-rend':1720 'await':459,883,886,899,971,1239,1254,1261 'back':350 'barrel':1277 'base':15,50 'belong':1067,1853 'bind':763,2009 'bloc':2220 'blow':715 'break':1772,1879,2127 'bridg':539,556,607,1181,2038 'bug':1143 'build':425,506,656,714,721,1238,1500 'buildcontext':1331,1353,1808 'button':1302,1606,1719 'buttonclicklisten':1495 'call':5,7,17,25,43,55,68,77,88,97,114,124,129,142,155,208,218,236,242,244,259,273,326,345,394,402,445,453,461,463,480,501,665,739,762,778,791,821,831,845,854,865,894,897,904,940,951,987,997,1037,1044,1058,1062,1093,1116,1117,1161,1166,1202,1212,1287,1293,1318,1332,1334,1339,1346,1354,1359,1392,1395,1400,1446,1458,1470,1535,1555,1563,1599,1679,1703,1718,1757,1781,1788,1804,1809,1839,1841,1867,1874,1890,1931,1941,1949,1965,2008,2053,2063,2074,2085,2088,2102,2109,2119,2124,2140,2204,2214 'callappsettings.builder':1263 'callback':472,1329,1352 'callingextens':423,1233,1690,1777,1956 'callkit':532,554,557,1123,1175,1543,1580,2029 'calllisten':1085 'calllogsrequestbuild':1365,1640 'callnavigationcontext':1120 'callnavigationcontext.navigatorkey':36,134,1022,1030,1056,1643,1694,1756,1963 'calls-on':844 'calls-sdk-flutt':479 'callsess':879 'callsession.getinstance':884 'callsettingsbuild':484,1356 'callus':283 'camera':1511,1982,2098 'cancel':1411 'cannot':248 'case':1816 'catalog':1270 'cert':628 'cf':773 'channel':538,606,1588,2037 'chat':30,73,83,120,228,268,295,316,440,447,488,836,1153,1397,1442,1462,1476,1480,1523,1533,1552,1561,1670,1824,1884,2167 'chat-sid':487 'check':331 'checklist':1938 'clash':1900 'class':690,1080 'cleanup':850,1428,1630 'code':366,382 'com.android.support':673 'combin':1578 'cometchat':2,6,16,24,29,54,72,76,82,123,154,164,178,254,258,439,444,500,664,738,775,810,1152,1160,1201,1281,1284,1286,1292,1469,1475,1478,1678,1883,1889,1940,1948,1952,2139,2143,2153,2161,2176,2188,2201,2206 'cometchat-android-v5-calls':774 'cometchat-cal':53,153,2138 'cometchat-flutter-v5-calls':1 'cometchat-flutter-v5-core':163,2142 'cometchat-flutter-v5-events':177,2152 'cometchat-flutter-v5-production':809,2175 'cometchat-flutter-v5-push':2160 'cometchat-flutter-v5-troubleshooting':2187 'cometchat-flutter-v6-calls':2200 'cometchat-flutter-v6-migration':2205 'cometchat.addcalllistener':1099 'cometchat.init':1255 'cometchat.initiatecall':460 'cometchat.login':231,261 'cometchat.removecalllistener':1108 'cometchatcallbutton':1297 'cometchatcallev':183,2157 'cometchatcalleventlisten':1086 'cometchatcallevents.addcalleventslistener':1102 'cometchatcallevents.removecalleventslistener':1110 'cometchatcallingextens':33,361,373,424,1234,1691,1778,1957 'cometchatcalllog':1363,1731 'cometchatcalllogdetail':1368 'cometchatcalls.endsession':871 'cometchatcalls.getloggedinuser':332 'cometchatcalls.init':1262,1483 'cometchatcalls.joinsession':507,1496,1615 'cometchatcalls.login':237,275 'cometchatcalls.loginwithauthtoken':306 'cometchatcallsexcept':522 'cometchatcalltype.video':456 'cometchatconfig.appid':1226,1256,1265 'cometchatconfig.authkey':1230 'cometchatconfig.region':1228,1259,1267 'cometchatexcept':287,293,313 'cometchatincomingcal':1317 'cometchatmessageev':182 'cometchatmessagehead':1305,1715,1784 'cometchatongoingcal':1355 'cometchatongoingcallservic':742 'cometchatongoingcallservice.abort':887 'cometchatongoingcallservice.launch':1504 'cometchatongoingcallservice.launch/abort':1503 'cometchatoutgoingcal':1338 'cometchatreceivertype.user':455 'cometchatsubscriptiontype.allusers':422,1232 'cometchatuikit.init':426,1240 'cometchatuikit.loginwithauthtoken':824 'cometchatuikitcal':385,1387 'cometchatuikitcalls.acceptcall':1403 'cometchatuikitcalls.endsession':1425 'cometchatuikitcalls.generatetoken':1412 'cometchatuikitcalls.initiatecall':1351,1391 'cometchatuikitcalls.rejectcall':1407 'cometchatuikitcalls.startsession':1420 'common':1336,1793 'compat':676 'compil':1782,1810 'compon':1269 'config':1510,1648,1659,1748,2186 'configur':127,2023 'confirm':1714 'conflict':2193 'connect':765,2011,2089 'connectionservic':1919 'const':1088 'contact':1612 'context':839,909 'contract':360 'convent':176 'convers':101 'copi':1374 'core':167,1189,2146 'cover':21,814 'crash':783,2199 'custom':87,561 'danger':1815 'dart':251,305,398,429,568,619,851,856,949,966,1052,1079,1221,1253,1289 'dart-sid':948 'dart.cloudsmith.io':1206 'dart.cloudsmith.io/cometchat/cometchat/':1205 'data':577,583,633,1918,1928 'data-messag':632 'debugprint':524 'declar':753,799 'dedic':1738 'default':712 'dep':668 'depend':1148 'detail':1385 'devic':573,2041 'dial':1344 'direct':386,925,1252 'dispatch':156,2141 'dispos':1107,1975 'distinct':1136,2173 'doc':195 'doesn':590,1785,2115,2125 'doubl':1141 'double-r':1140 'dozen':687 'driven':1547 'drop':1303 'dual':358,407,435,1217,1550 'dual-sdk':357,406,434,1216,1549 'duplic':689,1133 'e':288,294,314 'element':802 'enablejetifi':709 'end':547,549,863,898,1426 'end-to-end':546 'endcal':858 'endpoint':818 'endsess':2015 'entiti':1536 'entri':175 'environ':2185 'err':523 'err.message':527 'error':693,728,1811,2197 'even':1041 'event':181,1582,2156 'exclus':1314 'exist':118,874,1686,1823 'explicit':397,433 'export':1280,1373 'extend':1082 'extens':130,403,1167,1213 'fail':297,526,682 'fals':503,505,1633,1863 'fcm':576,631,1187,1518,1544,1573,1655 'fcm/apns':2165 'featur':1077 'final':410,451,457,496,1222 'fire':1063,1138 'firebas':534,574,1182,1188,1191,1583,1658,2022,2031 'first':152,241,595,719 'first-parti':594 'fix':733 'flow':918,1214,1489,1571 'flutter':3,10,45,58,60,165,179,204,482,531,551,553,589,704,720,811,876,1122,1149,1151,1174,1579,2028,2144,2154,2162,2177,2189,2202,2207 'fluttercallkitincoming.endallcalls':900,933,2016 'fluttercallkitincoming.showcallkitincoming':1592 'fold':2215 'foreground':648,756,788,1321,2003 'forget':1776 'forward':613 'four':755,2002 'framework':57 'function':1803,1807 'futur':857 'getx':14,49,171,1025,2150,2194,2222 'getx-bas':13,48 'global':139,1057,1702,1964 'google-services.json':1660,2024 'googleservice-info.plist':1663,2025 'grade':40 'ground':186 'group':1299,1316,1342,1725 'guard':353 'hand':92,349 'hand-rol':91 'handl':927,1840 'handler':963,1015,1170,1488,1569,1828,1989 'handler/permission_handler.dart':970 'hangup':849,2013,2096 'hard':158,202 'head':563,2068,2079 'heads-up':562,2067,2078 'hide':362 'high':582,1935 'histori':1367,1739 'host':748,1194,1204,1361 'icon':1605,1789 'id':415,1129,1134,1137,1981 'implement':1493,1627 'import':252,256,437,442,967,1274,1290 'in-app':1322,1762 'incom':141,533,555,1061,1124,1176,1406,1581,1838,1930,2030,2052,2073 'incoming-cal':140,1837 'incomingcal':1017 'info.plist':964,1649,1991 'init':1210,1219,1565 'init/login':169,2148 'initi':449,458,1046 'initiatecal':1399 'initst':1097 'instead':1805,1916 'integr':8,121,1431,1443,1668,1673 'intercept':1922 'intern':380,1220,1897 'io':111,558,587,630,976,1585,1990,2033,2044,2054 'ios/runner':1665 'ios/runner/appdelegate.swift':609 'ios/runner/info.plist':977 'issu':2195 'jetifi':658,680 'join':465,2061,2083 'joinsess':525 'key':264,280,420,1028 'keyboard':1870,2121 'keyboard-show':1869,2120 'kill':2117 'kit':86,95,102,392,1248,1272,1903 'lag':1199 'launch':324 'layer':115 'layout':1880 'leav':934 'leavesess':882,885 'legaci':672 'level':893 'lib/main.dart':1482,1560 'lib/screens/call_logs_screen.dart':1635 'lib/screens/call_screen.dart':1491 'lib/screens/ongoing_call_screen.dart':1614 'lib/services/voip_service.dart':1577 'lib/widgets/call_button.dart':1602 'line':736 'listen':143,1059,1094,1132,1574,1704,1849,1852,1966,1976 'listenerid':1089,1100,1103,1109,1111 'load':51 'lock':937,2048,2057 'lock-screen':936,2047 'login':210,272,296,319,339 'loginwithauthkey':827 'logout':917 'loud':730 'major':1909 'manag':760,2006 'mandatori':106,660 'manifest':744,1005,2001 'match':474,1464,1908 'materialapp':136,1054,1754 'materialapp.navigatorkey':1035,1642,1696,1961 'media':1557 'meet':1453 'meeting-room':1452 'merg':745 'messag':535,575,578,634,1183,1192,1584,2032 'method':1389 'methodchannel':617 'mic':2099 'microphon':1512,1983 'migrat':2209,2211 'mint':303,806,1414,2182 'mismatch':1831 'miss':793 'mistak':1337,1797 'mix':1882 'mode':66,157,371,389,401,432,541,639,931,1157,1245,1276,1328,1447,1451,1529,1542,1796 'mount':137,907,1018,1700 'must':234,752,797,1031,1905,1926 'mutual':1313 'namespac':796 'nativ':110,625,771,852,1509,1647,1747 'navig':1027,1040,1595,1761 'navigator.of':908 'navigator.popuntil':945,2017 'navigatorkey':1055 'never':1530 'next':1608 'noth':1790 'notif':565,586,1003,1915,1923,1984,1999,2070,2110 'nscamerausagedescript':979,1992 'nsmicrophoneusagedescript':988,1993 'null':250,343 'nullabl':352 'obvious':1813 'omit':708 'onaccept':1319,1799 'oncancel':1343 'ondeclin':1320,1800 'one':661,735 'onerror':286,292,312,521,1502,1619 'ongo':1598,1771,2062,2084,2108 'ongoing-cal':1597,2107 'onincomingcallreceiv':1115 'onitemclick':1364 'onsuccess':265,281,309,348,512,1501,1618 'onto':116 'open':2059,2081 'oper':63 'opt':643,1744 'opt-in':642,1743 'option':1729 'order':170,1211,2149 'os':892 'os-level':891 'outgo':452,462,2087 'overlap':2168 'overlay':1038,1758 'overrid':1095,1105,1113 'overwrit':1135 'own':404 'packag':20,22,126,253,257,438,443,968,1291,1904,2219 'pagin':1366,1638 'parti':596 'pass':1727 'patch':1684 'path':822,2014,2174 'pattern':162,185,819,1029,1379,1752,2134,2159 'payload':584,614,1591,1924 'peer':1193 'per':1835 'per-screen':1834 'permiss':758,961,962,969,1014,1169,1487,1513,1568,1985,1988,2005 'permission.camera':972 'permission.microphone':973 'permission.notification':974 'persist':318 'phone':790 'pick':1737 'piggyback':833 'pin':1899 'pkpushregistry.voip':611 'platform':537,605,1587,2036,2043 'platform-channel':536,604,1586,2035 'plugin':598 'plus':759,1010 'pod':2196 'pointer':2137 'pop':902 'popuntil':912 'prefer':322 'preflight':1402 'prerequisit':657 'prioriti':581,1934 'product':39,71,299,813,820,1433,2179 'production-grad':38 'proguard':2184 'properti':699 'pub.dev':1197 'public':194 'pubspec':2192 'pubspec.yaml':1147,1468,1682,1945 'pull':669 'purpos':37,1296,1390 'push':104,530,545,1527,1742,1913,2164,2171 'pushkit':588,597,626,1516,1572,1589,2034 'r':913 'r.isfirst':914 'rare':383 're':338,1279 're-export':1278 're-login':337 'read':148 'readi':270,285 'real':2040 'receiveruid':454 'recommend':646 'references/call-session.md':1507 'region':416,1227,1485 'regist':374,519,610,741 'registr':1060,1575,1657 'reject':1410 'releas':868,2097 'remot':1002,1998 'remote-notif':1001,1997 'remov':1973 'render':515,1607,1624,1722 'replac':2221 'request':975,1012,1570,1986 'requir':542 'reset':919 'resiz':1875 'resizetoavoidbottominset':1632,1862 'resolut':1198 'result':1349 'return':342,1622 'right':399,430,1053 'ring':450,571,1142,1325,1457,1538,1541,1765,1791,1843,2050,2071 'roll':93 'room':1454 'root':1021 'rootnavig':910 'rout':1051,1118,1637 'rtc':1418 'rule':108,159,173,203,652,769,779,1008,1172,1235,1628,1644,1650,1653,1697,1711,1773,1858,2018,2130 'runtim':1011,2039,2198 'sampl':191,477,1377 'sample-app':1376 'scaffold':707,1466,1558,1865 'scope':172,1417,2151 'screen':89,905,938,952,1078,1386,1600,1825,1836,1846,2049,2058 'sdk':74,78,188,209,219,229,269,274,317,327,346,359,408,436,448,464,481,832,837,866,1150,1218,1285,1288,1398,1401,1459,1463,1471,1477,1524,1534,1551,1553,1556,1562,1564,1898,1950,1953 'sdk/cometchat_calls_sdk.dart':260,446 'sdk/cometchat_chat_sdk.dart':441 'sdk/cometchat_sdk.dart':255 'sdks':379,396,1251 'see':367,1506 'seen':984 'send':1911,1927 'separ':19,225,843 'server':302,620,805,1925,2181 'server-mint':301,804,2180 'servic':649,757,766,789,1656,2004,2012 'serviceloc':920 'session':467,867,1416,1450,1528 'session-scop':1415 'session/joinsession':494 'sessionid':508,509,860,1357,1404,1408,1413,1421,1497,1616,1932 'sessionset':497,510,511,1498,1617 'sessionsettingsbuild':471,491,498,1499 'sessionstatuslisten':520,1494 'set':133,411,428,696,1033,1223,1242,1422,1631,1693 'setappid':1264 'setregion':1258,1266 'settitl':499 'setup':1145 'seven':201 'shape':473 'share':321,1283 'shell':147,1071,1092,1709,1857,1971 'ship':601 'show':1717,1787,1871,2122 'side':489,621,950 'signal':75,1554 'signatur':1832 'silent':782,1830 'singl':567 'singleton':880 'sizedbox.expand':518,1626 'skill':151,600,1675 'skill-cometchat-flutter-v5-calls' 'skip':725,932,943,1861 'slot':1307 'sourc':189,1195 'source-cometchat' 'special':206 'split':409,623,1444 'stabl':1127,1979 'stack':552 'standalon':67,365,388,431,540,1178,1185,1244,1430,1449,1540,1955,2020,2026 'start':335,1393,1423 'startaudiomut':504 'startvideopaus':502 'state':224,1073,1083,1710,1972 'statefulwidget':1492 'static':1087,1939 'status':1409 'step':214,685 'still':956 'strand':946 'string':859,1128,1980 'stuck':942,2104 'sub':1050 'sub-rout':1049 'subscribepresenceforallus':1260 'subscript':184,2158 'subscriptiontyp':421,1231 'substanti':1746 'succeed':232 'super.dispose':1112 'super.initstate':1098 'support':675 'support-compat':674 'surfac':289 'surpris':315 'swipe':2113 'swipe-up':2112 'system':853,2101 'tab/screen':1734 'take':1330 'talk':992 'telecom':764,2010 'tell':889 'termin':2045,2065 'throw':245 'tini':603 'token':247,304,808,817,825,847,1419,2183 'token-endpoint':816 'tokenfrombackend':308 'tool':795 'topic-agent-skills' 'topic-ai-agent' 'topic-chat' 'topic-claude-code' 'topic-cometchat' 'topic-cursor' 'topic-messaging' 'topic-nextjs' 'topic-react' 'topic-react-native' 'topic-ui-kit' 'touch':384,1531 'track':870 'trail':1306 'transit':667 'tree':959,1312 'troubleshoot':2191 'true':701,703,710,911 'truth':187 'two':65,2091 'two-way':2090 'type':490,1801,1929 'ui':85,391,855,895,941,1180,1247,1271,1326,1345,1548,1868,1902,2103 'uibackgroundmod':998,1994 'uid':262,276,277,828 'uikit':11,18,26,31,46,84,125,666,740,926,1154,1162,1203,1282,1372,1479,1546,1567,1680,1885,1891,1942 'uikit-driven':1545 'uikit/cometchat_calls_uikit.dart':1294 'uikitset':427,1241 'uikitsettingsbuild':35,168,412,1224,1687,1780,1959,2147 'uikitsettingsbuilder.callingextension':132,376 'unchang':654 'unifi':2218 'upstream':476 'us':417 'use':355,470,823,877,924,1024,1125,1249,1977 'user':266,267,282,291,310,311,351,1298,1315,1340,1611,1724,1736 'ux':1455 'v4':692 'v5':4,12,47,62,119,166,180,205,215,217,777,812,1023,1441,2145,2155,2163,2178,2190 'v6':2203,2208,2213 'verif':1937 'versa':1896 'version':61,1208 'via':34,131,320,375,517,743,1013,1625,1639,1987 'vice':1895 'video':42,986,996,1301,1436,1604,2094 'view':955,1360,1877,2129 'visibl':2111 'voic':41,994,1300,1435,1603 'voice-video':1434 'void':1096,1106,1114 'voip':103,529,544,627,1000,1179,1520,1526,1741,1996,2170 'way':2092 'webrtc':79,466,869,954,1362,1424,1876,2128 'wide':1066 'widget':98,513,514,516,1168,1273,1295,1623 'wire':23,377 'without':80,99,238,679,1755 'work':543,1766 'wrap':1396,1821 'www.cometchat.com':197 'www.cometchat.com/docs/calls/flutter/overview':196 'x':706,1887,1893 'xml':781,978 'yaml':1146,1200","prices":[{"id":"c82c4798-0b0e-4906-8130-4123dc0f0be9","listingId":"cce2bada-357f-4b55-9d50-48d31283ed08","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"cometchat","category":"cometchat-skills","install_from":"skills.sh"},"createdAt":"2026-05-07T13:05:08.987Z"}],"sources":[{"listingId":"cce2bada-357f-4b55-9d50-48d31283ed08","source":"github","sourceId":"cometchat/cometchat-skills/cometchat-flutter-v5-calls","sourceUrl":"https://github.com/cometchat/cometchat-skills/tree/main/skills/cometchat-flutter-v5-calls","isPrimary":false,"firstSeenAt":"2026-05-07T13:05:08.987Z","lastSeenAt":"2026-05-18T19:04:49.698Z"}],"details":{"listingId":"cce2bada-357f-4b55-9d50-48d31283ed08","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"cometchat","slug":"cometchat-flutter-v5-calls","github":{"repo":"cometchat/cometchat-skills","stars":27,"topics":["agent-skills","ai-agent","chat","claude-code","cometchat","cursor","messaging","nextjs","react","react-native","ui-kit"],"license":null,"html_url":"https://github.com/cometchat/cometchat-skills","pushed_at":"2026-05-18T05:04:24Z","description":"Add CometChat chat to any React, Next.js, React Native, Angular, Android, iOS, or Flutter project through your AI coding agent. Works with Claude Code, Cursor, Codex, VS Code Copilot, Windsurf, Cline, Kiro, and 50+ more agents.","skill_md_sha":"a37e1d275a71c38dc9e8e349944dae706e8792c0","skill_md_path":"skills/cometchat-flutter-v5-calls/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/cometchat/cometchat-skills/tree/main/skills/cometchat-flutter-v5-calls"},"layout":"multi","source":"github","category":"cometchat-skills","frontmatter":{"name":"cometchat-flutter-v5-calls","license":"MIT","description":"CometChat Calls integration for Flutter UIKit v5 (GetX-based, cometchat_calls_uikit separate package). Covers package wiring (cometchat_calls_uikit ^5.0.15 alongside cometchat_chat_uikit ^5.2), CometChatCallingExtension via UIKitSettingsBuilder, CallNavigationContext.navigatorKey, the kit's CometChatCallButtons / CometChatIncomingCall / CometChatOutgoingCall / CometChatOngoingCall / CometChatCallLogs widgets, dual-SDK ringing (CometChat.initiateCall + CometChatUIKitCalls.joinSession), Android FCM + ConnectionService for VoIP push, iOS CallKit + PushKit, foreground service correctness on Android 14+, hangup cleanup, and additive-vs-standalone modes.","compatibility":"Flutter >= 2.5, Dart >= 2.17; cometchat_chat_uikit ^5.2.14; cometchat_calls_uikit ^5.0.15; cometchat_calls_sdk ^4.2.2; cometchat_sdk ^4.1.2"},"skills_sh_url":"https://skills.sh/cometchat/cometchat-skills/cometchat-flutter-v5-calls"},"updatedAt":"2026-05-18T19:04:49.698Z"}}