@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
|
@@ -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
|
|
|
@@ -12,32 +12,35 @@ Camera / mic / speaker enumeration + switching mid-call. SDK exposes `getAudioIn
|
|
|
12
12
|
```ts
|
|
13
13
|
import { CometChatCalls } from "@cometchat/calls-sdk-javascript";
|
|
14
14
|
|
|
15
|
-
// Enumerate
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
const
|
|
15
|
+
// Enumerate — these getters are SYNCHRONOUS (they return arrays, not promises;
|
|
16
|
+
// do NOT `await` them).
|
|
17
|
+
const mics = CometChatCalls.getAudioInputDevices();
|
|
18
|
+
const speakers = CometChatCalls.getAudioOutputDevices();
|
|
19
|
+
const cameras = CometChatCalls.getVideoInputDevices();
|
|
19
20
|
|
|
20
21
|
// Currently selected
|
|
21
22
|
const currentMic = CometChatCalls.getCurrentAudioInputDevice();
|
|
22
23
|
|
|
23
|
-
// Switch (mid-call OK)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
// Switch (mid-call OK) — also synchronous, return void.
|
|
25
|
+
CometChatCalls.setAudioInputDevice(deviceId);
|
|
26
|
+
CometChatCalls.setAudioOutputDevice(deviceId);
|
|
27
|
+
CometChatCalls.setVideoInputDevice(deviceId);
|
|
27
28
|
|
|
28
|
-
// Listen for device changes (user plugs in headphones, etc.)
|
|
29
|
-
|
|
29
|
+
// Listen for device changes (user plugs in headphones, etc.). The valid event
|
|
30
|
+
// keys are onAudioInputDevicesChanged / onAudioOutputDevicesChanged /
|
|
31
|
+
// onVideoInputDevicesChanged (there is NO "onAudioModesUpdated"). addEventListener
|
|
32
|
+
// returns an unsubscribe function — there is no removeEventListener.
|
|
33
|
+
const off = CometChatCalls.addEventListener("onAudioInputDevicesChanged", (devices) => {
|
|
30
34
|
// re-enumerate; show toast "AirPods connected"
|
|
31
35
|
});
|
|
36
|
+
// later: off();
|
|
32
37
|
```
|
|
33
38
|
|
|
34
|
-
Each device
|
|
39
|
+
Each device is a standard `MediaDeviceInfo` (the SDK types are `AudioInputDevice = MediaDeviceInfo & { kind: 'audioinput' }`, etc.). The fields you use:
|
|
35
40
|
```ts
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// ... other fields per browser
|
|
40
|
-
}
|
|
41
|
+
// deviceId: string ← the ID you pass to setAudioInputDevice() (NOT `id`)
|
|
42
|
+
// label: string ← "Built-in Microphone" / "AirPods Pro" (empty until mic permission granted)
|
|
43
|
+
// kind: 'audioinput' | 'videoinput' | 'audiooutput'
|
|
41
44
|
```
|
|
42
45
|
|
|
43
46
|
---
|
|
@@ -48,12 +51,11 @@ interface MediaDevice {
|
|
|
48
51
|
import { useEffect, useState } from "react";
|
|
49
52
|
import { CometChatCalls } from "@cometchat/calls-sdk-javascript";
|
|
50
53
|
|
|
51
|
-
interface MediaDevice { id: string; label: string; }
|
|
52
|
-
|
|
53
54
|
function DevicePicker({ onConfirm }: { onConfirm: () => void }) {
|
|
54
|
-
|
|
55
|
-
const [
|
|
56
|
-
const [
|
|
55
|
+
// Devices are MediaDeviceInfo objects — use `deviceId`, NOT `id`.
|
|
56
|
+
const [mics, setMics] = useState<MediaDeviceInfo[]>([]);
|
|
57
|
+
const [cameras, setCameras] = useState<MediaDeviceInfo[]>([]);
|
|
58
|
+
const [speakers, setSpeakers] = useState<MediaDeviceInfo[]>([]);
|
|
57
59
|
const [selectedMic, setSelectedMic] = useState<string>();
|
|
58
60
|
const [selectedCamera, setSelectedCamera] = useState<string>();
|
|
59
61
|
const [selectedSpeaker, setSelectedSpeaker] = useState<string>();
|
|
@@ -67,24 +69,24 @@ function DevicePicker({ onConfirm }: { onConfirm: () => void }) {
|
|
|
67
69
|
// permission denied — labels will be empty; offer settings link
|
|
68
70
|
}
|
|
69
71
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
]);
|
|
72
|
+
// These getters are SYNCHRONOUS — no await / Promise.all needed.
|
|
73
|
+
const m = CometChatCalls.getAudioInputDevices();
|
|
74
|
+
const c = CometChatCalls.getVideoInputDevices();
|
|
75
|
+
const s = CometChatCalls.getAudioOutputDevices();
|
|
75
76
|
setMics(m); setCameras(c); setSpeakers(s);
|
|
76
77
|
|
|
77
|
-
setSelectedMic(CometChatCalls.getCurrentAudioInputDevice()?.
|
|
78
|
-
setSelectedCamera(CometChatCalls.getCurrentVideoInputDevice()?.
|
|
79
|
-
setSelectedSpeaker(CometChatCalls.getCurrentAudioOutputDevice()?.
|
|
78
|
+
setSelectedMic(CometChatCalls.getCurrentAudioInputDevice()?.deviceId ?? m[0]?.deviceId);
|
|
79
|
+
setSelectedCamera(CometChatCalls.getCurrentVideoInputDevice()?.deviceId ?? c[0]?.deviceId);
|
|
80
|
+
setSelectedSpeaker(CometChatCalls.getCurrentAudioOutputDevice()?.deviceId ?? s[0]?.deviceId);
|
|
80
81
|
}
|
|
81
82
|
load();
|
|
82
83
|
}, []);
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (
|
|
87
|
-
if (
|
|
85
|
+
function confirm() {
|
|
86
|
+
// setters are synchronous, return void
|
|
87
|
+
if (selectedMic) CometChatCalls.setAudioInputDevice(selectedMic);
|
|
88
|
+
if (selectedCamera) CometChatCalls.setVideoInputDevice(selectedCamera);
|
|
89
|
+
if (selectedSpeaker) CometChatCalls.setAudioOutputDevice(selectedSpeaker);
|
|
88
90
|
onConfirm();
|
|
89
91
|
}
|
|
90
92
|
|
|
@@ -93,19 +95,19 @@ function DevicePicker({ onConfirm }: { onConfirm: () => void }) {
|
|
|
93
95
|
<label>
|
|
94
96
|
Microphone
|
|
95
97
|
<select value={selectedMic} onChange={(e) => setSelectedMic(e.target.value)}>
|
|
96
|
-
{mics.map(d => <option key={d.
|
|
98
|
+
{mics.map(d => <option key={d.deviceId} value={d.deviceId}>{d.label || `Mic ${d.deviceId.slice(0, 6)}`}</option>)}
|
|
97
99
|
</select>
|
|
98
100
|
</label>
|
|
99
101
|
<label>
|
|
100
102
|
Camera
|
|
101
103
|
<select value={selectedCamera} onChange={(e) => setSelectedCamera(e.target.value)}>
|
|
102
|
-
{cameras.map(d => <option key={d.
|
|
104
|
+
{cameras.map(d => <option key={d.deviceId} value={d.deviceId}>{d.label || `Camera ${d.deviceId.slice(0, 6)}`}</option>)}
|
|
103
105
|
</select>
|
|
104
106
|
</label>
|
|
105
107
|
<label>
|
|
106
108
|
Speaker
|
|
107
109
|
<select value={selectedSpeaker} onChange={(e) => setSelectedSpeaker(e.target.value)}>
|
|
108
|
-
{speakers.map(d => <option key={d.
|
|
110
|
+
{speakers.map(d => <option key={d.deviceId} value={d.deviceId}>{d.label || `Speaker ${d.deviceId.slice(0, 6)}`}</option>)}
|
|
109
111
|
</select>
|
|
110
112
|
</label>
|
|
111
113
|
<button type="button" onClick={confirm}>Join call</button>
|
|
@@ -123,21 +125,23 @@ function DevicePicker({ onConfirm }: { onConfirm: () => void }) {
|
|
|
123
125
|
```tsx
|
|
124
126
|
function InCallDeviceSettings() {
|
|
125
127
|
const [showMenu, setShowMenu] = useState(false);
|
|
126
|
-
const [mics, setMics] = useState<
|
|
128
|
+
const [mics, setMics] = useState<MediaDeviceInfo[]>([]);
|
|
127
129
|
|
|
128
130
|
useEffect(() => {
|
|
129
131
|
if (!showMenu) return;
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
CometChatCalls.addEventListener("
|
|
136
|
-
|
|
132
|
+
// getAudioInputDevices() is synchronous — returns an array, no .then().
|
|
133
|
+
setMics(CometChatCalls.getAudioInputDevices());
|
|
134
|
+
|
|
135
|
+
// addEventListener returns an unsubscribe fn — call it to clean up
|
|
136
|
+
// (there is no removeEventListener on the SDK).
|
|
137
|
+
const off = CometChatCalls.addEventListener("onAudioInputDevicesChanged", () => {
|
|
138
|
+
setMics(CometChatCalls.getAudioInputDevices());
|
|
139
|
+
});
|
|
140
|
+
return () => off();
|
|
137
141
|
}, [showMenu]);
|
|
138
142
|
|
|
139
|
-
|
|
140
|
-
|
|
143
|
+
function selectMic(id: string) {
|
|
144
|
+
CometChatCalls.setAudioInputDevice(id); // synchronous, returns void
|
|
141
145
|
setShowMenu(false);
|
|
142
146
|
}
|
|
143
147
|
|
|
@@ -147,8 +151,8 @@ function InCallDeviceSettings() {
|
|
|
147
151
|
{showMenu && (
|
|
148
152
|
<ul role="menu">
|
|
149
153
|
{mics.map(d => (
|
|
150
|
-
<li key={d.
|
|
151
|
-
<button role="menuitem" onClick={() => selectMic(d.
|
|
154
|
+
<li key={d.deviceId}>
|
|
155
|
+
<button role="menuitem" onClick={() => selectMic(d.deviceId)}>{d.label}</button>
|
|
152
156
|
</li>
|
|
153
157
|
))}
|
|
154
158
|
</ul>
|
|
@@ -158,7 +162,7 @@ function InCallDeviceSettings() {
|
|
|
158
162
|
}
|
|
159
163
|
```
|
|
160
164
|
|
|
161
|
-
`
|
|
165
|
+
`onAudioInputDevicesChanged` (and `onAudioOutputDevicesChanged` / `onVideoInputDevicesChanged`) fire when the user plugs in headphones, AirPods connect, etc. Re-enumerate on the event.
|
|
162
166
|
|
|
163
167
|
---
|
|
164
168
|
|
|
@@ -179,7 +183,7 @@ if (safari) {
|
|
|
179
183
|
## Anti-patterns
|
|
180
184
|
|
|
181
185
|
1. **Calling `getAudioInputDevices` before requesting permission.** Returns devices with empty `label` strings — UI shows "undefined" or empty entries.
|
|
182
|
-
2. **Caching device list.** Devices change (plug/unplug). Re-enumerate on every menu open AND on `
|
|
186
|
+
2. **Caching device list.** Devices change (plug/unplug). Re-enumerate on every menu open AND on `onAudioInputDevicesChanged`.
|
|
183
187
|
3. **Hardcoding the first device as default.** Browsers may sort differently (built-in vs USB). Read `getCurrent*Device` first; only fall back to first if no current selection.
|
|
184
188
|
4. **Switching speakers in Safari.** `setAudioOutputDevice` silently fails. Detect Safari and hide the speaker picker (or show a "iOS uses system routing" tooltip).
|
|
185
189
|
5. **No listener cleanup on unmount.** Event accumulates listeners on remount; spam every device change.
|
|
@@ -190,7 +194,7 @@ if (safari) {
|
|
|
190
194
|
|
|
191
195
|
- [ ] Permission requested before enumeration (empty-label fix)
|
|
192
196
|
- [ ] `getCurrent*Device()` used as default in pickers
|
|
193
|
-
- [ ] `
|
|
197
|
+
- [ ] `onAudioInputDevicesChanged` listener for hot-swap detection (unsubscribe via the returned fn)
|
|
194
198
|
- [ ] Listener cleanup on unmount
|
|
195
199
|
- [ ] Safari speaker picker hidden / fallback message
|
|
196
200
|
- [ ] Browser smoke: plug/unplug headphones during call, picker updates
|
|
@@ -106,19 +106,17 @@ async function startGroupCall(guid: string, callType: "audio" | "video") {
|
|
|
106
106
|
const authToken = loggedInUser.getAuthToken();
|
|
107
107
|
const { token: callToken } = await CometChatCalls.generateToken(sessionId);
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
)
|
|
118
|
-
.build();
|
|
109
|
+
// joinSession takes a SessionSettings OBJECT (NOT CallSettingsBuilder.build() —
|
|
110
|
+
// that CallSettings is for the deprecated startSession). Events come from the
|
|
111
|
+
// static addEventListener bus, not OngoingCallListener.
|
|
112
|
+
const settings = { sessionType: callType === "audio" ? "VOICE" : "VIDEO" };
|
|
113
|
+
const offClosed = CometChatCalls.addEventListener("onConnectionClosed", () => {
|
|
114
|
+
/* hangup UI */
|
|
115
|
+
});
|
|
116
|
+
// later, on teardown: offClosed();
|
|
119
117
|
|
|
120
118
|
// 3. Mount the WebRTC view into your container element
|
|
121
|
-
await CometChatCalls.joinSession(callToken,
|
|
119
|
+
await CometChatCalls.joinSession(callToken, settings, containerElement);
|
|
122
120
|
}
|
|
123
121
|
```
|
|
124
122
|
|
|
@@ -182,17 +180,14 @@ async function joinGroupCall(sessionId: string, callType: "audio" | "video", con
|
|
|
182
180
|
const authToken = loggedInUser!.getAuthToken();
|
|
183
181
|
const { token: callToken } = await CometChatCalls.generateToken(sessionId);
|
|
184
182
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
.build();
|
|
194
|
-
|
|
195
|
-
await CometChatCalls.joinSession(callToken, callSettings, container);
|
|
183
|
+
// SessionSettings OBJECT for joinSession (not CallSettingsBuilder output).
|
|
184
|
+
const settings = { sessionType: callType === "audio" ? "VOICE" : "VIDEO" };
|
|
185
|
+
const offClosed = CometChatCalls.addEventListener("onConnectionClosed", () => {
|
|
186
|
+
/* hangup UI */
|
|
187
|
+
});
|
|
188
|
+
// later, on teardown: offClosed();
|
|
189
|
+
|
|
190
|
+
await CometChatCalls.joinSession(callToken, settings, container);
|
|
196
191
|
}
|
|
197
192
|
```
|
|
198
193
|
|
|
@@ -259,4 +254,4 @@ Since meetings don't ring, there's no "missed call" entity. If you want missed-m
|
|
|
259
254
|
- `call-session.md` — pure session-mode (URL-based, no chat-side signaling at all)
|
|
260
255
|
- `cometchat-react-calls/SKILL.md` rule 1.7 — IncomingCall mount (1:1 only; group calls don't use this)
|
|
261
256
|
- Canonical docs: https://www.cometchat.com/docs/calls/javascript/group-calls
|
|
262
|
-
- Kit source (
|
|
257
|
+
- Kit source (web React): `@cometchat/chat-uikit-react` → `src/components/Calling/CometChatCallButtons/CometChatCallButtons.tsx` (group call buttons send the `meeting` custom message)
|
|
@@ -9,22 +9,34 @@ Auto-ends calls where the local user is the only remaining participant. Two time
|
|
|
9
9
|
|
|
10
10
|
## SDK API
|
|
11
11
|
|
|
12
|
+
> ⚠️ **VALUES ARE IN MILLISECONDS.** `idleTimeoutPeriodBeforePrompt: 180` is **180 ms**, not 180 seconds — so the prompt fires the instant you join alone and the call exits in a fraction of a second (real customer bug, 2026-06). Always `* 1000`: 3 minutes = `180_000`.
|
|
13
|
+
|
|
14
|
+
Two equivalent ways to set it — **match whichever your join path uses:**
|
|
15
|
+
|
|
12
16
|
```ts
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
// (a) SessionSettings OBJECT — the session-mode path: joinSession(token, settings, container)
|
|
18
|
+
const settings = {
|
|
19
|
+
idleTimeoutPeriodBeforePrompt: 180_000, // 180s before the "still there?" prompt
|
|
20
|
+
idleTimeoutPeriodAfterPrompt: 60_000, // 60s grace (this is the SDK MINIMUM)
|
|
21
|
+
};
|
|
22
|
+
await CometChatCalls.joinSession(token, settings, containerRef.current);
|
|
23
|
+
|
|
24
|
+
// (b) Builder — the kit's callSettingsBuilder prop. ⚠️ The builder has ONLY a
|
|
25
|
+
// single .setIdleTimeoutPeriod(ms) — there are NO setIdleTimeoutPeriodBeforePrompt /
|
|
26
|
+
// setIdleTimeoutPeriodAfterPrompt builder methods. The before/after-prompt SPLIT
|
|
27
|
+
// exists only as the SessionSettings object fields in form (a) above.
|
|
28
|
+
const builder = new CometChatCalls.CallSettingsBuilder()
|
|
29
|
+
.setIdleTimeoutPeriod(180_000);
|
|
18
30
|
|
|
19
31
|
CometChatCalls.addEventListener("onSessionTimedOut", () => {
|
|
20
32
|
// Navigate away, show "session ended" UI
|
|
21
33
|
});
|
|
22
34
|
```
|
|
23
35
|
|
|
24
|
-
| Setting | Default | Min |
|
|
36
|
+
| Setting | Default | Min | Unit |
|
|
25
37
|
|---|---|---|---|
|
|
26
|
-
| `idleTimeoutPeriodBeforePrompt` | 60_000 (60s) |
|
|
27
|
-
| `idleTimeoutPeriodAfterPrompt` | 120_000 (120s) | 60_000 (60s)
|
|
38
|
+
| `idleTimeoutPeriodBeforePrompt` | 60_000 (60s) | — (don't use 0 / tiny — instant prompt) | **milliseconds** |
|
|
39
|
+
| `idleTimeoutPeriodAfterPrompt` | 120_000 (120s) | **60_000 (60s)** — smaller is silently clamped to 60s | **milliseconds** |
|
|
28
40
|
|
|
29
41
|
The SDK shows the prompt overlay automatically (kit's default UI). For custom UI you handle the prompt yourself.
|
|
30
42
|
|
|
@@ -132,10 +144,11 @@ function CustomCallView() {
|
|
|
132
144
|
### Pattern B — Long timeouts + custom prompt only
|
|
133
145
|
|
|
134
146
|
```ts
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
147
|
+
// SessionSettings object for joinSession (these before/after fields are object-only).
|
|
148
|
+
const settings = {
|
|
149
|
+
idleTimeoutPeriodBeforePrompt: 86_400_000, // 24 hours — effectively disabled
|
|
150
|
+
idleTimeoutPeriodAfterPrompt: 86_400_000,
|
|
151
|
+
};
|
|
139
152
|
```
|
|
140
153
|
|
|
141
154
|
Then implement your own timeout via Pattern A. Useful when you want UX-customized prompts instead of the SDK's default overlay.
|
|
@@ -10,10 +10,9 @@ Text messaging during a video/voice call. SDK provides the chat button in the co
|
|
|
10
10
|
## SDK API
|
|
11
11
|
|
|
12
12
|
```ts
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
.build();
|
|
13
|
+
// SessionSettings object passed to joinSession(token, settings, container).
|
|
14
|
+
// hideChatButton is a SessionSettings field, not a CallSettingsBuilder method.
|
|
15
|
+
const settings = { hideChatButton: false }; // show the kit's built-in chat button
|
|
17
16
|
|
|
18
17
|
CometChatCalls.addEventListener("onChatButtonClicked", () => {
|
|
19
18
|
// Open your chat panel
|
|
@@ -56,7 +55,7 @@ async function joinCallGroup(sessionId: string): Promise<void> {
|
|
|
56
55
|
}
|
|
57
56
|
```
|
|
58
57
|
|
|
59
|
-
Wire this into your call-start flow: after `
|
|
58
|
+
Wire this into your call-start flow: after `joinSession` succeeds, `joinCallGroup`.
|
|
60
59
|
|
|
61
60
|
---
|
|
62
61
|
|
|
@@ -83,8 +82,9 @@ function InCallChatPanel({ sessionId }: InCallChatPanelProps) {
|
|
|
83
82
|
// Listen for the SDK's button click
|
|
84
83
|
useEffect(() => {
|
|
85
84
|
const handler = () => setOpen(true);
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
// addEventListener returns an unsubscribe fn — there is no removeEventListener.
|
|
86
|
+
const off = CometChatCalls.addEventListener("onChatButtonClicked", handler);
|
|
87
|
+
return () => off();
|
|
88
88
|
}, []);
|
|
89
89
|
|
|
90
90
|
// Resolve the group object for the message list
|
|
@@ -35,8 +35,8 @@ If you're using CometChat UI Kits, this is enough — the kit's calls integratio
|
|
|
35
35
|
v5 introduces a dedicated Calls SDK auth step. After the user logs into the Chat SDK, call:
|
|
36
36
|
|
|
37
37
|
```ts
|
|
38
|
-
const authToken = (await CometChat.
|
|
39
|
-
await CometChatCalls.
|
|
38
|
+
const authToken = (await CometChat.getLoggedInUser())!.getAuthToken();
|
|
39
|
+
await CometChatCalls.loginWithAuthToken(authToken); // login() takes a uid; use loginWithAuthToken for a token
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
After this, `generateToken()` and `joinSession()` no longer need an authToken parameter.
|
|
@@ -120,11 +120,10 @@ After this, `generateToken()` and `joinSession()` no longer need an authToken pa
|
|
|
120
120
|
|
|
121
121
|
- CometChatCalls.startScreenShare()
|
|
122
122
|
+ CometChatCalls.startScreenSharing()
|
|
123
|
-
|
|
124
|
-
- CometChatCalls.enterPIPMode()
|
|
125
|
-
+ CometChatCalls.enablePictureInPictureLayout()
|
|
126
123
|
```
|
|
127
124
|
|
|
125
|
+
> PiP rename: v4's `enterPIPMode()` became the static `CometChatCalls.enablePictureInPictureLayout()` in v5 (paired with `disablePictureInPictureLayout()`). Note the `onPictureInPictureLayoutEnabled` / `...Disabled` **callbacks are on `MobileSDKEvents`, not `WebSDKEvents`** — they are NOT subscribable via `CometChatCalls.addEventListener` on the web SDK (verified in `@cometchat/calls-sdk-javascript` `index.d.ts`: `MobileSDKEvents` vs `WebSDKEvents`). On **web**, prefer browser-native picture-in-picture — see `references/picture-in-picture.md`.
|
|
126
|
+
|
|
128
127
|
---
|
|
129
128
|
|
|
130
129
|
## Step 7 — `startSession` → `joinSession`
|
|
@@ -134,14 +133,13 @@ After this, `generateToken()` and `joinSession()` no longer need an authToken pa
|
|
|
134
133
|
- CometChatCalls.startSession(token, callSettings, container);
|
|
135
134
|
- });
|
|
136
135
|
|
|
137
|
-
+ CometChatCalls.generateToken(sessionId).then((token) => {
|
|
136
|
+
+ CometChatCalls.generateToken(sessionId).then(({ token }) => {
|
|
138
137
|
+ CometChatCalls.joinSession(token, sessionSettings, container);
|
|
139
138
|
+ });
|
|
140
|
-
+
|
|
141
|
-
+ // Or — pass the sessionId directly (no manual token mint):
|
|
142
|
-
+ CometChatCalls.joinSession(sessionId, sessionSettings, container);
|
|
143
139
|
```
|
|
144
140
|
|
|
141
|
+
> `joinSession`'s first arg is the **callToken** (from `generateToken`), not a sessionId — there is no token-free join. `generateToken` resolves to `{ token }`, so destructure it.
|
|
142
|
+
|
|
145
143
|
---
|
|
146
144
|
|
|
147
145
|
## Removed methods (no v5 replacement)
|
|
@@ -154,7 +152,7 @@ After this, `generateToken()` and `joinSession()` no longer need an authToken pa
|
|
|
154
152
|
## Verification checklist
|
|
155
153
|
|
|
156
154
|
- [ ] `package.json` lists `@cometchat/calls-sdk-javascript@^5`
|
|
157
|
-
- [ ] `await CometChatCalls.
|
|
155
|
+
- [ ] `await CometChatCalls.loginWithAuthToken(authToken)` called after `CometChat.login`
|
|
158
156
|
- [ ] `OngoingCallListener` removed; granular `addEventListener` calls in place with cleanup
|
|
159
157
|
- [ ] `startSession` replaced with `joinSession`
|
|
160
158
|
- [ ] `endSession` replaced with `leaveSession`
|
|
@@ -169,4 +167,4 @@ After this, `generateToken()` and `joinSession()` no longer need an authToken pa
|
|
|
169
167
|
- Canonical migration guide: https://www.cometchat.com/docs/calls/javascript/migration-guide-v5
|
|
170
168
|
- `cometchat-react-calls/SKILL.md` — current architecture (v5)
|
|
171
169
|
- `cometchat-react-calls/references/call-layouts.md` — layout enum migration
|
|
172
|
-
- `cometchat-react-calls/references/recording.md` — recording events migration
|
|
170
|
+
- `cometchat-react-calls/references/recording-screen-share.md` — recording events migration
|