@cometchat/skills 4.2.1 → 4.4.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 +33 -12
- package/bin/install.js +59 -4
- package/package.json +14 -1
- package/skills/cometchat/SKILL.md +460 -77
- package/skills/cometchat/references/asking-questions.md +48 -0
- package/skills/cometchat-a11y/SKILL.md +3 -2
- package/skills/cometchat-android-v5/SKILL.md +2 -1
- package/skills/cometchat-android-v5-calls/SKILL.md +36 -22
- package/skills/cometchat-android-v5-calls/references/README.md +1 -1
- package/skills/cometchat-android-v5-calls/references/add-calls-to-existing-chat.md +7 -5
- package/skills/cometchat-android-v5-calls/references/audio-controls.md +4 -4
- package/skills/cometchat-android-v5-calls/references/call-layouts.md +33 -25
- package/skills/cometchat-android-v5-calls/references/call-session.md +2 -2
- package/skills/cometchat-android-v5-calls/references/custom-ui.md +5 -5
- package/skills/cometchat-android-v5-calls/references/event-listeners.md +2 -2
- package/skills/cometchat-android-v5-calls/references/idle-timeout.md +20 -14
- package/skills/cometchat-android-v5-calls/references/in-call-chat.md +1 -1
- package/skills/cometchat-android-v5-calls/references/migration-v4-to-v5.md +43 -27
- package/skills/cometchat-android-v5-calls/references/participant-management.md +3 -3
- package/skills/cometchat-android-v5-calls/references/raise-hand.md +25 -19
- package/skills/cometchat-android-v5-calls/references/recording.md +2 -2
- package/skills/cometchat-android-v5-calls/references/ringing-integration.md +1 -1
- package/skills/cometchat-android-v5-calls/references/screen-sharing.md +5 -9
- package/skills/cometchat-android-v5-calls/references/session-settings.md +3 -3
- package/skills/cometchat-android-v5-calls/references/setup.md +1 -1
- package/skills/cometchat-android-v5-calls/references/share-invite.md +9 -4
- package/skills/cometchat-android-v5-calls/references/video-controls.md +4 -4
- package/skills/cometchat-android-v5-calls/references/voip-calling.md +2 -2
- package/skills/cometchat-android-v5-components/SKILL.md +4 -3
- package/skills/cometchat-android-v5-core/SKILL.md +20 -2
- package/skills/cometchat-android-v5-customization/SKILL.md +171 -7
- package/skills/cometchat-android-v5-extensions/SKILL.md +7 -4
- package/skills/cometchat-android-v5-features/SKILL.md +5 -4
- package/skills/cometchat-android-v5-placement/SKILL.md +2 -1
- package/skills/cometchat-android-v5-production/SKILL.md +2 -1
- package/skills/cometchat-android-v5-push/SKILL.md +2 -3
- package/skills/cometchat-android-v5-testing/SKILL.md +2 -1
- package/skills/cometchat-android-v5-theming/SKILL.md +2 -1
- package/skills/cometchat-android-v5-troubleshooting/SKILL.md +3 -2
- package/skills/cometchat-android-v6/SKILL.md +2 -1
- package/skills/cometchat-android-v6-builder-settings/SKILL.md +11 -7
- package/skills/cometchat-android-v6-calls/SKILL.md +79 -18
- package/skills/cometchat-android-v6-calls/references/advanced-features.md +87 -0
- package/skills/cometchat-android-v6-calls/references/call-layouts.md +24 -15
- package/skills/cometchat-android-v6-calls/references/call-session.md +2 -2
- package/skills/cometchat-android-v6-calls/references/device-management.md +17 -16
- package/skills/cometchat-android-v6-calls/references/idle-timeout.md +7 -4
- package/skills/cometchat-android-v6-calls/references/in-call-chat.md +13 -8
- package/skills/cometchat-android-v6-calls/references/raise-hand.md +6 -4
- package/skills/cometchat-android-v6-compose-components/SKILL.md +52 -29
- package/skills/cometchat-android-v6-compose-customization/SKILL.md +156 -1
- package/skills/cometchat-android-v6-compose-placement/SKILL.md +129 -40
- package/skills/cometchat-android-v6-compose-theming/SKILL.md +27 -1
- package/skills/cometchat-android-v6-core/SKILL.md +389 -9
- package/skills/cometchat-android-v6-events/SKILL.md +4 -1
- package/skills/cometchat-android-v6-extensions/SKILL.md +2 -1
- package/skills/cometchat-android-v6-features/SKILL.md +26 -2
- package/skills/cometchat-android-v6-kotlin-components/SKILL.md +31 -1
- package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +172 -1
- package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +20 -5
- package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +36 -5
- package/skills/cometchat-android-v6-migration/SKILL.md +44 -42
- package/skills/cometchat-android-v6-production/SKILL.md +6 -3
- package/skills/cometchat-android-v6-push/SKILL.md +43 -2
- package/skills/cometchat-android-v6-testing/SKILL.md +11 -8
- package/skills/cometchat-android-v6-troubleshooting/SKILL.md +26 -5
- package/skills/cometchat-angular-calls/SKILL.md +256 -389
- package/skills/cometchat-angular-calls/references/add-calls-to-existing-chat.md +3 -2
- package/skills/cometchat-angular-calls/references/call-layouts.md +29 -12
- package/skills/cometchat-angular-calls/references/call-session.md +2 -2
- package/skills/cometchat-angular-calls/references/custom-ui.md +18 -10
- package/skills/cometchat-angular-calls/references/device-management.md +53 -34
- package/skills/cometchat-angular-calls/references/group-calls.md +45 -24
- package/skills/cometchat-angular-calls/references/idle-timeout.md +31 -15
- package/skills/cometchat-angular-calls/references/ngzone-and-async-callbacks.md +7 -6
- package/skills/cometchat-angular-calls/references/raise-hand.md +9 -4
- package/skills/cometchat-angular-calls/references/recording-screen-share.md +32 -39
- package/skills/cometchat-angular-calls/references/ringing-integration.md +3 -1
- package/skills/cometchat-angular-calls/references/share-invite.md +11 -5
- package/skills/cometchat-angular-calls/references/virtual-background.md +29 -0
- package/skills/cometchat-angular-components/SKILL.md +149 -620
- package/skills/cometchat-angular-core/SKILL.md +235 -293
- package/skills/cometchat-angular-customization/SKILL.md +415 -223
- package/skills/cometchat-angular-features/SKILL.md +216 -334
- package/skills/cometchat-angular-patterns/SKILL.md +168 -359
- package/skills/cometchat-angular-placement/SKILL.md +189 -560
- package/skills/cometchat-angular-production/SKILL.md +241 -92
- package/skills/cometchat-angular-push/SKILL.md +280 -294
- package/skills/cometchat-angular-testing/SKILL.md +430 -158
- package/skills/cometchat-angular-theming/SKILL.md +190 -265
- package/skills/cometchat-angular-troubleshooting/SKILL.md +192 -157
- package/skills/cometchat-astro-patterns/SKILL.md +22 -1
- package/skills/cometchat-calls/SKILL.md +25 -19
- package/skills/cometchat-calls/references/use-case-broadcast.md +15 -10
- package/skills/cometchat-calls/references/use-case-marketplace.md +2 -3
- package/skills/cometchat-calls/references/use-case-support.md +3 -4
- package/skills/cometchat-calls/references/use-case-team.md +23 -12
- package/skills/cometchat-calls/references/use-case-telehealth.md +3 -4
- package/skills/cometchat-components/SKILL.md +163 -25
- package/skills/cometchat-core/SKILL.md +412 -13
- package/skills/cometchat-customization/SKILL.md +50 -25
- package/skills/cometchat-features/SKILL.md +313 -34
- package/skills/cometchat-flutter-v5/SKILL.md +10 -4
- package/skills/cometchat-flutter-v5-calls/SKILL.md +188 -158
- package/skills/cometchat-flutter-v5-calls/references/add-calls-to-existing-chat.md +48 -24
- package/skills/cometchat-flutter-v5-calls/references/call-layouts.md +20 -15
- package/skills/cometchat-flutter-v5-calls/references/call-session.md +100 -145
- package/skills/cometchat-flutter-v5-calls/references/device-management.md +12 -8
- package/skills/cometchat-flutter-v5-calls/references/group-calls.md +30 -36
- package/skills/cometchat-flutter-v5-calls/references/idle-timeout.md +15 -13
- package/skills/cometchat-flutter-v5-calls/references/in-call-chat.md +12 -9
- package/skills/cometchat-flutter-v5-calls/references/migration-v4-to-v5.md +115 -65
- package/skills/cometchat-flutter-v5-calls/references/raise-hand.md +41 -30
- package/skills/cometchat-flutter-v5-calls/references/ringing-integration.md +17 -14
- package/skills/cometchat-flutter-v5-calls/references/share-invite.md +8 -2
- package/skills/cometchat-flutter-v5-conversations/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-core/SKILL.md +20 -2
- package/skills/cometchat-flutter-v5-customization/SKILL.md +136 -5
- package/skills/cometchat-flutter-v5-events/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-messages/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-production/SKILL.md +15 -6
- package/skills/cometchat-flutter-v5-push/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-testing/SKILL.md +17 -6
- package/skills/cometchat-flutter-v5-theming/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +7 -6
- package/skills/cometchat-flutter-v5-users-groups/SKILL.md +3 -2
- package/skills/cometchat-flutter-v6/SKILL.md +17 -16
- package/skills/cometchat-flutter-v6-calls/SKILL.md +78 -63
- package/skills/cometchat-flutter-v6-calls/references/add-calls-to-existing-chat.md +8 -6
- package/skills/cometchat-flutter-v6-calls/references/advanced-features.md +89 -0
- package/skills/cometchat-flutter-v6-calls/references/call-layouts.md +15 -12
- package/skills/cometchat-flutter-v6-calls/references/call-session.md +2 -2
- package/skills/cometchat-flutter-v6-calls/references/device-management.md +9 -3
- package/skills/cometchat-flutter-v6-calls/references/group-calls.md +10 -10
- package/skills/cometchat-flutter-v6-calls/references/idle-timeout.md +15 -7
- package/skills/cometchat-flutter-v6-calls/references/in-call-chat.md +6 -3
- package/skills/cometchat-flutter-v6-calls/references/raise-hand.md +23 -16
- package/skills/cometchat-flutter-v6-components/SKILL.md +32 -11
- package/skills/cometchat-flutter-v6-conversations/SKILL.md +39 -11
- package/skills/cometchat-flutter-v6-core/SKILL.md +348 -10
- package/skills/cometchat-flutter-v6-customization/SKILL.md +97 -25
- package/skills/cometchat-flutter-v6-events/SKILL.md +3 -2
- package/skills/cometchat-flutter-v6-features/SKILL.md +15 -6
- package/skills/cometchat-flutter-v6-messages/SKILL.md +111 -60
- package/skills/cometchat-flutter-v6-migration/SKILL.md +18 -25
- package/skills/cometchat-flutter-v6-placement/SKILL.md +79 -50
- package/skills/cometchat-flutter-v6-production/SKILL.md +13 -12
- package/skills/cometchat-flutter-v6-push/SKILL.md +43 -21
- package/skills/cometchat-flutter-v6-testing/SKILL.md +6 -6
- package/skills/cometchat-flutter-v6-theming/SKILL.md +38 -5
- package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +182 -17
- package/skills/cometchat-flutter-v6-users-groups/SKILL.md +12 -4
- package/skills/cometchat-i18n/SKILL.md +139 -78
- package/skills/cometchat-ios/SKILL.md +4 -2
- package/skills/cometchat-ios-calls/SKILL.md +225 -95
- package/skills/cometchat-ios-calls/references/add-calls-to-existing-chat.md +11 -9
- package/skills/cometchat-ios-calls/references/audio-modes-and-controls.md +45 -0
- package/skills/cometchat-ios-calls/references/avaudiosession-routing.md +6 -7
- package/skills/cometchat-ios-calls/references/call-layouts.md +31 -91
- package/skills/cometchat-ios-calls/references/call-session.md +51 -54
- package/skills/cometchat-ios-calls/references/callkit-and-pushkit.md +33 -29
- package/skills/cometchat-ios-calls/references/custom-ui.md +38 -38
- package/skills/cometchat-ios-calls/references/group-calls.md +33 -70
- package/skills/cometchat-ios-calls/references/idle-timeout.md +24 -25
- package/skills/cometchat-ios-calls/references/in-call-chat.md +19 -23
- package/skills/cometchat-ios-calls/references/migration-v4-to-v5.md +128 -70
- package/skills/cometchat-ios-calls/references/picture-in-picture.md +20 -20
- package/skills/cometchat-ios-calls/references/raise-hand.md +14 -227
- package/skills/cometchat-ios-calls/references/recording-screen-share.md +35 -122
- package/skills/cometchat-ios-calls/references/ringing-integration.md +17 -16
- package/skills/cometchat-ios-calls/references/share-invite.md +8 -12
- package/skills/cometchat-ios-calls/references/swiftui-uikit-hosting.md +4 -4
- package/skills/cometchat-ios-components/SKILL.md +200 -12
- package/skills/cometchat-ios-core/SKILL.md +281 -11
- package/skills/cometchat-ios-customization/SKILL.md +276 -110
- package/skills/cometchat-ios-features/SKILL.md +64 -36
- package/skills/cometchat-ios-placement/SKILL.md +15 -12
- package/skills/cometchat-ios-production/SKILL.md +12 -4
- package/skills/cometchat-ios-push/SKILL.md +53 -19
- package/skills/cometchat-ios-testing/SKILL.md +14 -9
- package/skills/cometchat-ios-theming/SKILL.md +39 -3
- package/skills/cometchat-ios-troubleshooting/SKILL.md +41 -21
- package/skills/cometchat-native-bare-patterns/SKILL.md +56 -18
- package/skills/cometchat-native-calls/SKILL.md +89 -19
- package/skills/cometchat-native-calls/references/add-calls-to-existing-chat.md +2 -2
- package/skills/cometchat-native-calls/references/call-layouts.md +15 -14
- package/skills/cometchat-native-calls/references/call-session.md +2 -2
- package/skills/cometchat-native-calls/references/custom-ui.md +12 -8
- package/skills/cometchat-native-calls/references/device-management.md +53 -30
- package/skills/cometchat-native-calls/references/group-calls.md +35 -30
- package/skills/cometchat-native-calls/references/idle-timeout.md +6 -6
- package/skills/cometchat-native-calls/references/in-call-chat.md +10 -8
- package/skills/cometchat-native-calls/references/migration-v4-to-v5.md +2 -2
- package/skills/cometchat-native-calls/references/raise-hand.md +15 -13
- package/skills/cometchat-native-calls/references/recording-screen-share.md +49 -170
- package/skills/cometchat-native-calls/references/share-invite.md +7 -5
- package/skills/cometchat-native-calls/references/voip-push-end-to-end.md +4 -2
- package/skills/cometchat-native-components/SKILL.md +91 -57
- package/skills/cometchat-native-core/SKILL.md +281 -9
- package/skills/cometchat-native-customization/SKILL.md +150 -28
- package/skills/cometchat-native-expo-patterns/SKILL.md +77 -27
- package/skills/cometchat-native-features/SKILL.md +79 -49
- package/skills/cometchat-native-placement/SKILL.md +19 -10
- package/skills/cometchat-native-production/SKILL.md +9 -3
- package/skills/cometchat-native-push/SKILL.md +2 -1
- package/skills/cometchat-native-testing/SKILL.md +1 -2
- package/skills/cometchat-native-theming/SKILL.md +54 -29
- package/skills/cometchat-native-troubleshooting/SKILL.md +71 -3
- package/skills/cometchat-nextjs-patterns/SKILL.md +48 -6
- package/skills/cometchat-placement/SKILL.md +42 -3
- package/skills/cometchat-production/SKILL.md +12 -5
- package/skills/cometchat-react-calls/SKILL.md +220 -10
- package/skills/cometchat-react-calls/references/add-calls-to-existing-chat.md +4 -3
- package/skills/cometchat-react-calls/references/call-layouts.md +5 -6
- package/skills/cometchat-react-calls/references/call-session.md +1 -1
- package/skills/cometchat-react-calls/references/custom-ui.md +61 -15
- package/skills/cometchat-react-calls/references/device-management.md +55 -51
- package/skills/cometchat-react-calls/references/group-calls.md +18 -23
- package/skills/cometchat-react-calls/references/idle-timeout.md +25 -12
- package/skills/cometchat-react-calls/references/in-call-chat.md +7 -7
- package/skills/cometchat-react-calls/references/migration-v4-to-v5.md +9 -11
- package/skills/cometchat-react-calls/references/raise-hand.md +14 -14
- package/skills/cometchat-react-calls/references/recording-screen-share.md +39 -38
- package/skills/cometchat-react-calls/references/ringing-integration.md +2 -2
- package/skills/cometchat-react-calls/references/share-invite.md +4 -5
- package/skills/cometchat-react-calls/references/testing-calls-on-web.md +20 -2
- package/skills/cometchat-react-calls/references/virtual-background.md +32 -0
- package/skills/cometchat-react-patterns/SKILL.md +57 -4
- package/skills/cometchat-react-push/SKILL.md +258 -72
- package/skills/cometchat-react-router-patterns/SKILL.md +43 -4
- package/skills/cometchat-react-testing/SKILL.md +14 -5
- package/skills/cometchat-theming/SKILL.md +181 -18
- package/skills/cometchat-troubleshooting/SKILL.md +40 -20
|
@@ -3,7 +3,6 @@ name: cometchat-native-core
|
|
|
3
3
|
description: "Shared rules for CometChat React Native UI Kit v5. Always loaded alongside framework (expo/bare) and placement skills. Read this first."
|
|
4
4
|
license: "MIT"
|
|
5
5
|
compatibility: "Node.js >=18; React Native >=0.70; @cometchat/chat-uikit-react-native ^5; @cometchat/chat-sdk-react-native ^4"
|
|
6
|
-
allowed-tools: "shell, file-read, file-search, file-list"
|
|
7
6
|
metadata:
|
|
8
7
|
author: "CometChat"
|
|
9
8
|
version: "3.0.0"
|
|
@@ -16,7 +15,7 @@ This is the foundational skill for every CometChat React Native UI Kit v5 integr
|
|
|
16
15
|
|
|
17
16
|
**Read this skill first, before any framework (`cometchat-native-expo-patterns` / `cometchat-native-bare-patterns`) or placement skill.**
|
|
18
17
|
|
|
19
|
-
Ground-truth sources: `docs/ui-kit/react-native/overview.mdx`, `react-native-cli-integration.mdx`, `expo-integration.mdx`, `methods.mdx`, and `@cometchat/chat-uikit-react-native@5.3.
|
|
18
|
+
Ground-truth sources: `docs/ui-kit/react-native/overview.mdx`, `react-native-cli-integration.mdx`, `expo-integration.mdx`, `methods.mdx`, and `@cometchat/chat-uikit-react-native@5.3.8`'s `src/index.ts` (file-based `initFromSettings` GA). **Official docs:** https://www.cometchat.com/docs/ui-kit/react-native/overview · **Docs MCP:** `claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp` (or fetch the URL directly without MCP).
|
|
20
19
|
|
|
21
20
|
---
|
|
22
21
|
|
|
@@ -30,7 +29,55 @@ CometChatUIKit.init(settings) → CometChatUIKit.login({ uid }) → rend
|
|
|
30
29
|
|
|
31
30
|
Breaking this order produces a blank screen, a "CometChat is not initialized" runtime error, or a hung login. No exceptions.
|
|
32
31
|
|
|
33
|
-
###
|
|
32
|
+
### File-based init with `cometchat-settings.json` (recommended)
|
|
33
|
+
|
|
34
|
+
> **Version requirement (ENG-35866 — Skills Telemetry).** `CometChatUIKit.initFromSettings(settings)` reads a `cometchat-settings.json` object and lets the SDK self-report `integrationSource = "ai-agent"` to `/user_sessions`. It ships GA in **`@cometchat/chat-uikit-react-native >= 5.3.8`** + **`@cometchat/chat-sdk-react-native >= 4.0.25`** (npm `latest`). On an older UI Kit the method does not exist — use the flat-object `init()` **fallback** below.
|
|
35
|
+
|
|
36
|
+
**Step 1 — create `cometchat-settings.json` at the project root.** Fill `appId` / `region` / `credentials.authKey` from the CLI `provision setup` output; leave everything else at the defaults below. Single source of credentials — no second copy to keep in sync.
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"appId": "APP_ID_HERE",
|
|
41
|
+
"region": "us",
|
|
42
|
+
"credentials": {
|
|
43
|
+
"authKey": "AUTH_KEY_HERE"
|
|
44
|
+
},
|
|
45
|
+
"chatSDK": {
|
|
46
|
+
"presenceSubscription": {
|
|
47
|
+
"type": "ALL_USERS",
|
|
48
|
+
"roles": []
|
|
49
|
+
},
|
|
50
|
+
"autoEstablishSocketConnection": true,
|
|
51
|
+
"adminHost": null,
|
|
52
|
+
"clientHost": null
|
|
53
|
+
},
|
|
54
|
+
"callsSDK": {
|
|
55
|
+
"host": null,
|
|
56
|
+
"adminHost": null,
|
|
57
|
+
"clientHost": null,
|
|
58
|
+
"callsHost": null
|
|
59
|
+
},
|
|
60
|
+
"uiKit": {
|
|
61
|
+
"subscribePresenceForAllUsers": true
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Step 2 — init by importing the JSON.** Metro bundles JSON imports natively (no extra config), so the file is read at build time exactly like the web kit:
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
// initFromSettings ships GA in @cometchat/chat-uikit-react-native >= 5.3.8 (ENG-35866)
|
|
70
|
+
import { CometChatUIKit } from "@cometchat/chat-uikit-react-native";
|
|
71
|
+
import cometchatSettings from "../cometchat-settings.json"; // adjust path to the file's location
|
|
72
|
+
|
|
73
|
+
await CometChatUIKit.initFromSettings(cometchatSettings);
|
|
74
|
+
// then: CometChatUIKit.login({ uid }) — see §2
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
- **Do NOT gitignore `cometchat-settings.json`.** The dev-mode `authKey` ships in the JS bundle either way; production integrations use server-minted auth tokens.
|
|
78
|
+
- The init-once flag + "init before first render" rules below apply unchanged — just swap the `init({...})` call for `initFromSettings(cometchatSettings)`.
|
|
79
|
+
|
|
80
|
+
### UIKitSettings — the init object (fallback — UI Kit before file-based init)
|
|
34
81
|
|
|
35
82
|
The v5 RN UI Kit's `init()` takes a flat `UIKitSettings` object (NOT a `UIKitSettingsBuilder` like the web kit). Pass fields directly:
|
|
36
83
|
|
|
@@ -60,6 +107,16 @@ async function initCometChat(): Promise<void> {
|
|
|
60
107
|
if (initialized) return;
|
|
61
108
|
initialized = true;
|
|
62
109
|
|
|
110
|
+
// Fail loud if env vars didn't load (EXPO_PUBLIC_* not set, or a config
|
|
111
|
+
// module returning undefined). Empty creds otherwise surface later as a
|
|
112
|
+
// cryptic init/login failure that's hard to trace. (audit P0-5)
|
|
113
|
+
if (!APP_ID || !REGION || !AUTH_KEY) {
|
|
114
|
+
throw new Error(
|
|
115
|
+
"CometChat credentials are empty — check your EXPO_PUBLIC_* env (or config module) " +
|
|
116
|
+
"and restart Metro with --reset-cache after editing it.",
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
63
120
|
await CometChatUIKit.init({
|
|
64
121
|
appId: APP_ID,
|
|
65
122
|
region: REGION,
|
|
@@ -80,12 +137,19 @@ Put the init call in a top-level `useEffect` (preferred — the provider pattern
|
|
|
80
137
|
### Development mode
|
|
81
138
|
|
|
82
139
|
```tsx
|
|
83
|
-
|
|
140
|
+
let user;
|
|
141
|
+
try {
|
|
142
|
+
user = await CometChatUIKit.getLoggedInUser();
|
|
143
|
+
} catch (e: any) {
|
|
144
|
+
if (e?.code !== "NOT_FOUND") throw e; // no-session is the expected "first run" path
|
|
145
|
+
}
|
|
84
146
|
if (!user) {
|
|
85
147
|
await CometChatUIKit.login({ uid: "cometchat-uid-1" }); // note: OBJECT form
|
|
86
148
|
}
|
|
87
149
|
```
|
|
88
150
|
|
|
151
|
+
**⚠️ `getLoggedInUser()` THROWS `code: "NOT_FOUND"` when there's no session** — it does NOT return `null`. An uncaught throw here is the #1 cause of "app stuck on splash screen" — the provider's `setReady(true)` never fires. Always wrap in try/catch and treat `NOT_FOUND` as the normal first-run path. (Validated on `@cometchat/chat-uikit-react-native@5.3.5`, kit source `CometChatUIKit.getLoggedInUser`.)
|
|
152
|
+
|
|
89
153
|
**⚠️ `login()` takes an object `{ uid: "..." }` on React Native**, not a bare string like on the web. Passing `"cometchat-uid-1"` directly silently fails.
|
|
90
154
|
|
|
91
155
|
Every new CometChat app ships 5 pre-seeded test users — `cometchat-uid-1` through `cometchat-uid-5`. Use one for development.
|
|
@@ -104,7 +168,12 @@ Guard with a module-level in-flight promise, same pattern as the web skill:
|
|
|
104
168
|
let loginInFlight: Promise<unknown> | null = null;
|
|
105
169
|
|
|
106
170
|
async function ensureLoggedIn(uid: string, authToken?: string): Promise<void> {
|
|
107
|
-
|
|
171
|
+
let existing;
|
|
172
|
+
try {
|
|
173
|
+
existing = await CometChatUIKit.getLoggedInUser();
|
|
174
|
+
} catch (e: any) {
|
|
175
|
+
if (e?.code !== "NOT_FOUND") throw e; // first-run path
|
|
176
|
+
}
|
|
108
177
|
if (existing) return;
|
|
109
178
|
if (loginInFlight) {
|
|
110
179
|
await loginInFlight; // reuse the pending promise
|
|
@@ -253,7 +322,12 @@ let initialized = false;
|
|
|
253
322
|
let loginInFlight: Promise<unknown> | null = null;
|
|
254
323
|
|
|
255
324
|
async function ensureLoggedIn(uid: string, authToken?: string): Promise<void> {
|
|
256
|
-
|
|
325
|
+
let existing;
|
|
326
|
+
try {
|
|
327
|
+
existing = await CometChatUIKit.getLoggedInUser();
|
|
328
|
+
} catch (e: any) {
|
|
329
|
+
if (e?.code !== "NOT_FOUND") throw e; // first-run path
|
|
330
|
+
}
|
|
257
331
|
if (existing) return;
|
|
258
332
|
if (loginInFlight) {
|
|
259
333
|
await loginInFlight;
|
|
@@ -376,17 +450,35 @@ npm install \
|
|
|
376
450
|
@cometchat/chat-sdk-react-native \
|
|
377
451
|
@cometchat/chat-uikit-react-native \
|
|
378
452
|
react-native-gesture-handler \
|
|
379
|
-
react-native-safe-area-context
|
|
453
|
+
react-native-safe-area-context \
|
|
454
|
+
@react-native-clipboard/clipboard \
|
|
455
|
+
react-native-svg \
|
|
456
|
+
react-native-video \
|
|
457
|
+
react-native-localize \
|
|
458
|
+
punycode
|
|
380
459
|
```
|
|
381
460
|
|
|
461
|
+
> The kit's declared peer deps include `@react-native-clipboard/clipboard`, `react-native-svg`, `react-native-video`, and `react-native-localize` (it imports all four) — install them or the bundle fails at runtime. `react-native-safe-area-context` is also required (imported by several components) though not formally declared.
|
|
462
|
+
|
|
463
|
+
> **Why `punycode` — still REQUIRED on 5.3.7 (kit 5.3.7's markdown path needs it).** The kit's `CometChatAIAssistantMessageBubble` pulls in `react-native-markdown-display` → `markdown-it@^10` → `linkify-it@^2`, which does `require('punycode')`. **React Native / Metro does not bundle Node core modules**, so Metro can't resolve `punycode` unless you install the userland package → otherwise the bundle fails with `Unable to resolve module punycode`. (This is NOT version-gone-from-Node — it's RN not shipping Node core libs; affects any kit whose markdown/AI path is reachable, incl. 5.3.5 AND 5.3.7.) **Verified 2026-06-14 on a real `expo export`: Expo SDK 56 + RN 0.85.3 + kit 5.3.7 FAILED on `punycode` until the userland package was installed**, then bundled clean (5.5 MB Hermes). Keep `punycode` in the install list — it is load-bearing whenever any feature that renders markdown / the AI Assistant bubble is reachable.
|
|
464
|
+
|
|
382
465
|
> Note: `react-native-reanimated` is NOT a peer dependency of the kit (verified against `@cometchat/chat-uikit-react-native@5.x` `peerDependencies`). Add it only if your own app uses it for other animations.
|
|
383
466
|
|
|
384
|
-
Expo adds `expo-av` / `expo-image-picker` depending on which features you enable. Calls require the separate package:
|
|
467
|
+
Expo adds `expo-av` / `expo-image-picker` depending on which features you enable. Calls require the separate package PLUS the WebRTC native peers AND the polyfill peers the calls-sdk imports but doesn't declare:
|
|
385
468
|
|
|
386
469
|
```bash
|
|
387
|
-
npm install @cometchat/calls-sdk-react-native
|
|
470
|
+
npm install @cometchat/calls-sdk-react-native \
|
|
471
|
+
@react-native-community/netinfo \
|
|
472
|
+
react-native-callstats \
|
|
473
|
+
react-native-webrtc \
|
|
474
|
+
react-native-background-timer \
|
|
475
|
+
react-native-url-polyfill \
|
|
476
|
+
react-native-performance \
|
|
477
|
+
valibot
|
|
388
478
|
```
|
|
389
479
|
|
|
480
|
+
> `@react-native-community/netinfo`, `react-native-callstats`, and `react-native-webrtc` are the WebRTC native peers; `react-native-background-timer`, `react-native-url-polyfill/auto`, and `react-native-performance` are imported at the top of the calls-sdk `dist/polyfills/browser.js`, and `valibot` is consumed deeper in the calls state machine. The polyfill peers + valibot are NOT in the calls-sdk `peerDependencies` array — they fail at bundle resolution if missing. (Validated 2026-05-26 on `@cometchat/calls-sdk-react-native@5.0.0`.) Then run `npx expo prebuild` (Expo) or `cd ios && pod install` (bare) so the native modules get autolinked into the next debug build. This mirrors the lists in `cometchat-native-features` / `cometchat-native-expo-patterns` / `cometchat-native-bare-patterns` — see `cometchat-native-calls` for full calls setup.
|
|
481
|
+
|
|
390
482
|
See `cometchat-native-features` for when to add the calls SDK.
|
|
391
483
|
|
|
392
484
|
---
|
|
@@ -405,3 +497,183 @@ See `cometchat-native-features` for when to add the calls SDK.
|
|
|
405
497
|
| `cometchat-native-customization` | When customizing components (text formatters, events, DataSource) |
|
|
406
498
|
| `cometchat-native-production` | When setting up server-side auth + user management |
|
|
407
499
|
| `cometchat-native-troubleshooting` | When diagnosing build errors, runtime failures, permission issues |
|
|
500
|
+
|
|
501
|
+
## Visual Builder integration
|
|
502
|
+
|
|
503
|
+
When the dispatcher's Step 3.1 sets `customize=visual` and the framework maps to builder platform `react-native`, skills runs **`cometchat builder export --platform react-native`** — a single CLI command that downloads the canonical static template ZIP from `preview.cometchat.com/downloads/cometchat-builder-react-native.zip`, fetches the per-builder settings JSON via `GET /vcb/builders/{id}`, applies F3 + F10 missing-field defaults, and writes the result to `--output` (default: `src/config/`).
|
|
504
|
+
|
|
505
|
+
The canonical app uses a **Zustand-backed config store** (`src/config/store.ts`) that exposes `useConfig(selector)` — components read theme tokens and feature flags reactively. The exported `config.json` carries the **envelope shape** `{ builderId, name, type, createdAt, updatedAt, expiresAt, settings: { chatFeatures, callFeatures, layout, style, noCode, agent } }` — the store reads `config.settings.*` from it (verified 2026-06-14 against a live `builder export --platform react-native`). Theme tokens live under `settings.style` (`{ theme, color, typography }`) — there is **no `settings.theme`** key. `settings.agent` (`{ chatHistory, newChat, agentIcon, showAgentIcon }`) IS present (AI-agent config).
|
|
506
|
+
|
|
507
|
+
This is intentionally lighter than the React web copy (full `src/CometChat/` directory). The RN builder repo is a QR-driven sample with custom navigation that doesn't fit cleanly into the customer's existing navigator. So `builder export` extracts the **configuration plumbing only** (per the repo's own README §"Integration in Your Existing React Native App"), then skills writes a minimal wrapper that consumes the config in the customer's existing four-wrapper chain.
|
|
508
|
+
|
|
509
|
+
### 1. Run `cometchat builder export`
|
|
510
|
+
|
|
511
|
+
```bash
|
|
512
|
+
cometchat builder export --platform react-native --json
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
Defaults to `--output src/config/`. The command writes:
|
|
516
|
+
|
|
517
|
+
| File | Content |
|
|
518
|
+
|---|---|
|
|
519
|
+
| `src/config/store.ts` | Zustand store with full `AppConfig` typings, AsyncStorage persistence, `useConfig<T>(selector)` hook, `useConfigStore`. Verbatim from canonical ZIP. |
|
|
520
|
+
| `src/config/config.json` | **Envelope-shape JSON** `{ builderId, name, type, createdAt, updatedAt, expiresAt, settings: { chatFeatures, callFeatures, layout, style, noCode, agent } }`. There is **no `theme` key** (theme tokens live under `settings.style.{theme,color,typography}`); `settings.agent` (`{chatHistory,newChat,agentIcon,showAgentIcon}`) IS present (verified live 2026-06-14). Settings come from `GET /vcb/builders/{id}`. `inAppSounds` / `mentionAll` are **CLI-injected defaults** (not returned by the builder). **No SKILLS-AUTO-GENERATED sentinel** (JSON forbids `//` comments). |
|
|
521
|
+
|
|
522
|
+
Resync = re-run the same command with `--force` (full re-download + replace). See `cometchat-core` §11.6 for the resync contract.
|
|
523
|
+
|
|
524
|
+
### Files patched
|
|
525
|
+
|
|
526
|
+
| Path | Patch |
|
|
527
|
+
|---|---|
|
|
528
|
+
| `package.json` | `npm install zustand @react-native-async-storage/async-storage` — required by the copied `store.ts`. Then the normal `cometchat-native-{bare,expo}-patterns` deps (11 explicit peers on bare, `npx expo install` list on Expo). If `useConfig(state => state.settings.callFeatures.*).oneOnOne*` returns true, also add `@cometchat/calls-sdk-react-native@5.0.0` + the Cloudsmith `@cometchat/calls-lib-webrtc` tarball per `cometchat-native-calls`. |
|
|
529
|
+
| Entry — `App.tsx` (bare) / `app/_layout.tsx` (Expo Router) | Init UI Kit + wrap the provider chain (`SafeAreaProvider → SafeAreaView → CometChatThemeProvider → CometChatI18nProvider`) with `theme` derived from `useConfig`. Template below. |
|
|
530
|
+
| `App.tsx` line 1 (bare) / app entry (Expo Router) | Gesture-handler side-effect import. The reference app uses `import './gesture-handler';` (a local shim file) as the **first import in `App.tsx`** — not in `index.js`. Bare CLI projects without that shim use `import 'react-native-gesture-handler';` instead. Either form must be the top-of-file side-effect import. |
|
|
531
|
+
| `index.js` (bare) | App registration. The reference wraps `<App />` in `<AppErrorBoundary><ActiveChatProvider>` before `AppRegistry.registerComponent`. Preserve the customer's existing `index.js` registration; only add these wrappers if you also copy the corresponding files. |
|
|
532
|
+
| `src/utils/AppConstants.tsx` (canonical pattern) OR `.env` (Step 2c convention) | Credentials. Skills writes the canonical path the customer already had from §2 (Expo: `process.env.EXPO_PUBLIC_*`; bare: `@env` via `react-native-dotenv`). |
|
|
533
|
+
| `ios/Podfile` + `ios/<App>/Info.plist` (bare) or `app.json` plugins (Expo) | Camera + microphone usage descriptions if any `callFeatures.voiceAndVideoCalling.*` is true. |
|
|
534
|
+
|
|
535
|
+
### Entry-file init pattern (bare RN / Expo)
|
|
536
|
+
|
|
537
|
+
```tsx
|
|
538
|
+
// App.tsx
|
|
539
|
+
import './gesture-handler'; // line 1, before any other import — gesture-handler side-effect
|
|
540
|
+
// (bare CLI w/o the shim file: `import 'react-native-gesture-handler';`)
|
|
541
|
+
import React, { useEffect, useState } from 'react';
|
|
542
|
+
import { Platform } from 'react-native';
|
|
543
|
+
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
|
|
544
|
+
import {
|
|
545
|
+
CometChatUIKit,
|
|
546
|
+
UIKitSettings,
|
|
547
|
+
CometChatThemeProvider,
|
|
548
|
+
CometChatI18nProvider,
|
|
549
|
+
CometChatTheme,
|
|
550
|
+
} from '@cometchat/chat-uikit-react-native';
|
|
551
|
+
import { CometChat } from '@cometchat/chat-sdk-react-native';
|
|
552
|
+
import type { DeepPartial } from '@cometchat/chat-uikit-react-native/src/shared/helper/types';
|
|
553
|
+
|
|
554
|
+
import { useConfig } from './src/config/store';
|
|
555
|
+
import RootStackNavigator from './src/navigation/RootStackNavigator'; // your existing navigator
|
|
556
|
+
|
|
557
|
+
// Map builder font name → platform-specific PostScript / asset name.
|
|
558
|
+
// Verbatim from the canonical `App.tsx` inside the React Native Visual Builder
|
|
559
|
+
// ZIP (download from https://preview.cometchat.com/downloads/cometchat-builder-react-native.zip).
|
|
560
|
+
const FONT_MAP: Record<string, { regular: string; medium: string; bold: string }> = {
|
|
561
|
+
'times new roman': {
|
|
562
|
+
regular: Platform.OS === 'ios' ? 'TimesNewRomanPSMT' : 'times_new_roman_regular',
|
|
563
|
+
medium: Platform.OS === 'ios' ? 'TimesNewRomanPSMT' : 'times_new_roman_medium',
|
|
564
|
+
bold: Platform.OS === 'ios' ? 'TimesNewRomanPS-BoldMT' : 'times_new_roman_bold',
|
|
565
|
+
},
|
|
566
|
+
inter: {
|
|
567
|
+
regular: Platform.OS === 'ios' ? 'Inter-Regular' : 'inter_regular',
|
|
568
|
+
medium: Platform.OS === 'ios' ? 'Inter-Medium' : 'inter_medium',
|
|
569
|
+
bold: Platform.OS === 'ios' ? 'Inter-Bold' : 'inter_bold',
|
|
570
|
+
},
|
|
571
|
+
roboto: {
|
|
572
|
+
regular: Platform.OS === 'ios' ? 'Roboto-Regular' : 'roboto_regular',
|
|
573
|
+
medium: Platform.OS === 'ios' ? 'Roboto-Medium' : 'roboto_medium',
|
|
574
|
+
bold: Platform.OS === 'ios' ? 'Roboto-Bold' : 'roboto_bold',
|
|
575
|
+
},
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
export default function App() {
|
|
579
|
+
const styleConfig = useConfig(state => state.settings.style);
|
|
580
|
+
const [isReady, setIsReady] = useState(false);
|
|
581
|
+
|
|
582
|
+
useEffect(() => {
|
|
583
|
+
// RN kit takes a FLAT UIKitSettings object — there is NO UIKitSettingsBuilder
|
|
584
|
+
// on react-native (see §1; the builder is web-only). Using it throws
|
|
585
|
+
// "UIKitSettingsBuilder is not a constructor".
|
|
586
|
+
CometChatUIKit.init({
|
|
587
|
+
appId: process.env.EXPO_PUBLIC_COMETCHAT_APP_ID!,
|
|
588
|
+
region: process.env.EXPO_PUBLIC_COMETCHAT_REGION!,
|
|
589
|
+
authKey: process.env.EXPO_PUBLIC_COMETCHAT_AUTH_KEY!,
|
|
590
|
+
subscriptionType: "ALL_USERS",
|
|
591
|
+
}).then(() => setIsReady(true)).catch(console.error);
|
|
592
|
+
}, []);
|
|
593
|
+
|
|
594
|
+
const fontKey = styleConfig.typography.font.toLowerCase().trim();
|
|
595
|
+
const fontVariants = FONT_MAP[fontKey] ?? FONT_MAP.inter;
|
|
596
|
+
|
|
597
|
+
const theme: { light: DeepPartial<CometChatTheme>; dark: DeepPartial<CometChatTheme> } = {
|
|
598
|
+
light: {
|
|
599
|
+
color: {
|
|
600
|
+
primary: styleConfig.color.brandColor,
|
|
601
|
+
textPrimary: styleConfig.color.primaryTextLight,
|
|
602
|
+
textSecondary: styleConfig.color.secondaryTextLight,
|
|
603
|
+
},
|
|
604
|
+
typography: { fontFamily: fontVariants.regular },
|
|
605
|
+
},
|
|
606
|
+
dark: {
|
|
607
|
+
color: {
|
|
608
|
+
primary: styleConfig.color.brandColor,
|
|
609
|
+
textPrimary: styleConfig.color.primaryTextDark,
|
|
610
|
+
textSecondary: styleConfig.color.secondaryTextDark,
|
|
611
|
+
},
|
|
612
|
+
typography: { fontFamily: fontVariants.regular },
|
|
613
|
+
},
|
|
614
|
+
};
|
|
615
|
+
|
|
616
|
+
if (!isReady) return null;
|
|
617
|
+
|
|
618
|
+
return (
|
|
619
|
+
<SafeAreaProvider>
|
|
620
|
+
<SafeAreaView edges={['top', 'bottom']} style={{ flex: 1 }}>
|
|
621
|
+
<CometChatThemeProvider theme={theme}>
|
|
622
|
+
<CometChatI18nProvider>
|
|
623
|
+
<RootStackNavigator />
|
|
624
|
+
</CometChatI18nProvider>
|
|
625
|
+
</CometChatThemeProvider>
|
|
626
|
+
</SafeAreaView>
|
|
627
|
+
</SafeAreaProvider>
|
|
628
|
+
);
|
|
629
|
+
}
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
**Critical:**
|
|
633
|
+
|
|
634
|
+
- `useConfig(state => state.settings.style)` is the canonical hook — **not** a static `import` of the JSON. The store hydrates from AsyncStorage on first read; importing the JSON directly would freeze the initial values and skip QR-update / resync flows that may follow.
|
|
635
|
+
- `CometChatThemeProvider`'s `theme` prop takes a `{ light, dark }` object (NOT a string like `"dark"`). The string-form `theme="dark"` was a v4-era shape and was removed in `chat-uikit-react-native@5+`.
|
|
636
|
+
- The reference app's provider chain is `SafeAreaProvider → SafeAreaView → CometChatThemeProvider → CometChatI18nProvider`, and gesture-handler is wired as a **top-of-file side-effect import** (`import './gesture-handler';` on App.tsx line 1) — **not** as a `<GestureHandlerRootView>` wrapper. Match this. (If you deliberately add `<GestureHandlerRootView style={{ flex: 1 }}>` as the outermost wrapper for extra hardening, that is also valid — but it is not what the reference ships, so don't present it as required.) Skipping safe areas, theming, i18n, or the gesture-handler import breaks gestures, safe areas, theming, or i18n — and fails silently in dev.
|
|
637
|
+
- `CometChatUIKit.init(settings)` returns a Promise — `isReady` gate before render prevents `RootStackNavigator` from mounting chat components before init resolves.
|
|
638
|
+
- The canonical RN builder app also registers a `CometChat.addCallListener` at the App level (handles incoming calls / busy / cancelled / ended). When `callFeatures.voiceAndVideoCalling.*` is true, copy that listener block verbatim from the canonical `App.tsx` inside the React Native Visual Builder ZIP (download from https://preview.cometchat.com/downloads/cometchat-builder-react-native.zip) (look for `'app'` listener id).
|
|
639
|
+
|
|
640
|
+
### Feature flag access
|
|
641
|
+
|
|
642
|
+
Components throughout the customer's app can read flags reactively:
|
|
643
|
+
|
|
644
|
+
```tsx
|
|
645
|
+
const reactionsEnabled = useConfig(s => s.settings.chatFeatures.deeperUserEngagement.reactions);
|
|
646
|
+
const audioCallsEnabled = useConfig(
|
|
647
|
+
s => s.settings.callFeatures.voiceAndVideoCalling.oneOnOneVoiceCalling,
|
|
648
|
+
);
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
Hide buttons / disable composer actions / skip mounting components based on these. The full `AppConfig` typings are in the copied `src/config/store.ts`.
|
|
652
|
+
|
|
653
|
+
### Resync flow
|
|
654
|
+
|
|
655
|
+
The "Re-sync visual builder" iteration menu option (see `cometchat/SKILL.md § Step 7`) is a one-command re-run:
|
|
656
|
+
|
|
657
|
+
```bash
|
|
658
|
+
cometchat builder export --platform react-native --force --json
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
`--force` is required (it explicitly authorizes replacing the existing `src/config/`). The command re-downloads the canonical static template, re-fetches the per-builder settings, and replaces the directory entirely.
|
|
662
|
+
|
|
663
|
+
Per the SKILLS-AUTO-GENERATED contract (see `cometchat-core` §11.6): customer hand-edits inside `src/config/` are lost on resync. Override via `App.tsx` (outside `src/config/`) or via the `useConfig` selector pattern documented in §"Theme derivation".
|
|
664
|
+
|
|
665
|
+
The customer reloads the dev build (`r` in Metro) — `useConfig` rehydrates from AsyncStorage on next mount.
|
|
666
|
+
|
|
667
|
+
### Calls + builder
|
|
668
|
+
|
|
669
|
+
> **Version note (intentional divergence):** the reference builder app `builder-apps/uikit-builder-app-react-native` still ships `@cometchat/calls-sdk-react-native@^4.3.0` (no `@cometchat/calls-lib-webrtc`; it uses `react-native-webrtc` directly). Skills intentionally targets **calls SDK v5** per the calls-v5-canonical policy. If you diff the reference app, don't "correct" the skill back to 4.3.0 — the v5 guidance below is deliberate.
|
|
670
|
+
|
|
671
|
+
If `callFeatures.voiceAndVideoCalling.*` is true:
|
|
672
|
+
1. Add `@cometchat/calls-sdk-react-native@5.0.0` + the Cloudsmith `@cometchat/calls-lib-webrtc` tarball (per `cometchat-native-calls`).
|
|
673
|
+
2. Wire `CometChat.addCallListener` + `CometChatUIEventHandler.addCallListener` in `App.tsx` — copy the listener block verbatim from the canonical app's `App.tsx`.
|
|
674
|
+
3. Mount `<CometChatIncomingCall>` between `<CometChatI18nProvider>` and `<RootStackNavigator>` when an `incomingCall` ref is set. The full pattern is in the canonical `App.tsx`.
|
|
675
|
+
4. Configure iOS PushKit + Android FCM data-message wiring — defer to `cometchat-native-push` and invoke it after the Visual Builder section completes.
|
|
676
|
+
|
|
677
|
+
### What is NOT honored in v1
|
|
678
|
+
|
|
679
|
+
`noCode.docked` (floating-widget shape) and `layout.withSideBar` don't have RN-native equivalents — RN uses tabs / stacks, not sidebars. The canonical `RootStackNavigator` from the builder repo IS NOT copied — the customer's existing navigator stays. Layout-tab features like `layout.tabs: ['chats','calls','users','groups']` need the customer's existing `bottom-tabs` navigator to add those tabs manually (skills can do this in a follow-up `cometchat-native-placement` flow). Theme + typography + chat features + call features ARE honored via `useConfig`.
|
|
@@ -3,7 +3,6 @@ name: cometchat-native-customization
|
|
|
3
3
|
description: "Customize the CometChat React Native UI Kit without forking — four-tier model: props → request builders → text formatters + message templates → DataSource decorators + event bus."
|
|
4
4
|
license: "MIT"
|
|
5
5
|
compatibility: "Node.js >=18; React Native >=0.70; @cometchat/chat-uikit-react-native ^5"
|
|
6
|
-
allowed-tools: "shell, file-read, file-search, file-list, ask-user"
|
|
7
6
|
metadata:
|
|
8
7
|
author: "CometChat"
|
|
9
8
|
version: "3.0.0"
|
|
@@ -25,7 +24,7 @@ Tier 4 — DataSource decorators + Events (last resort, powerful)
|
|
|
25
24
|
|
|
26
25
|
**Read `cometchat-native-components` first** — the catalog is the source of truth for prop names, slot views, and event listener names that this skill builds on.
|
|
27
26
|
|
|
28
|
-
Ground truth: `docs/ui-kit/react-native/custom-text-formatter-guide.mdx`, `mentions-formatter-guide.mdx`, `shortcut-formatter-guide.mdx`, `url-formatter-guide.mdx`, `events.mdx`, `methods.mdx`, `property-changes.mdx`, and the kit's source at `packages/ChatUiKit/src/shared/formatters/` and `packages/ChatUiKit/src/shared/events/`.
|
|
27
|
+
Ground truth: `docs/ui-kit/react-native/custom-text-formatter-guide.mdx`, `mentions-formatter-guide.mdx`, `shortcut-formatter-guide.mdx`, `url-formatter-guide.mdx`, `events.mdx`, `methods.mdx`, `property-changes.mdx`, and the kit's source at `packages/ChatUiKit/src/shared/formatters/` and `packages/ChatUiKit/src/shared/events/`. **Official docs:** https://www.cometchat.com/docs/ui-kit/react-native/overview · **Docs MCP:** `claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp` (or fetch the URL directly without MCP).
|
|
29
28
|
|
|
30
29
|
---
|
|
31
30
|
|
|
@@ -96,8 +95,10 @@ function CustomTitle({ user }: any) {
|
|
|
96
95
|
return (
|
|
97
96
|
<Text style={{
|
|
98
97
|
color: theme.color.textPrimary,
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
// heading3 is a VARIANT { bold, medium, regular } — read a weight, not a flat field
|
|
99
|
+
// (verified vs uikit-react-native-v5 theme/default/typography.ts)
|
|
100
|
+
fontFamily: theme.typography.heading3.regular.fontFamily,
|
|
101
|
+
fontSize: theme.typography.heading3.regular.fontSize,
|
|
101
102
|
}}>
|
|
102
103
|
{user?.getName()}
|
|
103
104
|
</Text>
|
|
@@ -213,7 +214,7 @@ class HashtagFormatter extends CometChatTextFormatter {
|
|
|
213
214
|
constructor() {
|
|
214
215
|
super();
|
|
215
216
|
this.setTrackingCharacter("#"); // optional — triggers suggestion list
|
|
216
|
-
this.setRegexPatterns(
|
|
217
|
+
this.setRegexPatterns(/\B#(\w+)\b/g); // takes a SINGLE RegExp, not an array (verified vs CometChatTextFormatter.ts: setRegexPatterns(regexPattern: RegExp))
|
|
217
218
|
}
|
|
218
219
|
|
|
219
220
|
// Called for each bubble's text; return string | JSX
|
|
@@ -273,7 +274,11 @@ const formatters = [
|
|
|
273
274
|
|
|
274
275
|
### 3b. Custom message template — entire custom bubble
|
|
275
276
|
|
|
276
|
-
For rendering a totally custom message type (interactive cards, scheduling, forms), use `CometChatMessageTemplate`.
|
|
277
|
+
For rendering a totally custom message type (interactive cards, scheduling, forms), use the kit's `CometChatMessageTemplate`.
|
|
278
|
+
|
|
279
|
+
> **Wrong-namespace trap (verified against kit source):** the template class is `CometChatMessageTemplate`, exported from `@cometchat/chat-uikit-react-native` (`packages/ChatUiKit/src/shared/modals/CometChatMessageTemplate.ts:116`; re-exported at `src/index.ts:47`). **There is NO `CometChat.MessageTemplate`** on the Chat SDK — `new CometChat.MessageTemplate(...)` does not exist. Always import the class from the UI Kit.
|
|
280
|
+
|
|
281
|
+
The constructor takes a **single options object** (`packages/ChatUiKit/src/shared/modals/CometChatMessageTemplate.ts:213-237`). View slots are **PascalCase** (`ContentView`, `BottomView`, `BubbleView`, `HeaderView`, `LeadingView`, `StatusInfoView`, `FooterView`, `ReplyView`); `options` is lowercase. The `options` callback signature is `(loggedInUser, message, theme, group?)` — note the **`theme` argument** before `group` (`CometChatMessageTemplate.ts:202-207`, invoked at `CometChatMessageList.tsx:3484` as `template.options(loggedInUser, item, mergedTheme, group)`).
|
|
277
282
|
|
|
278
283
|
```tsx
|
|
279
284
|
import {
|
|
@@ -290,26 +295,116 @@ const pollTemplate = new CometChatMessageTemplate({
|
|
|
290
295
|
BottomView: (message, alignment) => (
|
|
291
296
|
<PollVoteCounts message={message} />
|
|
292
297
|
),
|
|
293
|
-
options: (loggedInUser, message, group) => [
|
|
298
|
+
options: (loggedInUser, message, theme, group) => [
|
|
294
299
|
/* CometChatMessageOption[] — custom long-press menu items */
|
|
295
300
|
],
|
|
296
301
|
});
|
|
302
|
+
```
|
|
297
303
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
304
|
+
**Register by MERGING with the defaults — never replace.** The defaults accessor is `getAllMessageTemplates(theme, additionalParams?)` and it **requires the kit theme** (`packages/ChatUiKit/src/shared/framework/DataSource.ts:168`; impl at `MessageDataSource.tsx:1732`). The data source is reached via either `ChatConfigurator.getDataSource()` (`ChatConfigurator.ts:24`) or the equivalent `CometChatUIKit.getDataSource()` (`CometChatUIKit.ts:380`). Pass the theme from `useTheme()`:
|
|
305
|
+
|
|
306
|
+
```tsx
|
|
307
|
+
import {
|
|
308
|
+
ChatConfigurator,
|
|
309
|
+
useTheme,
|
|
310
|
+
} from "@cometchat/chat-uikit-react-native";
|
|
311
|
+
|
|
312
|
+
function Chat({ selectedUser }: any) {
|
|
313
|
+
const theme = useTheme();
|
|
314
|
+
// getAllMessageTemplates REQUIRES the theme arg
|
|
315
|
+
const defaults = ChatConfigurator.getDataSource().getAllMessageTemplates(theme);
|
|
316
|
+
|
|
317
|
+
return (
|
|
318
|
+
<CometChatMessageList
|
|
319
|
+
user={selectedUser}
|
|
320
|
+
templates={[pollTemplate, ...defaults]} // append your type, keep all built-ins
|
|
321
|
+
hideReplyInThreadOption
|
|
322
|
+
/>
|
|
323
|
+
);
|
|
324
|
+
}
|
|
303
325
|
```
|
|
304
326
|
|
|
305
|
-
|
|
327
|
+
If you pass only `templates={[pollTemplate]}` you will REPLACE the built-in text/image/video/file/group-action templates and the conversation will render blank for every non-custom message. Always spread `...defaults`.
|
|
328
|
+
|
|
329
|
+
### 3c. Override an existing type's bubble (text / image)
|
|
330
|
+
|
|
331
|
+
To change how a *built-in* type renders (e.g. a custom text bubble), don't write a new type — get the default templates, find the matching one by `type`, swap its `ContentView`, and pass the whole array back via `templates`. This preserves every other type and keeps the type's default `options`, `ReplyView`, etc.
|
|
306
332
|
|
|
307
333
|
```tsx
|
|
308
|
-
import { ChatConfigurator } from "@cometchat/chat-uikit-react-native";
|
|
309
|
-
|
|
310
|
-
|
|
334
|
+
import { ChatConfigurator, useTheme, CometChatUiKitConstants } from "@cometchat/chat-uikit-react-native";
|
|
335
|
+
|
|
336
|
+
function Chat({ selectedUser }: any) {
|
|
337
|
+
const theme = useTheme();
|
|
338
|
+
const templates = ChatConfigurator.getDataSource().getAllMessageTemplates(theme);
|
|
339
|
+
|
|
340
|
+
// type values come from CometChatUiKitConstants.MessageTypeConstants
|
|
341
|
+
const textTemplate = templates.find(
|
|
342
|
+
(t) => t.type === CometChatUiKitConstants.MessageTypeConstants.text,
|
|
343
|
+
);
|
|
344
|
+
if (textTemplate) {
|
|
345
|
+
textTemplate.ContentView = (message, alignment) => (
|
|
346
|
+
<MyCustomTextBubble message={message} alignment={alignment} />
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return (
|
|
351
|
+
<CometChatMessageList
|
|
352
|
+
user={selectedUser}
|
|
353
|
+
templates={templates} // mutated-in-place array — full default set, one view swapped
|
|
354
|
+
hideReplyInThreadOption
|
|
355
|
+
/>
|
|
356
|
+
);
|
|
357
|
+
}
|
|
311
358
|
```
|
|
312
359
|
|
|
360
|
+
`ContentView`'s signature is `(messageObject: CometChat.BaseMessage, alignment: MessageBubbleAlignmentType) => JSX.Element | null` (`CometChatMessageTemplate.ts:131-134`). Branch on `alignment === "left" | "right"` if you want incoming-vs-outgoing variants.
|
|
361
|
+
|
|
362
|
+
### 3d. Add a Forward-style long-press option to an existing type
|
|
363
|
+
|
|
364
|
+
A long-press menu item is a **`CometChatMessageOption`** — a plain object type (`id`, `title`, optional `icon`, `onPress`, `CustomView`, `style`), defined at `packages/ChatUiKit/src/shared/modals/CometChatMessageOption.ts:6-18`, exported from `src/index.ts:45`.
|
|
365
|
+
|
|
366
|
+
> **Wrong-namespace trap:** there is **no `CometChatActionsIcon` / `CometChatActionsView`** in the RN kit (that is the web kit's class — grep of `packages/ChatUiKit/src` returns zero hits). In RN, an option is the `CometChatMessageOption` object literal.
|
|
367
|
+
|
|
368
|
+
Append yours by overriding the type's template `options` callback. Call the default-options accessor first, then add your item — append, don't replace:
|
|
369
|
+
|
|
370
|
+
```tsx
|
|
371
|
+
import {
|
|
372
|
+
ChatConfigurator,
|
|
373
|
+
useTheme,
|
|
374
|
+
CometChatUiKitConstants,
|
|
375
|
+
} from "@cometchat/chat-uikit-react-native";
|
|
376
|
+
import type { CometChatMessageOption } from "@cometchat/chat-uikit-react-native";
|
|
377
|
+
|
|
378
|
+
function Chat({ selectedUser }: any) {
|
|
379
|
+
const theme = useTheme();
|
|
380
|
+
const templates = ChatConfigurator.getDataSource().getAllMessageTemplates(theme);
|
|
381
|
+
|
|
382
|
+
const textTemplate = templates.find(
|
|
383
|
+
(t) => t.type === CometChatUiKitConstants.MessageTypeConstants.text,
|
|
384
|
+
);
|
|
385
|
+
if (textTemplate) {
|
|
386
|
+
textTemplate.options = (loggedInUser, message, t, group) => {
|
|
387
|
+
// default long-press options for this message (reply, edit, delete, copy, ...)
|
|
388
|
+
const defaults = ChatConfigurator.getDataSource().getMessageOptions(
|
|
389
|
+
loggedInUser, message, t, group,
|
|
390
|
+
);
|
|
391
|
+
const forward: CometChatMessageOption = {
|
|
392
|
+
id: "forward",
|
|
393
|
+
title: "Forward",
|
|
394
|
+
onPress: (msg) => forwardMessage(msg),
|
|
395
|
+
};
|
|
396
|
+
return [...defaults, forward]; // append, keep the built-ins
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
return (
|
|
401
|
+
<CometChatMessageList user={selectedUser} templates={templates} hideReplyInThreadOption />
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
The default-options accessor is `getMessageOptions(loggedInUser, messageObject, theme, group?, additionalParams?)` (`DataSource.ts:57-63`; impl `MessageDataSource.tsx:587`). It returns `CometChatMessageOption[]`. The template's `options` callback is invoked by the list as `template.options(loggedInUser, item, mergedTheme, group)` (`CometChatMessageList.tsx:3484`).
|
|
407
|
+
|
|
313
408
|
### When to use text formatter vs message template
|
|
314
409
|
|
|
315
410
|
| Use formatter (Tier 3a) | Use template (Tier 3b) |
|
|
@@ -395,8 +490,11 @@ class MyDataSource extends DataSourceDecorator {
|
|
|
395
490
|
return builder;
|
|
396
491
|
}
|
|
397
492
|
|
|
398
|
-
|
|
399
|
-
|
|
493
|
+
// To register a custom type kit-wide, override getAllMessageTemplates —
|
|
494
|
+
// it returns the ARRAY. (getMessageTemplate(type, category, theme, ...)
|
|
495
|
+
// returns a SINGLE template-or-null, so don't merge an array there.)
|
|
496
|
+
getAllMessageTemplates(theme: any, additionalParams?: any) {
|
|
497
|
+
const defaults = super.getAllMessageTemplates(theme, additionalParams);
|
|
400
498
|
return [myCustomTemplate, ...defaults];
|
|
401
499
|
}
|
|
402
500
|
}
|
|
@@ -488,19 +586,39 @@ You can also use `WebFetch` on the URLs above. The docs MCP does NOT index the s
|
|
|
488
586
|
### "Render custom avatars for all users based on their department"
|
|
489
587
|
**Tier 1** — `LeadingView` slot on `CometChatConversations` + `CometChatUsers` + `CometChatMessageHeader`.
|
|
490
588
|
|
|
491
|
-
### "
|
|
492
|
-
**Tier 1** —
|
|
589
|
+
### "Add a custom attachment option (or remove one)"
|
|
590
|
+
**Tier 1** — the `attachmentOptions` prop on `CometChatMessageComposer`. **RN's signature is a single destructured object** `({ user, group, composerId }) => CometChatMessageComposerAction[]` (`CometChatMessageComposer.tsx:237-245`) — NOT the web kit's `(user, group) => ...`. Each action is a `CometChatMessageComposerAction` (a type, not a class: `id`, `title`, `icon`, `onPress`, `CustomView`, `style` — `shared/helper/types/index.ts:17`, exported as a type at `src/index.ts:43`).
|
|
591
|
+
|
|
592
|
+
Get the defaults to append to / filter from via `getAttachmentOptions(theme, user, group, composerId?, additionalParams?)` (`DataSource.ts:215`; impl `MessageDataSource.tsx:2123`):
|
|
493
593
|
|
|
494
594
|
```tsx
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
595
|
+
import { ChatConfigurator, useTheme } from "@cometchat/chat-uikit-react-native";
|
|
596
|
+
import type { CometChatMessageComposerAction } from "@cometchat/chat-uikit-react-native";
|
|
597
|
+
|
|
598
|
+
function Composer({ user, group }: any) {
|
|
599
|
+
const theme = useTheme();
|
|
600
|
+
return (
|
|
601
|
+
<CometChatMessageComposer
|
|
602
|
+
user={user}
|
|
603
|
+
group={group}
|
|
604
|
+
attachmentOptions={({ user, group, composerId }) => {
|
|
605
|
+
const defaults = ChatConfigurator.getDataSource().getAttachmentOptions(
|
|
606
|
+
theme, user, group, composerId,
|
|
607
|
+
);
|
|
608
|
+
const custom: CometChatMessageComposerAction = {
|
|
609
|
+
id: "send-location",
|
|
610
|
+
title: "Location",
|
|
611
|
+
onPress: (u, g) => sendLocation(u, g),
|
|
612
|
+
};
|
|
613
|
+
return [...defaults, custom]; // append; or .filter(...) to remove one
|
|
614
|
+
}}
|
|
615
|
+
/>
|
|
616
|
+
);
|
|
617
|
+
}
|
|
502
618
|
```
|
|
503
619
|
|
|
620
|
+
To **disable** an option instead, return `defaults.filter((opt) => opt.id !== "...")`.
|
|
621
|
+
|
|
504
622
|
### "Show only message types that contain the word 'urgent'"
|
|
505
623
|
**Tier 2** — `messageRequestBuilder` with `.setSearchKeyword("urgent")`.
|
|
506
624
|
|
|
@@ -548,7 +666,7 @@ const EMOJI_MAP: Record<string, string> = {
|
|
|
548
666
|
class EmojiShortcodeFormatter extends CometChatTextFormatter {
|
|
549
667
|
constructor() {
|
|
550
668
|
super();
|
|
551
|
-
this.setRegexPatterns(
|
|
669
|
+
this.setRegexPatterns(/:[a-z_]+:/g); // SINGLE RegExp, not an array
|
|
552
670
|
}
|
|
553
671
|
|
|
554
672
|
getFormattedText(input: string | null | React.ReactNode) {
|
|
@@ -592,3 +710,7 @@ import { TEXT_FORMATTERS } from "./formatters";
|
|
|
592
710
|
| `cometchat-native-customization` | This skill — four-tier triage + custom formatters / templates / DataSource / events |
|
|
593
711
|
| `cometchat-native-production` | When customization depends on production auth (token refresh, user-ID mapping) |
|
|
594
712
|
| `cometchat-native-troubleshooting` | Formatter doesn't apply, listener fires twice, slot view renders nothing, template not showing |
|
|
713
|
+
|
|
714
|
+
## Sound (in-app message + call sounds)
|
|
715
|
+
|
|
716
|
+
Sound is a customization sub-dimension. The UI Kit plays incoming/outgoing message + call sounds via `CometChatSoundManager` — mute it, swap custom audio, or play a specific sound. The full API + recipe lives in **`cometchat-native-theming`** (Sound section). Verify the access path against the installed kit before relying on it.
|