@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
|
@@ -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
|
|
@@ -74,7 +74,8 @@ Wherever you call `CometChat.login(uid, authKey)` (or your auth-token equivalent
|
|
|
74
74
|
```ts
|
|
75
75
|
const user = await CometChat.login(uid, authKey);
|
|
76
76
|
const authToken = user.getAuthToken();
|
|
77
|
-
|
|
77
|
+
// CometChatCalls.login(uid, authKey?) takes a UID — pass a token via loginWithAuthToken.
|
|
78
|
+
await CometChatCalls.loginWithAuthToken(authToken);
|
|
78
79
|
```
|
|
79
80
|
|
|
80
81
|
If you use server-minted auth tokens (production hygiene — see `cometchat-production`), the same auth token works for both SDKs.
|
|
@@ -121,11 +122,11 @@ If you want a custom call experience instead of the kit's default UI, see `comet
|
|
|
121
122
|
|
|
122
123
|
- [ ] `@cometchat/calls-sdk-javascript@^5` in package.json
|
|
123
124
|
- [ ] Calls SDK init runs AFTER chat SDK init
|
|
124
|
-
- [ ] `CometChatCalls.
|
|
125
|
+
- [ ] `CometChatCalls.loginWithAuthToken(authToken)` runs AFTER `CometChat.login`
|
|
125
126
|
- [ ] `CometChatIncomingCall` mounted at app root
|
|
126
127
|
- [ ] Call buttons visible in CometChatMessageHeader
|
|
127
128
|
- [ ] Run `cometchat verify --calls` — should pass all 20 checks
|
|
128
|
-
- [ ] Smoke test:
|
|
129
|
+
- [ ] Smoke test: **two ISOLATED browser contexts** (normal + Incognito window, or two browsers/devices — NOT two tabs of one browser; the Chat SDK shares one session per origin), call from one, ringing in the other
|
|
129
130
|
|
|
130
131
|
---
|
|
131
132
|
|
|
@@ -85,10 +85,9 @@ useEffect(() => {
|
|
|
85
85
|
const handler = (newLayout: string) => {
|
|
86
86
|
setLayout(newLayout as typeof layout);
|
|
87
87
|
};
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
};
|
|
88
|
+
// addEventListener returns an unsubscribe fn — there is no removeEventListener.
|
|
89
|
+
const off = CometChatCalls.addEventListener("onCallLayoutChanged", handler);
|
|
90
|
+
return () => off();
|
|
92
91
|
}, []);
|
|
93
92
|
```
|
|
94
93
|
|
|
@@ -138,7 +137,7 @@ For general meetings: don't lock. Let users pick.
|
|
|
138
137
|
1. **Calling `setLayout` before `joinSession` resolves.** Throws — the call surface isn't bound yet. Set the initial layout via `callSettings.layout` instead.
|
|
139
138
|
2. **Storing layout in URL or shared state.** Layout is per-participant local. Sharing it via URL/Firestore causes layout flicker as multiple peers fight to set it.
|
|
140
139
|
3. **String literals everywhere.** Use `CometChatCalls.constants.LAYOUT` so typos surface at autocomplete time, not runtime.
|
|
141
|
-
4. **Forgetting
|
|
140
|
+
4. **Forgetting to call the unsubscribe fn on unmount.** `addEventListener` returns a `() => void` — call it in cleanup (there is no `removeEventListener`). Otherwise the listener accumulates across calls → `setLayout` fires N times.
|
|
142
141
|
5. **Custom switcher AND kit's switcher both visible.** Confusing. Set `hideChangeLayoutButton: true` if you ship your own.
|
|
143
142
|
|
|
144
143
|
---
|
|
@@ -156,6 +155,6 @@ For general meetings: don't lock. Let users pick.
|
|
|
156
155
|
## Pointers
|
|
157
156
|
|
|
158
157
|
- `cometchat-react-calls/SKILL.md` — call surface architecture
|
|
159
|
-
- `cometchat-react-calls/references/recording.md` — sister cross-cutting concern
|
|
158
|
+
- `cometchat-react-calls/references/recording-screen-share.md` — sister cross-cutting concern
|
|
160
159
|
- `cometchat-react-calls/references/in-call-chat.md` — chat panel sits beside layout
|
|
161
160
|
- Canonical docs: https://www.cometchat.com/docs/calls/javascript/call-layouts
|
|
@@ -71,7 +71,7 @@ Each user calls this with the SAME `sessionId` but gets a token tied to their ow
|
|
|
71
71
|
|
|
72
72
|
## Join session
|
|
73
73
|
|
|
74
|
-
This pattern mirrors the upstream sample exactly:
|
|
74
|
+
This pattern mirrors the upstream sample exactly: `calls-sdk-javascript-5/sample-apps/cometchat-calls-sample-app-react/src/pages/join-session/JoinSession.tsx`. Customer-validated against the v5 SDK as the known-good shape.
|
|
75
75
|
|
|
76
76
|
```tsx
|
|
77
77
|
import { useEffect, useRef, useState } from "react";
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
When the kit's default `<CometChatOngoingCall />` doesn't fit your app's design system, drop down to the Calls SDK directly. Two escalation paths:
|
|
4
4
|
|
|
5
5
|
1. **Style the kit's component** — pass style props / CSS variable overrides. Cheapest. Covers most cases.
|
|
6
|
-
2. **Build your own surface on the SDK** —
|
|
6
|
+
2. **Build your own surface on the SDK** — drive the session directly with your own DOM container. Maximum control. The kit doesn't render anything; you do.
|
|
7
|
+
|
|
8
|
+
> ⚠️ **Two join APIs — pick by which settings type you build.** `joinSession(token, sessionSettings, container)` is the v5 canonical and takes a **`SessionSettings` object** (the `hide*` / `sessionType` / `layout` flags). It does **not** accept the output of `CallSettingsBuilder.build()` — those are incompatible types. The `CallSettingsBuilder` (with `enableDefaultLayout(false)`, `setCallListener`, etc.) produces a `CallSettings` consumed only by the **deprecated** `startSession(token, callSettings, container)`. So: **hybrid / hide-chrome custom UI → object + `joinSession`** (preferred); **fully-custom render-your-own-tiles (`enableDefaultLayout(false)`) → builder + `startSession`** (the one path where the deprecated call is still required, because `enableDefaultLayout` lives only on the builder).
|
|
7
9
|
|
|
8
10
|
This reference covers path 2 — full custom UI on the SDK. Path 1 is in the kit's component documentation (see `cometchat-customization`).
|
|
9
11
|
|
|
@@ -47,6 +49,8 @@ export function CustomOngoingCallView({ sessionId, authToken, onCallEnded }: Pro
|
|
|
47
49
|
const remoteVideoRef = useRef<HTMLVideoElement>(null);
|
|
48
50
|
|
|
49
51
|
useEffect(() => {
|
|
52
|
+
// ⚠️ CometChatCalls.OngoingCallListener is @deprecated (use addEventListener).
|
|
53
|
+
// It's only here because enableDefaultLayout(false) + startSession require it.
|
|
50
54
|
const callListener = new CometChatCalls.OngoingCallListener({
|
|
51
55
|
onUserListUpdated: (userList: unknown) => {
|
|
52
56
|
// userList = current participants — re-render your custom roster
|
|
@@ -62,9 +66,6 @@ export function CustomOngoingCallView({ sessionId, authToken, onCallEnded }: Pro
|
|
|
62
66
|
onError: (error: unknown) => {
|
|
63
67
|
console.error("Call error:", error);
|
|
64
68
|
},
|
|
65
|
-
onAudioModesUpdated: (audioModes: unknown[]) => {
|
|
66
|
-
// available mic / speaker devices
|
|
67
|
-
},
|
|
68
69
|
onCallSwitchedToVideo: (call: unknown) => {
|
|
69
70
|
// remote upgraded the call from voice to video
|
|
70
71
|
},
|
|
@@ -73,11 +74,15 @@ export function CustomOngoingCallView({ sessionId, authToken, onCallEnded }: Pro
|
|
|
73
74
|
},
|
|
74
75
|
});
|
|
75
76
|
|
|
77
|
+
// ⚠️ CallSettingsBuilder method names (verified against calls-sdk-javascript@5):
|
|
78
|
+
// - there is NO .setSessionID() on the builder — sessionId flows through
|
|
79
|
+
// generateToken(sessionId) below, NOT the builder
|
|
80
|
+
// - it's .setIsAudioOnlyCall(bool), not .setIsAudioOnly()
|
|
81
|
+
// - it's .setCallListener(listener), not .setCallEventListener()
|
|
76
82
|
const settings = new CometChatCalls.CallSettingsBuilder()
|
|
77
|
-
.
|
|
78
|
-
.setIsAudioOnly(false)
|
|
83
|
+
.setIsAudioOnlyCall(false)
|
|
79
84
|
.enableDefaultLayout(false) // ← key: we render the UI ourselves
|
|
80
|
-
.
|
|
85
|
+
.setCallListener(callListener)
|
|
81
86
|
.build();
|
|
82
87
|
|
|
83
88
|
// v5 generateToken takes ONLY sessionId — authToken is internal after CometChatCalls.login().
|
|
@@ -86,8 +91,11 @@ export function CustomOngoingCallView({ sessionId, authToken, onCallEnded }: Pro
|
|
|
86
91
|
// With custom UI you typically render your own <video> elements; the
|
|
87
92
|
// container can be hidden but must still be a real DOM node.
|
|
88
93
|
const container = document.getElementById("calls-container")!;
|
|
89
|
-
//
|
|
90
|
-
|
|
94
|
+
// This example builds CallSettings via CallSettingsBuilder (enableDefaultLayout(false)),
|
|
95
|
+
// so it MUST use startSession — joinSession only accepts a SessionSettings object,
|
|
96
|
+
// not the builder's CallSettings output. startSession is deprecated but is the only
|
|
97
|
+
// consumer of enableDefaultLayout(false)-style fully-custom settings.
|
|
98
|
+
CometChatCalls.startSession(tokenRes.token, settings, container);
|
|
91
99
|
});
|
|
92
100
|
|
|
93
101
|
return () => cleanup();
|
|
@@ -105,10 +113,10 @@ export function CustomOngoingCallView({ sessionId, authToken, onCallEnded }: Pro
|
|
|
105
113
|
<video ref={remoteVideoRef} autoPlay playsInline className="remote-tile" />
|
|
106
114
|
<video ref={localVideoRef} autoPlay playsInline muted className="local-tile" />
|
|
107
115
|
<ControlPanel
|
|
108
|
-
onMute={() => CometChatCalls.muteAudio(
|
|
109
|
-
onUnmute={() => CometChatCalls.
|
|
110
|
-
onCameraOff={() => CometChatCalls.pauseVideo(
|
|
111
|
-
onCameraOn={() => CometChatCalls.
|
|
116
|
+
onMute={() => CometChatCalls.muteAudio()}
|
|
117
|
+
onUnmute={() => CometChatCalls.unmuteAudio()}
|
|
118
|
+
onCameraOff={() => CometChatCalls.pauseVideo()}
|
|
119
|
+
onCameraOn={() => CometChatCalls.resumeVideo()}
|
|
112
120
|
onSwitchCamera={() => CometChatCalls.switchCamera()}
|
|
113
121
|
onEnd={() => {
|
|
114
122
|
CometChatCalls.leaveSession();
|
|
@@ -151,7 +159,45 @@ function ControlPanel(props: {
|
|
|
151
159
|
}
|
|
152
160
|
```
|
|
153
161
|
|
|
154
|
-
The SDK methods (`muteAudio`, `pauseVideo`, `switchCamera`) propagate to all participants via the SDK's signaling — you don't manage track state yourself.
|
|
162
|
+
The SDK methods (`muteAudio`/`unmuteAudio`, `pauseVideo`/`resumeVideo`, `switchCamera`) propagate to all participants via the SDK's signaling — you don't manage track state yourself.
|
|
163
|
+
|
|
164
|
+
> ⚠️ **These are no-argument methods.** `muteAudio(): void` / `pauseVideo(): void` — there is NO boolean parameter. `CometChatCalls.muteAudio(false)` does **not** unmute (the arg is ignored — it still mutes). Use the explicit pair: `muteAudio()` / `unmuteAudio()` and `pauseVideo()` / `resumeVideo()`. (There is **no** `toggleAudio()` / `toggleVideo()` in the v5 SDK — track the muted/paused state yourself and call the matching method of the pair.)
|
|
165
|
+
|
|
166
|
+
> ⚠️ **Optimistic local state desyncs.** A control panel that only flips its own `useState` on click (as the example above does) will show a stale label whenever mute/camera/screen-share change from *outside* your bar — a join-muted call (`startAudioMuted`), the browser's own "Stop sharing" button, or another surface. Reconcile by subscribing to the SDK's media events and driving state from them: `onAudioMuted` / `onAudioUnMuted` / `onVideoPaused` / `onVideoResumed` / `onScreenShareStarted` / `onScreenShareStopped` / `onRecordingStarted` / `onRecordingStopped`. Seed the initial state from your join options so the first render is correct too.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Two custom-panel models — and the `hideHeaderPanel` footgun
|
|
171
|
+
|
|
172
|
+
There are **two** ways to put your own controls on a call, and they are very different:
|
|
173
|
+
|
|
174
|
+
**Model A — fully custom (`enableDefaultLayout(false)`).** The SDK draws nothing; you render every tile, every button, the whole surface. That's the path above. It leans on **two deprecated V5 APIs** — `startSession` (the only consumer of builder-produced `CallSettings`) and the `CometChatCalls.OngoingCallListener` accessor (the SDK marks it `@deprecated → use addEventListener`) — because `enableDefaultLayout(false)` exists only on the builder and has no `SessionSettings`-object equivalent. Use it only when you truly must render your own video tiles, and accept owning a11y, recording/screen-share plumbing, and the eventual migration off these shims. **For everything else, prefer Model B — it's 100% current V5 (`joinSession` + object + `addEventListener`).**
|
|
175
|
+
|
|
176
|
+
**Model B — hybrid (keep the SDK layout, replace only the bottom bar).** Far cheaper and far more common. You keep the SDK's default layout but pass `SessionSettings` flags to `joinSession` to hide just the control bar, then render your own bar over it:
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
const settings = {
|
|
180
|
+
sessionType: 'VIDEO',
|
|
181
|
+
layout: 'TILE',
|
|
182
|
+
hideControlPanel: true, // ← hide ONLY the bottom control bar; render your own
|
|
183
|
+
// hideHeaderPanel: true, // ← ⚠️ DO NOT add this unless you mean it (see below)
|
|
184
|
+
};
|
|
185
|
+
await CometChatCalls.joinSession(token, settings, container);
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
> ⚠️ **`hideHeaderPanel: true` silently disables Virtual Background, In-Call Chat, and the Participant List.** Those three features live in the SDK's **header** panel, not the control bar. If you set `hideHeaderPanel: true` to "clean up" a custom-bar call, you remove them with no replacement — and there are **no plain `CometChatCalls` static methods** to rebuild VB or in-call chat in your own bar (VB is exposed only as call-session instance methods / action constants like `setBackgroundBlur`, not statics). So a custom *control* bar should hide only `hideControlPanel`; leave `hideHeaderPanel` false so VB / chat / participant-list stay reachable. Real customer bug, 2026-06: ticking a "custom control panel" option flipped both flags and made VB + chat vanish.
|
|
189
|
+
|
|
190
|
+
If you genuinely don't want the header either, you're back in Model A territory — own those features yourself.
|
|
191
|
+
|
|
192
|
+
### Participant count from a custom bar
|
|
193
|
+
|
|
194
|
+
Don't derive the roster from `onParticipantJoined` / `onParticipantLeft` increments — those fire only for participants who join/leave **after** you, so a counter seeded at 0 (or 1) **undercounts when you join a call already in progress**. Subscribe to the authoritative full-list event instead:
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
CometChatCalls.addEventListener('onParticipantListChanged', (list) =>
|
|
198
|
+
setParticipants(Math.max(1, list.length)), // list includes the local user
|
|
199
|
+
);
|
|
200
|
+
```
|
|
155
201
|
|
|
156
202
|
---
|
|
157
203
|
|
|
@@ -185,7 +231,7 @@ Once `startSession` runs, the SDK takes over the camera/mic — release your pre
|
|
|
185
231
|
|
|
186
232
|
The Calls SDK is layout-agnostic when `enableDefaultLayout(false)`. You compose remote tiles in any CSS layout:
|
|
187
233
|
|
|
188
|
-
- **Spotlight** — one large remote tile + small thumbnails for others. Track
|
|
234
|
+
- **Spotlight** — one large remote tile + small thumbnails for others. Track who's speaking via the `onDominantSpeakerChanged` event (NOT `onActiveSpeakerUpdated` — that name doesn't exist) and swap the spotlight.
|
|
189
235
|
- **Grid** — CSS grid with auto-fit columns, 1-N participant tiles equally sized.
|
|
190
236
|
- **Picture-in-picture** — small floating remote video that survives navigation. Mount it in a portal at the layout root (similar to `<CometChatIncomingCall />`).
|
|
191
237
|
|