@cometchat/skills 4.0.0 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -2
- package/bin/install.js +448 -57
- package/package.json +1 -1
- package/skills/cometchat/SKILL.md +337 -80
- package/skills/cometchat-a11y/SKILL.md +476 -0
- package/skills/cometchat-android-v5/SKILL.md +1 -1
- package/skills/cometchat-android-v5-calls/SKILL.md +413 -0
- package/skills/cometchat-android-v5-calls/references/README.md +53 -0
- package/skills/cometchat-android-v5-calls/references/add-calls-to-existing-chat.md +195 -0
- package/skills/cometchat-android-v5-calls/references/audio-controls.md +91 -0
- package/skills/cometchat-android-v5-calls/references/background-handling.md +168 -0
- package/skills/cometchat-android-v5-calls/references/call-layouts.md +123 -0
- package/skills/cometchat-android-v5-calls/references/call-logs.md +113 -0
- package/skills/cometchat-android-v5-calls/references/call-session.md +274 -0
- package/skills/cometchat-android-v5-calls/references/custom-ui.md +150 -0
- package/skills/cometchat-android-v5-calls/references/event-listeners.md +123 -0
- package/skills/cometchat-android-v5-calls/references/group-calls.md +205 -0
- package/skills/cometchat-android-v5-calls/references/idle-timeout.md +111 -0
- package/skills/cometchat-android-v5-calls/references/in-call-chat.md +134 -0
- package/skills/cometchat-android-v5-calls/references/join-session.md +120 -0
- package/skills/cometchat-android-v5-calls/references/migration-v4-to-v5.md +206 -0
- package/skills/cometchat-android-v5-calls/references/participant-management.md +110 -0
- package/skills/cometchat-android-v5-calls/references/picture-in-picture.md +106 -0
- package/skills/cometchat-android-v5-calls/references/raise-hand.md +242 -0
- package/skills/cometchat-android-v5-calls/references/recording.md +101 -0
- package/skills/cometchat-android-v5-calls/references/ringing-integration.md +152 -0
- package/skills/cometchat-android-v5-calls/references/screen-sharing.md +82 -0
- package/skills/cometchat-android-v5-calls/references/server-fcm-voip.md +215 -0
- package/skills/cometchat-android-v5-calls/references/session-settings.md +121 -0
- package/skills/cometchat-android-v5-calls/references/setup.md +137 -0
- package/skills/cometchat-android-v5-calls/references/share-invite.md +151 -0
- package/skills/cometchat-android-v5-calls/references/video-controls.md +87 -0
- package/skills/cometchat-android-v5-calls/references/voip-calling.md +526 -0
- package/skills/cometchat-android-v5-components/SKILL.md +1 -1
- package/skills/cometchat-android-v5-core/SKILL.md +1 -1
- package/skills/cometchat-android-v5-customization/SKILL.md +1 -1
- package/skills/cometchat-android-v5-extensions/SKILL.md +1 -1
- package/skills/cometchat-android-v5-features/SKILL.md +1 -1
- package/skills/cometchat-android-v5-placement/SKILL.md +1 -1
- package/skills/cometchat-android-v5-production/SKILL.md +1 -1
- package/skills/cometchat-android-v5-push/SKILL.md +1 -1
- package/skills/cometchat-android-v5-testing/SKILL.md +1 -1
- package/skills/cometchat-android-v5-theming/SKILL.md +1 -1
- package/skills/cometchat-android-v5-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-android-v6/SKILL.md +1 -1
- package/skills/cometchat-android-v6-builder-settings/SKILL.md +1 -1
- package/skills/cometchat-android-v6-calls/SKILL.md +375 -0
- package/skills/cometchat-android-v6-calls/references/add-calls-to-existing-chat.md +97 -0
- package/skills/cometchat-android-v6-calls/references/call-layouts.md +91 -0
- package/skills/cometchat-android-v6-calls/references/call-session.md +163 -0
- package/skills/cometchat-android-v6-calls/references/device-management.md +171 -0
- package/skills/cometchat-android-v6-calls/references/group-calls.md +191 -0
- package/skills/cometchat-android-v6-calls/references/idle-timeout.md +107 -0
- package/skills/cometchat-android-v6-calls/references/in-call-chat.md +136 -0
- package/skills/cometchat-android-v6-calls/references/raise-hand.md +186 -0
- package/skills/cometchat-android-v6-calls/references/ringing-integration.md +176 -0
- package/skills/cometchat-android-v6-calls/references/server-fcm-voip.md +127 -0
- package/skills/cometchat-android-v6-calls/references/share-invite.md +105 -0
- package/skills/cometchat-android-v6-compose-components/SKILL.md +2 -2
- package/skills/cometchat-android-v6-compose-customization/SKILL.md +1 -1
- package/skills/cometchat-android-v6-compose-placement/SKILL.md +1 -1
- package/skills/cometchat-android-v6-compose-theming/SKILL.md +1 -1
- package/skills/cometchat-android-v6-core/SKILL.md +1 -1
- package/skills/cometchat-android-v6-events/SKILL.md +1 -1
- package/skills/cometchat-android-v6-extensions/SKILL.md +1 -1
- package/skills/cometchat-android-v6-features/SKILL.md +1 -1
- package/skills/cometchat-android-v6-kotlin-components/SKILL.md +1 -1
- package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +1 -1
- package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +1 -1
- package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +1 -1
- package/skills/cometchat-android-v6-migration/SKILL.md +398 -0
- package/skills/cometchat-android-v6-production/SKILL.md +1 -1
- package/skills/cometchat-android-v6-push/SKILL.md +1 -1
- package/skills/cometchat-android-v6-testing/SKILL.md +1 -1
- package/skills/cometchat-android-v6-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-angular-calls/SKILL.md +511 -0
- package/skills/cometchat-angular-calls/references/add-calls-to-existing-chat.md +95 -0
- package/skills/cometchat-angular-calls/references/call-layouts.md +106 -0
- package/skills/cometchat-angular-calls/references/call-session.md +167 -0
- package/skills/cometchat-angular-calls/references/custom-ui.md +231 -0
- package/skills/cometchat-angular-calls/references/device-management.md +135 -0
- package/skills/cometchat-angular-calls/references/group-calls.md +412 -0
- package/skills/cometchat-angular-calls/references/idle-timeout.md +145 -0
- package/skills/cometchat-angular-calls/references/in-call-chat.md +148 -0
- package/skills/cometchat-angular-calls/references/lazy-loading-pitfalls.md +205 -0
- package/skills/cometchat-angular-calls/references/migration-v4-to-v5.md +53 -0
- package/skills/cometchat-angular-calls/references/ngzone-and-async-callbacks.md +183 -0
- package/skills/cometchat-angular-calls/references/picture-in-picture.md +285 -0
- package/skills/cometchat-angular-calls/references/raise-hand.md +167 -0
- package/skills/cometchat-angular-calls/references/recording-screen-share.md +267 -0
- package/skills/cometchat-angular-calls/references/ringing-integration.md +131 -0
- package/skills/cometchat-angular-calls/references/server-web-push-vapid.md +100 -0
- package/skills/cometchat-angular-calls/references/share-invite.md +116 -0
- package/skills/cometchat-angular-components/SKILL.md +1 -1
- package/skills/cometchat-angular-core/SKILL.md +1 -1
- package/skills/cometchat-angular-customization/SKILL.md +1 -1
- package/skills/cometchat-angular-features/SKILL.md +1 -1
- package/skills/cometchat-angular-patterns/SKILL.md +1 -1
- package/skills/cometchat-angular-placement/SKILL.md +1 -1
- package/skills/cometchat-angular-production/SKILL.md +1 -1
- package/skills/cometchat-angular-push/SKILL.md +403 -0
- package/skills/cometchat-angular-testing/SKILL.md +333 -0
- package/skills/cometchat-angular-theming/SKILL.md +1 -1
- package/skills/cometchat-angular-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-astro-patterns/SKILL.md +1 -1
- package/skills/cometchat-calls/SKILL.md +358 -0
- package/skills/cometchat-calls/references/use-case-broadcast.md +194 -0
- package/skills/cometchat-calls/references/use-case-marketplace.md +158 -0
- package/skills/cometchat-calls/references/use-case-support.md +190 -0
- package/skills/cometchat-calls/references/use-case-team.md +169 -0
- package/skills/cometchat-calls/references/use-case-telehealth.md +154 -0
- package/skills/cometchat-components/SKILL.md +1 -1
- package/skills/cometchat-core/SKILL.md +1 -1
- package/skills/cometchat-customization/SKILL.md +2 -2
- package/skills/cometchat-features/SKILL.md +2 -2
- package/skills/cometchat-flutter-v5/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-calls/SKILL.md +325 -94
- package/skills/cometchat-flutter-v5-calls/references/add-calls-to-existing-chat.md +169 -0
- package/skills/cometchat-flutter-v5-calls/references/call-layouts.md +98 -0
- package/skills/cometchat-flutter-v5-calls/references/call-session.md +330 -0
- package/skills/cometchat-flutter-v5-calls/references/device-management.md +120 -0
- package/skills/cometchat-flutter-v5-calls/references/group-calls.md +187 -0
- package/skills/cometchat-flutter-v5-calls/references/idle-timeout.md +97 -0
- package/skills/cometchat-flutter-v5-calls/references/in-call-chat.md +132 -0
- package/skills/cometchat-flutter-v5-calls/references/migration-v4-to-v5.md +160 -0
- package/skills/cometchat-flutter-v5-calls/references/raise-hand.md +244 -0
- package/skills/cometchat-flutter-v5-calls/references/ringing-integration.md +193 -0
- package/skills/cometchat-flutter-v5-calls/references/server-push-bridge.md +101 -0
- package/skills/cometchat-flutter-v5-calls/references/share-invite.md +142 -0
- package/skills/cometchat-flutter-v5-conversations/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-core/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-customization/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-events/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-messages/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-production/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-push/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-testing/SKILL.md +390 -0
- package/skills/cometchat-flutter-v5-theming/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-users-groups/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-calls/SKILL.md +308 -243
- package/skills/cometchat-flutter-v6-calls/references/add-calls-to-existing-chat.md +134 -0
- package/skills/cometchat-flutter-v6-calls/references/call-layouts.md +102 -0
- package/skills/cometchat-flutter-v6-calls/references/call-session.md +229 -0
- package/skills/cometchat-flutter-v6-calls/references/device-management.md +99 -0
- package/skills/cometchat-flutter-v6-calls/references/group-calls.md +190 -0
- package/skills/cometchat-flutter-v6-calls/references/idle-timeout.md +80 -0
- package/skills/cometchat-flutter-v6-calls/references/in-call-chat.md +122 -0
- package/skills/cometchat-flutter-v6-calls/references/raise-hand.md +268 -0
- package/skills/cometchat-flutter-v6-calls/references/ringing-integration.md +171 -0
- package/skills/cometchat-flutter-v6-calls/references/server-push-bridge.md +93 -0
- package/skills/cometchat-flutter-v6-calls/references/share-invite.md +102 -0
- package/skills/cometchat-flutter-v6-components/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-conversations/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-core/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-customization/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-events/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-features/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-messages/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-migration/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-placement/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-production/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-push/SKILL.md +452 -0
- package/skills/cometchat-flutter-v6-testing/SKILL.md +319 -0
- package/skills/cometchat-flutter-v6-theming/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-users-groups/SKILL.md +1 -1
- package/skills/cometchat-i18n/SKILL.md +358 -0
- package/skills/cometchat-ios/SKILL.md +5 -5
- package/skills/cometchat-ios-calls/SKILL.md +409 -0
- package/skills/cometchat-ios-calls/references/add-calls-to-existing-chat.md +172 -0
- package/skills/cometchat-ios-calls/references/avaudiosession-routing.md +189 -0
- package/skills/cometchat-ios-calls/references/call-layouts.md +136 -0
- package/skills/cometchat-ios-calls/references/call-session.md +221 -0
- package/skills/cometchat-ios-calls/references/callkit-and-pushkit.md +353 -0
- package/skills/cometchat-ios-calls/references/custom-ui.md +322 -0
- package/skills/cometchat-ios-calls/references/device-management.md +171 -0
- package/skills/cometchat-ios-calls/references/group-calls.md +396 -0
- package/skills/cometchat-ios-calls/references/idle-timeout.md +185 -0
- package/skills/cometchat-ios-calls/references/in-call-chat.md +183 -0
- package/skills/cometchat-ios-calls/references/migration-v4-to-v5.md +138 -0
- package/skills/cometchat-ios-calls/references/picture-in-picture.md +246 -0
- package/skills/cometchat-ios-calls/references/raise-hand.md +239 -0
- package/skills/cometchat-ios-calls/references/recording-screen-share.md +339 -0
- package/skills/cometchat-ios-calls/references/ringing-integration.md +142 -0
- package/skills/cometchat-ios-calls/references/server-apns-pushkit.md +267 -0
- package/skills/cometchat-ios-calls/references/share-invite.md +152 -0
- package/skills/cometchat-ios-calls/references/swiftui-uikit-hosting.md +246 -0
- package/skills/cometchat-ios-calls/references/voip-cert-setup.md +166 -0
- package/skills/cometchat-ios-components/SKILL.md +1 -1
- package/skills/cometchat-ios-core/SKILL.md +1 -1
- package/skills/cometchat-ios-customization/SKILL.md +1 -1
- package/skills/cometchat-ios-features/SKILL.md +1 -1
- package/skills/cometchat-ios-placement/SKILL.md +1 -1
- package/skills/cometchat-ios-production/SKILL.md +1 -1
- package/skills/cometchat-ios-push/SKILL.md +1 -1
- package/skills/cometchat-ios-testing/SKILL.md +371 -0
- package/skills/cometchat-ios-theming/SKILL.md +1 -1
- package/skills/cometchat-ios-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-native-bare-patterns/SKILL.md +45 -3
- package/skills/cometchat-native-calls/SKILL.md +599 -0
- package/skills/cometchat-native-calls/references/add-calls-to-existing-chat.md +203 -0
- package/skills/cometchat-native-calls/references/call-layouts.md +124 -0
- package/skills/cometchat-native-calls/references/call-session.md +182 -0
- package/skills/cometchat-native-calls/references/custom-ui.md +250 -0
- package/skills/cometchat-native-calls/references/device-management.md +135 -0
- package/skills/cometchat-native-calls/references/expo-vs-bare.md +179 -0
- package/skills/cometchat-native-calls/references/group-calls.md +291 -0
- package/skills/cometchat-native-calls/references/idle-timeout.md +128 -0
- package/skills/cometchat-native-calls/references/in-call-chat.md +143 -0
- package/skills/cometchat-native-calls/references/migration-v4-to-v5.md +72 -0
- package/skills/cometchat-native-calls/references/picture-in-picture.md +276 -0
- package/skills/cometchat-native-calls/references/raise-hand.md +203 -0
- package/skills/cometchat-native-calls/references/recording-screen-share.md +290 -0
- package/skills/cometchat-native-calls/references/ringing-integration.md +118 -0
- package/skills/cometchat-native-calls/references/server-push-bridge.md +135 -0
- package/skills/cometchat-native-calls/references/server-push-payloads.md +193 -0
- package/skills/cometchat-native-calls/references/share-invite.md +144 -0
- package/skills/cometchat-native-calls/references/voip-push-end-to-end.md +317 -0
- package/skills/cometchat-native-components/SKILL.md +1 -1
- package/skills/cometchat-native-core/SKILL.md +1 -1
- package/skills/cometchat-native-customization/SKILL.md +1 -1
- package/skills/cometchat-native-expo-patterns/SKILL.md +18 -1
- package/skills/cometchat-native-features/SKILL.md +1 -1
- package/skills/cometchat-native-placement/SKILL.md +1 -1
- package/skills/cometchat-native-production/SKILL.md +1 -1
- package/skills/cometchat-native-push/SKILL.md +1 -1
- package/skills/cometchat-native-testing/SKILL.md +1 -1
- package/skills/cometchat-native-theming/SKILL.md +1 -1
- package/skills/cometchat-native-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-nextjs-patterns/SKILL.md +1 -1
- package/skills/cometchat-placement/SKILL.md +29 -1
- package/skills/cometchat-production/SKILL.md +1 -1
- package/skills/cometchat-react-calls/SKILL.md +539 -0
- package/skills/cometchat-react-calls/references/add-calls-to-existing-chat.md +145 -0
- package/skills/cometchat-react-calls/references/call-layouts.md +161 -0
- package/skills/cometchat-react-calls/references/call-session.md +235 -0
- package/skills/cometchat-react-calls/references/custom-ui.md +201 -0
- package/skills/cometchat-react-calls/references/device-management.md +206 -0
- package/skills/cometchat-react-calls/references/group-calls.md +262 -0
- package/skills/cometchat-react-calls/references/idle-timeout.md +175 -0
- package/skills/cometchat-react-calls/references/in-call-chat.md +212 -0
- package/skills/cometchat-react-calls/references/migration-v4-to-v5.md +172 -0
- package/skills/cometchat-react-calls/references/picture-in-picture.md +245 -0
- package/skills/cometchat-react-calls/references/raise-hand.md +238 -0
- package/skills/cometchat-react-calls/references/recording-screen-share.md +143 -0
- package/skills/cometchat-react-calls/references/ringing-integration.md +255 -0
- package/skills/cometchat-react-calls/references/server-web-push-vapid.md +241 -0
- package/skills/cometchat-react-calls/references/share-invite.md +176 -0
- package/skills/cometchat-react-calls/references/testing-calls-on-web.md +198 -0
- package/skills/cometchat-react-calls/references/voip-and-web-push.md +165 -0
- package/skills/cometchat-react-patterns/SKILL.md +56 -8
- package/skills/cometchat-react-push/SKILL.md +448 -0
- package/skills/cometchat-react-router-patterns/SKILL.md +1 -1
- package/skills/cometchat-react-testing/SKILL.md +404 -0
- package/skills/cometchat-theming/SKILL.md +3 -3
- package/skills/cometchat-troubleshooting/SKILL.md +2 -2
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Adding calls to an existing chat integration (Flutter V5)
|
|
2
|
+
|
|
3
|
+
You have `cometchat_chat_uikit` v5 working. Adding calls = `cometchat_calls_uikit: ^5.0.15` plus iOS/Android native config.
|
|
4
|
+
|
|
5
|
+
**Read first:** `cometchat-flutter-v5-calls/SKILL.md` — Flutter calls architecture (GetX patterns).
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Step 1 — Add the calls package
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
# pubspec.yaml
|
|
13
|
+
dependencies:
|
|
14
|
+
cometchat_chat_uikit: ^5.x.x # existing
|
|
15
|
+
cometchat_calls_uikit: ^5.0.15 # NEW
|
|
16
|
+
flutter_callkit_incoming: ^2.0.4 # for OS-level incoming-call UI
|
|
17
|
+
flutter_voip_pushkit: ^0.2.1 # iOS PushKit
|
|
18
|
+
firebase_messaging: ^15.0.0 # Android FCM
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
flutter pub get
|
|
23
|
+
cd ios && pod install
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Step 2 — iOS + Android native config
|
|
29
|
+
|
|
30
|
+
**iOS** — same as native iOS calls (see `cometchat-ios-calls/references/add-calls-to-existing-chat.md`):
|
|
31
|
+
- Push Notifications + Background Modes (audio, voip, remote-notification) capabilities
|
|
32
|
+
- Info.plist: NSCameraUsageDescription, NSMicrophoneUsageDescription
|
|
33
|
+
|
|
34
|
+
**Android** — same as Android V5 calls (see `cometchat-android-v5-calls/references/add-calls-to-existing-chat.md`):
|
|
35
|
+
- All permissions
|
|
36
|
+
- ConnectionService declared
|
|
37
|
+
- `foregroundServiceType` for Android 14+
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Step 3 — Init order: chat → calls
|
|
42
|
+
|
|
43
|
+
In your existing init (typically `main.dart`):
|
|
44
|
+
|
|
45
|
+
```dart
|
|
46
|
+
import 'package:cometchat_chat_uikit/cometchat_chat_uikit.dart';
|
|
47
|
+
import 'package:cometchat_calls_uikit/cometchat_calls_uikit.dart';
|
|
48
|
+
|
|
49
|
+
Future<void> main() async {
|
|
50
|
+
WidgetsFlutterBinding.ensureInitialized();
|
|
51
|
+
|
|
52
|
+
// Existing chat init
|
|
53
|
+
final chatSettings = UIKitSettingsBuilder()
|
|
54
|
+
..setAppId(APP_ID)
|
|
55
|
+
..setRegion(REGION);
|
|
56
|
+
await CometChatUIKit.init(uiKitSettings: chatSettings.build());
|
|
57
|
+
|
|
58
|
+
// NEW: Calls init AFTER chat init
|
|
59
|
+
final callsSettings = CallAppSettings(appId: APP_ID, region: REGION);
|
|
60
|
+
await CometChatCalls.init(callsSettings);
|
|
61
|
+
|
|
62
|
+
runApp(const MyApp());
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Step 4 — Login both SDKs
|
|
69
|
+
|
|
70
|
+
After `CometChatUIKit.login`:
|
|
71
|
+
|
|
72
|
+
```dart
|
|
73
|
+
final user = await CometChatUIKit.login(uid: uid, authKey: AUTH_KEY);
|
|
74
|
+
final authToken = user.authToken;
|
|
75
|
+
await CometChatCalls.login(authToken: authToken);
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Step 5 — Mount IncomingCall at app root
|
|
81
|
+
|
|
82
|
+
```dart
|
|
83
|
+
class MyApp extends StatelessWidget {
|
|
84
|
+
@override
|
|
85
|
+
Widget build(BuildContext context) {
|
|
86
|
+
return MaterialApp(
|
|
87
|
+
home: Stack(
|
|
88
|
+
children: [
|
|
89
|
+
const AppRoot(),
|
|
90
|
+
// Sibling overlay
|
|
91
|
+
const CometChatIncomingCall(),
|
|
92
|
+
],
|
|
93
|
+
),
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Step 6 — VoIP push registration
|
|
102
|
+
|
|
103
|
+
```dart
|
|
104
|
+
import 'dart:io';
|
|
105
|
+
import 'package:flutter_voip_pushkit/flutter_voip_pushkit.dart';
|
|
106
|
+
import 'package:firebase_messaging/firebase_messaging.dart';
|
|
107
|
+
|
|
108
|
+
class CallPushService {
|
|
109
|
+
Future<void> register(String userUid) async {
|
|
110
|
+
if (Platform.isIOS) {
|
|
111
|
+
final voip = FlutterVoipPushKit();
|
|
112
|
+
voip.onTokenRefresh.listen((token) {
|
|
113
|
+
api.registerCallToken(uid: userUid, platform: 'ios-voip', token: token);
|
|
114
|
+
});
|
|
115
|
+
await voip.configure();
|
|
116
|
+
} else if (Platform.isAndroid) {
|
|
117
|
+
final messaging = FirebaseMessaging.instance;
|
|
118
|
+
await messaging.requestPermission();
|
|
119
|
+
final token = await messaging.getToken();
|
|
120
|
+
if (token != null) {
|
|
121
|
+
await api.registerCallToken(uid: userUid, platform: 'android-fcm', token: token);
|
|
122
|
+
}
|
|
123
|
+
messaging.onTokenRefresh.listen((t) {
|
|
124
|
+
api.registerCallToken(uid: userUid, platform: 'android-fcm', token: t);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Trigger after `CometChatCalls.login` completes.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Step 7 — Hangup teardown
|
|
136
|
+
|
|
137
|
+
```dart
|
|
138
|
+
Future<void> endCall(String sessionId) async {
|
|
139
|
+
CometChatCalls.leaveSession();
|
|
140
|
+
await CometChat.endCall(sessionId);
|
|
141
|
+
// OS-level UI dismiss via flutter_callkit_incoming
|
|
142
|
+
await FlutterCallkitIncoming.endCall(sessionId);
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Verification checklist
|
|
149
|
+
|
|
150
|
+
- [ ] `cometchat_calls_uikit: ^5.0.15` + native plugins in pubspec
|
|
151
|
+
- [ ] iOS Background Modes + Info.plist usage descriptions
|
|
152
|
+
- [ ] Android permissions + ConnectionService declared
|
|
153
|
+
- [ ] Calls init AFTER chat init in main()
|
|
154
|
+
- [ ] Calls login AFTER chat login
|
|
155
|
+
- [ ] `CometChatIncomingCall` sibling-overlay at root
|
|
156
|
+
- [ ] VoIP token registration triggered post-login
|
|
157
|
+
- [ ] Hangup teardown calls leaveSession + endCall + endCall (callkit)
|
|
158
|
+
- [ ] Real-device smoke: backgrounded incoming call rings on lock screen
|
|
159
|
+
- [ ] Run `cometchat verify --calls` — should pass
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Pointers
|
|
164
|
+
|
|
165
|
+
- `cometchat-react-calls/references/add-calls-to-existing-chat.md` — canonical
|
|
166
|
+
- `cometchat-flutter-v5-calls/SKILL.md` — GetX patterns
|
|
167
|
+
- `cometchat-flutter-v5-calls/references/server-push-bridge.md` — server-side push
|
|
168
|
+
- `cometchat-ios-calls/references/add-calls-to-existing-chat.md` — iOS native config
|
|
169
|
+
- `cometchat-android-v5-calls/references/add-calls-to-existing-chat.md` — Android native config
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Call layouts on Flutter V5 (GetX)
|
|
2
|
+
|
|
3
|
+
Same three layouts (TILE/SIDEBAR/SPOTLIGHT). Flutter-specific: `SegmentedButton` is the cross-platform native picker (Material 3); GetX wraps the SDK layout in an `Rx` for reactive UI.
|
|
4
|
+
|
|
5
|
+
**Canonical docs:** https://www.cometchat.com/docs/calls/flutter/call-layouts
|
|
6
|
+
**Read first:** `cometchat-react-calls/references/call-layouts.md` — layout matrix.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## SDK API
|
|
11
|
+
|
|
12
|
+
```dart
|
|
13
|
+
import 'package:cometchat_calls_uikit/cometchat_calls_uikit.dart';
|
|
14
|
+
|
|
15
|
+
final settings = CallSettingsBuilder()
|
|
16
|
+
..setLayout(CallLayout.tile) // CallLayout.tile | .sidebar | .spotlight
|
|
17
|
+
..setHideChangeLayoutButton(false);
|
|
18
|
+
|
|
19
|
+
// Mid-call switch
|
|
20
|
+
CometChatCalls.setLayout(CallLayout.spotlight);
|
|
21
|
+
|
|
22
|
+
// Listen — implement in your CometChatCallsEventsListener
|
|
23
|
+
@override
|
|
24
|
+
void onCallLayoutChanged(CallLayout layout) {
|
|
25
|
+
Get.find<CallLayoutController>().layout.value = layout;
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## GetX controller
|
|
32
|
+
|
|
33
|
+
```dart
|
|
34
|
+
class CallLayoutController extends GetxController {
|
|
35
|
+
final layout = CallLayout.tile.obs;
|
|
36
|
+
|
|
37
|
+
void set(CallLayout next) {
|
|
38
|
+
CometChatCalls.setLayout(next);
|
|
39
|
+
layout.value = next;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## SegmentedButton switcher
|
|
47
|
+
|
|
48
|
+
```dart
|
|
49
|
+
class LayoutSwitcher extends StatelessWidget {
|
|
50
|
+
const LayoutSwitcher({super.key});
|
|
51
|
+
|
|
52
|
+
@override
|
|
53
|
+
Widget build(BuildContext context) {
|
|
54
|
+
final ctrl = Get.find<CallLayoutController>();
|
|
55
|
+
return Obx(() => SegmentedButton<CallLayout>(
|
|
56
|
+
segments: const [
|
|
57
|
+
ButtonSegment(value: CallLayout.tile, label: Text('Tile')),
|
|
58
|
+
ButtonSegment(value: CallLayout.sidebar, label: Text('Sidebar')),
|
|
59
|
+
ButtonSegment(value: CallLayout.spotlight, label: Text('Spotlight')),
|
|
60
|
+
],
|
|
61
|
+
selected: {ctrl.layout.value},
|
|
62
|
+
onSelectionChanged: (set) {
|
|
63
|
+
if (set.isNotEmpty) ctrl.set(set.first);
|
|
64
|
+
},
|
|
65
|
+
));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`Obx` rebuilds when `layout` changes; the switcher stays in sync if the kit's switcher fires `onCallLayoutChanged`.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Anti-patterns
|
|
75
|
+
|
|
76
|
+
Web sister rules apply, plus Flutter-specific:
|
|
77
|
+
|
|
78
|
+
1. **`DropdownButton` instead of `SegmentedButton`.** Hides the options. `SegmentedButton` is Material 3's radio-group equivalent.
|
|
79
|
+
2. **`StatefulWidget` with `setState` instead of GetX `Rx`.** Multiple components (toolbar, header) can't share layout state — GetX `Rx` solves it.
|
|
80
|
+
3. **Forgetting `Obx` wrapper.** UI doesn't react to changes from the kit's switcher.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Verification checklist
|
|
85
|
+
|
|
86
|
+
- [ ] `CallLayoutController` registered (via `Get.put` at call start)
|
|
87
|
+
- [ ] `SegmentedButton` wrapped in `Obx`
|
|
88
|
+
- [ ] `onCallLayoutChanged` updates the controller
|
|
89
|
+
- [ ] Initial layout via `setLayout` on builder
|
|
90
|
+
- [ ] Real-device smoke: switcher cycles all 3 on Android + iOS
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Pointers
|
|
95
|
+
|
|
96
|
+
- `cometchat-react-calls/references/call-layouts.md` — sister
|
|
97
|
+
- `cometchat-flutter-v5-calls` SKILL.md
|
|
98
|
+
- Canonical docs: https://www.cometchat.com/docs/calls/flutter/call-layouts
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
# Call session — joinSession with no ringing (Flutter V5 / GetX)
|
|
2
|
+
|
|
3
|
+
Server-generated sessionId, both parties enter it. Customer-validated against `~/Downloads/calls-sdk/calls-sdk-flutter-5/sample-apps/cometchat-calls-sample-app-flutter/lib/screens/call_screen.dart`.
|
|
4
|
+
|
|
5
|
+
**Read first:** `cometchat-react-calls/references/call-session.md` — full architecture (sessionId strategies, server-side authorization, token generation). Then come back here for the Flutter-specific shape.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Hard rules (Flutter-specific overrides on top of the cross-platform rules)
|
|
10
|
+
|
|
11
|
+
1. **`CometChatCalls.joinSession(sessionId:, sessionSettings:, onSuccess:, onError:)` uses CALLBACKS, not Futures.** `onSuccess` receives a `Widget?` you must render. There is NO controller-based API in the Calls SDK; do not invent one.
|
|
12
|
+
2. **`SessionSettingsBuilder` is the canonical settings shape.** `SessionSettingsBuilder().setTitle().startVideoPaused(false).startAudioMuted(false).build()`. NOT `CallSettings(sessionType:, layout:)` — that is a chat-side type. The sample uses the Builder pattern.
|
|
13
|
+
3. **Implement `SessionStatusListeners`** for lifecycle events: `onSessionJoined`, `onSessionLeft`, `onConnectionClosed`, `onConnectionLost`, `onConnectionRestored`, `onSessionTimedOut`. Register via `CallSession.getInstance().addSessionStatusListener(this)` AFTER `onSuccess` fires.
|
|
14
|
+
3a. **Funnel ALL termination paths through a single guarded `_navigateBack()` helper.** The v5 Calls SDK fires 3 termination listeners in sequence on every hangup: `onLeaveSessionButtonClicked` → `onSessionLeft` → `onConnectionClosed`. If each one pops the navigator independently, the second pop crashes with `Bad state: No element` because the route is already gone. The upstream sample at `~/Downloads/calls-sdk/calls-sdk-flutter-5/sample-apps/cometchat-calls-sample-app-flutter/lib/screens/call_screen.dart` has the unguarded multi-pop pattern — it happens to work there because of timing differences but is fragile. **Always use a single guarded helper**:
|
|
15
|
+
```dart
|
|
16
|
+
bool _isLeavingSession = false;
|
|
17
|
+
|
|
18
|
+
void _navigateBack() {
|
|
19
|
+
if (_isLeavingSession) return;
|
|
20
|
+
if (!mounted) return;
|
|
21
|
+
if (!Navigator.of(context).canPop()) return;
|
|
22
|
+
_isLeavingSession = true;
|
|
23
|
+
CometChatOngoingCallService.abort();
|
|
24
|
+
Navigator.of(context).pop();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@override
|
|
28
|
+
void onSessionLeft() => _navigateBack();
|
|
29
|
+
@override
|
|
30
|
+
void onConnectionClosed() => _navigateBack();
|
|
31
|
+
@override
|
|
32
|
+
void onSessionTimedOut() => _navigateBack();
|
|
33
|
+
|
|
34
|
+
@override
|
|
35
|
+
void onLeaveSessionButtonClicked() {
|
|
36
|
+
// Trigger the leave; the listener chain calls _navigateBack().
|
|
37
|
+
_callSession?.leaveSession();
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
4. **`CometChatOngoingCallService.launch()` + `CometChatOngoingCallService.abort()`** manage the platform foreground service. Call `launch()` after `onSessionJoined`; call `abort()` inside the `_navigateBack()` helper (so it fires exactly once on the first termination event).
|
|
41
|
+
5. **Render the returned widget with `SizedBox.expand(child: videoWidget)`.** Anything that constrains the widget (Padding, Container with explicit width/height smaller than viewport) clips the call UI.
|
|
42
|
+
6. **For standalone session-only integrations, the Chat SDK is OPTIONAL.** The upstream Flutter sample only uses `cometchat_calls_sdk`. Keep dual-SDK only for additive (chat + calls) integrations.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Dependencies
|
|
47
|
+
|
|
48
|
+
```yaml
|
|
49
|
+
dependencies:
|
|
50
|
+
cometchat_calls_sdk: ^5.0.0
|
|
51
|
+
permission_handler: ^11.0.0
|
|
52
|
+
uni_links: ^0.5.1
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
For standalone session-only, you do NOT need `cometchat_chat_sdk`.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Call screen (StatefulWidget + SessionStatusListeners)
|
|
60
|
+
|
|
61
|
+
```dart
|
|
62
|
+
import 'package:cometchat_calls_sdk/cometchat_calls_sdk.dart';
|
|
63
|
+
import 'package:flutter/material.dart';
|
|
64
|
+
|
|
65
|
+
class CallScreen extends StatefulWidget {
|
|
66
|
+
const CallScreen({super.key, required this.sessionId});
|
|
67
|
+
final String sessionId;
|
|
68
|
+
|
|
69
|
+
@override
|
|
70
|
+
State<CallScreen> createState() => _CallScreenState();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
class _CallScreenState extends State<CallScreen>
|
|
74
|
+
implements SessionStatusListeners, ButtonClickListeners {
|
|
75
|
+
Widget? _videoContainer;
|
|
76
|
+
bool _isLoading = true;
|
|
77
|
+
bool _hasError = false;
|
|
78
|
+
String? _errorMessage;
|
|
79
|
+
bool _isLeavingSession = false;
|
|
80
|
+
CallSession? _callSession;
|
|
81
|
+
|
|
82
|
+
@override
|
|
83
|
+
void initState() {
|
|
84
|
+
super.initState();
|
|
85
|
+
_joinSession();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@override
|
|
89
|
+
void dispose() {
|
|
90
|
+
_unregisterListeners();
|
|
91
|
+
CometChatOngoingCallService.abort();
|
|
92
|
+
super.dispose();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
void _joinSession() {
|
|
96
|
+
final sessionSettings = (SessionSettingsBuilder()
|
|
97
|
+
.setTitle('CometChat Meeting')
|
|
98
|
+
.startVideoPaused(false)
|
|
99
|
+
.startAudioMuted(false))
|
|
100
|
+
.build();
|
|
101
|
+
|
|
102
|
+
CometChatCalls.joinSession(
|
|
103
|
+
sessionId: widget.sessionId,
|
|
104
|
+
sessionSettings: sessionSettings,
|
|
105
|
+
onSuccess: (Widget? videoWidget) {
|
|
106
|
+
if (!mounted) return;
|
|
107
|
+
setState(() {
|
|
108
|
+
_videoContainer = videoWidget;
|
|
109
|
+
_isLoading = false;
|
|
110
|
+
_hasError = false;
|
|
111
|
+
});
|
|
112
|
+
_registerListeners();
|
|
113
|
+
CometChatOngoingCallService.launch();
|
|
114
|
+
},
|
|
115
|
+
onError: (CometChatCallsException error) {
|
|
116
|
+
if (!mounted) return;
|
|
117
|
+
setState(() {
|
|
118
|
+
_isLoading = false;
|
|
119
|
+
_hasError = true;
|
|
120
|
+
_errorMessage = error.message ?? 'Failed to join session';
|
|
121
|
+
});
|
|
122
|
+
},
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
void _registerListeners() {
|
|
127
|
+
_callSession = CallSession.getInstance();
|
|
128
|
+
_callSession?.addSessionStatusListener(this);
|
|
129
|
+
_callSession?.addButtonClickListener(this);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
void _unregisterListeners() {
|
|
133
|
+
_callSession?.removeSessionStatusListener(this);
|
|
134
|
+
_callSession?.removeButtonClickListener(this);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
void _navigateBack() {
|
|
138
|
+
// ONE guarded path for all termination events (onSessionLeft +
|
|
139
|
+
// onConnectionClosed + onSessionTimedOut + post-leaveSession).
|
|
140
|
+
// The SDK fires multiple termination listeners in sequence; without
|
|
141
|
+
// this guard, the second pop crashes with `Bad state: No element`.
|
|
142
|
+
if (_isLeavingSession) return;
|
|
143
|
+
if (!mounted) return;
|
|
144
|
+
if (!Navigator.of(context).canPop()) return;
|
|
145
|
+
_isLeavingSession = true;
|
|
146
|
+
CometChatOngoingCallService.abort();
|
|
147
|
+
Navigator.of(context).pop();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// --- SessionStatusListeners ---
|
|
151
|
+
|
|
152
|
+
@override
|
|
153
|
+
void onSessionJoined() {
|
|
154
|
+
CometChatOngoingCallService.launch();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// All termination events funnel through ONE guarded _navigateBack().
|
|
158
|
+
// SDK fires onSessionLeft + onConnectionClosed in sequence on every
|
|
159
|
+
// hangup; unguarded pops crash with `Bad state: No element`.
|
|
160
|
+
@override
|
|
161
|
+
void onSessionLeft() => _navigateBack();
|
|
162
|
+
|
|
163
|
+
@override
|
|
164
|
+
void onConnectionClosed() => _navigateBack();
|
|
165
|
+
|
|
166
|
+
@override
|
|
167
|
+
void onSessionTimedOut() => _navigateBack();
|
|
168
|
+
|
|
169
|
+
@override
|
|
170
|
+
void onConnectionLost() {
|
|
171
|
+
if (mounted) {
|
|
172
|
+
ScaffoldMessenger.of(context).showSnackBar(
|
|
173
|
+
const SnackBar(content: Text('Connection lost')),
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
@override
|
|
179
|
+
void onConnectionRestored() {
|
|
180
|
+
if (mounted) {
|
|
181
|
+
ScaffoldMessenger.of(context).showSnackBar(
|
|
182
|
+
const SnackBar(content: Text('Connection restored')),
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// --- ButtonClickListeners (stub the ones you don't customize) ---
|
|
188
|
+
|
|
189
|
+
@override
|
|
190
|
+
void onLeaveSessionButtonClicked() {
|
|
191
|
+
// Trigger leave; the listener chain calls _navigateBack().
|
|
192
|
+
_callSession?.leaveSession();
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
@override
|
|
196
|
+
void onChangeLayoutButtonClicked() {}
|
|
197
|
+
@override
|
|
198
|
+
void onChatButtonClicked() {}
|
|
199
|
+
@override
|
|
200
|
+
void onParticipantListButtonClicked() {}
|
|
201
|
+
@override
|
|
202
|
+
void onRaiseHandButtonClicked() {}
|
|
203
|
+
@override
|
|
204
|
+
void onRecordingToggleButtonClicked() {}
|
|
205
|
+
@override
|
|
206
|
+
void onShareInviteButtonClicked() {}
|
|
207
|
+
@override
|
|
208
|
+
void onSwitchCameraButtonClicked() {}
|
|
209
|
+
@override
|
|
210
|
+
void onToggleAudioButtonClicked() {}
|
|
211
|
+
@override
|
|
212
|
+
void onToggleVideoButtonClicked() {}
|
|
213
|
+
|
|
214
|
+
@override
|
|
215
|
+
Widget build(BuildContext context) {
|
|
216
|
+
return Scaffold(
|
|
217
|
+
backgroundColor: Colors.black,
|
|
218
|
+
body: _buildBody(),
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
Widget _buildBody() {
|
|
223
|
+
if (_isLoading) {
|
|
224
|
+
return const Center(child: CircularProgressIndicator(color: Colors.deepPurple));
|
|
225
|
+
}
|
|
226
|
+
if (_hasError) {
|
|
227
|
+
return Center(child: Text(_errorMessage ?? 'Error', style: const TextStyle(color: Colors.white)));
|
|
228
|
+
}
|
|
229
|
+
if (_videoContainer != null) {
|
|
230
|
+
return SizedBox.expand(child: _videoContainer);
|
|
231
|
+
}
|
|
232
|
+
return const SizedBox.shrink();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Why this shape:**
|
|
238
|
+
|
|
239
|
+
- **Callback API** (`onSuccess`, `onError`) instead of `Future` — `joinSession` returns void; the widget arrives via `onSuccess`. Awaiting it does nothing useful.
|
|
240
|
+
- **`SessionSettingsBuilder`** instead of `CallSettings` — `CallSettings` is the chat-side type for ringing-mode call entities; `SessionSettingsBuilder` is what session-mode actually accepts.
|
|
241
|
+
- **`SessionStatusListeners` interface implementation** instead of stream subscriptions — register against `CallSession.getInstance()` after `onSuccess`. Returns nothing; cleanup via `removeSessionStatusListener` in `dispose`.
|
|
242
|
+
- **`CometChatOngoingCallService.launch()/abort()`** — required for foreground-service correctness on Android 14+. Without `abort()` the service notification persists after the call ends.
|
|
243
|
+
- **`SizedBox.expand`** — the SDK's returned widget must fill its parent. Constraining it (Container with width/height, Padding) clips the call surface.
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Permissions (Android `AndroidManifest.xml` + iOS `Info.plist`)
|
|
248
|
+
|
|
249
|
+
Android:
|
|
250
|
+
```xml
|
|
251
|
+
<uses-permission android:name="android.permission.CAMERA" />
|
|
252
|
+
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
|
253
|
+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
|
254
|
+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
|
|
255
|
+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
iOS:
|
|
259
|
+
```xml
|
|
260
|
+
<key>NSCameraUsageDescription</key>
|
|
261
|
+
<string>Camera is needed for video calls</string>
|
|
262
|
+
<key>NSMicrophoneUsageDescription</key>
|
|
263
|
+
<string>Microphone is needed for calls</string>
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Runtime request before `_joinSession`:
|
|
267
|
+
```dart
|
|
268
|
+
await Permission.camera.request();
|
|
269
|
+
await Permission.microphone.request();
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Deep-link routing (uni_links)
|
|
275
|
+
|
|
276
|
+
```dart
|
|
277
|
+
void initDeepLinks() {
|
|
278
|
+
uriLinkStream.listen((Uri? uri) {
|
|
279
|
+
if (uri == null) return;
|
|
280
|
+
if (uri.pathSegments.length >= 2 && uri.pathSegments[0] == 'meet') {
|
|
281
|
+
final sessionId = uri.pathSegments[1];
|
|
282
|
+
Get.toNamed('/meet/$sessionId');
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
See `cometchat-flutter-v5-calls/references/share-invite.md` for full deep-link config.
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Anti-patterns
|
|
293
|
+
|
|
294
|
+
1. **Using `CallSettings(sessionType:, layout:)` instead of `SessionSettingsBuilder()`.** `CallSettings` is the chat-side entity type, not the session-mode settings shape. Wrong type → joinSession rejects.
|
|
295
|
+
2. **`CometChatOngoingCallController` / `CometChatOngoingCallView`.** These do not exist in the Calls SDK. Prior versions of this skill cited them — they are NOT part of the public Flutter Calls SDK API.
|
|
296
|
+
3. **Awaiting `CometChatCalls.joinSession(...)`** as if it returns a `Future<Widget>`. It returns void; widget arrives via `onSuccess`.
|
|
297
|
+
4. **Skipping `CometChatOngoingCallService.abort()` in cleanup paths.** Android foreground-service notification persists after the call ends; user sees "Ongoing call" with no way to clear it.
|
|
298
|
+
5. **Rendering the returned widget inside a constrained `Container`.** Clips to that size. Use `SizedBox.expand`.
|
|
299
|
+
6. **No `mounted` check before `Navigator.pop`.** Async callback fires after dispose → exception.
|
|
300
|
+
7. **`StatelessWidget` for the call screen.** Can't track `_isLeavingSession` flag or listener references → double leave / leaked listeners.
|
|
301
|
+
8. **Popping the navigator from each termination listener independently.** Crashes with `Bad state: No element` on the second pop because the route is already gone. The SDK fires 3 termination events in sequence (`onLeaveSessionButtonClicked` → `onSessionLeft` → `onConnectionClosed`). Funnel them through ONE guarded `_navigateBack()` helper that checks `_isLeavingSession` + `mounted` + `canPop()`. Customer-found 2026-05-17 (Flutter v5 cohort hangup crash).
|
|
302
|
+
8. **Initializing Chat SDK for a session-only integration.** Wastes time and adds two extra failure modes. Drop `CometChat.init` / `CometChat.login` entirely for standalone session apps.
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Verification checklist
|
|
307
|
+
|
|
308
|
+
- [ ] `joinSession` called with `sessionId:`, `sessionSettings:`, `onSuccess:`, `onError:` — NOT `callToken:`, `callSettings:`, `controller:`
|
|
309
|
+
- [ ] Settings built via `SessionSettingsBuilder()`, not `CallSettings`
|
|
310
|
+
- [ ] `SessionStatusListeners` interface implemented and registered against `CallSession.getInstance()` in `onSuccess`
|
|
311
|
+
- [ ] Returned widget rendered via `SizedBox.expand(child: _videoContainer)`
|
|
312
|
+
- [ ] `CometChatOngoingCallService.launch()` called after `onSessionJoined`
|
|
313
|
+
- [ ] `CometChatOngoingCallService.abort()` called in EVERY termination path (dispose, onSessionLeft, onConnectionClosed, onSessionTimedOut, error)
|
|
314
|
+
- [ ] Listeners removed in `dispose` (avoid leaks)
|
|
315
|
+
- [ ] `mounted` check before `Navigator.pop`
|
|
316
|
+
- [ ] Single guarded `_navigateBack()` helper handles ALL termination events (no per-listener pops)
|
|
317
|
+
- [ ] iOS `Info.plist` + Android `AndroidManifest.xml` permissions configured
|
|
318
|
+
- [ ] **Standalone session-only:** no `cometchat_chat_sdk` dependency — Calls SDK alone
|
|
319
|
+
- [ ] **Additive (chat + calls):** dual-SDK contract preserved (Chat first, then Calls)
|
|
320
|
+
- [ ] Real-device smoke: tap meeting link → app opens at /meet → joins → video flows → leave → notification clears
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## Pointers
|
|
325
|
+
|
|
326
|
+
- `cometchat-react-calls/references/call-session.md` — cross-platform architecture
|
|
327
|
+
- `cometchat-flutter-v5-calls/SKILL.md` — Flutter V5 / GetX seven hard rules
|
|
328
|
+
- `cometchat-flutter-v5-calls/references/share-invite.md` — deep-link config
|
|
329
|
+
- Upstream Flutter sample — `~/Downloads/calls-sdk/calls-sdk-flutter-5/sample-apps/cometchat-calls-sample-app-flutter/lib/screens/call_screen.dart`
|
|
330
|
+
- Canonical docs: https://www.cometchat.com/docs/calls/flutter/join-session
|