@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,244 @@
|
|
|
1
|
+
# Raise hand on Flutter (UIKit V5, GetX-based)
|
|
2
|
+
|
|
3
|
+
Same SDK conceptual API as web/native. Flutter V5 uses GetX for state management — the canonical pattern is a `GetxController` that wraps the call event listener and publishes raised-hand state via `Rx<List<RaisedParticipant>>`.
|
|
4
|
+
|
|
5
|
+
**Canonical docs:** https://www.cometchat.com/docs/calls/flutter/raise-hand
|
|
6
|
+
**Read first:** `cometchat-react-calls/references/raise-hand.md` — UX shape + anti-patterns are identical; this is the V5 GetX-specific wiring.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## SDK API
|
|
11
|
+
|
|
12
|
+
```dart
|
|
13
|
+
import 'package:cometchat_calls_uikit/cometchat_calls_uikit.dart';
|
|
14
|
+
|
|
15
|
+
// Local user
|
|
16
|
+
CometChatCalls.raiseHand();
|
|
17
|
+
CometChatCalls.lowerHand();
|
|
18
|
+
|
|
19
|
+
// Listener — registered via the call event listener attached to the OngoingCall widget
|
|
20
|
+
class CallListener implements CometChatCallsEventsListener {
|
|
21
|
+
@override
|
|
22
|
+
void onParticipantHandRaised(Participant participant) {
|
|
23
|
+
// participant.uid, participant.name
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@override
|
|
27
|
+
void onParticipantHandLowered(Participant participant) {
|
|
28
|
+
// ...
|
|
29
|
+
}
|
|
30
|
+
// ... other event handlers
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Settings flag
|
|
34
|
+
final settings = CallSettingsBuilder()
|
|
35
|
+
..hideRaiseHandButton = true;
|
|
36
|
+
final builtSettings = settings.build();
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## GetX controller
|
|
42
|
+
|
|
43
|
+
```dart
|
|
44
|
+
import 'package:get/get.dart';
|
|
45
|
+
import 'package:cometchat_calls_uikit/cometchat_calls_uikit.dart';
|
|
46
|
+
|
|
47
|
+
class RaisedParticipant {
|
|
48
|
+
final String uid;
|
|
49
|
+
final String name;
|
|
50
|
+
final DateTime raisedAt;
|
|
51
|
+
RaisedParticipant({required this.uid, required this.name, required this.raisedAt});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
class RaiseHandController extends GetxController implements CometChatCallsEventsListener {
|
|
55
|
+
final localRaised = false.obs;
|
|
56
|
+
final raised = <RaisedParticipant>[].obs;
|
|
57
|
+
|
|
58
|
+
void toggle() {
|
|
59
|
+
if (localRaised.value) {
|
|
60
|
+
CometChatCalls.lowerHand();
|
|
61
|
+
} else {
|
|
62
|
+
CometChatCalls.raiseHand();
|
|
63
|
+
}
|
|
64
|
+
localRaised.value = !localRaised.value;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@override
|
|
68
|
+
void onParticipantHandRaised(Participant p) {
|
|
69
|
+
final entry = RaisedParticipant(
|
|
70
|
+
uid: p.uid, name: p.name, raisedAt: DateTime.now(),
|
|
71
|
+
);
|
|
72
|
+
raised.removeWhere((r) => r.uid == p.uid);
|
|
73
|
+
raised.add(entry);
|
|
74
|
+
raised.sort((a, b) => a.raisedAt.compareTo(b.raisedAt));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@override
|
|
78
|
+
void onParticipantHandLowered(Participant p) {
|
|
79
|
+
raised.removeWhere((r) => r.uid == p.uid);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ... implement other CometChatCallsEventsListener methods (no-ops or pass-through)
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`.obs` is GetX's reactive marker. UI rebuilds automatically when these mutate.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Toggle button widget
|
|
91
|
+
|
|
92
|
+
```dart
|
|
93
|
+
class RaiseHandButton extends StatelessWidget {
|
|
94
|
+
const RaiseHandButton({super.key});
|
|
95
|
+
|
|
96
|
+
@override
|
|
97
|
+
Widget build(BuildContext context) {
|
|
98
|
+
final ctrl = Get.find<RaiseHandController>();
|
|
99
|
+
return Obx(() => GestureDetector(
|
|
100
|
+
onTap: () {
|
|
101
|
+
ctrl.toggle();
|
|
102
|
+
// Announce for screen readers
|
|
103
|
+
SemanticsService.announce(
|
|
104
|
+
ctrl.localRaised.value ? 'Hand raised' : 'Hand lowered',
|
|
105
|
+
TextDirection.ltr,
|
|
106
|
+
);
|
|
107
|
+
},
|
|
108
|
+
child: Semantics(
|
|
109
|
+
button: true,
|
|
110
|
+
selected: ctrl.localRaised.value,
|
|
111
|
+
label: ctrl.localRaised.value ? 'Lower hand' : 'Raise hand',
|
|
112
|
+
child: Container(
|
|
113
|
+
padding: const EdgeInsets.all(12),
|
|
114
|
+
decoration: BoxDecoration(
|
|
115
|
+
color: ctrl.localRaised.value
|
|
116
|
+
? const Color(0xFFFFD60A)
|
|
117
|
+
: Colors.white24,
|
|
118
|
+
borderRadius: BorderRadius.circular(32),
|
|
119
|
+
),
|
|
120
|
+
child: Row(
|
|
121
|
+
children: [
|
|
122
|
+
const Text('✋'),
|
|
123
|
+
const SizedBox(width: 4),
|
|
124
|
+
Text(ctrl.localRaised.value ? 'Lower' : 'Raise'),
|
|
125
|
+
],
|
|
126
|
+
),
|
|
127
|
+
),
|
|
128
|
+
),
|
|
129
|
+
));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`SemanticsService.announce` is the Flutter equivalent of `aria-live` / `UIAccessibility.post(.announcement, ...)` — TalkBack and VoiceOver pick up the announcement.
|
|
135
|
+
|
|
136
|
+
`Semantics` wrapper sets `button: true`, `selected:`, `label:` — these map to platform a11y conventions.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Raised-hands sheet (DraggableScrollableSheet)
|
|
141
|
+
|
|
142
|
+
```dart
|
|
143
|
+
class RaisedHandsSheet extends StatelessWidget {
|
|
144
|
+
const RaisedHandsSheet({super.key});
|
|
145
|
+
|
|
146
|
+
@override
|
|
147
|
+
Widget build(BuildContext context) {
|
|
148
|
+
final ctrl = Get.find<RaiseHandController>();
|
|
149
|
+
return DraggableScrollableSheet(
|
|
150
|
+
initialChildSize: 0.1,
|
|
151
|
+
minChildSize: 0.1,
|
|
152
|
+
maxChildSize: 0.5,
|
|
153
|
+
builder: (context, scrollController) => Container(
|
|
154
|
+
decoration: const BoxDecoration(
|
|
155
|
+
color: Colors.white,
|
|
156
|
+
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
|
157
|
+
),
|
|
158
|
+
child: Obx(() => ListView(
|
|
159
|
+
controller: scrollController,
|
|
160
|
+
padding: const EdgeInsets.all(16),
|
|
161
|
+
children: [
|
|
162
|
+
Text(
|
|
163
|
+
'Raised hands (${ctrl.raised.length})',
|
|
164
|
+
style: const TextStyle(fontWeight: FontWeight.w600),
|
|
165
|
+
),
|
|
166
|
+
const SizedBox(height: 8),
|
|
167
|
+
for (final p in ctrl.raised)
|
|
168
|
+
ListTile(
|
|
169
|
+
leading: const Text('✋', style: TextStyle(fontSize: 20)),
|
|
170
|
+
title: Text(p.name),
|
|
171
|
+
trailing: Text(
|
|
172
|
+
'${DateTime.now().difference(p.raisedAt).inSeconds}s ago',
|
|
173
|
+
style: const TextStyle(color: Colors.grey),
|
|
174
|
+
),
|
|
175
|
+
),
|
|
176
|
+
],
|
|
177
|
+
)),
|
|
178
|
+
),
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Wiring to the call session
|
|
187
|
+
|
|
188
|
+
```dart
|
|
189
|
+
@override
|
|
190
|
+
void initState() {
|
|
191
|
+
super.initState();
|
|
192
|
+
Get.put(RaiseHandController());
|
|
193
|
+
|
|
194
|
+
// Attach to the call session — the controller IS the listener
|
|
195
|
+
final ctrl = Get.find<RaiseHandController>();
|
|
196
|
+
CometChatCalls.addCallEventListener('raise-hand', ctrl);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
@override
|
|
200
|
+
void dispose() {
|
|
201
|
+
CometChatCalls.removeCallEventListener('raise-hand');
|
|
202
|
+
Get.delete<RaiseHandController>();
|
|
203
|
+
super.dispose();
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Use a STABLE listener ID ('raise-hand'). Changing IDs across remounts orphans listeners — duplicate events fire for each.
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Anti-patterns
|
|
212
|
+
|
|
213
|
+
Web sister reference rules apply, plus Flutter V5-specific:
|
|
214
|
+
|
|
215
|
+
1. **Forgetting `Get.delete<RaiseHandController>()` on dispose.** GetX retains the controller across navigation — listeners survive past the call view, fire stale events.
|
|
216
|
+
2. **`Get.put(RaiseHandController(), permanent: true)` for the call.** Lifetime is too long; controller survives logout. Use scoped `Get.put` without permanent.
|
|
217
|
+
3. **Skipping `Semantics` wrapper on the button.** TalkBack reads the GestureDetector as untyped — bad a11y.
|
|
218
|
+
4. **`Obx` rebuilding the entire widget tree** when only one `.obs` field changes. Wrap minimally — the `Obx` should hug only the reactive part.
|
|
219
|
+
5. **DraggableScrollableSheet without `initialChildSize` < `minChildSize`** — sheet pops above the screen on render, looks broken.
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Verification checklist
|
|
224
|
+
|
|
225
|
+
- [ ] `RaiseHandController` is a `GetxController`
|
|
226
|
+
- [ ] `localRaised` and `raised` are `.obs` reactive
|
|
227
|
+
- [ ] `Obx` wraps only reactive parts of the UI
|
|
228
|
+
- [ ] `Semantics` wrapper on toggle button with `button: true, selected:, label:`
|
|
229
|
+
- [ ] `SemanticsService.announce` on toggle
|
|
230
|
+
- [ ] Stable listener ID for `addCallEventListener` / `removeCallEventListener`
|
|
231
|
+
- [ ] `Get.delete<RaiseHandController>()` in `dispose()`
|
|
232
|
+
- [ ] `hideRaiseHandButton: true` in CallSettings if custom UI
|
|
233
|
+
- [ ] Real-device smoke: 3 devices (mix of iOS + Android), raise from 2 → host sees both
|
|
234
|
+
- [ ] TalkBack / VoiceOver announces "Hand raised" / "Hand lowered" on toggle
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Pointers
|
|
239
|
+
|
|
240
|
+
- `cometchat-react-calls/references/raise-hand.md` — sister reference (UX shape)
|
|
241
|
+
- `cometchat-flutter-v5-calls` SKILL.md — V5 hard rules + GetX scope rules
|
|
242
|
+
- `cometchat-flutter-v6-calls/references/raise-hand.md` — V6 sibling (Bloc-based — different state shape)
|
|
243
|
+
- `cometchat-a11y` — Flutter Semantics + SemanticsService
|
|
244
|
+
- Canonical docs: https://www.cometchat.com/docs/calls/flutter/raise-hand
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Ringing — call signaling with custom UI (Flutter V5 / GetX)
|
|
2
|
+
|
|
3
|
+
Same SDK shape as web/RN. Flutter-specific deltas: GetX-controlled state, flutter_callkit_incoming for OS-level backgrounded UI, just_audio for foreground ringtone.
|
|
4
|
+
|
|
5
|
+
**Read first:** `cometchat-react-calls/references/ringing-integration.md` — full architecture, hard rules.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## SDK API + GetX controller
|
|
10
|
+
|
|
11
|
+
```dart
|
|
12
|
+
import 'package:cometchat_chat_uikit/cometchat_chat_uikit.dart';
|
|
13
|
+
import 'package:cometchat_calls_uikit/cometchat_calls_uikit.dart';
|
|
14
|
+
|
|
15
|
+
class CallSignalingController extends GetxController implements CallListener {
|
|
16
|
+
final incoming = Rx<Call?>(null);
|
|
17
|
+
final outgoing = Rx<Call?>(null);
|
|
18
|
+
final activeSessionId = Rx<String?>(null);
|
|
19
|
+
|
|
20
|
+
static const _listenerId = 'app';
|
|
21
|
+
|
|
22
|
+
@override
|
|
23
|
+
void onInit() {
|
|
24
|
+
super.onInit();
|
|
25
|
+
CometChat.addCallListener(_listenerId, this);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@override
|
|
29
|
+
void onIncomingCallReceived(Call call) {
|
|
30
|
+
incoming.value = call;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@override
|
|
34
|
+
void onOutgoingCallAccepted(Call call) {
|
|
35
|
+
outgoing.value = null;
|
|
36
|
+
activeSessionId.value = call.sessionId;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@override
|
|
40
|
+
void onOutgoingCallRejected(Call call) {
|
|
41
|
+
outgoing.value = null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@override
|
|
45
|
+
void onIncomingCallCancelled(Call call) {
|
|
46
|
+
incoming.value = null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@override
|
|
50
|
+
void onCallEndedMessageReceived(Call call) {
|
|
51
|
+
incoming.value = null;
|
|
52
|
+
outgoing.value = null;
|
|
53
|
+
activeSessionId.value = null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
Future<void> initiate(String receiverUid, {String type = 'video'}) async {
|
|
57
|
+
final call = Call(
|
|
58
|
+
receiverUid: receiverUid,
|
|
59
|
+
callType: type == 'video' ? CometChatCallType.video : CometChatCallType.audio,
|
|
60
|
+
receiverType: CometChatReceiverType.user,
|
|
61
|
+
);
|
|
62
|
+
final result = await CometChat.initiateCall(call: call);
|
|
63
|
+
if (result is Call) outgoing.value = result;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
Future<void> accept(Call call) async {
|
|
67
|
+
final result = await CometChat.acceptCall(sessionId: call.sessionId!);
|
|
68
|
+
if (result is Call) {
|
|
69
|
+
incoming.value = null;
|
|
70
|
+
activeSessionId.value = result.sessionId;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
Future<void> reject(Call call) async {
|
|
75
|
+
await CometChat.rejectCall(
|
|
76
|
+
sessionId: call.sessionId!,
|
|
77
|
+
status: CallStatus.rejected,
|
|
78
|
+
);
|
|
79
|
+
incoming.value = null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@override
|
|
83
|
+
void onClose() {
|
|
84
|
+
CometChat.removeCallListener(_listenerId);
|
|
85
|
+
super.onClose();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Initialize at app start via `Get.put(CallSignalingController(), permanent: true);` so the listener survives navigation.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Incoming-call overlay
|
|
95
|
+
|
|
96
|
+
```dart
|
|
97
|
+
class IncomingCallOverlay extends StatelessWidget {
|
|
98
|
+
const IncomingCallOverlay({super.key});
|
|
99
|
+
|
|
100
|
+
@override
|
|
101
|
+
Widget build(BuildContext context) {
|
|
102
|
+
final ctrl = Get.find<CallSignalingController>();
|
|
103
|
+
|
|
104
|
+
return Obx(() {
|
|
105
|
+
final call = ctrl.incoming.value;
|
|
106
|
+
if (call == null) return const SizedBox.shrink();
|
|
107
|
+
|
|
108
|
+
return Material(
|
|
109
|
+
color: Colors.black.withOpacity(0.85),
|
|
110
|
+
child: Center(
|
|
111
|
+
child: Column(
|
|
112
|
+
mainAxisSize: MainAxisSize.min,
|
|
113
|
+
children: [
|
|
114
|
+
CircleAvatar(
|
|
115
|
+
radius: 60,
|
|
116
|
+
backgroundImage: NetworkImage(call.callInitiator?.avatar ?? ''),
|
|
117
|
+
),
|
|
118
|
+
const SizedBox(height: 16),
|
|
119
|
+
Text(
|
|
120
|
+
call.callInitiator?.name ?? 'Unknown',
|
|
121
|
+
style: const TextStyle(color: Colors.white, fontSize: 24),
|
|
122
|
+
),
|
|
123
|
+
Text('Incoming ${call.type} call', style: const TextStyle(color: Colors.white70)),
|
|
124
|
+
const SizedBox(height: 32),
|
|
125
|
+
Row(
|
|
126
|
+
mainAxisAlignment: MainAxisAlignment.center,
|
|
127
|
+
children: [
|
|
128
|
+
Semantics(
|
|
129
|
+
label: 'Decline call',
|
|
130
|
+
button: true,
|
|
131
|
+
child: FloatingActionButton(
|
|
132
|
+
backgroundColor: Colors.red,
|
|
133
|
+
onPressed: () => ctrl.reject(call),
|
|
134
|
+
child: const Icon(Icons.call_end),
|
|
135
|
+
),
|
|
136
|
+
),
|
|
137
|
+
const SizedBox(width: 32),
|
|
138
|
+
Semantics(
|
|
139
|
+
label: 'Accept call',
|
|
140
|
+
button: true,
|
|
141
|
+
child: FloatingActionButton(
|
|
142
|
+
backgroundColor: Colors.green,
|
|
143
|
+
onPressed: () => ctrl.accept(call),
|
|
144
|
+
child: const Icon(Icons.call),
|
|
145
|
+
),
|
|
146
|
+
),
|
|
147
|
+
],
|
|
148
|
+
),
|
|
149
|
+
],
|
|
150
|
+
),
|
|
151
|
+
),
|
|
152
|
+
);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Wrap above the navigator (typically in `MaterialApp.builder` or as a sibling Stack item) so it surfaces over any route.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Backgrounded ring — flutter_callkit_incoming + push (mandatory)
|
|
163
|
+
|
|
164
|
+
GetX listeners only fire while the app is alive. For backgrounded/killed ring, server fires push (APNs PushKit on iOS, FCM data-message on Android) → `flutter_callkit_incoming` shows OS-level UI. See `cometchat-flutter-v5-calls/references/server-push-bridge.md`.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Anti-patterns
|
|
169
|
+
|
|
170
|
+
Web sister rules apply, plus Flutter-specific:
|
|
171
|
+
|
|
172
|
+
1. **`Get.put` without `permanent: true`.** Controller disposed on route change → listener gone → backgrounded calls miss.
|
|
173
|
+
2. **`StatefulWidget` with `setState` instead of `Obx`.** Rx values won't trigger rebuild without `Obx` wrapper.
|
|
174
|
+
3. **JS-style ringtone via `audioplayers` during a CallKit ring.** Both play at once.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Verification checklist
|
|
179
|
+
|
|
180
|
+
- [ ] `Get.put(CallSignalingController(), permanent: true)` at app start
|
|
181
|
+
- [ ] `IncomingCallOverlay` mounted in `MaterialApp.builder`
|
|
182
|
+
- [ ] `removeCallListener` in `onClose`
|
|
183
|
+
- [ ] `flutter_callkit_incoming` wired for backgrounded ring
|
|
184
|
+
- [ ] Real-device smoke (iOS + Android): foreground, backgrounded, killed ring all surface UI
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Pointers
|
|
189
|
+
|
|
190
|
+
- `cometchat-react-calls/references/ringing-integration.md` — canonical
|
|
191
|
+
- `cometchat-flutter-v5-calls/SKILL.md` — Flutter calls architecture
|
|
192
|
+
- `cometchat-flutter-v5-calls/references/server-push-bridge.md` — backgrounded ring
|
|
193
|
+
- Canonical docs: https://www.cometchat.com/docs/calls/flutter/ringing
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Server-side push routing for Flutter V5 (iOS PushKit + Android FCM)
|
|
2
|
+
|
|
3
|
+
Same server architecture as React Native — your server uses the iOS APNs PushKit canonical for iPhones and the Android FCM HTTP v1 canonical for Android. Flutter-specific changes are in token registration on the client.
|
|
4
|
+
|
|
5
|
+
**Canonical docs:**
|
|
6
|
+
- iOS: `cometchat-ios-calls/references/server-apns-pushkit.md`
|
|
7
|
+
- Android: `cometchat-android-v5-calls/references/server-fcm-voip.md`
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Dependencies
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
dependencies:
|
|
15
|
+
flutter_callkit_incoming: ^2.0.4
|
|
16
|
+
flutter_voip_pushkit: ^0.2.1
|
|
17
|
+
firebase_messaging: ^15.0.0
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Token registration (Flutter client)
|
|
23
|
+
|
|
24
|
+
```dart
|
|
25
|
+
import 'dart:io';
|
|
26
|
+
import 'package:flutter_voip_pushkit/flutter_voip_pushkit.dart';
|
|
27
|
+
import 'package:firebase_messaging/firebase_messaging.dart';
|
|
28
|
+
|
|
29
|
+
class CallPushService {
|
|
30
|
+
Future<void> registerCallTokens(String userUid) async {
|
|
31
|
+
if (Platform.isIOS) {
|
|
32
|
+
final voip = FlutterVoipPushKit();
|
|
33
|
+
voip.onTokenRefresh.listen((token) async {
|
|
34
|
+
await api.registerCallToken(
|
|
35
|
+
uid: userUid,
|
|
36
|
+
platform: 'ios-voip',
|
|
37
|
+
token: token,
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
voip.onPushNotification.listen((payload) {
|
|
41
|
+
// flutter_callkit_incoming surfaces the OS UI from here
|
|
42
|
+
});
|
|
43
|
+
// Trigger token registration
|
|
44
|
+
await voip.configure();
|
|
45
|
+
} else if (Platform.isAndroid) {
|
|
46
|
+
final messaging = FirebaseMessaging.instance;
|
|
47
|
+
await messaging.requestPermission();
|
|
48
|
+
final token = await messaging.getToken();
|
|
49
|
+
if (token != null) {
|
|
50
|
+
await api.registerCallToken(
|
|
51
|
+
uid: userUid,
|
|
52
|
+
platform: 'android-fcm',
|
|
53
|
+
token: token,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
messaging.onTokenRefresh.listen((newToken) async {
|
|
57
|
+
await api.registerCallToken(
|
|
58
|
+
uid: userUid,
|
|
59
|
+
platform: 'android-fcm',
|
|
60
|
+
token: newToken,
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Server-side: same as RN
|
|
71
|
+
|
|
72
|
+
Identical webhook + dispatcher to RN — the platform-specific server templates do all the work. See `cometchat-native-calls/references/server-push-bridge.md` for the dispatcher code.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Anti-patterns
|
|
77
|
+
|
|
78
|
+
RN sister rules apply, plus Flutter-specific:
|
|
79
|
+
|
|
80
|
+
1. **Calling `voip.configure()` before login.** Same problem as RN — register AFTER CometChat login.
|
|
81
|
+
2. **Forgetting `firebase_messaging` background isolate setup.** Android background pushes when the app is killed need `FirebaseMessaging.onBackgroundMessage(handler)` registered in `main.dart` before `runApp`.
|
|
82
|
+
3. **Skipping `flutter_callkit_incoming.showCallkitIncoming` in the push handler.** Without this, Flutter doesn't surface the OS-level call UI even though the push arrived.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Verification checklist
|
|
87
|
+
|
|
88
|
+
- [ ] iOS: `FlutterVoipPushKit.configure()` + onTokenRefresh listener
|
|
89
|
+
- [ ] Android: `FirebaseMessaging.instance.getToken()` + onTokenRefresh
|
|
90
|
+
- [ ] Background isolate handler for Android (`onBackgroundMessage`)
|
|
91
|
+
- [ ] Server has both APNs + FCM dispatchers
|
|
92
|
+
- [ ] Real-device smoke: both iOS and Android ring when caller dials
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Pointers
|
|
97
|
+
|
|
98
|
+
- `cometchat-ios-calls/references/server-apns-pushkit.md` — iOS canonical
|
|
99
|
+
- `cometchat-android-v5-calls/references/server-fcm-voip.md` — Android canonical
|
|
100
|
+
- `cometchat-native-calls/references/server-push-bridge.md` — RN sister (same dispatcher pattern)
|
|
101
|
+
- `cometchat-flutter-v5-calls` SKILL.md — Flutter calls architecture
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Share invite on Flutter V5 (GetX)
|
|
2
|
+
|
|
3
|
+
Same SDK API. Flutter-specific: `share_plus` package wraps both iOS UIActivityViewController and Android Intent.ACTION_SEND under one cross-platform API.
|
|
4
|
+
|
|
5
|
+
**Canonical docs:** https://www.cometchat.com/docs/calls/flutter/share-invite
|
|
6
|
+
**Read first:** `cometchat-react-calls/references/share-invite.md` — deep-link rule, dialog UX.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Dependencies
|
|
11
|
+
|
|
12
|
+
```yaml
|
|
13
|
+
dependencies:
|
|
14
|
+
share_plus: ^10.0.0
|
|
15
|
+
uni_links: ^0.5.1 # for deep-link handling
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Hard rule: deep-link routing
|
|
21
|
+
|
|
22
|
+
Configure both platforms:
|
|
23
|
+
|
|
24
|
+
**iOS** (`ios/Runner/Info.plist`):
|
|
25
|
+
```xml
|
|
26
|
+
<key>com.apple.developer.associated-domains</key>
|
|
27
|
+
<array><string>applinks:yourapp.com</string></array>
|
|
28
|
+
```
|
|
29
|
+
Plus apple-app-site-association on your domain (see iOS reference).
|
|
30
|
+
|
|
31
|
+
**Android** (`android/app/src/main/AndroidManifest.xml`):
|
|
32
|
+
```xml
|
|
33
|
+
<activity android:name=".MainActivity" ...>
|
|
34
|
+
<intent-filter android:autoVerify="true">
|
|
35
|
+
<action android:name="android.intent.action.VIEW" />
|
|
36
|
+
<category android:name="android.intent.category.DEFAULT" />
|
|
37
|
+
<category android:name="android.intent.category.BROWSABLE" />
|
|
38
|
+
<data android:scheme="https"
|
|
39
|
+
android:host="yourapp.com"
|
|
40
|
+
android:pathPrefix="/call" />
|
|
41
|
+
</intent-filter>
|
|
42
|
+
</activity>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Plus the corresponding `assetlinks.json` on your domain.
|
|
46
|
+
|
|
47
|
+
Handle in app:
|
|
48
|
+
```dart
|
|
49
|
+
void initDeepLinks() {
|
|
50
|
+
uriLinkStream.listen((Uri? uri) {
|
|
51
|
+
if (uri == null) return;
|
|
52
|
+
if (uri.pathSegments.length >= 2 && uri.pathSegments[0] == 'call') {
|
|
53
|
+
final sessionId = uri.pathSegments[1];
|
|
54
|
+
Get.toNamed('/call/$sessionId');
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## SDK API
|
|
63
|
+
|
|
64
|
+
```dart
|
|
65
|
+
final settings = CallSettingsBuilder()
|
|
66
|
+
..setHideShareInviteButton(false);
|
|
67
|
+
|
|
68
|
+
@override
|
|
69
|
+
void onShareInviteButtonClicked() {
|
|
70
|
+
Get.find<ShareInviteController>().share(sessionId);
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## share_plus
|
|
77
|
+
|
|
78
|
+
```dart
|
|
79
|
+
import 'package:share_plus/share_plus.dart';
|
|
80
|
+
|
|
81
|
+
class ShareInviteController extends GetxController {
|
|
82
|
+
Future<void> share(String sessionId) async {
|
|
83
|
+
final url = 'https://yourapp.com/call/$sessionId';
|
|
84
|
+
final result = await Share.share(
|
|
85
|
+
"I'm on a call — tap to join.\n$url",
|
|
86
|
+
subject: 'Join my call', // Android: title; iOS: ignored
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
if (result.status == ShareResultStatus.success) {
|
|
90
|
+
// logged + maybe haptic feedback
|
|
91
|
+
}
|
|
92
|
+
// dismissed/unavailable: silent
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`Share.share` opens iOS UIActivityViewController on iOS and the Android chooser on Android. The same call works on both.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## iPad popover anchor
|
|
102
|
+
|
|
103
|
+
`share_plus` requires a source rect on iPad:
|
|
104
|
+
|
|
105
|
+
```dart
|
|
106
|
+
final box = context.findRenderObject() as RenderBox?;
|
|
107
|
+
await Share.share(
|
|
108
|
+
text,
|
|
109
|
+
sharePositionOrigin: box != null ? box.localToGlobal(Offset.zero) & box.size : null,
|
|
110
|
+
);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Pass `sharePositionOrigin` from the button's render box. Without it, share sheet crashes on iPad.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Anti-patterns
|
|
118
|
+
|
|
119
|
+
Web sister rules apply, plus Flutter-specific:
|
|
120
|
+
|
|
121
|
+
1. **Calling `Share.share` without iPad anchor.** Crash on iPad in production.
|
|
122
|
+
2. **Hard-coding URL.** Use `dotenv` or `--dart-define=APP_URL=...`.
|
|
123
|
+
3. **No deep-link config for both platforms.** Only iOS works (or only Android), not both — partial UX.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Verification checklist
|
|
128
|
+
|
|
129
|
+
- [ ] `share_plus` installed
|
|
130
|
+
- [ ] Associated Domains (iOS) + auto-verified app links (Android) configured
|
|
131
|
+
- [ ] `assetlinks.json` + `apple-app-site-association` hosted
|
|
132
|
+
- [ ] `Share.share` called with `sharePositionOrigin` for iPad
|
|
133
|
+
- [ ] App URL via env, not hard-coded
|
|
134
|
+
- [ ] Real-device smoke: share via Messages on iOS, WhatsApp on Android → opens app
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Pointers
|
|
139
|
+
|
|
140
|
+
- `cometchat-react-calls/references/share-invite.md` — sister
|
|
141
|
+
- `cometchat-flutter-v5-calls` SKILL.md
|
|
142
|
+
- Canonical docs: https://www.cometchat.com/docs/calls/flutter/share-invite
|
|
@@ -3,7 +3,7 @@ name: cometchat-flutter-v5-conversations
|
|
|
3
3
|
description: "Use when working with CometChat Flutter UIKit v5 conversation list component. Triggers on CometChatConversations, conversation list, recent chats."
|
|
4
4
|
license: "MIT"
|
|
5
5
|
compatibility: "cometchat_chat_uikit ^5.2.14; cometchat_uikit_shared ^5.2.3"
|
|
6
|
-
allowed-tools: "
|
|
6
|
+
allowed-tools: "shell, file-read, file-search, file-list"
|
|
7
7
|
metadata:
|
|
8
8
|
author: "CometChat"
|
|
9
9
|
version: "3.0.0"
|
|
@@ -3,7 +3,7 @@ name: cometchat-flutter-v5-core
|
|
|
3
3
|
description: "Use when writing any code that uses CometChat Flutter UIKit v5 (cometchat_chat_uikit v5.2.14, cometchat_calls_uikit v5.0.15, cometchat_uikit_shared v5.2.3). Contains hard rules that prevent silent failures."
|
|
4
4
|
license: "MIT"
|
|
5
5
|
compatibility: "cometchat_chat_uikit ^5.2.14; cometchat_calls_uikit ^5.0.15; cometchat_uikit_shared ^5.2.3; cometchat_sdk ^4.1.2; get ^4.6.5"
|
|
6
|
-
allowed-tools: "
|
|
6
|
+
allowed-tools: "shell, file-read, file-search, file-list"
|
|
7
7
|
metadata:
|
|
8
8
|
author: "CometChat"
|
|
9
9
|
version: "3.0.0"
|