@cometchat/skills 4.1.0 → 4.2.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/bin/install.js +298 -41
- package/package.json +1 -1
- package/skills/cometchat/SKILL.md +146 -27
- package/skills/cometchat-a11y/SKILL.md +476 -0
- package/skills/cometchat-android-v5/SKILL.md +1 -1
- package/skills/cometchat-android-v5-calls/SKILL.md +413 -0
- package/skills/cometchat-android-v5-calls/references/README.md +53 -0
- package/skills/cometchat-android-v5-calls/references/add-calls-to-existing-chat.md +195 -0
- package/skills/cometchat-android-v5-calls/references/audio-controls.md +91 -0
- package/skills/cometchat-android-v5-calls/references/background-handling.md +168 -0
- package/skills/cometchat-android-v5-calls/references/call-layouts.md +123 -0
- package/skills/cometchat-android-v5-calls/references/call-logs.md +113 -0
- package/skills/cometchat-android-v5-calls/references/call-session.md +274 -0
- package/skills/cometchat-android-v5-calls/references/custom-ui.md +150 -0
- package/skills/cometchat-android-v5-calls/references/event-listeners.md +123 -0
- package/skills/cometchat-android-v5-calls/references/group-calls.md +205 -0
- package/skills/cometchat-android-v5-calls/references/idle-timeout.md +111 -0
- package/skills/cometchat-android-v5-calls/references/in-call-chat.md +134 -0
- package/skills/cometchat-android-v5-calls/references/join-session.md +120 -0
- package/skills/cometchat-android-v5-calls/references/migration-v4-to-v5.md +206 -0
- package/skills/cometchat-android-v5-calls/references/participant-management.md +110 -0
- package/skills/cometchat-android-v5-calls/references/picture-in-picture.md +106 -0
- package/skills/cometchat-android-v5-calls/references/raise-hand.md +242 -0
- package/skills/cometchat-android-v5-calls/references/recording.md +101 -0
- package/skills/cometchat-android-v5-calls/references/ringing-integration.md +152 -0
- package/skills/cometchat-android-v5-calls/references/screen-sharing.md +82 -0
- package/skills/cometchat-android-v5-calls/references/server-fcm-voip.md +215 -0
- package/skills/cometchat-android-v5-calls/references/session-settings.md +121 -0
- package/skills/cometchat-android-v5-calls/references/setup.md +137 -0
- package/skills/cometchat-android-v5-calls/references/share-invite.md +151 -0
- package/skills/cometchat-android-v5-calls/references/video-controls.md +87 -0
- package/skills/cometchat-android-v5-calls/references/voip-calling.md +526 -0
- package/skills/cometchat-android-v5-components/SKILL.md +1 -1
- package/skills/cometchat-android-v5-core/SKILL.md +1 -1
- package/skills/cometchat-android-v5-customization/SKILL.md +1 -1
- package/skills/cometchat-android-v5-extensions/SKILL.md +1 -1
- package/skills/cometchat-android-v5-features/SKILL.md +1 -1
- package/skills/cometchat-android-v5-placement/SKILL.md +1 -1
- package/skills/cometchat-android-v5-production/SKILL.md +1 -1
- package/skills/cometchat-android-v5-push/SKILL.md +1 -1
- package/skills/cometchat-android-v5-testing/SKILL.md +1 -1
- package/skills/cometchat-android-v5-theming/SKILL.md +1 -1
- package/skills/cometchat-android-v5-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-android-v6/SKILL.md +1 -1
- package/skills/cometchat-android-v6-builder-settings/SKILL.md +1 -1
- package/skills/cometchat-android-v6-calls/SKILL.md +375 -0
- package/skills/cometchat-android-v6-calls/references/add-calls-to-existing-chat.md +97 -0
- package/skills/cometchat-android-v6-calls/references/call-layouts.md +91 -0
- package/skills/cometchat-android-v6-calls/references/call-session.md +163 -0
- package/skills/cometchat-android-v6-calls/references/device-management.md +171 -0
- package/skills/cometchat-android-v6-calls/references/group-calls.md +191 -0
- package/skills/cometchat-android-v6-calls/references/idle-timeout.md +107 -0
- package/skills/cometchat-android-v6-calls/references/in-call-chat.md +136 -0
- package/skills/cometchat-android-v6-calls/references/raise-hand.md +186 -0
- package/skills/cometchat-android-v6-calls/references/ringing-integration.md +176 -0
- package/skills/cometchat-android-v6-calls/references/server-fcm-voip.md +127 -0
- package/skills/cometchat-android-v6-calls/references/share-invite.md +105 -0
- package/skills/cometchat-android-v6-compose-components/SKILL.md +2 -2
- package/skills/cometchat-android-v6-compose-customization/SKILL.md +1 -1
- package/skills/cometchat-android-v6-compose-placement/SKILL.md +1 -1
- package/skills/cometchat-android-v6-compose-theming/SKILL.md +1 -1
- package/skills/cometchat-android-v6-core/SKILL.md +1 -1
- package/skills/cometchat-android-v6-events/SKILL.md +1 -1
- package/skills/cometchat-android-v6-extensions/SKILL.md +1 -1
- package/skills/cometchat-android-v6-features/SKILL.md +1 -1
- package/skills/cometchat-android-v6-kotlin-components/SKILL.md +1 -1
- package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +1 -1
- package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +1 -1
- package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +1 -1
- package/skills/cometchat-android-v6-migration/SKILL.md +398 -0
- package/skills/cometchat-android-v6-production/SKILL.md +1 -1
- package/skills/cometchat-android-v6-push/SKILL.md +1 -1
- package/skills/cometchat-android-v6-testing/SKILL.md +1 -1
- package/skills/cometchat-android-v6-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-angular-calls/SKILL.md +511 -0
- package/skills/cometchat-angular-calls/references/add-calls-to-existing-chat.md +95 -0
- package/skills/cometchat-angular-calls/references/call-layouts.md +106 -0
- package/skills/cometchat-angular-calls/references/call-session.md +167 -0
- package/skills/cometchat-angular-calls/references/custom-ui.md +231 -0
- package/skills/cometchat-angular-calls/references/device-management.md +135 -0
- package/skills/cometchat-angular-calls/references/group-calls.md +412 -0
- package/skills/cometchat-angular-calls/references/idle-timeout.md +145 -0
- package/skills/cometchat-angular-calls/references/in-call-chat.md +148 -0
- package/skills/cometchat-angular-calls/references/lazy-loading-pitfalls.md +205 -0
- package/skills/cometchat-angular-calls/references/migration-v4-to-v5.md +53 -0
- package/skills/cometchat-angular-calls/references/ngzone-and-async-callbacks.md +183 -0
- package/skills/cometchat-angular-calls/references/picture-in-picture.md +285 -0
- package/skills/cometchat-angular-calls/references/raise-hand.md +167 -0
- package/skills/cometchat-angular-calls/references/recording-screen-share.md +267 -0
- package/skills/cometchat-angular-calls/references/ringing-integration.md +131 -0
- package/skills/cometchat-angular-calls/references/server-web-push-vapid.md +100 -0
- package/skills/cometchat-angular-calls/references/share-invite.md +116 -0
- package/skills/cometchat-angular-components/SKILL.md +1 -1
- package/skills/cometchat-angular-core/SKILL.md +1 -1
- package/skills/cometchat-angular-customization/SKILL.md +1 -1
- package/skills/cometchat-angular-features/SKILL.md +1 -1
- package/skills/cometchat-angular-patterns/SKILL.md +1 -1
- package/skills/cometchat-angular-placement/SKILL.md +1 -1
- package/skills/cometchat-angular-production/SKILL.md +1 -1
- package/skills/cometchat-angular-push/SKILL.md +403 -0
- package/skills/cometchat-angular-testing/SKILL.md +333 -0
- package/skills/cometchat-angular-theming/SKILL.md +1 -1
- package/skills/cometchat-angular-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-astro-patterns/SKILL.md +1 -1
- package/skills/cometchat-calls/SKILL.md +358 -0
- package/skills/cometchat-calls/references/use-case-broadcast.md +194 -0
- package/skills/cometchat-calls/references/use-case-marketplace.md +158 -0
- package/skills/cometchat-calls/references/use-case-support.md +190 -0
- package/skills/cometchat-calls/references/use-case-team.md +169 -0
- package/skills/cometchat-calls/references/use-case-telehealth.md +154 -0
- package/skills/cometchat-components/SKILL.md +1 -1
- package/skills/cometchat-core/SKILL.md +1 -1
- package/skills/cometchat-customization/SKILL.md +2 -2
- package/skills/cometchat-features/SKILL.md +2 -2
- package/skills/cometchat-flutter-v5/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-calls/SKILL.md +325 -94
- package/skills/cometchat-flutter-v5-calls/references/add-calls-to-existing-chat.md +169 -0
- package/skills/cometchat-flutter-v5-calls/references/call-layouts.md +98 -0
- package/skills/cometchat-flutter-v5-calls/references/call-session.md +330 -0
- package/skills/cometchat-flutter-v5-calls/references/device-management.md +120 -0
- package/skills/cometchat-flutter-v5-calls/references/group-calls.md +187 -0
- package/skills/cometchat-flutter-v5-calls/references/idle-timeout.md +97 -0
- package/skills/cometchat-flutter-v5-calls/references/in-call-chat.md +132 -0
- package/skills/cometchat-flutter-v5-calls/references/migration-v4-to-v5.md +160 -0
- package/skills/cometchat-flutter-v5-calls/references/raise-hand.md +244 -0
- package/skills/cometchat-flutter-v5-calls/references/ringing-integration.md +193 -0
- package/skills/cometchat-flutter-v5-calls/references/server-push-bridge.md +101 -0
- package/skills/cometchat-flutter-v5-calls/references/share-invite.md +142 -0
- package/skills/cometchat-flutter-v5-conversations/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-core/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-customization/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-events/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-messages/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-production/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-push/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-testing/SKILL.md +390 -0
- package/skills/cometchat-flutter-v5-theming/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-flutter-v5-users-groups/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-calls/SKILL.md +308 -243
- package/skills/cometchat-flutter-v6-calls/references/add-calls-to-existing-chat.md +134 -0
- package/skills/cometchat-flutter-v6-calls/references/call-layouts.md +102 -0
- package/skills/cometchat-flutter-v6-calls/references/call-session.md +229 -0
- package/skills/cometchat-flutter-v6-calls/references/device-management.md +99 -0
- package/skills/cometchat-flutter-v6-calls/references/group-calls.md +190 -0
- package/skills/cometchat-flutter-v6-calls/references/idle-timeout.md +80 -0
- package/skills/cometchat-flutter-v6-calls/references/in-call-chat.md +122 -0
- package/skills/cometchat-flutter-v6-calls/references/raise-hand.md +268 -0
- package/skills/cometchat-flutter-v6-calls/references/ringing-integration.md +171 -0
- package/skills/cometchat-flutter-v6-calls/references/server-push-bridge.md +93 -0
- package/skills/cometchat-flutter-v6-calls/references/share-invite.md +102 -0
- package/skills/cometchat-flutter-v6-components/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-conversations/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-core/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-customization/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-events/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-features/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-messages/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-migration/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-placement/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-production/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-push/SKILL.md +452 -0
- package/skills/cometchat-flutter-v6-testing/SKILL.md +319 -0
- package/skills/cometchat-flutter-v6-theming/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-users-groups/SKILL.md +1 -1
- package/skills/cometchat-i18n/SKILL.md +358 -0
- package/skills/cometchat-ios/SKILL.md +5 -5
- package/skills/cometchat-ios-calls/SKILL.md +409 -0
- package/skills/cometchat-ios-calls/references/add-calls-to-existing-chat.md +172 -0
- package/skills/cometchat-ios-calls/references/avaudiosession-routing.md +189 -0
- package/skills/cometchat-ios-calls/references/call-layouts.md +136 -0
- package/skills/cometchat-ios-calls/references/call-session.md +221 -0
- package/skills/cometchat-ios-calls/references/callkit-and-pushkit.md +353 -0
- package/skills/cometchat-ios-calls/references/custom-ui.md +322 -0
- package/skills/cometchat-ios-calls/references/device-management.md +171 -0
- package/skills/cometchat-ios-calls/references/group-calls.md +396 -0
- package/skills/cometchat-ios-calls/references/idle-timeout.md +185 -0
- package/skills/cometchat-ios-calls/references/in-call-chat.md +183 -0
- package/skills/cometchat-ios-calls/references/migration-v4-to-v5.md +138 -0
- package/skills/cometchat-ios-calls/references/picture-in-picture.md +246 -0
- package/skills/cometchat-ios-calls/references/raise-hand.md +239 -0
- package/skills/cometchat-ios-calls/references/recording-screen-share.md +339 -0
- package/skills/cometchat-ios-calls/references/ringing-integration.md +142 -0
- package/skills/cometchat-ios-calls/references/server-apns-pushkit.md +267 -0
- package/skills/cometchat-ios-calls/references/share-invite.md +152 -0
- package/skills/cometchat-ios-calls/references/swiftui-uikit-hosting.md +246 -0
- package/skills/cometchat-ios-calls/references/voip-cert-setup.md +166 -0
- package/skills/cometchat-ios-components/SKILL.md +1 -1
- package/skills/cometchat-ios-core/SKILL.md +1 -1
- package/skills/cometchat-ios-customization/SKILL.md +1 -1
- package/skills/cometchat-ios-features/SKILL.md +1 -1
- package/skills/cometchat-ios-placement/SKILL.md +1 -1
- package/skills/cometchat-ios-production/SKILL.md +1 -1
- package/skills/cometchat-ios-push/SKILL.md +1 -1
- package/skills/cometchat-ios-testing/SKILL.md +371 -0
- package/skills/cometchat-ios-theming/SKILL.md +1 -1
- package/skills/cometchat-ios-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-native-bare-patterns/SKILL.md +45 -3
- package/skills/cometchat-native-calls/SKILL.md +599 -0
- package/skills/cometchat-native-calls/references/add-calls-to-existing-chat.md +203 -0
- package/skills/cometchat-native-calls/references/call-layouts.md +124 -0
- package/skills/cometchat-native-calls/references/call-session.md +182 -0
- package/skills/cometchat-native-calls/references/custom-ui.md +250 -0
- package/skills/cometchat-native-calls/references/device-management.md +135 -0
- package/skills/cometchat-native-calls/references/expo-vs-bare.md +179 -0
- package/skills/cometchat-native-calls/references/group-calls.md +291 -0
- package/skills/cometchat-native-calls/references/idle-timeout.md +128 -0
- package/skills/cometchat-native-calls/references/in-call-chat.md +143 -0
- package/skills/cometchat-native-calls/references/migration-v4-to-v5.md +72 -0
- package/skills/cometchat-native-calls/references/picture-in-picture.md +276 -0
- package/skills/cometchat-native-calls/references/raise-hand.md +203 -0
- package/skills/cometchat-native-calls/references/recording-screen-share.md +290 -0
- package/skills/cometchat-native-calls/references/ringing-integration.md +118 -0
- package/skills/cometchat-native-calls/references/server-push-bridge.md +135 -0
- package/skills/cometchat-native-calls/references/server-push-payloads.md +193 -0
- package/skills/cometchat-native-calls/references/share-invite.md +144 -0
- package/skills/cometchat-native-calls/references/voip-push-end-to-end.md +317 -0
- package/skills/cometchat-native-components/SKILL.md +1 -1
- package/skills/cometchat-native-core/SKILL.md +1 -1
- package/skills/cometchat-native-customization/SKILL.md +1 -1
- package/skills/cometchat-native-expo-patterns/SKILL.md +18 -1
- package/skills/cometchat-native-features/SKILL.md +1 -1
- package/skills/cometchat-native-placement/SKILL.md +1 -1
- package/skills/cometchat-native-production/SKILL.md +1 -1
- package/skills/cometchat-native-push/SKILL.md +1 -1
- package/skills/cometchat-native-testing/SKILL.md +1 -1
- package/skills/cometchat-native-theming/SKILL.md +1 -1
- package/skills/cometchat-native-troubleshooting/SKILL.md +1 -1
- package/skills/cometchat-nextjs-patterns/SKILL.md +1 -1
- package/skills/cometchat-placement/SKILL.md +1 -1
- package/skills/cometchat-production/SKILL.md +1 -1
- package/skills/cometchat-react-calls/SKILL.md +539 -0
- package/skills/cometchat-react-calls/references/add-calls-to-existing-chat.md +145 -0
- package/skills/cometchat-react-calls/references/call-layouts.md +161 -0
- package/skills/cometchat-react-calls/references/call-session.md +235 -0
- package/skills/cometchat-react-calls/references/custom-ui.md +201 -0
- package/skills/cometchat-react-calls/references/device-management.md +206 -0
- package/skills/cometchat-react-calls/references/group-calls.md +262 -0
- package/skills/cometchat-react-calls/references/idle-timeout.md +175 -0
- package/skills/cometchat-react-calls/references/in-call-chat.md +212 -0
- package/skills/cometchat-react-calls/references/migration-v4-to-v5.md +172 -0
- package/skills/cometchat-react-calls/references/picture-in-picture.md +245 -0
- package/skills/cometchat-react-calls/references/raise-hand.md +238 -0
- package/skills/cometchat-react-calls/references/recording-screen-share.md +143 -0
- package/skills/cometchat-react-calls/references/ringing-integration.md +255 -0
- package/skills/cometchat-react-calls/references/server-web-push-vapid.md +241 -0
- package/skills/cometchat-react-calls/references/share-invite.md +176 -0
- package/skills/cometchat-react-calls/references/testing-calls-on-web.md +198 -0
- package/skills/cometchat-react-calls/references/voip-and-web-push.md +165 -0
- package/skills/cometchat-react-patterns/SKILL.md +1 -1
- package/skills/cometchat-react-push/SKILL.md +448 -0
- package/skills/cometchat-react-router-patterns/SKILL.md +1 -1
- package/skills/cometchat-react-testing/SKILL.md +404 -0
- package/skills/cometchat-theming/SKILL.md +3 -3
- package/skills/cometchat-troubleshooting/SKILL.md +2 -2
|
@@ -3,7 +3,7 @@ name: cometchat-android-v6-troubleshooting
|
|
|
3
3
|
description: "CometChat Android UIKit v6 troubleshooting — diagnostic table, common issues, and fixes for both Kotlin Views and Compose stacks"
|
|
4
4
|
license: "MIT"
|
|
5
5
|
compatibility: "Android 9.0+ (API 28); Kotlin 1.9+; com.cometchat:chatuikit-compose-android:6.x / com.cometchat:chatuikit-kotlin-android:6.x"
|
|
6
|
-
allowed-tools: "
|
|
6
|
+
allowed-tools: "shell, file-read, file-search, file-list"
|
|
7
7
|
metadata:
|
|
8
8
|
author: "CometChat"
|
|
9
9
|
version: "3.0.1"
|
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cometchat-angular-calls
|
|
3
|
+
description: CometChat Calls SDK integration for Angular 12-15 apps. Wraps the @cometchat/calls-sdk-javascript SDK in Angular service + component patterns. Covers dual-SDK init via APP_INITIALIZER, the Angular UI Kit's <cometchat-call-buttons> / <cometchat-incoming-call> / <cometchat-ongoing-call> / <cometchat-call-logs> selectors, getRTCToken, getUserMedia handling, route-guard placement, NgZone correctness for SDK callbacks, and additive-vs-standalone modes.
|
|
4
|
+
license: "MIT"
|
|
5
|
+
compatibility: "Angular 12-15 (LTS focus on 15); @cometchat/calls-sdk-javascript ^4.x; @cometchat/chat-sdk-javascript ^4.x; @cometchat/chat-uikit-angular ^4.x (additive mode)"
|
|
6
|
+
allowed-tools: "shell, file-read, file-search, file-list, ask-user"
|
|
7
|
+
metadata:
|
|
8
|
+
author: "CometChat"
|
|
9
|
+
version: "4.0.0"
|
|
10
|
+
tags: "cometchat angular calls voice video webrtc app-initializer ngzone uikit-angular calls-sdk-javascript getrtc-token call-buttons incoming-call ongoing-call call-logs"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Purpose
|
|
14
|
+
|
|
15
|
+
Production-grade voice + video calling for Angular 12-15 apps. Loaded by `cometchat-calls` when `framework === "angular"`. Operates in two modes:
|
|
16
|
+
|
|
17
|
+
- **Standalone** — calls is the product. `@cometchat/chat-sdk-javascript` (signaling) + `@cometchat/calls-sdk-javascript` (WebRTC) wrapped in Angular services. Custom call screens.
|
|
18
|
+
- **Additive** — calls layered onto an existing CometChat Angular UI Kit integration. Adds `<cometchat-call-buttons>` inline, mounts `<cometchat-incoming-call>` at the root of `AppComponent`.
|
|
19
|
+
|
|
20
|
+
**Read these other skills first:**
|
|
21
|
+
- `cometchat-calls` — dispatcher (modes, hard rules, anti-patterns)
|
|
22
|
+
- `cometchat-angular-core` — `UIKitSettingsBuilder`, `APP_INITIALIZER` init pattern, login order, `environment.ts` credentials
|
|
23
|
+
- `cometchat-angular-patterns` — lazy loading, route guards, standalone-vs-NgModule integration
|
|
24
|
+
|
|
25
|
+
**Ground truth:**
|
|
26
|
+
- SDK source — `~/Downloads/calls-sdk/calls-sdk-javascript-5/package/`
|
|
27
|
+
- Angular sample app — `~/Downloads/calls-sdk/calls-sdk-javascript-5/sample-apps/cometchat-calls-sample-app-angular/`
|
|
28
|
+
- Existing skill — `cometchat-angular-features` (calls section will move into here)
|
|
29
|
+
- Public docs — https://www.cometchat.com/docs/calls/javascript/overview (Angular wrapper docs are sparse — sample app is canonical)
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 1. Hard rules — Angular specialization
|
|
34
|
+
|
|
35
|
+
### 1.0 Calls SDK login is its own step (v5+)
|
|
36
|
+
|
|
37
|
+
Angular uses the same JS SDKs as React. The v5 Calls SDK has its own auth state, separate from the Chat SDK. After `CometChat.login(uid, AUTH_KEY)` succeeds, you MUST also call `await CometChatCalls.login(uid, AUTH_KEY)` — without it, the FIRST calls API call throws **"auth token cannot be null"**.
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
// auth.service.ts
|
|
41
|
+
import { Injectable } from "@angular/core";
|
|
42
|
+
import { CometChat } from "@cometchat/chat-sdk-javascript";
|
|
43
|
+
import { CometChatCalls } from "@cometchat/calls-sdk-javascript";
|
|
44
|
+
|
|
45
|
+
@Injectable({ providedIn: "root" })
|
|
46
|
+
export class AuthService {
|
|
47
|
+
async login(uid: string): Promise<void> {
|
|
48
|
+
await CometChat.login(uid, environment.cometchatAuthKey);
|
|
49
|
+
// v5 Calls SDK requires a separate login. Don't skip.
|
|
50
|
+
await CometChatCalls.login(uid, environment.cometchatAuthKey);
|
|
51
|
+
// Production: await CometChatCalls.loginWithAuthToken(authTokenFromBackend);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Surprises:**
|
|
57
|
+
- The Chat SDK persists login via localStorage; the **Calls SDK does NOT** across page reloads in Angular (it stores its session in localStorage too, but state can drift). Always check `CometChatCalls.getLoggedInUser()` on app bootstrap and re-login if null.
|
|
58
|
+
- Run the login inside an Angular zone — if you bypass `NgZone` and the login resolves from a Web Worker context (rare), change detection won't fire downstream. Default `await` in a service method is fine.
|
|
59
|
+
|
|
60
|
+
### 1.1 Dual-SDK contract
|
|
61
|
+
|
|
62
|
+
Same web shape, wrapped in services:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
// call-init.service.ts
|
|
66
|
+
import { Injectable } from "@angular/core";
|
|
67
|
+
import { CometChat } from "@cometchat/chat-sdk-javascript";
|
|
68
|
+
import { CometChatCalls } from "@cometchat/calls-sdk-javascript";
|
|
69
|
+
import { environment } from "../../environments/environment";
|
|
70
|
+
|
|
71
|
+
@Injectable({ providedIn: "root" })
|
|
72
|
+
export class CallInitService {
|
|
73
|
+
private initialized = false;
|
|
74
|
+
|
|
75
|
+
async init(): Promise<void> {
|
|
76
|
+
if (this.initialized) return;
|
|
77
|
+
|
|
78
|
+
// Chat SDK — required for ringing
|
|
79
|
+
const appSettings = new CometChat.AppSettingsBuilder()
|
|
80
|
+
.subscribePresenceForAllUsers()
|
|
81
|
+
.setRegion(environment.cometchat.region)
|
|
82
|
+
.build();
|
|
83
|
+
await CometChat.init(environment.cometchat.appId, appSettings);
|
|
84
|
+
|
|
85
|
+
// Calls SDK — WebRTC session
|
|
86
|
+
const callAppSettings = new CometChatCalls.CallAppSettingsBuilder()
|
|
87
|
+
.setAppId(environment.cometchat.appId)
|
|
88
|
+
.setRegion(environment.cometchat.region)
|
|
89
|
+
.build();
|
|
90
|
+
CometChatCalls.init(callAppSettings);
|
|
91
|
+
|
|
92
|
+
this.initialized = true;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Wired via `APP_INITIALIZER` in `app.module.ts`:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
{
|
|
101
|
+
provide: APP_INITIALIZER,
|
|
102
|
+
useFactory: (svc: CallInitService) => () => svc.init(),
|
|
103
|
+
deps: [CallInitService],
|
|
104
|
+
multi: true,
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 1.2 VoIP push — N/A on Angular web (same as React)
|
|
109
|
+
|
|
110
|
+
Same as `cometchat-react-calls` rule 1.2 — browsers don't have VoIP push. Web Push (Service Worker + `Notification`) is opt-in fallback.
|
|
111
|
+
|
|
112
|
+
### 1.3 Lifecycle — `getUserMedia` cleanup
|
|
113
|
+
|
|
114
|
+
Same as web. Custom WebRTC surfaces must `getTracks().forEach(t => t.stop())` on hangup. The `<cometchat-ongoing-call>` selector handles it for additive mode.
|
|
115
|
+
|
|
116
|
+
### 1.4 Server-minted auth tokens
|
|
117
|
+
|
|
118
|
+
`cometchat-angular-production` covers this. Production calls use `CometChat.login(authToken)`, not `CometChat.login(uid, authKey)`.
|
|
119
|
+
|
|
120
|
+
### 1.5 Hangup cleanup — see rule 1.3 + zone consistency
|
|
121
|
+
|
|
122
|
+
When a Calls SDK callback fires outside Angular's zone, the UI doesn't update. Standard fix:
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import { NgZone } from "@angular/core";
|
|
126
|
+
|
|
127
|
+
export class OngoingCallComponent {
|
|
128
|
+
constructor(private zone: NgZone) {}
|
|
129
|
+
|
|
130
|
+
ngOnInit() {
|
|
131
|
+
CometChatCalls.joinSession(token, settings, container); // v5 canonical (startSession is a deprecated shim)
|
|
132
|
+
|
|
133
|
+
// Wrap any UI-mutating callback in NgZone.run
|
|
134
|
+
callListener.onCallEnded = () => {
|
|
135
|
+
this.zone.run(() => {
|
|
136
|
+
this.callEnded = true;
|
|
137
|
+
this.cleanup();
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
cleanup() {
|
|
143
|
+
CometChatCalls.leaveSession();
|
|
144
|
+
this.stream?.getTracks().forEach(t => t.stop());
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Without `NgZone.run`, change detection doesn't fire and the UI looks frozen until the next user interaction.
|
|
150
|
+
|
|
151
|
+
**⚠️ Where does the WebRTC `#callContainer` live? Two valid patterns; pick one explicitly.**
|
|
152
|
+
|
|
153
|
+
The container `<div>` must exist in the DOM when `CometChatCalls.joinSession(token, settings, container)` runs. Angular's `@if` (or `*ngIf`) gates this — get the gate wrong and the call surface never renders. Two patterns work; the second is recommended for new code:
|
|
154
|
+
|
|
155
|
+
#### Pattern A — Single-component, gated by `@if (phase === 'ongoing')`
|
|
156
|
+
|
|
157
|
+
The container lives inside the same component that owns call state. Race: after `phase.set('ongoing')`, the next microtask runs BEFORE Angular's zone-driven render, so `@ViewChild` is still null. Use a **full task tick**, not a microtask:
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
this.phase.set('ongoing');
|
|
161
|
+
|
|
162
|
+
// ❌ WRONG — microtask runs before Angular renders the @if block
|
|
163
|
+
// await Promise.resolve();
|
|
164
|
+
|
|
165
|
+
// ✅ RIGHT — full task tick gives Angular's change detector time to mount the container
|
|
166
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
167
|
+
|
|
168
|
+
const container = this.callContainer?.nativeElement;
|
|
169
|
+
if (!container) throw new Error('Call container not ready.');
|
|
170
|
+
await CometChatCalls.joinSession(callToken, callSettings, container);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Validated 2026-05-13 against a Next.js peer.
|
|
174
|
+
|
|
175
|
+
#### Pattern B — Separate `OngoingCallComponent`, parent-conditional mount (RECOMMENDED)
|
|
176
|
+
|
|
177
|
+
The container lives in its own component, and the **parent** decides whether to instantiate that component (not an inner `@if` inside the child template). This sidesteps the race entirely:
|
|
178
|
+
|
|
179
|
+
```html
|
|
180
|
+
<!-- app.component.html — parent gates the whole overlay component -->
|
|
181
|
+
<router-outlet />
|
|
182
|
+
|
|
183
|
+
@if (state.isInCall()) {
|
|
184
|
+
<app-ongoing-call />
|
|
185
|
+
}
|
|
186
|
+
@if (state.isIncoming()) {
|
|
187
|
+
<app-incoming-call-overlay />
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
```html
|
|
192
|
+
<!-- ongoing-call.component.html — NO inner @if, container always exists when this component is mounted -->
|
|
193
|
+
<div class="oc-shell">
|
|
194
|
+
<div #callContainer class="oc-container"></div>
|
|
195
|
+
<button (click)="endCall()">End call</button>
|
|
196
|
+
</div>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
// ongoing-call.component.ts
|
|
201
|
+
@Component({ /* ... */, changeDetection: ChangeDetectionStrategy.OnPush })
|
|
202
|
+
export class OngoingCallComponent implements AfterViewInit, OnDestroy {
|
|
203
|
+
@ViewChild('callContainer', { static: true })
|
|
204
|
+
private callContainer!: ElementRef<HTMLDivElement>;
|
|
205
|
+
|
|
206
|
+
protected readonly state = inject(CallStateService);
|
|
207
|
+
|
|
208
|
+
async ngAfterViewInit(): Promise<void> {
|
|
209
|
+
// No setTimeout(0) needed — the component is only instantiated when
|
|
210
|
+
// the parent's @if (state.isInCall()) flips true. The @ViewChild is
|
|
211
|
+
// guaranteed resolved by the time ngAfterViewInit fires.
|
|
212
|
+
await this.state.startWebRtcSession(this.callContainer.nativeElement);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
ngOnDestroy(): void {
|
|
216
|
+
this.state.endWebRtcSessionOnly();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Why Pattern B is race-free:** the component is only INSTANTIATED when `state.isInCall()` becomes true. `ngAfterViewInit` fires after the view tree is built, by which point `#callContainer` exists. No `setTimeout 0` workaround needed.
|
|
222
|
+
|
|
223
|
+
**Anti-pattern caught 2026-05-14:** mounting `<app-ongoing-call />` unconditionally with `@if (state.isInCall())` INSIDE the child template. `{static: true}` becomes a lie — the element isn't in the DOM at view-init on first mount → `ngAfterViewInit` throws `TypeError: Cannot read properties of undefined (reading 'nativeElement')` → `provideAppInitializer` rejects → bootstrap "completes with error" but the app still renders with stale initial signals.
|
|
224
|
+
|
|
225
|
+
### 1.6 Permissions — browser handles `getUserMedia`
|
|
226
|
+
|
|
227
|
+
Same as web. Surface `NotAllowedError` and `NotFoundError` to a clear UI message. HTTPS required (or localhost).
|
|
228
|
+
|
|
229
|
+
### 1.7 IncomingCall mounted at app root
|
|
230
|
+
|
|
231
|
+
`<cometchat-incoming-call>` belongs in `AppComponent`'s template, ABOVE `<router-outlet>`:
|
|
232
|
+
|
|
233
|
+
```html
|
|
234
|
+
<!-- app.component.html -->
|
|
235
|
+
<cometchat-incoming-call></cometchat-incoming-call>
|
|
236
|
+
<router-outlet></router-outlet>
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Inside a feature-module template means the listener disappears on route change → calls only ring when that route is active. Same canonical bug as React.
|
|
240
|
+
|
|
241
|
+
For lazy-loaded features that include calls, the dispatcher in `cometchat-angular-patterns` shows the eager-load-only pattern for the calls module.
|
|
242
|
+
|
|
243
|
+
**⚠️ Mixed-stack receiver inconsistency (validated 2026-05-15).** If your Angular app is the RECEIVER in a mixed-stack scenario (mobile kit-based caller → Angular custom UI receiver), confirm a **single active session per UID** before relying on `onIncomingCallReceived`. Symptom: server records the incoming call (visible in REST `GET /users/{uid}/calls`), but the listener never fires on the active Angular tab — typically because a stale session for the same UID elsewhere is eating the call-delivery routing. Workaround:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# Evict all sessions for the receiver UID before testing
|
|
247
|
+
curl -X DELETE 'https://<APP_ID>.api-<REGION>.cometchat.io/v3/users/<uid>/auth_tokens' \
|
|
248
|
+
-H 'appId: <APP_ID>' \
|
|
249
|
+
-H 'apiKey: <REST_API_KEY>'
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Then hard-refresh the Angular tab so a fresh login mints a clean token. The reverse direction (Angular caller → mobile receiver) works without this workaround. Tracked for v4.3 investigation; full context in `project_pixel_to_angular_ringing_inconsistency` memory entry.
|
|
253
|
+
|
|
254
|
+
### 1.8 Signals required for cross-service state under OnPush
|
|
255
|
+
|
|
256
|
+
Validated 2026-05-14 on Angular 21.2.0. Single biggest "looks-correct-but-fails-silently" bug in this stack.
|
|
257
|
+
|
|
258
|
+
```ts
|
|
259
|
+
// ❌ Plain property — captured at component construction. With OnPush, the
|
|
260
|
+
// template re-reads the captured value only when an explicit re-render
|
|
261
|
+
// happens. If the service sets it later, the template stays stuck on
|
|
262
|
+
// the initial value forever.
|
|
263
|
+
@Injectable({ providedIn: 'root' })
|
|
264
|
+
export class CallInitService {
|
|
265
|
+
loggedInUid: string | null = null;
|
|
266
|
+
async init() { /* ... */ this.loggedInUid = 'cometchat-uid-5'; }
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// In a component with OnPush, this looks reactive but isn't:
|
|
270
|
+
protected readonly loggedInUid = this.callInit.loggedInUid;
|
|
271
|
+
// Template: {{ loggedInUid ?? 'connecting…' }} → stuck on "connecting…" forever
|
|
272
|
+
|
|
273
|
+
// ✅ Signal — reactive readers re-render on .set()
|
|
274
|
+
@Injectable({ providedIn: 'root' })
|
|
275
|
+
export class CallInitService {
|
|
276
|
+
readonly loggedInUid = signal<string | null>(null);
|
|
277
|
+
async init() { /* ... */ this.loggedInUid.set('cometchat-uid-5'); }
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// In the component (still OnPush):
|
|
281
|
+
protected readonly loggedInUid = this.callInit.loggedInUid;
|
|
282
|
+
// Template: {{ loggedInUid() ?? 'connecting…' }} → updates within the next microtask
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
**Rule:** ANY service state that the template observes MUST be a signal (or an observable consumed via the `async` pipe / `toSignal`). Plain properties don't trigger OnPush change detection from outside the component's input/event surface.
|
|
286
|
+
|
|
287
|
+
Cross-service state set during `provideAppInitializer` is the classic case — by the time the component is constructed, the service property may or may not be set, and even if it isn't yet, a later `.set()` would never reach the template under OnPush.
|
|
288
|
+
|
|
289
|
+
### 1.9 `provideAppInitializer` failures are silent — surface them in the UI
|
|
290
|
+
|
|
291
|
+
Modern Angular bootstrap "completes" even when `provideAppInitializer` throws — the error logs to `console.error` and the app still mounts in a partial state. Visible symptom: UI renders but cross-service state is stuck at initial values.
|
|
292
|
+
|
|
293
|
+
Best practice — make init errors visible:
|
|
294
|
+
|
|
295
|
+
```ts
|
|
296
|
+
@Injectable({ providedIn: 'root' })
|
|
297
|
+
export class CallInitService {
|
|
298
|
+
readonly loggedInUid = signal<string | null>(null);
|
|
299
|
+
readonly initError = signal<string | null>(null);
|
|
300
|
+
readonly initStep = signal<string>('not-started');
|
|
301
|
+
|
|
302
|
+
async init(): Promise<void> {
|
|
303
|
+
try {
|
|
304
|
+
this.initStep.set('chat-init');
|
|
305
|
+
await CometChat.init(/* ... */);
|
|
306
|
+
|
|
307
|
+
this.initStep.set('calls-init');
|
|
308
|
+
await CometChatCalls.init(/* ... */);
|
|
309
|
+
|
|
310
|
+
this.initStep.set('chat-login');
|
|
311
|
+
await CometChat.login(/* ... */);
|
|
312
|
+
|
|
313
|
+
this.initStep.set('calls-login');
|
|
314
|
+
// ERR_ALREADY_LOGGED_IN is common on HMR — tolerate it
|
|
315
|
+
try {
|
|
316
|
+
await CometChatCalls.login(/* ... */);
|
|
317
|
+
} catch (e: any) {
|
|
318
|
+
const code = e?.code ?? e?.message ?? '';
|
|
319
|
+
if (!/already/i.test(String(code))) throw e;
|
|
320
|
+
console.warn('[CallInitService] calls.login non-fatal:', e);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
this.loggedInUid.set(uid);
|
|
324
|
+
this.initStep.set('ready');
|
|
325
|
+
} catch (e: any) {
|
|
326
|
+
const msg = e?.message ?? e?.code ?? JSON.stringify(e);
|
|
327
|
+
console.error('[CallInitService] init failed at step', this.initStep(), e);
|
|
328
|
+
this.initError.set(`Failed at "${this.initStep()}": ${msg}`);
|
|
329
|
+
throw e; // re-throw so APP_INITIALIZER still logs the failure
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
Then render `initError` in the root template:
|
|
336
|
+
|
|
337
|
+
```html
|
|
338
|
+
@if (initError(); as err) {
|
|
339
|
+
<div class="init-error">Init failed: {{ err }}</div>
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Without this surface, a single bug deep in init causes the dev to spend 20+ minutes guessing where the failure is. Validated 2026-05-14 — the `initStep` instrumentation immediately revealed an `ngAfterViewInit` ViewChild bug that had previously looked like a "stuck on connecting" without any clue.
|
|
344
|
+
|
|
345
|
+
### 1.10 `ERR_ALREADY_LOGGED_IN` on HMR is non-fatal
|
|
346
|
+
|
|
347
|
+
`CometChatCalls.login` is intolerant of re-login during dev HMR cycles. Wrap in a tolerant catch that only re-throws non-"already" errors (see 1.9 code above). The chat-side session survives HMR, so the calls session can ride on it.
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
## 2. Setup
|
|
352
|
+
|
|
353
|
+
### Install
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
npm install @cometchat/chat-sdk-javascript @cometchat/calls-sdk-javascript
|
|
357
|
+
# additive mode: @cometchat/chat-uikit-angular is already installed
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### `app.module.ts` (NgModule path)
|
|
361
|
+
|
|
362
|
+
```ts
|
|
363
|
+
import { NgModule, APP_INITIALIZER, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
|
|
364
|
+
import { CometChatUIKitModule } from "@cometchat/chat-uikit-angular"; // additive mode
|
|
365
|
+
import { CallInitService } from "./services/call-init.service";
|
|
366
|
+
|
|
367
|
+
@NgModule({
|
|
368
|
+
imports: [
|
|
369
|
+
CometChatUIKitModule, // additive mode only
|
|
370
|
+
],
|
|
371
|
+
providers: [
|
|
372
|
+
{
|
|
373
|
+
provide: APP_INITIALIZER,
|
|
374
|
+
useFactory: (svc: CallInitService) => () => svc.init(),
|
|
375
|
+
deps: [CallInitService],
|
|
376
|
+
multi: true,
|
|
377
|
+
},
|
|
378
|
+
],
|
|
379
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA], // required by UI Kit selectors
|
|
380
|
+
})
|
|
381
|
+
export class AppModule {}
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### Standalone components (Angular 14+)
|
|
385
|
+
|
|
386
|
+
```ts
|
|
387
|
+
// main.ts
|
|
388
|
+
bootstrapApplication(AppComponent, {
|
|
389
|
+
providers: [
|
|
390
|
+
{
|
|
391
|
+
provide: APP_INITIALIZER,
|
|
392
|
+
useFactory: (svc: CallInitService) => () => svc.init(),
|
|
393
|
+
deps: [CallInitService],
|
|
394
|
+
multi: true,
|
|
395
|
+
},
|
|
396
|
+
],
|
|
397
|
+
});
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
The standalone-component path skips `CometChatUIKitModule` — instead, individual standalone selectors are imported per-component.
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## 3. Components catalog
|
|
405
|
+
|
|
406
|
+
### Calls SDK primitives (used in standalone or custom components)
|
|
407
|
+
|
|
408
|
+
Same shape as `cometchat-react-calls` Section 3 — `CometChatCalls.init`, `generateToken(sessionId)` (single arg in v5; auth is internal after login), `joinSession(token, settings, htmlElement)` (v5 canonical; `startSession` is a deprecated shim), `leaveSession()` (v5 canonical; `endSession()` is deprecated), `CallSettingsBuilder`, etc. The audit-verified API surface is documented in `cometchat-react-calls` and applies unchanged in Angular (same JS SDK).
|
|
409
|
+
|
|
410
|
+
### UI Kit selectors (additive mode — `@cometchat/chat-uikit-angular`)
|
|
411
|
+
|
|
412
|
+
| Selector | Purpose |
|
|
413
|
+
|---|---|
|
|
414
|
+
| `<cometchat-call-buttons [user]="u">` | Voice + video buttons (typically inside `<cometchat-message-header>`) |
|
|
415
|
+
| `<cometchat-incoming-call>` | Root-mounted listener |
|
|
416
|
+
| `<cometchat-outgoing-call>` | Auto-mounted on initiate |
|
|
417
|
+
| `<cometchat-ongoing-call>` | Active call view |
|
|
418
|
+
| `<cometchat-call-logs (itemClick)="onLogClick($event)">` | Paginated history |
|
|
419
|
+
|
|
420
|
+
`CUSTOM_ELEMENTS_SCHEMA` (or full module imports) must be in the consuming module — same rule as the chat selectors.
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
## 4. Standalone integration
|
|
425
|
+
|
|
426
|
+
When `product === "voice-video"` and there is no existing UI Kit.
|
|
427
|
+
|
|
428
|
+
**Split by calling mode — these are two different shapes:**
|
|
429
|
+
|
|
430
|
+
### 4a. Standalone — Session mode (meeting-room UX, no ringing)
|
|
431
|
+
|
|
432
|
+
Calls SDK ONLY. NO Chat SDK. Matches the upstream sample at `~/Downloads/calls-sdk/calls-sdk-javascript-5/sample-apps/cometchat-calls-sample-app-angular/`. The skill scaffolds:
|
|
433
|
+
|
|
434
|
+
1. **`services/call-init.service.ts`** — `CometChatCalls.init({ appId, region, authKey })` ONLY. No `CometChat.init`. Exposed via `provideAppInitializer`. Pass `authKey` at init time so `CometChatCalls.login(uid)` needs no second arg.
|
|
435
|
+
2. **`pages/join-session/join-session.component.ts`** — UID picker (dev mode) + "Start meeting" / "Join meeting" + the meeting-room container (`@if (inMeeting()) { <div class="meeting-container" #meetingContainer></div> }`). Container CSS: `position: fixed; width: 100vw; height: 100vh`. `CometChatCalls.joinSession(token, {}, container.nativeElement)` with empty settings. See `references/call-session.md` for the full canonical pattern.
|
|
436
|
+
3. **Routing** — `/meet/:sessionId` route registered with `data: { reuseRoute: false }`.
|
|
437
|
+
4. **`environment.ts`** — credentials block.
|
|
438
|
+
5. **HTTPS check** — warns if dev server is HTTP non-localhost.
|
|
439
|
+
|
|
440
|
+
**Why no Chat SDK:** session mode never touches the Chat SDK call entity. Initializing both SDKs adds two failure modes (Chat init, Chat login race) for zero benefit. The upstream Angular sample confirms this — it never imports `@cometchat/chat-sdk-javascript`.
|
|
441
|
+
|
|
442
|
+
### 4b. Standalone — Ringing mode (CallButtons + Incoming/Outgoing/Ongoing kit selectors)
|
|
443
|
+
|
|
444
|
+
Dual-SDK: Chat SDK signaling channel + Calls SDK media channel. The skill scaffolds:
|
|
445
|
+
|
|
446
|
+
1. **`services/call-init.service.ts`** — Chat SDK + Calls SDK init (sequential), exposed via `APP_INITIALIZER`.
|
|
447
|
+
2. **`components/call-button/call-button.component.ts`** — Voice + video buttons, `[user]` input, emits `(callInitiated)`.
|
|
448
|
+
3. **`pages/ongoing-call/ongoing-call.component.ts`** — `(deactivate)` route guard cleans up if user navigates away mid-call. WebRTC view via direct `CometChatCalls.joinSession`. Rule 1.5 cleanup.
|
|
449
|
+
4. **`pages/call-logs/call-logs.component.ts`** — `/calls` route, paginated via `CallLogRequestBuilder`.
|
|
450
|
+
5. **`AppComponent` template** — `<cometchat-incoming-call>` (or a custom incoming-call equivalent in standalone mode) above `<router-outlet>`.
|
|
451
|
+
6. **Routing** — `/calls` and `/ongoing-call/:sessionId` routes registered in `app-routing.module.ts`.
|
|
452
|
+
7. **`environment.ts`** — credentials block (rule from `cometchat-angular-core`).
|
|
453
|
+
8. **Optional Web Push** — Service Worker registration via `@angular/service-worker` if user opts in.
|
|
454
|
+
|
|
455
|
+
## 5. Additive integration
|
|
456
|
+
|
|
457
|
+
When `cometchat-angular-core` integration already exists. The skill:
|
|
458
|
+
|
|
459
|
+
1. Adds `@cometchat/calls-sdk-javascript`.
|
|
460
|
+
2. Patches existing `init.service.ts` (or whatever the project named it) to add `CometChatCalls.init` after `CometChat.init`.
|
|
461
|
+
3. Adds `<cometchat-incoming-call>` to `AppComponent` template (rule 1.7).
|
|
462
|
+
4. Wires `<cometchat-call-buttons [user]="user">` inside the existing message-header template if not already present (often auto-rendered by `<cometchat-message-header>` when `[user]` is set).
|
|
463
|
+
5. Optionally adds a `/calls` route for `<cometchat-call-logs>`.
|
|
464
|
+
|
|
465
|
+
## 6. Anti-patterns
|
|
466
|
+
|
|
467
|
+
1. **Initializing in a feature module's `ngOnInit`** instead of `APP_INITIALIZER` / `provideAppInitializer`. The chat SDK auth context isn't ready when the component tries to use it. APP_INITIALIZER blocks bootstrap until init succeeds.
|
|
468
|
+
2. **Mounting `<cometchat-incoming-call>` inside a feature module's component.** Disappears on route change. Mount in AppComponent (rule 1.7).
|
|
469
|
+
3. **Skipping `NgZone.run` for SDK callbacks.** UI doesn't update on call-end. Rule 1.5.
|
|
470
|
+
4. **Skipping `CUSTOM_ELEMENTS_SCHEMA`.** Selectors render but Angular logs "is not a known element" errors and breaks zone-aware bindings.
|
|
471
|
+
5. **Using `CometChatCalls.joinSession` without `await CometChatCalls.generateToken`** — same anti-pattern as React.
|
|
472
|
+
6. **Lazy-loading the calls module.** Calls must be initialized at bootstrap; lazy-loading defers init past the point where calls might already be coming in. Eager-load anything that imports `CallInitService`.
|
|
473
|
+
7. **Running over HTTP non-localhost.** `getUserMedia` denies; `ng serve` is HTTPS-capable via `--ssl`.
|
|
474
|
+
8. **Plain properties on services consumed by OnPush components** (rule 1.8). Captured-at-construction state stays stuck on the initial value forever. Use signals.
|
|
475
|
+
9. **Inner `@if (state.isInCall())` inside the ongoing-call component's own template** (rule 1.5 Pattern B anti-pattern). Makes `{static: true}` `@ViewChild('callContainer')` a lie — `ngAfterViewInit` reads `undefined.nativeElement`. Gate at the parent.
|
|
476
|
+
10. **Letting `provideAppInitializer` failures bubble silently** (rule 1.9). App mounts in a half-initialized state; UI looks like it's "stuck connecting." Always surface an `initError` signal in the UI.
|
|
477
|
+
11. **Failing on `ERR_ALREADY_LOGGED_IN`** during HMR (rule 1.10). Common during dev; wrap `CometChatCalls.login` in a tolerant catch.
|
|
478
|
+
|
|
479
|
+
## 7. Verification checklist
|
|
480
|
+
|
|
481
|
+
**Static:**
|
|
482
|
+
|
|
483
|
+
- [ ] `@cometchat/chat-sdk-javascript` and `@cometchat/calls-sdk-javascript` in `package.json`
|
|
484
|
+
- [ ] `APP_INITIALIZER` / `provideAppInitializer` registered in `app.module.ts` or `app.config.ts`
|
|
485
|
+
- [ ] `CallInitService.init` calls Chat SDK init then Calls SDK init (sequential)
|
|
486
|
+
- [ ] `CallInitService.loggedInUid` is a `signal<string | null>` (NOT a plain property) — rule 1.8
|
|
487
|
+
- [ ] `CallInitService` exposes `initError: signal<string | null>` and the root template renders it — rule 1.9
|
|
488
|
+
- [ ] `CometChatCalls.login` wrapped in tolerant catch for `ERR_ALREADY_LOGGED_IN` — rule 1.10
|
|
489
|
+
- [ ] `CUSTOM_ELEMENTS_SCHEMA` in the consuming module
|
|
490
|
+
- [ ] `<cometchat-incoming-call>` in AppComponent template above `<router-outlet>` (or split-component Pattern B per rule 1.5 — `@if (state.isInCall())` / `@if (state.isIncoming())` parent-conditional mount)
|
|
491
|
+
- [ ] All SDK callbacks that mutate UI are wrapped in `NgZone.run`
|
|
492
|
+
- [ ] Hangup path includes `CometChatCalls.leaveSession()` + track stops
|
|
493
|
+
- [ ] `environment.ts` has `cometchat: { appId, region, authKey }` (dev) or token-endpoint config (prod)
|
|
494
|
+
- [ ] Module-level `initialized` flag in CallInitService
|
|
495
|
+
- [ ] Node version ≥ 20.19 or ≥ 22.12 (Angular CLI 21+ requirement)
|
|
496
|
+
|
|
497
|
+
**Runtime (browser):**
|
|
498
|
+
|
|
499
|
+
- [ ] Outgoing call connects, two-way audio + video
|
|
500
|
+
- [ ] Incoming call rings on a separate route within the same app
|
|
501
|
+
- [ ] Camera light off within 2 seconds of hangup
|
|
502
|
+
- [ ] Route navigation during call cleanly disconnects (deactivate guard runs)
|
|
503
|
+
- [ ] HTTPS or localhost only
|
|
504
|
+
|
|
505
|
+
## 8. Pointers
|
|
506
|
+
|
|
507
|
+
- `cometchat-angular-core` — UIKitSettingsBuilder, APP_INITIALIZER pattern, environment.ts
|
|
508
|
+
- `cometchat-angular-components` — full UI Kit selector catalog (additive mode)
|
|
509
|
+
- `cometchat-angular-patterns` — lazy loading, route guards, standalone-vs-NgModule
|
|
510
|
+
- `cometchat-angular-production` — server-minted tokens, external-backend recipes (Express/Hono/Firebase/Vercel)
|
|
511
|
+
- `cometchat-angular-troubleshooting` — CUSTOM_ELEMENTS_SCHEMA, zone issues, SSR/Universal
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Adding calls to an existing chat integration (Angular)
|
|
2
|
+
|
|
3
|
+
Same SDK as web; Angular-specific deltas: NgZone wrapping, NgModule registration, root-level CometChatIncomingCall mounting.
|
|
4
|
+
|
|
5
|
+
**Read first:** `cometchat-react-calls/references/add-calls-to-existing-chat.md` — canonical web steps.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Step 1 — Install + init
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @cometchat/calls-sdk-javascript@5
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Update your existing init (typically in an `AppInitService`):
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
@Injectable({ providedIn: "root" })
|
|
19
|
+
export class AppInitService {
|
|
20
|
+
async init(): Promise<void> {
|
|
21
|
+
const settings = new CometChat.AppSettingsBuilder().setRegion(env.REGION).build();
|
|
22
|
+
await CometChat.init(env.APP_ID, settings);
|
|
23
|
+
await CometChatCalls.init({ appId: env.APP_ID, region: env.REGION });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Step 2 — Login
|
|
31
|
+
|
|
32
|
+
In your auth service, after `CometChat.login`:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
const user = await CometChat.login(uid, env.AUTH_KEY);
|
|
36
|
+
const authToken = user.getAuthToken();
|
|
37
|
+
await CometChatCalls.login(authToken);
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Step 3 — Mount IncomingCall at app root
|
|
43
|
+
|
|
44
|
+
```html
|
|
45
|
+
<!-- app.component.html -->
|
|
46
|
+
<router-outlet></router-outlet>
|
|
47
|
+
<cometchat-incoming-call></cometchat-incoming-call>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
// app.module.ts (or standalone-component imports)
|
|
52
|
+
import { CometChatIncomingCall } from "@cometchat/chat-uikit-angular";
|
|
53
|
+
|
|
54
|
+
@NgModule({
|
|
55
|
+
declarations: [AppComponent],
|
|
56
|
+
imports: [CometChatIncomingCall, /* ... */],
|
|
57
|
+
})
|
|
58
|
+
export class AppModule {}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Step 4 — NgZone wrap on calls events
|
|
64
|
+
|
|
65
|
+
If you subscribe to `CometChatCalls.addEventListener` outside the kit's components, wrap with `NgZone.run`:
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
@Injectable({ providedIn: "root" })
|
|
69
|
+
export class CallEventsService {
|
|
70
|
+
constructor(private zone: NgZone) {
|
|
71
|
+
CometChatCalls.addEventListener("onSessionLeft", () => {
|
|
72
|
+
this.zone.run(() => this.onSessionLeft$.next());
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Verification checklist
|
|
81
|
+
|
|
82
|
+
- [ ] `@cometchat/calls-sdk-javascript@^5` in package.json
|
|
83
|
+
- [ ] Calls SDK init runs after chat SDK init in `AppInitService`
|
|
84
|
+
- [ ] `CometChatCalls.login(authToken)` after `CometChat.login`
|
|
85
|
+
- [ ] `<cometchat-incoming-call>` rendered at app root (sibling of `router-outlet`)
|
|
86
|
+
- [ ] All custom `addEventListener` callbacks wrapped in `NgZone.run`
|
|
87
|
+
- [ ] Run `cometchat verify --calls` — should pass
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Pointers
|
|
92
|
+
|
|
93
|
+
- `cometchat-react-calls/references/add-calls-to-existing-chat.md` — canonical
|
|
94
|
+
- `cometchat-angular-calls/SKILL.md`
|
|
95
|
+
- `references/ngzone-and-async-callbacks.md`
|