@cometchat/skills 3.0.0 → 4.0.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/LICENSE +21 -0
- package/README.md +44 -17
- package/bin/install.js +389 -43
- package/package.json +19 -9
- package/skills/cometchat/SKILL.md +1066 -265
- package/skills/cometchat-android-v5/SKILL.md +120 -0
- package/skills/cometchat-android-v5-components/SKILL.md +430 -0
- package/skills/cometchat-android-v5-core/SKILL.md +468 -0
- package/skills/cometchat-android-v5-customization/SKILL.md +305 -0
- package/skills/cometchat-android-v5-extensions/SKILL.md +124 -0
- package/skills/cometchat-android-v5-features/SKILL.md +130 -0
- package/skills/cometchat-android-v5-placement/SKILL.md +276 -0
- package/skills/cometchat-android-v5-production/SKILL.md +94 -0
- package/skills/cometchat-android-v5-push/SKILL.md +620 -0
- package/skills/cometchat-android-v5-testing/SKILL.md +187 -0
- package/skills/cometchat-android-v5-theming/SKILL.md +166 -0
- package/skills/cometchat-android-v5-troubleshooting/SKILL.md +73 -0
- package/skills/cometchat-android-v6/SKILL.md +107 -0
- package/skills/cometchat-android-v6-builder-settings/SKILL.md +145 -0
- package/skills/cometchat-android-v6-compose-components/SKILL.md +202 -0
- package/skills/cometchat-android-v6-compose-customization/SKILL.md +280 -0
- package/skills/cometchat-android-v6-compose-placement/SKILL.md +213 -0
- package/skills/cometchat-android-v6-compose-theming/SKILL.md +224 -0
- package/skills/cometchat-android-v6-core/SKILL.md +354 -0
- package/skills/cometchat-android-v6-events/SKILL.md +212 -0
- package/skills/cometchat-android-v6-extensions/SKILL.md +191 -0
- package/skills/cometchat-android-v6-features/SKILL.md +130 -0
- package/skills/cometchat-android-v6-kotlin-components/SKILL.md +197 -0
- package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +268 -0
- package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +248 -0
- package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +202 -0
- package/skills/cometchat-android-v6-production/SKILL.md +187 -0
- package/skills/cometchat-android-v6-push/SKILL.md +274 -0
- package/skills/cometchat-android-v6-testing/SKILL.md +279 -0
- package/skills/cometchat-android-v6-troubleshooting/SKILL.md +249 -0
- package/skills/cometchat-angular-components/SKILL.md +706 -0
- package/skills/cometchat-angular-core/SKILL.md +444 -0
- package/skills/cometchat-angular-customization/SKILL.md +424 -0
- package/skills/cometchat-angular-features/SKILL.md +447 -0
- package/skills/cometchat-angular-patterns/SKILL.md +447 -0
- package/skills/cometchat-angular-placement/SKILL.md +685 -0
- package/skills/cometchat-angular-production/SKILL.md +415 -0
- package/skills/cometchat-angular-theming/SKILL.md +365 -0
- package/skills/cometchat-angular-troubleshooting/SKILL.md +329 -0
- package/skills/cometchat-astro-patterns/SKILL.md +3 -3
- package/skills/cometchat-components/SKILL.md +11 -0
- package/skills/cometchat-core/SKILL.md +11 -6
- package/skills/cometchat-customization/references/component-catalog.md +1 -1
- package/skills/cometchat-features/SKILL.md +176 -108
- package/skills/cometchat-flutter-v5/SKILL.md +167 -0
- package/skills/cometchat-flutter-v5-calls/SKILL.md +192 -0
- package/skills/cometchat-flutter-v5-conversations/SKILL.md +117 -0
- package/skills/cometchat-flutter-v5-core/SKILL.md +221 -0
- package/skills/cometchat-flutter-v5-customization/SKILL.md +227 -0
- package/skills/cometchat-flutter-v5-events/SKILL.md +155 -0
- package/skills/cometchat-flutter-v5-messages/SKILL.md +258 -0
- package/skills/cometchat-flutter-v5-production/SKILL.md +207 -0
- package/skills/cometchat-flutter-v5-push/SKILL.md +284 -0
- package/skills/cometchat-flutter-v5-theming/SKILL.md +160 -0
- package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +129 -0
- package/skills/cometchat-flutter-v5-users-groups/SKILL.md +151 -0
- package/skills/cometchat-flutter-v6/SKILL.md +445 -0
- package/skills/cometchat-flutter-v6-calls/SKILL.md +333 -0
- package/skills/cometchat-flutter-v6-components/SKILL.md +365 -0
- package/skills/cometchat-flutter-v6-conversations/SKILL.md +210 -0
- package/skills/cometchat-flutter-v6-core/SKILL.md +305 -0
- package/skills/cometchat-flutter-v6-customization/SKILL.md +666 -0
- package/skills/cometchat-flutter-v6-events/SKILL.md +216 -0
- package/skills/cometchat-flutter-v6-features/SKILL.md +406 -0
- package/skills/cometchat-flutter-v6-messages/SKILL.md +333 -0
- package/skills/cometchat-flutter-v6-migration/SKILL.md +381 -0
- package/skills/cometchat-flutter-v6-placement/SKILL.md +398 -0
- package/skills/cometchat-flutter-v6-production/SKILL.md +632 -0
- package/skills/cometchat-flutter-v6-theming/SKILL.md +260 -0
- package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +726 -0
- package/skills/cometchat-flutter-v6-users-groups/SKILL.md +216 -0
- package/skills/cometchat-ios/SKILL.md +323 -0
- package/skills/cometchat-ios-components/SKILL.md +651 -0
- package/skills/cometchat-ios-core/SKILL.md +822 -0
- package/skills/cometchat-ios-customization/SKILL.md +825 -0
- package/skills/cometchat-ios-features/SKILL.md +725 -0
- package/skills/cometchat-ios-placement/SKILL.md +750 -0
- package/skills/cometchat-ios-production/SKILL.md +730 -0
- package/skills/cometchat-ios-push/SKILL.md +582 -0
- package/skills/cometchat-ios-theming/SKILL.md +631 -0
- package/skills/cometchat-ios-troubleshooting/SKILL.md +983 -0
- package/skills/cometchat-native-bare-patterns/SKILL.md +470 -0
- package/skills/cometchat-native-components/SKILL.md +594 -0
- package/skills/cometchat-native-core/SKILL.md +407 -0
- package/skills/cometchat-native-customization/SKILL.md +594 -0
- package/skills/cometchat-native-expo-patterns/SKILL.md +485 -0
- package/skills/cometchat-native-features/SKILL.md +608 -0
- package/skills/cometchat-native-placement/SKILL.md +500 -0
- package/skills/cometchat-native-production/SKILL.md +694 -0
- package/skills/cometchat-native-push/SKILL.md +593 -0
- package/skills/cometchat-native-testing/SKILL.md +583 -0
- package/skills/cometchat-native-theming/SKILL.md +656 -0
- package/skills/cometchat-native-troubleshooting/SKILL.md +433 -0
- package/skills/cometchat-nextjs-patterns/SKILL.md +5 -5
- package/skills/cometchat-production/SKILL.md +60 -0
- package/skills/cometchat-react-router-patterns/SKILL.md +23 -21
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cometchat-flutter-v5-calls
|
|
3
|
+
description: "Use when working with CometChat Flutter UIKit v5 call components. Triggers on CometChatCallButtons, CometChatIncomingCall, CometChatOutgoingCall, CometChatOngoingCall, CometChatCallLogs, calling."
|
|
4
|
+
license: "MIT"
|
|
5
|
+
compatibility: "cometchat_calls_uikit ^5.0.15; cometchat_calls_sdk ^4.2.2; cometchat_sdk ^4.1.2"
|
|
6
|
+
allowed-tools: "executeBash, readFile, fileSearch, listDirectory"
|
|
7
|
+
metadata:
|
|
8
|
+
author: "CometChat"
|
|
9
|
+
version: "3.0.0"
|
|
10
|
+
tags: "cometchat flutter v5 calls voice video incoming outgoing ongoing logs"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# CometChat Flutter UIKit v5 — Calls
|
|
14
|
+
|
|
15
|
+
Components and utilities for voice/video calling.
|
|
16
|
+
|
|
17
|
+
## Package Structure
|
|
18
|
+
|
|
19
|
+
Calls are in a **separate package**: `cometchat_calls_uikit`.
|
|
20
|
+
|
|
21
|
+
```yaml
|
|
22
|
+
dependencies:
|
|
23
|
+
cometchat_calls_uikit: ^5.0.15
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Import everything from:
|
|
27
|
+
```dart
|
|
28
|
+
import 'package:cometchat_calls_uikit/cometchat_calls_uikit.dart';
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
This re-exports `cometchat_uikit_shared`, `cometchat_sdk`, and `cometchat_calls_sdk`.
|
|
32
|
+
|
|
33
|
+
## Rule: CALLS_INIT_ORDER
|
|
34
|
+
|
|
35
|
+
Chat SDK must be initialized BEFORE Calls SDK. The calling extension handles this automatically when configured via `UIKitSettingsBuilder.callingExtension`.
|
|
36
|
+
|
|
37
|
+
```dart
|
|
38
|
+
// ✅ CORRECT — enable calling via UIKitSettings
|
|
39
|
+
final settings = (UIKitSettingsBuilder()
|
|
40
|
+
..appId = 'APP_ID'
|
|
41
|
+
..region = 'us'
|
|
42
|
+
..authKey = 'AUTH_KEY'
|
|
43
|
+
..subscriptionType = CometChatSubscriptionType.allUsers
|
|
44
|
+
..callingExtension = CometChatCallingExtension())
|
|
45
|
+
.build();
|
|
46
|
+
|
|
47
|
+
CometChatUIKit.init(uiKitSettings: settings);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`CometChatCallingExtension` extends `ExtensionsDataSource` and uses `ChatConfigurator.enable()` to register the calling decorator.
|
|
51
|
+
|
|
52
|
+
## Rule: CALL_NAVIGATION_CONTEXT
|
|
53
|
+
|
|
54
|
+
`CallNavigationContext.navigatorKey` must be set on `MaterialApp` for call overlays to navigate:
|
|
55
|
+
|
|
56
|
+
```dart
|
|
57
|
+
MaterialApp(
|
|
58
|
+
navigatorKey: CallNavigationContext.navigatorKey,
|
|
59
|
+
)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## CometChatCallButtons
|
|
63
|
+
|
|
64
|
+
Voice and video call buttons for a user or group.
|
|
65
|
+
|
|
66
|
+
```dart
|
|
67
|
+
CometChatCallButtons(user: user)
|
|
68
|
+
CometChatCallButtons(group: group, hideVoiceCallButton: true)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Key props: `user`, `group`, `callButtonsStyle`, `hideVoiceCallButton`, `hideVideoCallButton`, `outgoingCallConfiguration`, `callSettingsBuilder`, `onError`.
|
|
72
|
+
|
|
73
|
+
## CometChatCallLogs
|
|
74
|
+
|
|
75
|
+
Call history list.
|
|
76
|
+
|
|
77
|
+
```dart
|
|
78
|
+
CometChatCallLogs(
|
|
79
|
+
onItemClick: (callLog) {
|
|
80
|
+
// CometChatCallLogDetails is NOT a UIKit export — copy the
|
|
81
|
+
// sample-app pattern from `sample_app/lib/call_log_details/` into
|
|
82
|
+
// your own project and route to it here.
|
|
83
|
+
Navigator.push(context, MaterialPageRoute(
|
|
84
|
+
builder: (_) => YourCallLogDetailsScreen(callLog: callLog),
|
|
85
|
+
));
|
|
86
|
+
},
|
|
87
|
+
)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Key props: `callLogsRequestBuilder`, `callLogsStyle`, `onItemClick`, `listItemView`, `subTitleView`, `trailingView`, `onError`.
|
|
91
|
+
|
|
92
|
+
## CometChatIncomingCall / CometChatOutgoingCall / CometChatOngoingCall
|
|
93
|
+
|
|
94
|
+
These are typically managed automatically by `CometChatCallingExtension`. Manual usage is rare.
|
|
95
|
+
|
|
96
|
+
- `CometChatIncomingCall(call: call, onAccept: (BuildContext, Call)? ..., onDecline: (BuildContext, Call)? ...)` — callbacks take `(BuildContext, Call)`, NOT `(Call)` alone.
|
|
97
|
+
- `CometChatOutgoingCall(call: returnedCall, user: user OR group: group, onCancelled: (BuildContext, Call)? ...)` — takes the active `Call` object plus the `User` or `Group` it's directed at. The `call:` param holds the result of `CometChatUIKitCalls.initiateCall(...)`. Callbacks are `(BuildContext, Call)?`, NOT `(Call)?` alone.
|
|
98
|
+
- `CometChatOngoingCall(callSettingsBuilder: ..., sessionId: ...)`
|
|
99
|
+
|
|
100
|
+
## Call Flow — Outgoing
|
|
101
|
+
|
|
102
|
+
1. User taps call button → `CometChatUIKitCalls.initiateCall(call)`
|
|
103
|
+
2. `CometChatOutgoingCall` screen pushed
|
|
104
|
+
3. Recipient accepts → `CometChatOngoingCall` replaces outgoing
|
|
105
|
+
4. Call ends → screens pop back
|
|
106
|
+
|
|
107
|
+
## Call Flow — Incoming
|
|
108
|
+
|
|
109
|
+
1. `CometChatCallingExtension` listens via SDK listener
|
|
110
|
+
2. `CometChatIncomingCall` overlay displayed via `CallNavigationContext.navigatorKey`
|
|
111
|
+
3. Accept → `CometChatUIKitCalls.acceptCall(sessionId)` → `CometChatOngoingCall`
|
|
112
|
+
4. Decline → `CometChatUIKitCalls.rejectCall(sessionId, status)`
|
|
113
|
+
|
|
114
|
+
## Incoming Call Handling (Global)
|
|
115
|
+
|
|
116
|
+
Handle incoming calls at the app level (dashboard/home), not per-screen:
|
|
117
|
+
|
|
118
|
+
```dart
|
|
119
|
+
class _DashboardState extends State<Dashboard>
|
|
120
|
+
with CallListener, CometChatCallEventListener {
|
|
121
|
+
|
|
122
|
+
@override
|
|
123
|
+
void initState() {
|
|
124
|
+
super.initState();
|
|
125
|
+
_listenerId = 'calls_${DateTime.now().millisecondsSinceEpoch}';
|
|
126
|
+
CometChat.addCallListener(_listenerId, this);
|
|
127
|
+
CometChatCallEvents.addCallEventsListener(_listenerId, this);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
@override
|
|
131
|
+
void dispose() {
|
|
132
|
+
CometChat.removeCallListener(_listenerId);
|
|
133
|
+
CometChatCallEvents.removeCallEventsListener(_listenerId);
|
|
134
|
+
super.dispose();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@override
|
|
138
|
+
void onIncomingCallReceived(Call call) {
|
|
139
|
+
// Handle incoming call globally
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Permissions
|
|
145
|
+
|
|
146
|
+
Request camera and microphone permissions before calls:
|
|
147
|
+
|
|
148
|
+
```dart
|
|
149
|
+
await [Permission.camera, Permission.microphone].request();
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Golden Path — Enable Calling
|
|
153
|
+
|
|
154
|
+
```dart
|
|
155
|
+
// 1. Configure calling extension
|
|
156
|
+
final settings = (UIKitSettingsBuilder()
|
|
157
|
+
..appId = 'APP_ID'
|
|
158
|
+
..region = 'us'
|
|
159
|
+
..authKey = 'AUTH_KEY'
|
|
160
|
+
..subscriptionType = CometChatSubscriptionType.allUsers
|
|
161
|
+
..callingExtension = CometChatCallingExtension())
|
|
162
|
+
.build();
|
|
163
|
+
|
|
164
|
+
// 2. Init
|
|
165
|
+
CometChatUIKit.init(uiKitSettings: settings);
|
|
166
|
+
|
|
167
|
+
// 3. Set navigator key
|
|
168
|
+
MaterialApp(navigatorKey: CallNavigationContext.navigatorKey)
|
|
169
|
+
|
|
170
|
+
// 4. Call buttons appear automatically in CometChatMessageHeader
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Anti-Patterns
|
|
174
|
+
|
|
175
|
+
```dart
|
|
176
|
+
// ❌ WRONG — forgetting navigatorKey
|
|
177
|
+
MaterialApp(/* missing navigatorKey */)
|
|
178
|
+
|
|
179
|
+
// ❌ WRONG — not enabling calling extension
|
|
180
|
+
UIKitSettingsBuilder()..appId = 'APP_ID'..region = 'us'
|
|
181
|
+
// Missing: ..callingExtension = CometChatCallingExtension()
|
|
182
|
+
|
|
183
|
+
// ❌ WRONG — handling incoming calls per-screen instead of globally
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Checklist — Calls
|
|
187
|
+
|
|
188
|
+
- [ ] `CometChatCallingExtension()` set on `UIKitSettingsBuilder.callingExtension`
|
|
189
|
+
- [ ] `CallNavigationContext.navigatorKey` set on `MaterialApp.navigatorKey`
|
|
190
|
+
- [ ] Incoming call handling is global (dashboard level)
|
|
191
|
+
- [ ] Camera/microphone permissions requested
|
|
192
|
+
- [ ] Import from `package:cometchat_calls_uikit/cometchat_calls_uikit.dart`
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cometchat-flutter-v5-conversations
|
|
3
|
+
description: "Use when working with CometChat Flutter UIKit v5 conversation list component. Triggers on CometChatConversations, conversation list, recent chats."
|
|
4
|
+
license: "MIT"
|
|
5
|
+
compatibility: "cometchat_chat_uikit ^5.2.14; cometchat_uikit_shared ^5.2.3"
|
|
6
|
+
allowed-tools: "executeBash, readFile, fileSearch, listDirectory"
|
|
7
|
+
metadata:
|
|
8
|
+
author: "CometChat"
|
|
9
|
+
version: "3.0.0"
|
|
10
|
+
tags: "cometchat flutter v5 conversations list recent chats"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# CometChat Flutter UIKit v5 — Conversations
|
|
14
|
+
|
|
15
|
+
The `CometChatConversations` component displays a list of recent conversations.
|
|
16
|
+
|
|
17
|
+
## Key Props
|
|
18
|
+
|
|
19
|
+
| Prop | Type | Default | Description |
|
|
20
|
+
|------|------|---------|-------------|
|
|
21
|
+
| `conversationsRequestBuilder` | `ConversationsRequestBuilder?` | — | Custom fetch builder |
|
|
22
|
+
| `conversationsStyle` | `CometChatConversationsStyle` | `const CometChatConversationsStyle()` | Visual styling |
|
|
23
|
+
| `onItemTap` | `Function(Conversation)?` | — | Tap callback (**no BuildContext**) |
|
|
24
|
+
| `onItemLongPress` | `Function(Conversation)?` | — | Long press callback |
|
|
25
|
+
| `subtitleView` | `Widget? Function(BuildContext, Conversation)?` | — | Custom subtitle |
|
|
26
|
+
| `listItemView` | `Widget Function(Conversation)?` | — | Custom list item (replaces the whole row) |
|
|
27
|
+
| `leadingView` | `Widget? Function(BuildContext, Conversation)?` | — | Custom leading widget (avatar slot) |
|
|
28
|
+
| `titleView` | `Widget? Function(BuildContext, Conversation)?` | — | Custom title widget |
|
|
29
|
+
| `trailingView` | `Widget? Function(Conversation)?` | — | Custom trailing widget (single-arg — asymmetric with the other slots) |
|
|
30
|
+
| `title` | `String?` | — | List title |
|
|
31
|
+
| `showBackButton` | `bool` | `false` | Show back button |
|
|
32
|
+
| `onBack` | `VoidCallback?` | — | Back button callback |
|
|
33
|
+
| `hideAppbar` | `bool?` | `false` | Hide app bar |
|
|
34
|
+
| `appBarOptions` | `List<Widget>?` | — | App bar trailing widgets |
|
|
35
|
+
| `usersStatusVisibility` | `bool?` | `true` | Show online status |
|
|
36
|
+
| `receiptsVisibility` | `bool?` | `true` | Show read receipts |
|
|
37
|
+
| `textFormatters` | `List<CometChatTextFormatter>?` | — | Text formatters for subtitles |
|
|
38
|
+
| `controllerTag` | `String?` | — | Custom GetX controller tag |
|
|
39
|
+
| `hideSearch` | `bool?` | — | Hide search bar |
|
|
40
|
+
| `searchReadOnly` | `bool` | `false` | Read-only search |
|
|
41
|
+
| `onSearchTap` | `GestureTapCallback?` | — | Search tap callback |
|
|
42
|
+
| `deleteConversationOptionVisibility` | `bool?` | `true` | Show delete option |
|
|
43
|
+
| `loadingStateView` | `WidgetBuilder?` | — | Custom loading state |
|
|
44
|
+
| `emptyStateView` | `WidgetBuilder?` | — | Custom empty state |
|
|
45
|
+
| `errorStateView` | `WidgetBuilder?` | — | Custom error state |
|
|
46
|
+
| `setOptions` | `Function?` | — | Replace long-press options |
|
|
47
|
+
| `addOptions` | `Function?` | — | Add to long-press options |
|
|
48
|
+
|
|
49
|
+
## Basic Usage
|
|
50
|
+
|
|
51
|
+
```dart
|
|
52
|
+
CometChatConversations(
|
|
53
|
+
onItemTap: (conversation) {
|
|
54
|
+
User? user;
|
|
55
|
+
Group? group;
|
|
56
|
+
if (conversation.conversationWith is User) {
|
|
57
|
+
user = conversation.conversationWith as User;
|
|
58
|
+
} else {
|
|
59
|
+
group = conversation.conversationWith as Group;
|
|
60
|
+
}
|
|
61
|
+
Navigator.push(context, MaterialPageRoute(
|
|
62
|
+
builder: (_) => MessagesScreen(user: user, group: group),
|
|
63
|
+
));
|
|
64
|
+
},
|
|
65
|
+
)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Custom Request Builder
|
|
69
|
+
|
|
70
|
+
```dart
|
|
71
|
+
CometChatConversations(
|
|
72
|
+
conversationsRequestBuilder: ConversationsRequestBuilder()
|
|
73
|
+
..limit = 30
|
|
74
|
+
..conversationType = ConversationType.user,
|
|
75
|
+
)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Internal Architecture (GetX)
|
|
79
|
+
|
|
80
|
+
The component creates `CometChatConversationsController` via `Get.put()` in `initState()` and deletes it in `dispose()` (unless `controllerTag` is provided externally).
|
|
81
|
+
|
|
82
|
+
Theme values are cached in `didChangeDependencies()` (unconditionally, no flag):
|
|
83
|
+
```dart
|
|
84
|
+
@override
|
|
85
|
+
void didChangeDependencies() {
|
|
86
|
+
typography = CometChatThemeHelper.getTypography(context);
|
|
87
|
+
colorPalette = CometChatThemeHelper.getColorPalette(context);
|
|
88
|
+
spacing = CometChatThemeHelper.getSpacing(context);
|
|
89
|
+
style = CometChatThemeHelper.getTheme<CometChatConversationsStyle>(
|
|
90
|
+
context: context, defaultTheme: CometChatConversationsStyle.of)
|
|
91
|
+
.merge(widget.conversationsStyle);
|
|
92
|
+
super.didChangeDependencies();
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Anti-Patterns
|
|
97
|
+
|
|
98
|
+
```dart
|
|
99
|
+
// ❌ WRONG — trying to access controller before component mounts
|
|
100
|
+
final controller = Get.find<CometChatConversationsController>();
|
|
101
|
+
|
|
102
|
+
// ❌ WRONG — manually creating controller outside the widget
|
|
103
|
+
Get.put(CometChatConversationsController(...));
|
|
104
|
+
|
|
105
|
+
// ❌ WRONG — not extracting User/Group from conversation
|
|
106
|
+
onItemTap: (conversation) {
|
|
107
|
+
Navigator.push(context, MaterialPageRoute(
|
|
108
|
+
builder: (_) => MessagesScreen(user: conversation.conversationWith), // Type error
|
|
109
|
+
));
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Checklist — Conversations
|
|
114
|
+
|
|
115
|
+
- [ ] `onItemTap` extracts `User`/`Group` from `conversation.conversationWith` with type check
|
|
116
|
+
- [ ] Navigation to messages screen passes extracted `user` or `group`
|
|
117
|
+
- [ ] Let the widget manage its own GetX controller lifecycle
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cometchat-flutter-v5-core
|
|
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
|
+
license: "MIT"
|
|
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: "executeBash, readFile, fileSearch, listDirectory"
|
|
7
|
+
metadata:
|
|
8
|
+
author: "CometChat"
|
|
9
|
+
version: "3.0.0"
|
|
10
|
+
tags: "cometchat flutter v5 core rules init login logout lifecycle getx"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# CometChat Flutter UIKit v5 — Core Rules
|
|
14
|
+
|
|
15
|
+
Non-negotiable constraints for all CometChat UIKit v5 code. Violating these causes silent failures or crashes.
|
|
16
|
+
|
|
17
|
+
## Key v5 Architecture Facts
|
|
18
|
+
|
|
19
|
+
- State management: **GetX** (GetBuilder, GetxController, Get.put, Get.find, Get.delete)
|
|
20
|
+
- Separate packages: `cometchat_chat_uikit` + `cometchat_calls_uikit` + `cometchat_uikit_shared`
|
|
21
|
+
- SDK: `cometchat_sdk ^4.1.2` + `cometchat_calls_sdk ^4.2.2`
|
|
22
|
+
- **Imports — two barrels.** For chat-only projects: `package:cometchat_chat_uikit/cometchat_chat_uikit.dart`. For projects that also need voice/video calling: ADD `package:cometchat_calls_uikit/cometchat_calls_uikit.dart` as a SECOND import — the calls barrel re-exports shared + SDK only and does NOT re-export `cometchat_chat_uikit`. Chat widgets like `CometChatConversations`, `CometChatMessageList`, `CometChatMessageComposer` are reachable only through the chat barrel.
|
|
23
|
+
- `CometChatUIKit.login(uid)` takes a **String** directly (not an object)
|
|
24
|
+
- No ServiceLocator pattern — controllers are created via `Get.put()` internally
|
|
25
|
+
- Style classes use `ThemeExtension` with `merge()` pattern
|
|
26
|
+
|
|
27
|
+
## Rule: INIT_FIRST
|
|
28
|
+
|
|
29
|
+
`CometChatUIKit.init()` must complete before any login, component usage, or SDK call.
|
|
30
|
+
|
|
31
|
+
```dart
|
|
32
|
+
// ✅ CORRECT
|
|
33
|
+
final settings = (UIKitSettingsBuilder()
|
|
34
|
+
..appId = 'APP_ID'
|
|
35
|
+
..region = 'us'
|
|
36
|
+
..authKey = 'AUTH_KEY'
|
|
37
|
+
..subscriptionType = CometChatSubscriptionType.allUsers)
|
|
38
|
+
.build();
|
|
39
|
+
|
|
40
|
+
CometChatUIKit.init(
|
|
41
|
+
uiKitSettings: settings,
|
|
42
|
+
onSuccess: (_) => debugPrint('Init done'),
|
|
43
|
+
onError: (e) => debugPrint('Init failed: ${e.message}'),
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
// ❌ WRONG — login before init completes
|
|
47
|
+
CometChatUIKit.init(uiKitSettings: settings);
|
|
48
|
+
CometChatUIKit.login('uid'); // Race condition
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Rule: AUTH_CHECK_AFTER_INIT
|
|
52
|
+
|
|
53
|
+
After `CometChatUIKit.init()` completes, the static field `CometChatUIKit.loggedInUser` is populated if a cached session exists (init internally calls `getLoggedInUser()`). You can check it synchronously in `onSuccess`, or use `CometChatUIKit.getLoggedInUser()` for an explicit async check.
|
|
54
|
+
|
|
55
|
+
```dart
|
|
56
|
+
// ✅ CORRECT — synchronous check after init
|
|
57
|
+
CometChatUIKit.init(
|
|
58
|
+
uiKitSettings: settings,
|
|
59
|
+
onSuccess: (_) {
|
|
60
|
+
final hasUser = CometChatUIKit.loggedInUser != null;
|
|
61
|
+
// Route to home or login
|
|
62
|
+
},
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
// ✅ ALSO CORRECT — explicit async check (used by master app)
|
|
66
|
+
CometChatUIKit.init(
|
|
67
|
+
uiKitSettings: settings,
|
|
68
|
+
onSuccess: (_) async {
|
|
69
|
+
final user = await CometChatUIKit.getLoggedInUser();
|
|
70
|
+
if (user != null) {
|
|
71
|
+
await CometChatUIKit.login(user.uid, onSuccess: ...);
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Note: `CometChatUIKit.login()` handles re-login gracefully — if the user is already logged in with the same UID, it returns the cached user without hitting the server.
|
|
78
|
+
|
|
79
|
+
## Rule: LISTENER_LIFECYCLE
|
|
80
|
+
|
|
81
|
+
SDK listeners MUST be registered with a unique ID in `initState()` (or GetxController `onInit()`) and removed in `dispose()` (or `onClose()`).
|
|
82
|
+
|
|
83
|
+
```dart
|
|
84
|
+
// ✅ CORRECT
|
|
85
|
+
class _MyScreenState extends State<MyScreen> with MessageListener {
|
|
86
|
+
late final String _listenerId;
|
|
87
|
+
|
|
88
|
+
@override
|
|
89
|
+
void initState() {
|
|
90
|
+
super.initState();
|
|
91
|
+
_listenerId = 'my_screen_${DateTime.now().millisecondsSinceEpoch}';
|
|
92
|
+
CometChat.addMessageListener(_listenerId, this);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@override
|
|
96
|
+
void dispose() {
|
|
97
|
+
CometChat.removeMessageListener(_listenerId);
|
|
98
|
+
super.dispose();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ❌ WRONG — hardcoded ID causes collisions; missing dispose removal
|
|
103
|
+
CometChat.addMessageListener('messages', this); // Collision!
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Rule: THEME_CACHE
|
|
107
|
+
|
|
108
|
+
Cache theme values in `didChangeDependencies()` — unconditionally, no flag needed. Never call `CometChatThemeHelper.getColorPalette(context)` in `build()`.
|
|
109
|
+
|
|
110
|
+
`getColorPalette()` creates a new `CometChatColorPalette` object every call, resolving each token individually via `Theme.of(context)`. During keyboard animation, `MediaQuery` changes trigger rebuilds, making this expensive in `build()`.
|
|
111
|
+
|
|
112
|
+
```dart
|
|
113
|
+
// ✅ CORRECT — matches actual package pattern (no flag)
|
|
114
|
+
@override
|
|
115
|
+
void didChangeDependencies() {
|
|
116
|
+
super.didChangeDependencies();
|
|
117
|
+
colorPalette = CometChatThemeHelper.getColorPalette(context);
|
|
118
|
+
spacing = CometChatThemeHelper.getSpacing(context);
|
|
119
|
+
typography = CometChatThemeHelper.getTypography(context);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ❌ WRONG — lookup in build causes jank
|
|
123
|
+
@override
|
|
124
|
+
Widget build(BuildContext context) {
|
|
125
|
+
final colors = CometChatThemeHelper.getColorPalette(context); // Expensive!
|
|
126
|
+
return Container(color: colors.primary);
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Do NOT use a `_themeInitialized` flag — it prevents theme updates when the system switches between light/dark mode.
|
|
131
|
+
|
|
132
|
+
## Rule: SUBSCRIPTION_TYPE_REQUIRED
|
|
133
|
+
|
|
134
|
+
Omitting `subscriptionType` in `UIKitSettingsBuilder` silently disables all presence events (online/offline, typing indicators). No error is thrown.
|
|
135
|
+
|
|
136
|
+
```dart
|
|
137
|
+
// ✅ CORRECT
|
|
138
|
+
UIKitSettingsBuilder()
|
|
139
|
+
..subscriptionType = CometChatSubscriptionType.allUsers
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Rule: REGION_LOWERCASE
|
|
143
|
+
|
|
144
|
+
Region must be a lowercase string: `'us'`, `'eu'`, or `'in'`.
|
|
145
|
+
|
|
146
|
+
## Rule: MUID_PRESERVATION
|
|
147
|
+
|
|
148
|
+
When handling `ccMessageSent` events, compare by `muid` first, then `id` — the SDK may return an empty `muid` in the success callback.
|
|
149
|
+
|
|
150
|
+
## Pattern: Callback → Async Bridge (Completer)
|
|
151
|
+
|
|
152
|
+
```dart
|
|
153
|
+
import 'dart:async';
|
|
154
|
+
|
|
155
|
+
Future<bool> initAsync(UIKitSettings settings) {
|
|
156
|
+
final completer = Completer<bool>();
|
|
157
|
+
CometChatUIKit.init(
|
|
158
|
+
uiKitSettings: settings,
|
|
159
|
+
onSuccess: (_) => completer.complete(true),
|
|
160
|
+
onError: (e) => completer.complete(false),
|
|
161
|
+
);
|
|
162
|
+
return completer.future;
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## v5 Component Architecture Pattern (GetX)
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
{component}/
|
|
170
|
+
├── cometchat_{component}.dart # StatefulWidget
|
|
171
|
+
├── cometchat_{component}_controller.dart # extends GetxController
|
|
172
|
+
├── cometchat_{component}_style.dart # ThemeExtension with merge()
|
|
173
|
+
└── {component}_builder_protocol.dart # Request builder protocol
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Internal lifecycle:
|
|
177
|
+
```dart
|
|
178
|
+
@override
|
|
179
|
+
void initState() {
|
|
180
|
+
super.initState();
|
|
181
|
+
tag = widget.controllerTag ?? 'default_tag_${DateTime.now().millisecondsSinceEpoch}';
|
|
182
|
+
controller = Get.put<Controller>(Controller(...), tag: tag);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
@override
|
|
186
|
+
void dispose() {
|
|
187
|
+
if (widget.controllerTag == null) {
|
|
188
|
+
Get.delete<Controller>(tag: tag);
|
|
189
|
+
}
|
|
190
|
+
super.dispose();
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Android Build Requirements
|
|
195
|
+
|
|
196
|
+
- `android.useAndroidX=true` and `android.enableJetifier=true` in `gradle.properties`
|
|
197
|
+
- `minSdk 26` in `android/app/build.gradle`
|
|
198
|
+
- ProGuard: `-keep class com.cometchat.** { *; }` and `-keep interface com.cometchat.** { *; }`
|
|
199
|
+
|
|
200
|
+
## Top 10 Error Debugging
|
|
201
|
+
|
|
202
|
+
| Symptom | Cause | Fix |
|
|
203
|
+
|---------|-------|-----|
|
|
204
|
+
| "Authentication null" | `CometChatUIKit.init()` not called | Call init before login/components |
|
|
205
|
+
| "APP ID null" | appId not set in UIKitSettingsBuilder | Set `..appId = 'YOUR_APP_ID'` |
|
|
206
|
+
| No typing indicators / presence | `subscriptionType` not set | Set `..subscriptionType = CometChatSubscriptionType.allUsers` |
|
|
207
|
+
| Theme jank during keyboard | Theme looked up in `build()` | Cache in `didChangeDependencies()` |
|
|
208
|
+
| Listener leak / duplicate events | Listener not removed in `dispose()` | Always remove with same ID |
|
|
209
|
+
| GetX controller not found | Using `Get.find()` before `Get.put()` | Let UIKit components manage their own controllers |
|
|
210
|
+
| Region error | Uppercase region string | Use lowercase: 'us', 'eu', 'in' |
|
|
211
|
+
| Release build crash | Missing ProGuard keep rules | Add `-keep class com.cometchat.** { *; }` |
|
|
212
|
+
|
|
213
|
+
## Checklist — Every CometChat v5 Screen
|
|
214
|
+
|
|
215
|
+
- [ ] `CometChatUIKit.init()` called before any usage
|
|
216
|
+
- [ ] `subscriptionType` set in UIKitSettingsBuilder
|
|
217
|
+
- [ ] `region` is lowercase
|
|
218
|
+
- [ ] Theme cached in `didChangeDependencies()`, not `build()`
|
|
219
|
+
- [ ] SDK listeners registered with unique ID, removed in `dispose()`
|
|
220
|
+
- [ ] Colors from `CometChatThemeHelper`, never hardcoded
|
|
221
|
+
- [ ] Imports: `package:cometchat_chat_uikit/cometchat_chat_uikit.dart` always; ADD `package:cometchat_calls_uikit/cometchat_calls_uikit.dart` if you use voice/video
|