@cometchat/skills 4.3.0 → 4.4.1
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/bin/install.js +27 -0
- package/package.json +14 -1
- package/skills/cometchat/SKILL.md +233 -69
- 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 +5 -3
- 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 +208 -28
- 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 +232 -312
- 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 +3 -2
- 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 +258 -20
- package/skills/cometchat-customization/SKILL.md +50 -25
- package/skills/cometchat-features/SKILL.md +314 -35
- 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 +5 -4
- 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 +72 -57
- package/skills/cometchat-flutter-v6-calls/references/add-calls-to-existing-chat.md +5 -3
- 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 +182 -21
- 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 +41 -19
- package/skills/cometchat-flutter-v6-testing/SKILL.md +4 -4
- 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 +140 -79
- 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 +173 -45
- 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 +36 -19
- package/skills/cometchat-native-calls/SKILL.md +29 -17
- 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 +84 -52
- package/skills/cometchat-native-core/SKILL.md +102 -33
- package/skills/cometchat-native-customization/SKILL.md +150 -28
- package/skills/cometchat-native-expo-patterns/SKILL.md +60 -29
- package/skills/cometchat-native-features/SKILL.md +24 -17
- 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 +11 -5
- package/skills/cometchat-nextjs-patterns/SKILL.md +22 -8
- 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 +45 -5
- package/skills/cometchat-react-push/SKILL.md +258 -72
- package/skills/cometchat-react-router-patterns/SKILL.md +12 -6
- 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-troubleshooting
|
|
|
3
3
|
description: "Diagnose CometChat React Native UI Kit integration failures — init/login, gesture handler, pod install, iOS privacy manifest, Android Maven, Metro cache, permissions, calls, extensions, v4-to-v5 upgrade. For push-specific symptoms see cometchat-native-push § 12."
|
|
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"
|
|
@@ -16,7 +15,7 @@ Teaches Claude how to diagnose and fix CometChat React Native integration failur
|
|
|
16
15
|
|
|
17
16
|
**Read `cometchat-native-core` first** — most "why doesn't this work" issues trace to the init/login/wrapper chain explained there.
|
|
18
17
|
|
|
19
|
-
Ground truth: `docs/ui-kit/react-native/troubleshooting.mdx`, `apple-privacy-manifest-guide.mdx`, `upgrading-from-v4.mdx`, and first-hand failure modes from real integrations.
|
|
18
|
+
Ground truth: `docs/ui-kit/react-native/troubleshooting.mdx`, `apple-privacy-manifest-guide.mdx`, `upgrading-from-v4.mdx`, and first-hand failure modes from real integrations. **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
|
|
|
@@ -90,6 +89,9 @@ done
|
|
|
90
89
|
|
|
91
90
|
Missing peer deps → install + `pod install` (bare) or `expo install` (Expo) + rebuild.
|
|
92
91
|
|
|
92
|
+
> ⚠️ **`--legacy-peer-deps` silently DROPS peers.** If the project installed with `npm install --legacy-peer-deps` (common to dodge RN peer-range conflicts), npm **skips** unmet peer deps instead of erroring — you get a "successful" install with `react-native-svg` / `gesture-handler` / `safe-area-context` / async-storage missing, then a runtime crash. Re-run the check above after any `--legacy-peer-deps` install and install the missing ones **explicitly**.
|
|
93
|
+
> ⚠️ **`@cometchat/calls-lib-webrtc` is Cloudsmith-only — NOT on npm** (`npm view @cometchat/calls-lib-webrtc` → 404, verified). If a calls install fails resolving it, add the Cloudsmith tarball/registry per `cometchat-native-calls`; a plain `npm install @cometchat/calls-lib-webrtc` will never work.
|
|
94
|
+
|
|
93
95
|
---
|
|
94
96
|
|
|
95
97
|
## 2. Symptom → fix lookup tables
|
|
@@ -152,6 +154,9 @@ Quick-reference tables. Work through in order; if none match, drop into § 3 dee
|
|
|
152
154
|
| Fast Refresh doesn't pick up new deps | Native dep change (requires rebuild) | Restart Metro + rebuild (iOS/Android) |
|
|
153
155
|
| "Maximum update depth exceeded" after theme change | Theme object recreated each render | Define theme at module scope or in `useMemo(() => ..., [])` |
|
|
154
156
|
| App crashes on first JS load | Entry file error (syntax or import order) | Check `index.js` — `react-native-gesture-handler` should be line 1 |
|
|
157
|
+
| Unhandled promise rejection at startup with `id=0` / module-load TypeError, but chat + calls work fine | Known non-blocking init artifact from the kit/calls-sdk module-level code (F77); source-map unresolvable | **Non-blocking — do NOT chase it.** Chat and calls are fully functional. Documented as a known v4.x artifact. Don't refactor user code to "fix" it. |
|
|
158
|
+
| Error banner shows literal `[object Object]` instead of a message | `setError(String(e))` / `setError(\`${e}\`)` — CometChatException stringifies to `[object Object]` | Use `e.message` (or a `formatCometChatError(e)` helper): `setError(e?.message ?? String(e))`. |
|
|
159
|
+
| (Expo) Credentials/config changes don't take effect after editing app config | `expo.extra` manifest is **cached** | Restart with `npx expo start --clear`; for a dev build, rebuild. The `expo.extra` block is baked into the manifest at build/start time. |
|
|
155
160
|
|
|
156
161
|
### 2f. Theming
|
|
157
162
|
|
|
@@ -421,10 +426,10 @@ If the user is upgrading from `@cometchat/chat-uikit-react-native@4`, these are
|
|
|
421
426
|
|
|
422
427
|
```bash
|
|
423
428
|
# 1. Update the main kit
|
|
424
|
-
npm install @cometchat/chat-uikit-react-native
|
|
429
|
+
npm install @cometchat/chat-uikit-react-native@^5
|
|
425
430
|
|
|
426
431
|
# 2. Install the full peer-dep set (v5 doesn't auto-install them like v4 did)
|
|
427
|
-
npm install @cometchat/chat-sdk-react-native \
|
|
432
|
+
npm install @cometchat/chat-sdk-react-native@^4 \
|
|
428
433
|
@react-native-async-storage/async-storage \
|
|
429
434
|
@react-native-clipboard/clipboard \
|
|
430
435
|
@react-native-community/datetimepicker \
|
|
@@ -460,7 +465,8 @@ cd ios && pod install && cd ..
|
|
|
460
465
|
|
|
461
466
|
If none of the lookup tables or deep dives apply:
|
|
462
467
|
|
|
463
|
-
1. **
|
|
468
|
+
1. **Run `cometchat doctor`** (the structured first pass — combines detect + info + verify + known-issue matching). Start here; it often pinpoints the layer (state / drift / env / deps) before you read logs.
|
|
469
|
+
2. **Read the raw error.** RN errors are usually specific ("Module 'X' not found in app 'Y'" is different from "TurboModuleRegistry.getEnforcing").
|
|
464
470
|
2. **Check the dev console + native logs.** For iOS: Xcode → View → Debug Area → Activate Console. For Android: `adb logcat | grep -E "cometchat|CometChat|ReactNative"`.
|
|
465
471
|
3. **Search the upstream docs MCP** (`cometchat-docs` if installed).
|
|
466
472
|
4. **Search the sample app** (`examples/SampleApp/` or `examples/SampleAppExpo/`) for a working version of the pattern the user is trying.
|
|
@@ -3,13 +3,14 @@ name: cometchat-nextjs-patterns
|
|
|
3
3
|
description: "Framework-specific patterns for integrating CometChat React UI Kit v6 into Next.js projects (App Router and Pages Router). Covers SSR prevention, provider setup, route placement, API routes, and common pitfalls."
|
|
4
4
|
license: "MIT"
|
|
5
5
|
compatibility: "Node.js >=18; React >=18; Next.js >=13; @cometchat/chat-uikit-react ^6; @cometchat/chat-sdk-javascript ^4"
|
|
6
|
-
allowed-tools: "shell, file-read, file-search, file-list"
|
|
7
6
|
metadata:
|
|
8
7
|
author: "CometChat"
|
|
9
8
|
version: "3.0.0"
|
|
10
9
|
tags: "chat cometchat nextjs next react ssr app-router pages-router patterns"
|
|
11
10
|
---
|
|
12
11
|
|
|
12
|
+
> **Ground truth:** `@cometchat/chat-uikit-react@^6` (+ `@cometchat/calls-sdk-javascript@^5`) — installed package types + `ui-kit/react`. **Official docs:** https://www.cometchat.com/docs/ui-kit/react/overview · **Docs MCP:** `claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp` (or fetch the URL directly without MCP). Verify symbols against the installed package/source before relying on them.
|
|
13
|
+
|
|
13
14
|
## Purpose
|
|
14
15
|
|
|
15
16
|
This skill teaches Claude how to integrate CometChat into a Next.js project. Next.js is the most complex framework to integrate with because of Server-Side Rendering (SSR) and the Server Component / Client Component boundary. Every CometChat component is browser-only -- getting this wrong is the #1 source of integration failures.
|
|
@@ -72,12 +73,13 @@ import React from "react";
|
|
|
72
73
|
import React from "react";
|
|
73
74
|
```
|
|
74
75
|
|
|
75
|
-
### App Router: dynamic import from
|
|
76
|
+
### App Router: dynamic import from a Client Component (Next.js 15+ rule)
|
|
76
77
|
|
|
77
|
-
|
|
78
|
+
> ⚠️ **Next.js 15+ change (verified by runtime smoke 2026-06-02):** `dynamic(..., { ssr: false })` is **FORBIDDEN in Server Components** — Next.js 15+ throws a build error. The page that owns the dynamic-import MUST be a Client Component (`"use client"` at line 1). Otherwise the build fails with `Ecmascript file had an error` even if everything else is correct.
|
|
78
79
|
|
|
79
80
|
```tsx
|
|
80
|
-
// app/messages/page.tsx
|
|
81
|
+
// app/messages/page.tsx
|
|
82
|
+
"use client"; // ← REQUIRED in Next.js 15+ when using `dynamic({ ssr: false })`
|
|
81
83
|
import dynamic from "next/dynamic";
|
|
82
84
|
|
|
83
85
|
const ChatView = dynamic(() => import("../../components/ChatView"), {
|
|
@@ -90,7 +92,11 @@ export default function MessagesPage() {
|
|
|
90
92
|
}
|
|
91
93
|
```
|
|
92
94
|
|
|
93
|
-
The `ChatView` component itself must
|
|
95
|
+
The `ChatView` component file itself must also have `"use client"` at the top. Both ends of the dynamic-import boundary need the directive.
|
|
96
|
+
|
|
97
|
+
**If you cannot make the page a Client Component** (because it needs server data-fetching), wrap your data-fetching in a separate Server Component sibling and pass results down via props to a Client Component that owns the CometChat subtree.
|
|
98
|
+
|
|
99
|
+
**Build still fails after applying both `"use client"` and `dynamic(... ssr:false)`?** Add `export const dynamic = "force-dynamic";` at the top of the page to opt out of static prerendering entirely (or `export const runtime = "edge";` for edge runtime). This is sometimes needed in Next.js 16 even with everything else correct — verified during 2026-06-02 smoke against Next.js 16.2.7. Skill-side suspicion: kit's module-eval-time `window` references still trip static prerender even via dynamic boundary.
|
|
94
100
|
|
|
95
101
|
### Pages Router: dynamic import
|
|
96
102
|
|
|
@@ -190,7 +196,8 @@ export function CometChatProvider({ children }: CometChatProviderProps) {
|
|
|
190
196
|
|
|
191
197
|
setIsReady(true);
|
|
192
198
|
} catch (e) {
|
|
193
|
-
setError(
|
|
199
|
+
setError(formatCometChatError(e)); // from cometchat-core §6 errors.ts — NOT String(e),
|
|
200
|
+
// which renders "[object Object]" on kit errors (ENG-35719)
|
|
194
201
|
}
|
|
195
202
|
}
|
|
196
203
|
|
|
@@ -239,6 +246,13 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|
|
239
246
|
|
|
240
247
|
**Note:** Importing a `"use client"` component from a Server Component is fine. Next.js renders the Server Component on the server and defers the Client Component to the browser. The `CometChatProvider` only runs its `useEffect` (and init) in the browser.
|
|
241
248
|
|
|
249
|
+
> ⚠️ **Option A REQUIRES `force-dynamic` on the layout (verified — real build, Next 16.2.9 + kit 6.5.1).** Mounting the provider in `app/layout.tsx` pulls the kit module into the layout's module graph, so `next build` evaluates it during the **static prerender** of *every* route — including `/` (which imports no CometChat code) and the framework-generated `/_not-found` — and crashes with `ReferenceError: window is not defined`. `"use client"` does NOT prevent this in Next 16. The per-page `export const dynamic = "force-dynamic"` from §"Build still fails…" cannot fix it, because `/_not-found` has no page file to annotate. **The fix is to put the directive on the LAYOUT, where it cascades to all routes including `/_not-found`:**
|
|
250
|
+
> ```tsx
|
|
251
|
+
> // app/layout.tsx — add this alongside the provider mount
|
|
252
|
+
> export const dynamic = "force-dynamic";
|
|
253
|
+
> ```
|
|
254
|
+
> If you would rather keep static prerendering for non-chat routes, use **Option B** (scoped route group) so `/` and `/_not-found` never import the kit — that is the cleaner choice for marketing/SSG-heavy sites.
|
|
255
|
+
|
|
242
256
|
### Where to mount: Option B -- Scoped (chat only on chat routes)
|
|
243
257
|
|
|
244
258
|
Use a route group to scope the provider to chat-related routes:
|
|
@@ -836,7 +850,7 @@ If the project has a custom `pages/_document.tsx` for font preloading or third-p
|
|
|
836
850
|
|
|
837
851
|
## 12. Complete integration checklist (App Router)
|
|
838
852
|
|
|
839
|
-
1. Install packages: `npm install @cometchat/chat-uikit-react @cometchat/chat-sdk-javascript`
|
|
853
|
+
1. Install packages: `npm install @cometchat/chat-uikit-react@^6 @cometchat/chat-sdk-javascript@^4` — **⚠️ keep the `@^6` major pin; never install bare.** v7 is on npm — a bare `npm install @cometchat/chat-uikit-react` pulls it once it's tagged `latest`, and these v6 skills break against the v7 API.
|
|
840
854
|
2. Create `.env.local` with `NEXT_PUBLIC_COMETCHAT_APP_ID`, `NEXT_PUBLIC_COMETCHAT_REGION`, `NEXT_PUBLIC_COMETCHAT_AUTH_KEY`
|
|
841
855
|
3. Import `@cometchat/chat-uikit-react/css-variables.css` in `app/globals.css`
|
|
842
856
|
4. Create `app/providers/CometChatProvider.tsx` with `"use client"` (section 3)
|
|
@@ -847,7 +861,7 @@ If the project has a custom `pages/_document.tsx` for font preloading or third-p
|
|
|
847
861
|
|
|
848
862
|
## 13. Complete integration checklist (Pages Router)
|
|
849
863
|
|
|
850
|
-
1. Install packages: `npm install @cometchat/chat-uikit-react @cometchat/chat-sdk-javascript`
|
|
864
|
+
1. Install packages: `npm install @cometchat/chat-uikit-react@^6 @cometchat/chat-sdk-javascript@^4` — **⚠️ keep the `@^6` major pin; never install bare.** v7 is on npm — a bare `npm install @cometchat/chat-uikit-react` pulls it once it's tagged `latest`, and these v6 skills break against the v7 API.
|
|
851
865
|
2. Create `.env.local` with `NEXT_PUBLIC_COMETCHAT_APP_ID`, `NEXT_PUBLIC_COMETCHAT_REGION`, `NEXT_PUBLIC_COMETCHAT_AUTH_KEY`
|
|
852
866
|
3. Import `@cometchat/chat-uikit-react/css-variables.css` in `pages/_app.tsx`
|
|
853
867
|
4. Create `components/CometChatProvider.tsx` (section 3 code, without `"use client"`)
|
|
@@ -3,13 +3,14 @@ name: cometchat-placement
|
|
|
3
3
|
description: "Production integration patterns -- how to add CometChat as a route, modal, drawer, embedded panel, or widget in an existing project. Teaches Claude WHERE to put chat."
|
|
4
4
|
license: "MIT"
|
|
5
5
|
compatibility: "@cometchat/chat-uikit-react ^6; @cometchat/chat-sdk-javascript ^4"
|
|
6
|
-
allowed-tools: "shell, file-read, file-search, file-list"
|
|
7
6
|
metadata:
|
|
8
7
|
author: "CometChat"
|
|
9
8
|
version: "3.0.0"
|
|
10
9
|
tags: "chat cometchat react placement route modal drawer widget embedded integration"
|
|
11
10
|
---
|
|
12
11
|
|
|
12
|
+
> **Ground truth:** `@cometchat/chat-uikit-react@^6` components composed for placement + `docs/ui-kit/react`. **Official docs:** https://www.cometchat.com/docs/ui-kit/react/overview · **Docs MCP:** `claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp` (or fetch the URL directly without MCP). Verify symbols against the installed package/source before relying on them.
|
|
13
|
+
|
|
13
14
|
## Purpose
|
|
14
15
|
|
|
15
16
|
This skill teaches you WHERE to put CometChat in an existing project. It covers five placement patterns: route, modal, drawer, embedded panel, and floating widget. Each pattern includes step-by-step instructions and complete code examples.
|
|
@@ -168,6 +169,30 @@ chat products.
|
|
|
168
169
|
|
|
169
170
|
---
|
|
170
171
|
|
|
172
|
+
> **Composer choice for narrow/two-pane panes:** the canonical React v6 sample apps use **`CometChatCompactMessageComposer`** (not `CometChatMessageComposer`) in the two-pane messages view — it's the kit's space-optimized composer for a sidebar-width pane (`cometchat-uikit-react-v6/sample-app/src/components/CometChatMessages/CometChatMessages.tsx:85`). Both compile and work; prefer `CometChatCompactMessageComposer` for the split/two-pane layouts below and `CometChatMessageComposer` for full-width single-thread layouts.
|
|
173
|
+
|
|
174
|
+
## Height & scroll — the message-view column MUST be bounded
|
|
175
|
+
|
|
176
|
+
Every header+list+composer example below puts the three components as **direct
|
|
177
|
+
flex children** of a `display:flex; flexDirection:column` column. That works ONLY
|
|
178
|
+
if the column has a bounded height — i.e. the full chain (`html`/`body`/`#root` →
|
|
179
|
+
…→ this column) uses a definite **`height`** (e.g. `#root { height: 100vh }`),
|
|
180
|
+
never `min-height`, and every flex ancestor of `CometChatMessageList` has
|
|
181
|
+
`minHeight: 0`. Delete the Vite/CRA starter `#root { min-height: 100vh; max-width: … }`.
|
|
182
|
+
|
|
183
|
+
If the list still won't scroll (most common symptom), or you wrap the list in its
|
|
184
|
+
own `<div>` for custom chrome/tabs, you hit the kit's auto-injected `.cometchat`
|
|
185
|
+
element — see **`cometchat-react-patterns` → "Container height (and the flex-shrink
|
|
186
|
+
trap)" Bug 3**: give the list its own wrapper class with BOTH `.your-list-wrapper
|
|
187
|
+
{ flex: 1 1 0; min-height: 0; height: 100%; overflow: hidden }` (the **explicit
|
|
188
|
+
`height: 100%` is required** — a flex-grow-only height is indefinite, so the kit's
|
|
189
|
+
injected child collapses to content height and clips) AND a child rule
|
|
190
|
+
`.your-list-wrapper > .cometchat { height: 100%; overflow: hidden }` (inline styles
|
|
191
|
+
can't target the injected child). Those two rules are the single most common fix for
|
|
192
|
+
"I set heights everywhere and it still won't scroll."
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
171
196
|
## Thread replies — hidden by default in every example below
|
|
172
197
|
|
|
173
198
|
Every `<CometChatMessageList ...>` in the placement patterns below
|
|
@@ -607,6 +632,17 @@ The `CometChatProvider` (or equivalent init logic) MUST be at the app root, NOT
|
|
|
607
632
|
|
|
608
633
|
A side panel that slides in from the right. Better than a modal for ongoing conversations because the user can keep it open while browsing.
|
|
609
634
|
|
|
635
|
+
> ⚠️ **Known kit-side traps in narrow containers (≤ ~480px). Mitigate, don't ignore (ENG-35702/03/04/06):**
|
|
636
|
+
>
|
|
637
|
+
> 1. **Unread-count badges clip at the right edge in 320px panes** — kit's conversation-list item doesn't reserve trailing padding for the pill. Workaround until the kit fix lands: target `.cometchat-conversation-list-item__badge { margin-right: 8px; flex-shrink: 0; }` in your overrides, OR widen the drawer to ≥ 480px on the inner content (use `width: min(420px, 100vw)` + 8px inner padding).
|
|
638
|
+
> 2. **`Delete Conversation?` confirmation card overflows the list pane** — kit renders the dialog inside the list column instead of portalling to a top-level scrim. There's no clean CSS workaround today; if the integration depends on right-click delete, raise the drawer width above ~480px so the card fits inside.
|
|
639
|
+
> 3. **Composer attachment popover (`+` button) anchors to the wrong ancestor** — opens at viewport bottom-right instead of above the trigger when mounted inside a drawer/modal. Workaround: ensure the drawer container has `position: relative` (NOT just `position: fixed`) on its inner card so absolute popovers anchor correctly. If the popover still misaligns, mount the composer in a full-screen-on-mobile variant (the `right: -100%` recipe from §"Recipe — breakpoint-aware drawer").
|
|
640
|
+
> 4. **Voice recorder bubble UI is broken at kit v6.x** — the in-bubble recorder shows visual artifacts AND the pause-resume timer restarts at 00:00 instead of continuing. There is no client-side workaround; if voice messages are part of the integration's core surface, document the limitation for the customer and consider hiding the voice button (`<CometChatMessageComposer hideVoiceRecordingButton={true} />`) until the kit fix ships.
|
|
641
|
+
> 5. **`CometChatMessageList` does NOT auto-resubscribe on conversation switch** — passing a new `user` or `group` prop keeps the old listeners. **Required workaround when switching conversations inside a single drawer/modal:** pass `key={user?.getUid() ?? group?.getGuid()}` to force a remount + listener re-subscribe. Without it, switching from Alice → Bob silently shows Alice's messages with Bob's header. (ENG-35702)
|
|
642
|
+
> 6. **`CometChatMessageList` may render BLANK on conversations with unread messages** — kit-side data-path bug, no header or empty-state, just blank. No client-side workaround today; if the customer reports a blank list, capture the screenshot + UID/GUID + unread count and file a kit ticket. (ENG-35702 kit-side blocker)
|
|
643
|
+
>
|
|
644
|
+
> These are kit-side bugs filed in Linear (ENG-35702, 35703, 35704, 35706); the workarounds above are interim until the next kit release.
|
|
645
|
+
|
|
610
646
|
### Steps
|
|
611
647
|
|
|
612
648
|
#### 1. Create a ChatDrawer component
|
|
@@ -688,9 +724,12 @@ export function ChatDrawer({ isOpen, onClose, targetUserId, targetGroupId }: Cha
|
|
|
688
724
|
style={{
|
|
689
725
|
position: "fixed",
|
|
690
726
|
top: 0,
|
|
691
|
-
|
|
727
|
+
// Breakpoint-aware: full-width on mobile (≤ 640px), 400px on desktop.
|
|
728
|
+
// The "-100%" closed offset slides the drawer off-screen at any width,
|
|
729
|
+
// so mobile-full-screen works without recomputing the offset (ENG-35715).
|
|
730
|
+
right: isOpen ? 0 : "-100%",
|
|
692
731
|
bottom: 0,
|
|
693
|
-
width: "400px",
|
|
732
|
+
width: "min(400px, 100vw)",
|
|
694
733
|
maxWidth: "100vw",
|
|
695
734
|
zIndex: 1000,
|
|
696
735
|
backgroundColor: "var(--cometchat-background-color-01, #fff)",
|
|
@@ -3,13 +3,14 @@ name: cometchat-production
|
|
|
3
3
|
description: "Production readiness for CometChat — server-side token auth, user management CRUD, environment hardening, and security checklist. Replaces dev-mode authKey with server-side tokens."
|
|
4
4
|
license: "MIT"
|
|
5
5
|
compatibility: "Node.js >=18; @cometchat/chat-uikit-react ^6; @cometchat/chat-sdk-javascript ^4"
|
|
6
|
-
allowed-tools: "shell, file-read, file-search, file-list"
|
|
7
6
|
metadata:
|
|
8
7
|
author: "CometChat"
|
|
9
8
|
version: "3.0.0"
|
|
10
9
|
tags: "cometchat production auth token security user-management rest-api"
|
|
11
10
|
---
|
|
12
11
|
|
|
12
|
+
> **Ground truth:** `docs/fundamentals/user-auth` + per-platform UI Kit. **Official docs:** https://www.cometchat.com/docs/fundamentals/user-auth · **Docs MCP:** `claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp` (or fetch the URL directly without MCP). Verify symbols against the installed package/source before relying on them.
|
|
13
|
+
|
|
13
14
|
## Purpose
|
|
14
15
|
|
|
15
16
|
This skill teaches Claude how to harden a CometChat integration for production. It covers two critical areas:
|
|
@@ -71,8 +72,10 @@ The CometChat REST API requires two headers:
|
|
|
71
72
|
|
|
72
73
|
| Key type | Where to find | Purpose | Security |
|
|
73
74
|
|---|---|---|---|
|
|
74
|
-
| **Auth Key** | Dashboard → Your App → API & Auth Keys → "Auth Keys" table | Client-side SDK
|
|
75
|
-
| **REST API Key** | Dashboard → Your App → API & Auth Keys → "Rest API Keys" table | Server-to-server: token generation, user CRUD, message send | Server only. Never expose to client. |
|
|
75
|
+
| **Auth Key** (`authOnly` scope) | Dashboard → Your App → API & Auth Keys → "Auth Keys" table | Client-side SDK `CometChatUIKit.login(uid)` in dev mode; server-side it can **create users + mint auth tokens** (`POST /v3/users`, `POST /v3/users/{uid}/auth_tokens`) but **NOT** update/delete users | Exposed in browser. Dev only. |
|
|
76
|
+
| **REST API Key** (`fullAccess` scope) | Dashboard → Your App → API & Auth Keys → "Rest API Keys" table | Server-to-server: token generation, **full** user CRUD (incl. **update/delete**), message send | Server only. Never expose to client. |
|
|
77
|
+
|
|
78
|
+
> **Scope split (verified against `fundamentals/key-concepts.mdx` + the chat-apis `apikey` scope enum `fullAccess`/`authOnly`):** the Auth Key can *create & login* users and mint tokens, but **`PUT`/`DELETE /v3/users/{uid}` require a `fullAccess` REST API Key** — an `authOnly` Auth Key is rejected. So a user-management endpoint that does update/delete MUST use `COMETCHAT_REST_API_KEY`, not the Auth Key. (Heads-up: the CLI's `add-user-mgmt` / `production-auth` scaffolds currently name the server var `COMETCHAT_AUTH_KEY`; for full CRUD, populate it with — or rename it to — a `fullAccess` REST API Key. Tracked as a CLI-alignment follow-up.)
|
|
76
79
|
|
|
77
80
|
The `.env` should have both for production:
|
|
78
81
|
```env
|
|
@@ -585,8 +588,12 @@ async function refreshSession(uid: string): Promise<void> {
|
|
|
585
588
|
CometChat.addConnectionListener(
|
|
586
589
|
"auth-refresh-listener",
|
|
587
590
|
new CometChat.ConnectionListener({
|
|
588
|
-
onDisconnected: () => {
|
|
589
|
-
|
|
591
|
+
onDisconnected: async () => {
|
|
592
|
+
// Web kit method is getLoggedinUser() (lowercase "i") and is ASYNC —
|
|
593
|
+
// it returns a Promise, so you must await it (you can't chain ?.getUid()
|
|
594
|
+
// on the call directly). The synchronous capital-I form is the Angular kit.
|
|
595
|
+
const me = await CometChatUIKit.getLoggedinUser();
|
|
596
|
+
const uid = me?.getUid();
|
|
590
597
|
if (uid) {
|
|
591
598
|
refreshSession(uid).catch((e) => {
|
|
592
599
|
console.error("CometChat refresh failed; user may need to re-login", e);
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cometchat-react-calls
|
|
3
|
-
description: CometChat Calls SDK integration for web React apps (Vite, CRA, Next.js, React Router, Astro). Covers @cometchat/calls-sdk-javascript install, dual-SDK init (Chat SDK + Calls SDK), getRTCToken, the kit's CometChatIncomingCall / CometChatOutgoingCall / CometChatOngoingCall components, CallButtons composition, getUserMedia permissions, browser TURN/STUN handling, and additive-vs-standalone modes.
|
|
3
|
+
description: CometChat Calls SDK integration for web React apps (Vite, CRA, Next.js, React Router, Astro). Covers @cometchat/calls-sdk-javascript install, dual-SDK init (Chat SDK + Calls SDK), generateToken (v4's getRTCToken was removed in v5), the kit's CometChatIncomingCall / CometChatOutgoingCall / CometChatOngoingCall components, CallButtons composition, getUserMedia permissions, browser TURN/STUN handling, and additive-vs-standalone modes.
|
|
4
4
|
license: "MIT"
|
|
5
5
|
compatibility: "React >= 18, Next.js >= 13, React Router v6/v7, Astro >= 4; @cometchat/calls-sdk-javascript ^5 (v5.0.0 stable shipped; pin to `@5` because the npm `latest` dist-tag still points at v4.2.6 — see §Install); @cometchat/chat-sdk-javascript ^4.x; @cometchat/chat-uikit-react ^6.x (additive mode)"
|
|
6
|
-
allowed-tools: "shell, file-read, file-search, file-list, ask-user"
|
|
7
6
|
metadata:
|
|
8
7
|
author: "CometChat"
|
|
9
8
|
version: "4.0.0"
|
|
10
9
|
tags: "cometchat react calls voice video webrtc nextjs react-router astro getRTCToken getusermedia browser-permissions vite cra"
|
|
11
10
|
---
|
|
12
11
|
|
|
12
|
+
> **Ground truth:** `@cometchat/chat-uikit-react@^6` (+ `@cometchat/calls-sdk-javascript@^5`) — installed package types + `ui-kit/react`. **Official docs:** https://www.cometchat.com/docs/calls/javascript/overview · **Docs MCP:** `claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp` (or fetch the URL directly without MCP). Verify symbols against the installed package/source before relying on them.
|
|
13
|
+
|
|
13
14
|
## ⚠️ STOP — mandatory precondition before any code
|
|
14
15
|
|
|
15
16
|
**Before writing one line of code, you MUST resolve `mode = ringing | session`.** This decides which entire integration shape you scaffold — they don't share UI, navigation, or surface.
|
|
@@ -80,6 +81,25 @@ If you can't use flex (e.g. fixed-height modal), just give the container explici
|
|
|
80
81
|
|
|
81
82
|
---
|
|
82
83
|
|
|
84
|
+
## ⚠️ Idle timeout is in MILLISECONDS (the "Are you still there? → instant exit" bug)
|
|
85
|
+
|
|
86
|
+
The idle-timeout values are **milliseconds, not seconds.** This is the single most common calls-config footgun (customer-reported 2026-06): setting `idleTimeoutPeriodBeforePrompt: 180` thinking "180 seconds" means **180 ms** — so the moment you join a session alone, the "Are you still there?" prompt fires and the call exits in a fraction of a second.
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
// ✗ WRONG — read as 180ms / 30ms → prompt + exit almost instantly on join
|
|
90
|
+
const settings = { idleTimeoutPeriodBeforePrompt: 180, idleTimeoutPeriodAfterPrompt: 30 };
|
|
91
|
+
|
|
92
|
+
// ✓ RIGHT — milliseconds. (defaults: 60_000 / 120_000)
|
|
93
|
+
const settings = {
|
|
94
|
+
idleTimeoutPeriodBeforePrompt: 180_000, // 180s before the prompt
|
|
95
|
+
idleTimeoutPeriodAfterPrompt: 60_000, // 60s grace before disconnect
|
|
96
|
+
};
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Set them as `SessionSettings` **object fields** (used with `joinSession(token, settings, container)`): `{ idleTimeoutPeriodBeforePrompt: 180_000, idleTimeoutPeriodAfterPrompt: 60_000 }`. ⚠️ There are **no** `setIdleTimeoutPeriodBeforePrompt`/`AfterPrompt` builder methods — `CallSettingsBuilder` has only a single `setIdleTimeoutPeriod(ms)`; the before/after split exists **only** as the two object fields. **`idleTimeoutPeriodAfterPrompt` has a 60_000 ms (60s) minimum** — smaller values are silently clamped to 60s. To effectively disable it, use a huge value (`86_400_000` = 24h), never `0` or a tiny number. The timer only counts down when you're the **only** participant — so a single-person session/test triggers it fastest. Full recipe (prompt UI + extend/leave): `references/idle-timeout.md`.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
83
103
|
## ⚠️ Next.js / SSR — mandatory bundler config
|
|
84
104
|
|
|
85
105
|
Both SDKs ship code that **breaks Next.js's SSR pass**:
|
|
@@ -217,10 +237,25 @@ Production-grade voice + video calling for React-family web apps. Loaded by `com
|
|
|
217
237
|
- Framework-specific patterns: `cometchat-react-patterns` / `cometchat-nextjs-patterns` / `cometchat-react-router-patterns` / `cometchat-astro-patterns`
|
|
218
238
|
|
|
219
239
|
**Ground truth:**
|
|
220
|
-
- SDK source —
|
|
221
|
-
- Sample apps —
|
|
240
|
+
- SDK source — `calls-sdk-javascript-5/package/`
|
|
241
|
+
- Sample apps — `calls-sdk-javascript-5/sample-apps/{react,vue,angular,svelte,ionic}/`
|
|
222
242
|
- Public docs — https://www.cometchat.com/docs/calls/javascript/overview
|
|
223
243
|
|
|
244
|
+
## When to use
|
|
245
|
+
|
|
246
|
+
- React-family web apps with voice/video calling: Vite + React, Next.js (App or Pages Router), React Router v6/v7, Astro with React islands.
|
|
247
|
+
- The user wants 1:1 OR group calls AND wants the calls UI surface (not pure server-side / signaling-only).
|
|
248
|
+
- Either calling mode applies — ringing (kit-driven incoming call screen) OR session (meeting-room URL pattern).
|
|
249
|
+
|
|
250
|
+
## When NOT to use
|
|
251
|
+
|
|
252
|
+
- **Chat-only integrations (no calling at all)** — skip this skill entirely. Load only `cometchat-core` + `cometchat-react-patterns` + `cometchat-components`. Don't install `@cometchat/calls-sdk-javascript` — the calls SDK alone is ~700 KB; with the kit + chat SDK the full production bundle of a chat-**and**-calls app is ~4.8 MB JS (verified — real `vite build`). That's expected; a green build also emits benign `COMMONJS_VARIABLE_IN_ESM` warnings from the calls SDK's own code and a >500 KB chunk-size warning — these are NOT failures.
|
|
253
|
+
- **Native mobile (Android / iOS / RN / Flutter)** — load the cohort-specific calls skill (`cometchat-native-calls`, `cometchat-android-v6-calls`, `cometchat-ios-calls`, `cometchat-flutter-v6-calls`). The Calls SDK is platform-specific; APIs and lifecycle differ.
|
|
254
|
+
- **Angular** — load `cometchat-angular-calls`. Same underlying JS Calls SDK but wrapped in Angular Services + `@Output()` event bindings (NOT React-style callback props — verified runtime smoke 2026-06-02 caught the v4→v5 binding inversion).
|
|
255
|
+
- **SDK-only (no UI Kit)** — `cometchat-react-calls` §4c covers the SDK-only path in detail; this is the right skill, but you're using a specific subset. Don't import `<CometChatCallButtons>` / `<CometChatOngoingCall>` / `<CometChatIncomingCall>` from `@cometchat/chat-uikit-react` in that mode.
|
|
256
|
+
- **Server-side token-mint server work** — load `cometchat-production` for the REST-API token recipes; this skill is client-side.
|
|
257
|
+
- **Visual Builder calls** — load `cometchat-core` §11 + the framework-specific patterns; the Visual Builder generates calls wiring differently.
|
|
258
|
+
|
|
224
259
|
---
|
|
225
260
|
|
|
226
261
|
## 1. The seven hard rules — web specialization
|
|
@@ -242,11 +277,13 @@ const initiated = await CometChat.initiateCall(outgoing);
|
|
|
242
277
|
// ✓ RIGHT — join WebRTC session (Calls SDK v5)
|
|
243
278
|
import { CometChatCalls } from "@cometchat/calls-sdk-javascript";
|
|
244
279
|
|
|
245
|
-
// v5 — plain SessionSettings object, no Builder
|
|
280
|
+
// v5 — plain SessionSettings object, no Builder.
|
|
281
|
+
// `as const` keeps the string literals narrow ("VIDEO"/"TILE") so they satisfy
|
|
282
|
+
// the SDK's SessionType / Layout unions — a bare object widens them to `string`.
|
|
246
283
|
const sessionSettings = {
|
|
247
284
|
sessionType: "VIDEO", // or "VOICE"
|
|
248
285
|
layout: "TILE",
|
|
249
|
-
};
|
|
286
|
+
} as const;
|
|
250
287
|
|
|
251
288
|
// v5 — generateToken takes ONLY sessionId (Calls SDK has its own auth state
|
|
252
289
|
// after CometChatCalls.login(); no authToken arg needed).
|
|
@@ -288,9 +325,11 @@ function endCall() {
|
|
|
288
325
|
|
|
289
326
|
Skipping this leaves the camera light on until the tab is closed. Same canonical bug as iOS rule 1.5.
|
|
290
327
|
|
|
291
|
-
### 1.4
|
|
328
|
+
### 1.4 Calls login — the DEFAULT path needs NONE; only `directCalling`/SDK-only do
|
|
292
329
|
|
|
293
|
-
|
|
330
|
+
> ✅ **For the common case — additive ringing / default calling — do NOT call `CometChatCalls.login`.** Install the calls SDK, let the call buttons appear automatically in `CometChatMessageHeader`, and mount `<CometChatIncomingCall />` once at the app root. That's the whole wiring. **Both canonical React v6 sample apps do calls this exact way with ZERO `CometChatCalls.login`/`CometChatCalls.init`** (verified: `cometchat-uikit-react-v6/sample-app/src/components/CometChatHome/CometChatHome.tsx:1740` mounts only `<CometChatIncomingCall />`; no `CometChatCalls.login` anywhere in either sample). The kit's default `defaultCalling` mode rides the Chat SDK's signaling — adding a calls-login step here is needless plumbing, and an empty/wrong arg makes it **silently no-op**.
|
|
331
|
+
|
|
332
|
+
**`CometChatCalls.login` is required ONLY for** (a) `CallWorkflow.directCalling` (conference-style 1:1) or (b) the SDK-only / custom-WebRTC surface (§4c). In those cases — and only those — the v5 Calls SDK needs its own login: after `CometChat.login()` resolves on the chat side, call **`CometChatCalls.login(uid, apiKey)`** for dev or **`CometChatCalls.loginWithAuthToken(authToken)`** for production. The auth token is the same one your backend mints via the CometChat Create-Auth-Token API; the Calls SDK and Chat SDK accept it interchangeably.
|
|
294
333
|
|
|
295
334
|
```ts
|
|
296
335
|
// Dev
|
|
@@ -300,8 +339,12 @@ await CometChatCalls.login(uid, import.meta.env.VITE_COMETCHAT_API_KEY);
|
|
|
300
339
|
await CometChatCalls.loginWithAuthToken(authTokenFromBackend);
|
|
301
340
|
```
|
|
302
341
|
|
|
342
|
+
> **About `VITE_COMETCHAT_API_KEY`:** `CometChatCalls.login(uid, apiKey)` takes the app's **Auth Key** — the same value `cometchat-core` writes as `VITE_COMETCHAT_AUTH_KEY` (the env-prefix table establishes `APP_ID`/`REGION`/`AUTH_KEY`, not a separate `API_KEY`). In dev you can reuse `VITE_COMETCHAT_AUTH_KEY` here; if you prefer the `_API_KEY` name for readability, add it to your `.env` with the same Auth Key value. Don't leave it undefined — an empty arg makes the Calls login silently no-op (see the `directCalling` trap above).
|
|
343
|
+
|
|
303
344
|
`cometchat-production` (web) covers the token-endpoint pattern.
|
|
304
345
|
|
|
346
|
+
> ⚠️ **`CallWorkflow.directCalling` silently fails without this login.** When you opt 1:1 calls into the conference-style UI by passing `callWorkflow={CallWorkflow.directCalling}` to `<CometChatCallButtons>` / `<CometChatOngoingCall>` etc., the kit routes through the Calls SDK directly and **requires `CometChatCalls.login()` to have completed**. Without it, calls **ring for ~2 seconds then drop with no error message** — the most painful failure mode in this skill. The UI Kit's default `defaultCalling` mode does NOT have this requirement (it uses the Chat SDK's signaling). Rule when emitting `directCalling`: always include the `CometChatCalls.login(...)` call alongside the Chat login above (ENG-35709).
|
|
347
|
+
|
|
305
348
|
### 1.5 Hangup cleanup — see rule 1.3
|
|
306
349
|
|
|
307
350
|
### 1.6 Permissions — `getUserMedia` prompts
|
|
@@ -328,6 +371,69 @@ There are no manifest-level permission declarations on web. HTTPS is required
|
|
|
328
371
|
|
|
329
372
|
Mounting it inside a route component means it disappears on navigation — calls only ring on the screen where it's mounted. That's the canonical "calls don't work" bug on web.
|
|
330
373
|
|
|
374
|
+
### 1.8 Init order — Chat init → Chat login → Calls init → Calls login (ENG-35708)
|
|
375
|
+
|
|
376
|
+
The order is load-bearing. Two crashes from real testers trace back to this:
|
|
377
|
+
|
|
378
|
+
- **`CometChatCalls.init` before `CometChat.login` → calls integration broke.** The Calls SDK reads context from the Chat SDK that only exists once a Chat session is established. Swapping init order silently fails or returns 401s on the first `generateToken`.
|
|
379
|
+
- **Crash on `Start Call` when only the Calls SDK was initialized.** No Chat SDK init at all → the ringing flow can't fire `initiateCall` because the Chat SDK isn't there.
|
|
380
|
+
|
|
381
|
+
**The only correct order in additive mode (chat + calls):**
|
|
382
|
+
|
|
383
|
+
```
|
|
384
|
+
CometChat.init(appId, settings)
|
|
385
|
+
→ CometChat.login(uid, authKey) // OR loginWithAuthToken(token)
|
|
386
|
+
→ CometChatCalls.init({appId, region})
|
|
387
|
+
→ CometChatCalls.login(uid, apiKey) // OR loginWithAuthToken(serverToken)
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
In **standalone session-mode** (`product === "voice-video"`, no chat), use ONLY the Calls SDK — never call `CometChat.init` / `CometChat.login` at all. The kit's session-mode sample doesn't import the Chat SDK; matching that shape eliminates a class of "Chat init failed mid-meeting" failures.
|
|
391
|
+
|
|
392
|
+
### 1.9 Don't double-up call buttons (ENG-35708)
|
|
393
|
+
|
|
394
|
+
Two testers reported call buttons appearing twice on the message screen. Cause: the kit's `<CometChatMessageHeader user={user} />` already renders `<CometChatCallButtons>` internally when a `user` prop is set (and the kit's default messages page mounts the header). Adding your own `<CometChatCallButtons user={user} />` next to either of those produces a duplicate set.
|
|
395
|
+
|
|
396
|
+
**Rule before emitting `<CometChatCallButtons>`:**
|
|
397
|
+
|
|
398
|
+
1. Check whether the surrounding kit component already shows them. `CometChatMessageHeader` (any path that auto-renders the header) and the kit's default messages page include call buttons by default. (Note: there is no `CometChatConversationsWithMessages` composite in v6 — it was removed.)
|
|
399
|
+
2. If yes, do NOT add a second `<CometChatCallButtons>`. To swap appearance or behavior, use the kit's `messageHeaderView` slot or set the relevant `hide*` flag instead of adding another instance.
|
|
400
|
+
3. If no — you're on a custom screen that does not use those kit components — then `<CometChatCallButtons user={user} />` is appropriate. Mount it once, beside the user-info block.
|
|
401
|
+
|
|
402
|
+
### 1.10 `CometChatOngoingCall` expects a `callSettingsBuilder`, NOT a built `CallSettings` (ENG-35708)
|
|
403
|
+
|
|
404
|
+
`CallSettingsBuilder` is not a bare export of either package — access it via the kit re-export: `import { CometChatUIKitCalls } from "@cometchat/chat-uikit-react"`, then `new CometChatUIKitCalls.CallSettingsBuilder()`. The prop shape is the **builder instance** (not the built settings object). The agent emitted:
|
|
405
|
+
|
|
406
|
+
```tsx
|
|
407
|
+
// ✗ Wrong — TypeScript error on the prop type
|
|
408
|
+
const callSettings = new CometChatUIKitCalls.CallSettingsBuilder().enableDefaultLayout(true).build();
|
|
409
|
+
<CometChatOngoingCall callSettingsBuilder={callSettings} />
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
The correct usage is:
|
|
413
|
+
|
|
414
|
+
```tsx
|
|
415
|
+
// ✓ Right. Verified against the kit's CometChatOngoingCallProps (6.5.x):
|
|
416
|
+
// sessionID: string ← REQUIRED (non-optional) — omitting it TS-errors
|
|
417
|
+
// callSettingsBuilder?: ... ← OPTIONAL; the kit defaults to new CometChatUIKitCalls.CallSettingsBuilder()
|
|
418
|
+
// There is NO .setSessionID() on the builder — the session id is its OWN prop.
|
|
419
|
+
// The builder holds only configuration setters (enableDefaultLayout /
|
|
420
|
+
// setIsAudioOnlyCall / show*Button).
|
|
421
|
+
const callSettingsBuilder = new CometChatUIKitCalls.CallSettingsBuilder()
|
|
422
|
+
.enableDefaultLayout(true)
|
|
423
|
+
.setIsAudioOnlyCall(false);
|
|
424
|
+
<CometChatOngoingCall sessionID={sessionId} callSettingsBuilder={callSettingsBuilder} />
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
> **Prefer the additive path over a manual `<CometChatOngoingCall>` mount.** Mounting `<CometChatIncomingCall />` at the app root and letting the kit drive the Outgoing → Ongoing transition needs no `sessionID` plumbing and is the build-clean, recommended approach (§1.x). Reach for a manual `<CometChatOngoingCall>` only when you're building a custom call screen — and then `sessionID` is mandatory.
|
|
428
|
+
|
|
429
|
+
Why this shape: the kit composes the builder with internal listeners (call-end, error, recording state) before calling `.build()`. Pre-building forecloses that composition. Pass the builder; let the kit build.
|
|
430
|
+
|
|
431
|
+
> ⚠️ **`callSettingsBuilder` is a different shape on different components** (verified vs the v6 React kit source — do not assume one form):
|
|
432
|
+
> - `<CometChatOngoingCall>` → a **builder instance** (`callSettingsBuilder={new CometChatUIKitCalls.CallSettingsBuilder()...}`), prop typed `typeof CometChatUIKitCalls.CallSettings`.
|
|
433
|
+
> - `<CometChatCallButtons>` → a **callback**: `callSettingsBuilder={(isAudioOnlyCall, user?, group?) => new CometChatUIKitCalls.CallSettingsBuilder()...}`.
|
|
434
|
+
> - `<CometChatIncomingCall>` (and Outgoing) → a **callback** taking the call: `callSettingsBuilder={(call) => new CometChatUIKitCalls.CallSettingsBuilder()...}`.
|
|
435
|
+
> All three are optional — omit the prop and the kit uses its own default builder (the simplest correct path). Only the OngoingCall form takes a bare instance; passing an instance where a callback is expected is a TS error.
|
|
436
|
+
|
|
331
437
|
---
|
|
332
438
|
|
|
333
439
|
## 2. Setup
|
|
@@ -380,7 +486,10 @@ export async function initCometChat() {
|
|
|
380
486
|
export async function loginCometChat(uid: string) {
|
|
381
487
|
await CometChat.login(uid, import.meta.env.VITE_COMETCHAT_AUTH_KEY);
|
|
382
488
|
|
|
383
|
-
// v5 — Calls SDK login.
|
|
489
|
+
// v5 — Calls SDK login. ⚠ Only needed for CallWorkflow.directCalling or the
|
|
490
|
+
// SDK-only/custom-WebRTC surface (see §1.4) — for the COMMON additive/default
|
|
491
|
+
// ringing path you can OMIT this whole block (the kit rides the Chat SDK's
|
|
492
|
+
// signaling). Shown here for completeness; harmless when included with a valid key.
|
|
384
493
|
if (!CometChatCalls.getLoggedInUser()) {
|
|
385
494
|
await CometChatCalls.login(uid, import.meta.env.VITE_COMETCHAT_API_KEY);
|
|
386
495
|
// OR: await CometChatCalls.loginWithAuthToken(serverMintedToken);
|
|
@@ -390,6 +499,8 @@ export async function loginCometChat(uid: string) {
|
|
|
390
499
|
|
|
391
500
|
The module-level `initialized` flag prevents StrictMode double-init in React 18+ dev mode. The `getLoggedInUser()` guard prevents re-login on hot reload.
|
|
392
501
|
|
|
502
|
+
> ⚠️ **Additive mode: the chat layer must init via `CometChatUIKit.init()`, not raw `CometChat.init()`.** The example above shows `CometChat.init()` for the SDK-only path. But when you use the kit's call components (`<CometChatCallButtons>` / `<CometChatIncomingCall>` / `<CometChatOngoingCall>`), they read `uiKitSettings` that **only `CometChatUIKit.init(new UIKitSettingsBuilder()…build())` sets** — your `cometchat-core` setup already does this. Initializing the chat layer with raw `CometChat.init()` instead leaves the components logging **`uiKitSettings not available`** (non-fatal — calls still connect — but a real DX smell). In additive mode, keep `CometChatUIKit.init()` as your chat init and have this calls module ADD only `CometChatCalls.init()` + `CometChatCalls.login()` on top. *(Verified by a two-user live call smoke 2026-06-04: with `CometChatUIKit.init()` the ring→accept→join flow runs with zero console errors; with raw `CometChat.init()` both sides log the warning.)*
|
|
503
|
+
|
|
393
504
|
### Framework-specific env prefixes (already covered by `cometchat-core`)
|
|
394
505
|
|
|
395
506
|
| Framework | Env prefix |
|
|
@@ -464,7 +575,7 @@ When `product === "voice-video"` and there is no existing chat UI integration.
|
|
|
464
575
|
|
|
465
576
|
### 4a. Standalone — Session mode (meeting-room UX, no ringing)
|
|
466
577
|
|
|
467
|
-
Calls SDK ONLY. NO Chat SDK. Matches the upstream sample at
|
|
578
|
+
Calls SDK ONLY. NO Chat SDK. Matches the upstream sample at `calls-sdk-javascript-5/sample-apps/cometchat-calls-sample-app-react/`. The skill scaffolds:
|
|
468
579
|
|
|
469
580
|
1. **`cometchat/init.ts`** — `CometChatCalls.init({ appId, region, authKey })` ONLY. No `CometChat.init`, no `CometChat.login`. Pass `authKey` at init time so subsequent `CometChatCalls.login(uid)` calls need no second arg.
|
|
470
581
|
2. **`cometchat/CometChatProvider.tsx`** — Runs Calls SDK init on mount, exposes `loggedInUser` via `CometChatCalls.getLoggedInUser()`, gates children on success.
|
|
@@ -487,6 +598,104 @@ Dual-SDK: Chat SDK signaling channel + Calls SDK media channel. The skill scaffo
|
|
|
487
598
|
7. **Optional Web Push** — Service Worker registration + push subscription endpoint, if the user opts in.
|
|
488
599
|
8. **HTTPS check** — warns if dev server is HTTP non-localhost.
|
|
489
600
|
|
|
601
|
+
### 4c. SDK-only — without any UI Kit call components (ENG-35707)
|
|
602
|
+
|
|
603
|
+
When the user wants to build their own call UI (custom controls, a custom in-call screen) but still wants ringing semantics, they're on the SDK-only path: Chat SDK for signaling + Calls SDK for media, NO `<CometChatCallButtons>` / `<CometChatOngoingCall>` / `<CometChatIncomingCall>` from the UI Kit. The previous version of this skill was UI-Kit-first and these gotchas were silent. Cover them explicitly when you scaffold this shape.
|
|
604
|
+
|
|
605
|
+
#### Constants — two enums, same meaning, easy to confuse
|
|
606
|
+
|
|
607
|
+
| Constant | Source | Use it for |
|
|
608
|
+
|---|---|---|
|
|
609
|
+
| `CometChat.CALL_TYPE.AUDIO` / `.VIDEO` | `@cometchat/chat-sdk-javascript` | The **Chat SDK** call entity — passed to `new CometChat.Call(receiver, callType, receiverType)` and to `CometChat.initiateCall`. |
|
|
610
|
+
| `CometChat.RECEIVER_TYPE.USER` / `.GROUP` | `@cometchat/chat-sdk-javascript` | The **Chat SDK** call entity — passed alongside `callType`. |
|
|
611
|
+
| `CometChatCalls.constants.TYPE.VOICE` / `.VIDEO` | `@cometchat/calls-sdk-javascript` | The **Calls SDK** session-type enum. Matches the `SessionSettings` `sessionType` value (`'VOICE'` / `'VIDEO'`). |
|
|
612
|
+
|
|
613
|
+
These are NOT interchangeable. `CometChat.CALL_TYPE.AUDIO` (Chat SDK) ≠ `CometChatCalls.constants.TYPE.VOICE` (Calls SDK) even though they mean the same thing. Use the Chat SDK enum on the `Call` entity you pass to `initiateCall`; use the Calls SDK enum on `SessionSettings.sessionType`.
|
|
614
|
+
|
|
615
|
+
> Note: `CallSettingsBuilder` has **no** `setCallType(...)` method — that lives on `CallLogRequestBuilder` (and takes `'video' | 'audio'` for filtering call logs). The audio knob for a session is `CallSettingsBuilder().setIsAudioOnlyCall(true)`, or `sessionType: 'VOICE'` in the `SessionSettings` object form. (Verified against the calls-sdk `index.d.ts`.)
|
|
616
|
+
|
|
617
|
+
#### Audio-only calls — `setIsAudioOnlyCall(true)` on `CallSettingsBuilder`
|
|
618
|
+
|
|
619
|
+
The audio-only knob lives on the Calls SDK's `CallSettingsBuilder`, not on the Chat SDK call entity. You set the Chat SDK call type to `AUDIO` for the ringing/signaling channel, and then ALSO set `setIsAudioOnlyCall(true)` on the call settings used for `joinSession`:
|
|
620
|
+
|
|
621
|
+
```typescript
|
|
622
|
+
// joinSession's 2nd arg is a SessionSettings OBJECT (NOT the output of
|
|
623
|
+
// CallSettingsBuilder.build() — that's a CallSettings, accepted only by the
|
|
624
|
+
// deprecated startSession). The session is carried by the `token` (from
|
|
625
|
+
// generateToken(sessionId)); there is no sessionId/setSessionID in the settings.
|
|
626
|
+
// Voice-only: set sessionType: 'VOICE' (the object equivalent of the v4
|
|
627
|
+
// builder's setIsAudioOnlyCall(true)).
|
|
628
|
+
const settings = { sessionType: 'VOICE' };
|
|
629
|
+
|
|
630
|
+
const result = await CometChatCalls.joinSession(token, settings, containerRef.current);
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
Without `sessionType: 'VOICE'`, voice calls still acquire the camera (it's just not rendered) — which trips the browser permission prompt and lights the camera indicator. Always pair `CALL_TYPE.AUDIO` (Chat) + `sessionType: 'VOICE'` in the join settings (Calls) for voice calls.
|
|
634
|
+
|
|
635
|
+
#### Container-mount timing — `joinSession` MUST fire after the container is in the DOM
|
|
636
|
+
|
|
637
|
+
This is the most painful SDK-only failure mode. The natural site to call `joinSession` is the call-listener event `onOutgoingCallAccepted` (caller side) or `onIncomingCallReceived` → user-accepts (receiver side). But those events fire BEFORE your in-call panel has rendered — the container `<div ref={containerRef}>` is still `null`. `joinSession(token, settings, null)` throws `Container dimensions and number of tiles must be positive` (or silently no-ops in some kit versions).
|
|
638
|
+
|
|
639
|
+
**Pattern: drive the container via state and join in a `useEffect` that depends on both the call state AND the container ref.**
|
|
640
|
+
|
|
641
|
+
```tsx
|
|
642
|
+
function CallScreen() {
|
|
643
|
+
const [phase, setPhase] = useState<"idle" | "joining" | "in-call">("idle");
|
|
644
|
+
const [callToken, setCallToken] = useState<string | null>(null);
|
|
645
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
646
|
+
|
|
647
|
+
// Step 1: register call listeners
|
|
648
|
+
useEffect(() => {
|
|
649
|
+
const listenerID = "call-screen-" + Date.now();
|
|
650
|
+
CometChat.addCallListener(listenerID, new CometChat.CallListener({
|
|
651
|
+
onOutgoingCallAccepted: async (call: any) => {
|
|
652
|
+
// DO NOT call joinSession here — the container ref is still null.
|
|
653
|
+
// Just flip the phase and let the effect below handle it.
|
|
654
|
+
const tokenRes = await CometChatCalls.generateToken(call.getSessionId(), authToken);
|
|
655
|
+
setCallToken(tokenRes.token);
|
|
656
|
+
setPhase("in-call");
|
|
657
|
+
},
|
|
658
|
+
onIncomingCallReceived: (call: any) => { /* show your accept UI */ },
|
|
659
|
+
}));
|
|
660
|
+
return () => CometChat.removeCallListener(listenerID);
|
|
661
|
+
}, []);
|
|
662
|
+
|
|
663
|
+
// Step 2: when phase flips to "in-call" AND container is mounted, join
|
|
664
|
+
useEffect(() => {
|
|
665
|
+
if (phase !== "in-call" || !callToken || !containerRef.current) return;
|
|
666
|
+
const container = containerRef.current;
|
|
667
|
+
if (container.clientWidth === 0 || container.clientHeight === 0) return; // not laid out yet
|
|
668
|
+
// session is carried by callToken (from generateToken). joinSession takes a
|
|
669
|
+
// SessionSettings OBJECT — {} uses the default layout. (Do NOT pass
|
|
670
|
+
// CallSettingsBuilder.build() here — that CallSettings type is for the
|
|
671
|
+
// deprecated startSession, and is incompatible with joinSession.)
|
|
672
|
+
CometChatCalls.joinSession(callToken, {}, container);
|
|
673
|
+
}, [phase, callToken]);
|
|
674
|
+
|
|
675
|
+
return (
|
|
676
|
+
<>
|
|
677
|
+
{phase === "in-call" && (
|
|
678
|
+
<div ref={containerRef} style={{ position: "fixed", inset: 0, width: "100vw", height: "100vh" }} />
|
|
679
|
+
)}
|
|
680
|
+
</>
|
|
681
|
+
);
|
|
682
|
+
}
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
The key idea: the call-listener handler doesn't call `joinSession` directly. It updates state. The effect that depends on `phase` AND the ref runs ONLY after React has committed the container `<div>` to the DOM. This is the same race as "modal `<dialog>` mounted before `showModal()`" — it's a React/DOM-timing issue, not a SDK bug.
|
|
686
|
+
|
|
687
|
+
#### Group calls vs 1:1 calls — defaults differ
|
|
688
|
+
|
|
689
|
+
- **1:1 calls** use the ringing pattern: `new CometChat.Call(receiverUid, CALL_TYPE.VIDEO, RECEIVER_TYPE.USER)` → `CometChat.initiateCall(call)` → receiver gets `onIncomingCallReceived`. Default call type for a 1:1 video chat is video; for audio chat, audio.
|
|
690
|
+
- **Group calls** in the UI Kit go through a **custom-message broadcast** (`CometChatCallButtons` sends `CustomMessage type="meeting"`), not `initiateCall`. SDK-only groups: send your own custom message + `CometChatCalls.joinSession` with a shared sessionId — there is no "ring a group" primitive.
|
|
691
|
+
- **Group call default is voice** in the kit's `CometChatCallButtons` for groups; 1:1 default is video. If you're building custom buttons, replicate this — group calls are usually meeting-style (voice + screen share); 1:1s are usually video.
|
|
692
|
+
|
|
693
|
+
Cross-reference: `cometchat-native-calls` §3 documents the same group-call custom-message pattern for React Native (memory: [[project_group_calls_kit_semantic]]).
|
|
694
|
+
|
|
695
|
+
#### Container CSS — non-zero dimensions before `joinSession`
|
|
696
|
+
|
|
697
|
+
Already covered in the §⚠️ "Call container — must have non-zero dimensions" callout at the top, but it bears repeating in the SDK-only flow because there's no UI Kit component wrapping the container. Inline-render the container with `position: fixed; inset: 0; width: 100vw; height: 100vh` (full-screen overlay) OR `display: flex; flex: 1; min-height: 600px` (embedded). NEVER `display: none` + toggle — the container measures zero while hidden and `joinSession` throws.
|
|
698
|
+
|
|
490
699
|
## 5. Additive integration
|
|
491
700
|
|
|
492
701
|
When `cometchat-core` integration already exists. The skill:
|
|
@@ -532,6 +741,7 @@ When `cometchat-core` integration already exists. The skill:
|
|
|
532
741
|
|
|
533
742
|
## 8. Pointers
|
|
534
743
|
|
|
744
|
+
- `references/virtual-background.md` — blur / custom image / clear (web-only; native iOS/Android don't support it)
|
|
535
745
|
- `cometchat-core` — provider pattern, init guard, login order
|
|
536
746
|
- `cometchat-components` — full UI Kit catalog (additive mode)
|
|
537
747
|
- `cometchat-{nextjs,react,react-router,astro}-patterns` — framework-specific SSR guards, route placement
|