@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.
Files changed (101) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +44 -17
  3. package/bin/install.js +389 -43
  4. package/package.json +19 -9
  5. package/skills/cometchat/SKILL.md +1066 -265
  6. package/skills/cometchat-android-v5/SKILL.md +120 -0
  7. package/skills/cometchat-android-v5-components/SKILL.md +430 -0
  8. package/skills/cometchat-android-v5-core/SKILL.md +468 -0
  9. package/skills/cometchat-android-v5-customization/SKILL.md +305 -0
  10. package/skills/cometchat-android-v5-extensions/SKILL.md +124 -0
  11. package/skills/cometchat-android-v5-features/SKILL.md +130 -0
  12. package/skills/cometchat-android-v5-placement/SKILL.md +276 -0
  13. package/skills/cometchat-android-v5-production/SKILL.md +94 -0
  14. package/skills/cometchat-android-v5-push/SKILL.md +620 -0
  15. package/skills/cometchat-android-v5-testing/SKILL.md +187 -0
  16. package/skills/cometchat-android-v5-theming/SKILL.md +166 -0
  17. package/skills/cometchat-android-v5-troubleshooting/SKILL.md +73 -0
  18. package/skills/cometchat-android-v6/SKILL.md +107 -0
  19. package/skills/cometchat-android-v6-builder-settings/SKILL.md +145 -0
  20. package/skills/cometchat-android-v6-compose-components/SKILL.md +202 -0
  21. package/skills/cometchat-android-v6-compose-customization/SKILL.md +280 -0
  22. package/skills/cometchat-android-v6-compose-placement/SKILL.md +213 -0
  23. package/skills/cometchat-android-v6-compose-theming/SKILL.md +224 -0
  24. package/skills/cometchat-android-v6-core/SKILL.md +354 -0
  25. package/skills/cometchat-android-v6-events/SKILL.md +212 -0
  26. package/skills/cometchat-android-v6-extensions/SKILL.md +191 -0
  27. package/skills/cometchat-android-v6-features/SKILL.md +130 -0
  28. package/skills/cometchat-android-v6-kotlin-components/SKILL.md +197 -0
  29. package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +268 -0
  30. package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +248 -0
  31. package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +202 -0
  32. package/skills/cometchat-android-v6-production/SKILL.md +187 -0
  33. package/skills/cometchat-android-v6-push/SKILL.md +274 -0
  34. package/skills/cometchat-android-v6-testing/SKILL.md +279 -0
  35. package/skills/cometchat-android-v6-troubleshooting/SKILL.md +249 -0
  36. package/skills/cometchat-angular-components/SKILL.md +706 -0
  37. package/skills/cometchat-angular-core/SKILL.md +444 -0
  38. package/skills/cometchat-angular-customization/SKILL.md +424 -0
  39. package/skills/cometchat-angular-features/SKILL.md +447 -0
  40. package/skills/cometchat-angular-patterns/SKILL.md +447 -0
  41. package/skills/cometchat-angular-placement/SKILL.md +685 -0
  42. package/skills/cometchat-angular-production/SKILL.md +415 -0
  43. package/skills/cometchat-angular-theming/SKILL.md +365 -0
  44. package/skills/cometchat-angular-troubleshooting/SKILL.md +329 -0
  45. package/skills/cometchat-astro-patterns/SKILL.md +3 -3
  46. package/skills/cometchat-components/SKILL.md +11 -0
  47. package/skills/cometchat-core/SKILL.md +11 -6
  48. package/skills/cometchat-customization/references/component-catalog.md +1 -1
  49. package/skills/cometchat-features/SKILL.md +176 -108
  50. package/skills/cometchat-flutter-v5/SKILL.md +167 -0
  51. package/skills/cometchat-flutter-v5-calls/SKILL.md +192 -0
  52. package/skills/cometchat-flutter-v5-conversations/SKILL.md +117 -0
  53. package/skills/cometchat-flutter-v5-core/SKILL.md +221 -0
  54. package/skills/cometchat-flutter-v5-customization/SKILL.md +227 -0
  55. package/skills/cometchat-flutter-v5-events/SKILL.md +155 -0
  56. package/skills/cometchat-flutter-v5-messages/SKILL.md +258 -0
  57. package/skills/cometchat-flutter-v5-production/SKILL.md +207 -0
  58. package/skills/cometchat-flutter-v5-push/SKILL.md +284 -0
  59. package/skills/cometchat-flutter-v5-theming/SKILL.md +160 -0
  60. package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +129 -0
  61. package/skills/cometchat-flutter-v5-users-groups/SKILL.md +151 -0
  62. package/skills/cometchat-flutter-v6/SKILL.md +445 -0
  63. package/skills/cometchat-flutter-v6-calls/SKILL.md +333 -0
  64. package/skills/cometchat-flutter-v6-components/SKILL.md +365 -0
  65. package/skills/cometchat-flutter-v6-conversations/SKILL.md +210 -0
  66. package/skills/cometchat-flutter-v6-core/SKILL.md +305 -0
  67. package/skills/cometchat-flutter-v6-customization/SKILL.md +666 -0
  68. package/skills/cometchat-flutter-v6-events/SKILL.md +216 -0
  69. package/skills/cometchat-flutter-v6-features/SKILL.md +406 -0
  70. package/skills/cometchat-flutter-v6-messages/SKILL.md +333 -0
  71. package/skills/cometchat-flutter-v6-migration/SKILL.md +381 -0
  72. package/skills/cometchat-flutter-v6-placement/SKILL.md +398 -0
  73. package/skills/cometchat-flutter-v6-production/SKILL.md +632 -0
  74. package/skills/cometchat-flutter-v6-theming/SKILL.md +260 -0
  75. package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +726 -0
  76. package/skills/cometchat-flutter-v6-users-groups/SKILL.md +216 -0
  77. package/skills/cometchat-ios/SKILL.md +323 -0
  78. package/skills/cometchat-ios-components/SKILL.md +651 -0
  79. package/skills/cometchat-ios-core/SKILL.md +822 -0
  80. package/skills/cometchat-ios-customization/SKILL.md +825 -0
  81. package/skills/cometchat-ios-features/SKILL.md +725 -0
  82. package/skills/cometchat-ios-placement/SKILL.md +750 -0
  83. package/skills/cometchat-ios-production/SKILL.md +730 -0
  84. package/skills/cometchat-ios-push/SKILL.md +582 -0
  85. package/skills/cometchat-ios-theming/SKILL.md +631 -0
  86. package/skills/cometchat-ios-troubleshooting/SKILL.md +983 -0
  87. package/skills/cometchat-native-bare-patterns/SKILL.md +470 -0
  88. package/skills/cometchat-native-components/SKILL.md +594 -0
  89. package/skills/cometchat-native-core/SKILL.md +407 -0
  90. package/skills/cometchat-native-customization/SKILL.md +594 -0
  91. package/skills/cometchat-native-expo-patterns/SKILL.md +485 -0
  92. package/skills/cometchat-native-features/SKILL.md +608 -0
  93. package/skills/cometchat-native-placement/SKILL.md +500 -0
  94. package/skills/cometchat-native-production/SKILL.md +694 -0
  95. package/skills/cometchat-native-push/SKILL.md +593 -0
  96. package/skills/cometchat-native-testing/SKILL.md +583 -0
  97. package/skills/cometchat-native-theming/SKILL.md +656 -0
  98. package/skills/cometchat-native-troubleshooting/SKILL.md +433 -0
  99. package/skills/cometchat-nextjs-patterns/SKILL.md +5 -5
  100. package/skills/cometchat-production/SKILL.md +60 -0
  101. 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