@cometchat/skills 3.1.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/README.md +35 -17
- package/bin/install.js +389 -43
- package/package.json +17 -8
- package/skills/cometchat/SKILL.md +653 -50
- 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 +2 -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-react-router-patterns/SKILL.md +23 -21
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cometchat-flutter-v6-core
|
|
3
|
+
description: >
|
|
4
|
+
Use when writing any code that uses cometchat_chat_uikit. Contains hard rules that prevent
|
|
5
|
+
silent failures, crashes, and subtle bugs. Covers CometChatUIKit.init, login, logout,
|
|
6
|
+
UIKitSettings, UIKitSettingsBuilder, listener lifecycle, theme caching, Scaffold
|
|
7
|
+
resizeToAvoidBottomInset, subscriptionType, region, muid preservation, and the
|
|
8
|
+
Clean Architecture + BLoC component pattern. Also use when seeing errors like
|
|
9
|
+
"Authentication null", "APP ID null", ERR_ALREADY_LOGGED_IN, or StateError from
|
|
10
|
+
uninitialized ServiceLocator. Make sure to use this skill for any CometChat Flutter
|
|
11
|
+
UIKit code, even simple widget usage.
|
|
12
|
+
license: "MIT"
|
|
13
|
+
compatibility: "cometchat_chat_uikit ^6.0.0-beta2; flutter_bloc ^8.1.0"
|
|
14
|
+
allowed-tools: "executeBash, readFile, readCode, fileSearch, listDirectory, grepSearch"
|
|
15
|
+
metadata:
|
|
16
|
+
author: "CometChat"
|
|
17
|
+
version: "3.0.0"
|
|
18
|
+
tags: "cometchat flutter core rules init login logout lifecycle"
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# CometChat Flutter UIKit — Core Rules
|
|
22
|
+
|
|
23
|
+
Non-negotiable constraints for all CometChat UIKit code. Violating these causes silent failures or crashes.
|
|
24
|
+
|
|
25
|
+
## Rule: INIT_FIRST
|
|
26
|
+
|
|
27
|
+
`CometChatUIKit.init()` must complete before any login, component usage, or SDK call.
|
|
28
|
+
|
|
29
|
+
```dart
|
|
30
|
+
// ✅ CORRECT
|
|
31
|
+
final settings = (UIKitSettingsBuilder()
|
|
32
|
+
..appId = 'APP_ID'
|
|
33
|
+
..region = 'us'
|
|
34
|
+
..authKey = 'AUTH_KEY'
|
|
35
|
+
..subscriptionType = CometChatSubscriptionType.allUsers)
|
|
36
|
+
.build();
|
|
37
|
+
|
|
38
|
+
await CometChatUIKit.init(
|
|
39
|
+
uiKitSettings: settings,
|
|
40
|
+
onSuccess: (_) => debugPrint('Init done'),
|
|
41
|
+
onError: (e) => debugPrint('Init failed: ${e.message}'),
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// ❌ WRONG — login before init completes
|
|
45
|
+
CometChatUIKit.init(uiKitSettings: settings);
|
|
46
|
+
CometChatUIKit.login('uid'); // Race condition
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Rule: AUTH_CHECK_AFTER_INIT
|
|
50
|
+
|
|
51
|
+
After `CometChatUIKit.init()` completes (in its `onSuccess`), the static field `CometChatUIKit.loggedInUser` is already populated if a cached session exists. Use this synchronous check — do NOT call `CometChat.getLoggedInUser()` separately.
|
|
52
|
+
|
|
53
|
+
```dart
|
|
54
|
+
// ✅ CORRECT — synchronous check after init completes
|
|
55
|
+
CometChatUIKit.init(
|
|
56
|
+
uiKitSettings: settings,
|
|
57
|
+
onSuccess: (_) {
|
|
58
|
+
final hasUser = CometChatUIKit.loggedInUser != null;
|
|
59
|
+
// Route to home or login based on hasUser
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
// ❌ WRONG — separate async getLoggedInUser call after init
|
|
64
|
+
CometChatUIKit.init(
|
|
65
|
+
uiKitSettings: settings,
|
|
66
|
+
onSuccess: (_) {
|
|
67
|
+
CometChat.getLoggedInUser(
|
|
68
|
+
onSuccess: (user) { ... }, // Unreliable when no session exists
|
|
69
|
+
onError: (e) { ... },
|
|
70
|
+
);
|
|
71
|
+
},
|
|
72
|
+
);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The `init()` method internally calls `getLoggedInUser()` and sets `CometChatUIKit.loggedInUser` before firing `onSuccess`. Calling it again is redundant and the callback-based version can silently fail when no session exists (the SDK logs "Please log in to CometChat before calling this method" and neither callback fires consistently).
|
|
76
|
+
|
|
77
|
+
This also applies to `login()` and `loginWithAuthToken()` — all three populate `CometChatUIKit.loggedInUser` before calling `onSuccess`.
|
|
78
|
+
|
|
79
|
+
```dart
|
|
80
|
+
// ❌ ALSO WRONG — async getLoggedInUser after init (redundant native bridge round-trip)
|
|
81
|
+
CometChatUIKit.init(
|
|
82
|
+
uiKitSettings: settings,
|
|
83
|
+
onSuccess: (_) async {
|
|
84
|
+
final user = await CometChatUIKit.getLoggedInUser(); // Unnecessary!
|
|
85
|
+
if (user != null) { ... }
|
|
86
|
+
},
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
// ❌ ALSO WRONG — raw SDK getLoggedInUser (bypasses UIKit, unreliable)
|
|
90
|
+
User? existingUser = await CometChat.getLoggedInUser();
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Rule: SCAFFOLD_NO_RESIZE
|
|
94
|
+
|
|
95
|
+
Any `Scaffold` containing `CometChatMessageComposer` MUST set `resizeToAvoidBottomInset: false`. The composer handles keyboard spacing internally via `SliverSpacing`. Leaving it `true` causes double-compensation and layout jumps.
|
|
96
|
+
|
|
97
|
+
```dart
|
|
98
|
+
// ✅ CORRECT
|
|
99
|
+
Scaffold(
|
|
100
|
+
resizeToAvoidBottomInset: false,
|
|
101
|
+
body: Column(
|
|
102
|
+
children: [
|
|
103
|
+
Expanded(child: CometChatMessageList(user: user)),
|
|
104
|
+
CometChatMessageComposer(user: user),
|
|
105
|
+
],
|
|
106
|
+
),
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
// ❌ WRONG — default is true, causes double keyboard compensation
|
|
110
|
+
Scaffold(
|
|
111
|
+
body: Column(
|
|
112
|
+
children: [
|
|
113
|
+
Expanded(child: CometChatMessageList(user: user)),
|
|
114
|
+
CometChatMessageComposer(user: user),
|
|
115
|
+
],
|
|
116
|
+
),
|
|
117
|
+
)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Rule: LISTENER_LIFECYCLE
|
|
121
|
+
|
|
122
|
+
SDK listeners MUST be registered with a unique ID in `initState()` and removed with the same ID in `dispose()`. Forgetting removal causes duplicate events and memory leaks.
|
|
123
|
+
|
|
124
|
+
```dart
|
|
125
|
+
// ✅ CORRECT
|
|
126
|
+
class _MyScreenState extends State<MyScreen> with MessageListener {
|
|
127
|
+
late final String _listenerId;
|
|
128
|
+
|
|
129
|
+
@override
|
|
130
|
+
void initState() {
|
|
131
|
+
super.initState();
|
|
132
|
+
_listenerId = 'my_screen_${DateTime.now().millisecondsSinceEpoch}';
|
|
133
|
+
CometChat.addMessageListener(_listenerId, this);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
@override
|
|
137
|
+
void dispose() {
|
|
138
|
+
CometChat.removeMessageListener(_listenerId);
|
|
139
|
+
super.dispose();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// ❌ WRONG — hardcoded ID causes collisions; missing dispose removal
|
|
144
|
+
class _MyScreenState extends State<MyScreen> with MessageListener {
|
|
145
|
+
@override
|
|
146
|
+
void initState() {
|
|
147
|
+
super.initState();
|
|
148
|
+
CometChat.addMessageListener('messages', this); // Collision!
|
|
149
|
+
}
|
|
150
|
+
// Missing dispose → listener leaks
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Rule: THEME_CACHE
|
|
155
|
+
|
|
156
|
+
Cache theme values in `didChangeDependencies()` with a `_themeInitialized` flag. Never call `CometChatThemeHelper.getColorPalette(context)` in `build()` — during keyboard animation, `MediaQuery` changes trigger rebuilds, and each lookup does expensive InheritedWidget traversal (44-95ms instead of <16ms).
|
|
157
|
+
|
|
158
|
+
```dart
|
|
159
|
+
// ✅ CORRECT — Hybrid pattern
|
|
160
|
+
class _MyWidgetState extends State<MyWidget> {
|
|
161
|
+
late CometChatColorPalette _colorPalette;
|
|
162
|
+
late CometChatSpacing _spacing;
|
|
163
|
+
late CometChatTypography _typography;
|
|
164
|
+
bool _themeInitialized = false;
|
|
165
|
+
|
|
166
|
+
@override
|
|
167
|
+
void didChangeDependencies() {
|
|
168
|
+
super.didChangeDependencies();
|
|
169
|
+
if (!_themeInitialized) {
|
|
170
|
+
_colorPalette = CometChatThemeHelper.getColorPalette(context);
|
|
171
|
+
_spacing = CometChatThemeHelper.getSpacing(context);
|
|
172
|
+
_typography = CometChatThemeHelper.getTypography(context);
|
|
173
|
+
_themeInitialized = true;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// ❌ WRONG — lookup in build causes jank
|
|
179
|
+
@override
|
|
180
|
+
Widget build(BuildContext context) {
|
|
181
|
+
final colors = CometChatThemeHelper.getColorPalette(context); // Expensive!
|
|
182
|
+
return Container(color: colors.primary);
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Rule: SUBSCRIPTION_TYPE_REQUIRED
|
|
187
|
+
|
|
188
|
+
Omitting `subscriptionType` in `UIKitSettingsBuilder` silently disables all presence events (online/offline, typing indicators). No error is thrown.
|
|
189
|
+
|
|
190
|
+
```dart
|
|
191
|
+
// ✅ CORRECT
|
|
192
|
+
UIKitSettingsBuilder()
|
|
193
|
+
..subscriptionType = CometChatSubscriptionType.allUsers
|
|
194
|
+
|
|
195
|
+
// ❌ WRONG — no error, but presence events never fire
|
|
196
|
+
UIKitSettingsBuilder()
|
|
197
|
+
..appId = 'APP_ID'
|
|
198
|
+
..region = 'us'
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Rule: REGION_LOWERCASE
|
|
202
|
+
|
|
203
|
+
Region must be a lowercase string. The SDK validates against `['us', 'eu', 'in']`.
|
|
204
|
+
|
|
205
|
+
```dart
|
|
206
|
+
// ✅ CORRECT
|
|
207
|
+
..region = 'us'
|
|
208
|
+
|
|
209
|
+
// ❌ WRONG — throws ERR_INVALID_REGION
|
|
210
|
+
..region = 'US'
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Rule: SERVICE_LOCATOR_INIT
|
|
214
|
+
|
|
215
|
+
Each component's `ServiceLocator.instance.setup()` must be called before creating its BLoC. The UIKit widgets do this automatically, but if you create BLoCs manually:
|
|
216
|
+
|
|
217
|
+
```dart
|
|
218
|
+
// ✅ CORRECT
|
|
219
|
+
ConversationsServiceLocator.instance.setup();
|
|
220
|
+
final bloc = ConversationsBloc(
|
|
221
|
+
getLoggedInUserUseCase: ConversationsServiceLocator.instance.getLoggedInUserUseCase,
|
|
222
|
+
// ...
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
// ❌ WRONG — StateError: not initialized
|
|
226
|
+
final bloc = ConversationsBloc(
|
|
227
|
+
getLoggedInUserUseCase: ConversationsServiceLocator.instance.getLoggedInUserUseCase,
|
|
228
|
+
);
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Rule: MUID_PRESERVATION
|
|
232
|
+
|
|
233
|
+
When sending messages, the SDK may return an empty `muid` in the success callback. The UIKit preserves the original `muid` for pending→sent deduplication. If you handle `ccMessageSent` events, compare by `muid` first, then `id`.
|
|
234
|
+
|
|
235
|
+
## Pattern: Callback → Async Bridge
|
|
236
|
+
|
|
237
|
+
The CometChat SDK uses callback-based APIs (`onSuccess`/`onError`). Wrap them with `Completer` for async/await:
|
|
238
|
+
|
|
239
|
+
```dart
|
|
240
|
+
import 'dart:async';
|
|
241
|
+
|
|
242
|
+
Future<User> loginAsync(String uid) {
|
|
243
|
+
final completer = Completer<User>();
|
|
244
|
+
CometChatUIKit.login(uid,
|
|
245
|
+
onSuccess: (user) => completer.complete(user),
|
|
246
|
+
onError: (e) => completer.completeError(e),
|
|
247
|
+
);
|
|
248
|
+
return completer.future;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Usage
|
|
252
|
+
try {
|
|
253
|
+
final user = await loginAsync('user123');
|
|
254
|
+
} on CometChatException catch (e) {
|
|
255
|
+
debugPrint('Login failed: ${e.message}');
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
This pattern is used internally by the UIKit's repository layer. Use it when calling SDK methods directly outside UIKit components.
|
|
260
|
+
|
|
261
|
+
## Component Architecture Pattern
|
|
262
|
+
|
|
263
|
+
Every component follows this structure:
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
{component}/
|
|
267
|
+
├── bloc/
|
|
268
|
+
│ ├── {component}_bloc.dart # Extends Bloc<Event, State>, registers SDK listeners
|
|
269
|
+
│ ├── {component}_event.dart # Equatable events
|
|
270
|
+
│ └── {component}_state.dart # Equatable state with copyWith
|
|
271
|
+
├── domain/
|
|
272
|
+
│ ├── usecases/ # One class per operation
|
|
273
|
+
│ └── repositories/ # Abstract interface
|
|
274
|
+
├── data/
|
|
275
|
+
│ ├── repositories/ # Impl delegates to datasource
|
|
276
|
+
│ └── datasources/ # SDK calls
|
|
277
|
+
├── di/
|
|
278
|
+
│ └── {component}_service_locator.dart # Singleton, setup() method
|
|
279
|
+
└── widgets/ # UI, uses BlocConsumer/BlocBuilder
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Naming Conventions
|
|
283
|
+
|
|
284
|
+
| Type | Pattern | Example |
|
|
285
|
+
|------|---------|---------|
|
|
286
|
+
| Widget | `CometChat{Name}` | `CometChatConversations` |
|
|
287
|
+
| BLoC | `{Name}Bloc` | `ConversationsBloc` |
|
|
288
|
+
| Event | `{Verb}{Name}` | `LoadConversations`, `MessageReceived` |
|
|
289
|
+
| State | `{Name}State` | `ConversationsLoaded`, `MessageListState` |
|
|
290
|
+
| Repository | `{Name}Repository` / `{Name}RepositoryImpl` | `ConversationsRepository` |
|
|
291
|
+
| Use Case | `{Verb}{Name}UseCase` | `GetConversationsUseCase` |
|
|
292
|
+
| Service Locator | `{Name}ServiceLocator` | `ConversationsServiceLocator` |
|
|
293
|
+
| Style | `CometChat{Name}Style` | `CometChatConversationsStyle` |
|
|
294
|
+
|
|
295
|
+
## Checklist — Every CometChat Screen
|
|
296
|
+
|
|
297
|
+
- [ ] `CometChatUIKit.init()` called before any usage
|
|
298
|
+
- [ ] Auth check uses `CometChatUIKit.loggedInUser` after init, not `CometChat.getLoggedInUser()`
|
|
299
|
+
- [ ] `subscriptionType` set in UIKitSettingsBuilder
|
|
300
|
+
- [ ] `region` is lowercase
|
|
301
|
+
- [ ] Scaffold has `resizeToAvoidBottomInset: false` if composer is present
|
|
302
|
+
- [ ] Theme cached in `didChangeDependencies()`, not `build()`
|
|
303
|
+
- [ ] SDK listeners registered with unique ID, removed in `dispose()`
|
|
304
|
+
- [ ] Colors from `CometChatThemeHelper`, never hardcoded
|
|
305
|
+
- [ ] Strings from `Translations.of(context)`, never hardcoded
|