@cometchat/skills 4.3.0 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/LICENSE +21 -0
  2. package/bin/install.js +27 -0
  3. package/package.json +14 -1
  4. package/skills/cometchat/SKILL.md +233 -69
  5. package/skills/cometchat/references/asking-questions.md +48 -0
  6. package/skills/cometchat-a11y/SKILL.md +3 -2
  7. package/skills/cometchat-android-v5/SKILL.md +2 -1
  8. package/skills/cometchat-android-v5-calls/SKILL.md +36 -22
  9. package/skills/cometchat-android-v5-calls/references/README.md +1 -1
  10. package/skills/cometchat-android-v5-calls/references/add-calls-to-existing-chat.md +7 -5
  11. package/skills/cometchat-android-v5-calls/references/audio-controls.md +4 -4
  12. package/skills/cometchat-android-v5-calls/references/call-layouts.md +33 -25
  13. package/skills/cometchat-android-v5-calls/references/call-session.md +2 -2
  14. package/skills/cometchat-android-v5-calls/references/custom-ui.md +5 -5
  15. package/skills/cometchat-android-v5-calls/references/event-listeners.md +2 -2
  16. package/skills/cometchat-android-v5-calls/references/idle-timeout.md +20 -14
  17. package/skills/cometchat-android-v5-calls/references/in-call-chat.md +1 -1
  18. package/skills/cometchat-android-v5-calls/references/migration-v4-to-v5.md +43 -27
  19. package/skills/cometchat-android-v5-calls/references/participant-management.md +3 -3
  20. package/skills/cometchat-android-v5-calls/references/raise-hand.md +25 -19
  21. package/skills/cometchat-android-v5-calls/references/recording.md +2 -2
  22. package/skills/cometchat-android-v5-calls/references/ringing-integration.md +1 -1
  23. package/skills/cometchat-android-v5-calls/references/screen-sharing.md +5 -9
  24. package/skills/cometchat-android-v5-calls/references/session-settings.md +3 -3
  25. package/skills/cometchat-android-v5-calls/references/setup.md +1 -1
  26. package/skills/cometchat-android-v5-calls/references/share-invite.md +9 -4
  27. package/skills/cometchat-android-v5-calls/references/video-controls.md +4 -4
  28. package/skills/cometchat-android-v5-calls/references/voip-calling.md +2 -2
  29. package/skills/cometchat-android-v5-components/SKILL.md +4 -3
  30. package/skills/cometchat-android-v5-core/SKILL.md +5 -3
  31. package/skills/cometchat-android-v5-customization/SKILL.md +171 -7
  32. package/skills/cometchat-android-v5-extensions/SKILL.md +7 -4
  33. package/skills/cometchat-android-v5-features/SKILL.md +5 -4
  34. package/skills/cometchat-android-v5-placement/SKILL.md +2 -1
  35. package/skills/cometchat-android-v5-production/SKILL.md +2 -1
  36. package/skills/cometchat-android-v5-push/SKILL.md +2 -3
  37. package/skills/cometchat-android-v5-testing/SKILL.md +2 -1
  38. package/skills/cometchat-android-v5-theming/SKILL.md +2 -1
  39. package/skills/cometchat-android-v5-troubleshooting/SKILL.md +3 -2
  40. package/skills/cometchat-android-v6/SKILL.md +2 -1
  41. package/skills/cometchat-android-v6-builder-settings/SKILL.md +11 -7
  42. package/skills/cometchat-android-v6-calls/SKILL.md +79 -18
  43. package/skills/cometchat-android-v6-calls/references/advanced-features.md +87 -0
  44. package/skills/cometchat-android-v6-calls/references/call-layouts.md +24 -15
  45. package/skills/cometchat-android-v6-calls/references/call-session.md +2 -2
  46. package/skills/cometchat-android-v6-calls/references/device-management.md +17 -16
  47. package/skills/cometchat-android-v6-calls/references/idle-timeout.md +7 -4
  48. package/skills/cometchat-android-v6-calls/references/in-call-chat.md +13 -8
  49. package/skills/cometchat-android-v6-calls/references/raise-hand.md +6 -4
  50. package/skills/cometchat-android-v6-compose-components/SKILL.md +52 -29
  51. package/skills/cometchat-android-v6-compose-customization/SKILL.md +156 -1
  52. package/skills/cometchat-android-v6-compose-placement/SKILL.md +129 -40
  53. package/skills/cometchat-android-v6-compose-theming/SKILL.md +27 -1
  54. package/skills/cometchat-android-v6-core/SKILL.md +208 -28
  55. package/skills/cometchat-android-v6-events/SKILL.md +4 -1
  56. package/skills/cometchat-android-v6-extensions/SKILL.md +2 -1
  57. package/skills/cometchat-android-v6-features/SKILL.md +26 -2
  58. package/skills/cometchat-android-v6-kotlin-components/SKILL.md +31 -1
  59. package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +172 -1
  60. package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +20 -5
  61. package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +36 -5
  62. package/skills/cometchat-android-v6-migration/SKILL.md +44 -42
  63. package/skills/cometchat-android-v6-production/SKILL.md +6 -3
  64. package/skills/cometchat-android-v6-push/SKILL.md +43 -2
  65. package/skills/cometchat-android-v6-testing/SKILL.md +11 -8
  66. package/skills/cometchat-android-v6-troubleshooting/SKILL.md +26 -5
  67. package/skills/cometchat-angular-calls/SKILL.md +256 -389
  68. package/skills/cometchat-angular-calls/references/add-calls-to-existing-chat.md +3 -2
  69. package/skills/cometchat-angular-calls/references/call-layouts.md +29 -12
  70. package/skills/cometchat-angular-calls/references/call-session.md +2 -2
  71. package/skills/cometchat-angular-calls/references/custom-ui.md +18 -10
  72. package/skills/cometchat-angular-calls/references/device-management.md +53 -34
  73. package/skills/cometchat-angular-calls/references/group-calls.md +45 -24
  74. package/skills/cometchat-angular-calls/references/idle-timeout.md +31 -15
  75. package/skills/cometchat-angular-calls/references/ngzone-and-async-callbacks.md +7 -6
  76. package/skills/cometchat-angular-calls/references/raise-hand.md +9 -4
  77. package/skills/cometchat-angular-calls/references/recording-screen-share.md +32 -39
  78. package/skills/cometchat-angular-calls/references/ringing-integration.md +3 -1
  79. package/skills/cometchat-angular-calls/references/share-invite.md +11 -5
  80. package/skills/cometchat-angular-calls/references/virtual-background.md +29 -0
  81. package/skills/cometchat-angular-components/SKILL.md +149 -620
  82. package/skills/cometchat-angular-core/SKILL.md +232 -312
  83. package/skills/cometchat-angular-customization/SKILL.md +415 -223
  84. package/skills/cometchat-angular-features/SKILL.md +216 -334
  85. package/skills/cometchat-angular-patterns/SKILL.md +168 -359
  86. package/skills/cometchat-angular-placement/SKILL.md +189 -560
  87. package/skills/cometchat-angular-production/SKILL.md +241 -92
  88. package/skills/cometchat-angular-push/SKILL.md +280 -294
  89. package/skills/cometchat-angular-testing/SKILL.md +430 -158
  90. package/skills/cometchat-angular-theming/SKILL.md +190 -265
  91. package/skills/cometchat-angular-troubleshooting/SKILL.md +192 -157
  92. package/skills/cometchat-astro-patterns/SKILL.md +2 -1
  93. package/skills/cometchat-calls/SKILL.md +25 -19
  94. package/skills/cometchat-calls/references/use-case-broadcast.md +15 -10
  95. package/skills/cometchat-calls/references/use-case-marketplace.md +2 -3
  96. package/skills/cometchat-calls/references/use-case-support.md +3 -4
  97. package/skills/cometchat-calls/references/use-case-team.md +23 -12
  98. package/skills/cometchat-calls/references/use-case-telehealth.md +3 -4
  99. package/skills/cometchat-components/SKILL.md +163 -25
  100. package/skills/cometchat-core/SKILL.md +255 -19
  101. package/skills/cometchat-customization/SKILL.md +50 -25
  102. package/skills/cometchat-features/SKILL.md +313 -34
  103. package/skills/cometchat-flutter-v5/SKILL.md +10 -4
  104. package/skills/cometchat-flutter-v5-calls/SKILL.md +188 -158
  105. package/skills/cometchat-flutter-v5-calls/references/add-calls-to-existing-chat.md +48 -24
  106. package/skills/cometchat-flutter-v5-calls/references/call-layouts.md +20 -15
  107. package/skills/cometchat-flutter-v5-calls/references/call-session.md +100 -145
  108. package/skills/cometchat-flutter-v5-calls/references/device-management.md +12 -8
  109. package/skills/cometchat-flutter-v5-calls/references/group-calls.md +30 -36
  110. package/skills/cometchat-flutter-v5-calls/references/idle-timeout.md +15 -13
  111. package/skills/cometchat-flutter-v5-calls/references/in-call-chat.md +12 -9
  112. package/skills/cometchat-flutter-v5-calls/references/migration-v4-to-v5.md +115 -65
  113. package/skills/cometchat-flutter-v5-calls/references/raise-hand.md +41 -30
  114. package/skills/cometchat-flutter-v5-calls/references/ringing-integration.md +17 -14
  115. package/skills/cometchat-flutter-v5-calls/references/share-invite.md +8 -2
  116. package/skills/cometchat-flutter-v5-conversations/SKILL.md +2 -1
  117. package/skills/cometchat-flutter-v5-core/SKILL.md +5 -4
  118. package/skills/cometchat-flutter-v5-customization/SKILL.md +136 -5
  119. package/skills/cometchat-flutter-v5-events/SKILL.md +2 -1
  120. package/skills/cometchat-flutter-v5-messages/SKILL.md +2 -1
  121. package/skills/cometchat-flutter-v5-production/SKILL.md +15 -6
  122. package/skills/cometchat-flutter-v5-push/SKILL.md +2 -1
  123. package/skills/cometchat-flutter-v5-testing/SKILL.md +17 -6
  124. package/skills/cometchat-flutter-v5-theming/SKILL.md +2 -1
  125. package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +7 -6
  126. package/skills/cometchat-flutter-v5-users-groups/SKILL.md +3 -2
  127. package/skills/cometchat-flutter-v6/SKILL.md +17 -16
  128. package/skills/cometchat-flutter-v6-calls/SKILL.md +72 -57
  129. package/skills/cometchat-flutter-v6-calls/references/add-calls-to-existing-chat.md +5 -3
  130. package/skills/cometchat-flutter-v6-calls/references/advanced-features.md +89 -0
  131. package/skills/cometchat-flutter-v6-calls/references/call-layouts.md +15 -12
  132. package/skills/cometchat-flutter-v6-calls/references/call-session.md +2 -2
  133. package/skills/cometchat-flutter-v6-calls/references/device-management.md +9 -3
  134. package/skills/cometchat-flutter-v6-calls/references/group-calls.md +10 -10
  135. package/skills/cometchat-flutter-v6-calls/references/idle-timeout.md +15 -7
  136. package/skills/cometchat-flutter-v6-calls/references/in-call-chat.md +6 -3
  137. package/skills/cometchat-flutter-v6-calls/references/raise-hand.md +23 -16
  138. package/skills/cometchat-flutter-v6-components/SKILL.md +32 -11
  139. package/skills/cometchat-flutter-v6-conversations/SKILL.md +39 -11
  140. package/skills/cometchat-flutter-v6-core/SKILL.md +182 -21
  141. package/skills/cometchat-flutter-v6-customization/SKILL.md +97 -25
  142. package/skills/cometchat-flutter-v6-events/SKILL.md +3 -2
  143. package/skills/cometchat-flutter-v6-features/SKILL.md +15 -6
  144. package/skills/cometchat-flutter-v6-messages/SKILL.md +111 -60
  145. package/skills/cometchat-flutter-v6-migration/SKILL.md +18 -25
  146. package/skills/cometchat-flutter-v6-placement/SKILL.md +79 -50
  147. package/skills/cometchat-flutter-v6-production/SKILL.md +13 -12
  148. package/skills/cometchat-flutter-v6-push/SKILL.md +41 -19
  149. package/skills/cometchat-flutter-v6-testing/SKILL.md +4 -4
  150. package/skills/cometchat-flutter-v6-theming/SKILL.md +38 -5
  151. package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +182 -17
  152. package/skills/cometchat-flutter-v6-users-groups/SKILL.md +12 -4
  153. package/skills/cometchat-i18n/SKILL.md +139 -78
  154. package/skills/cometchat-ios/SKILL.md +4 -2
  155. package/skills/cometchat-ios-calls/SKILL.md +225 -95
  156. package/skills/cometchat-ios-calls/references/add-calls-to-existing-chat.md +11 -9
  157. package/skills/cometchat-ios-calls/references/audio-modes-and-controls.md +45 -0
  158. package/skills/cometchat-ios-calls/references/avaudiosession-routing.md +6 -7
  159. package/skills/cometchat-ios-calls/references/call-layouts.md +31 -91
  160. package/skills/cometchat-ios-calls/references/call-session.md +51 -54
  161. package/skills/cometchat-ios-calls/references/callkit-and-pushkit.md +33 -29
  162. package/skills/cometchat-ios-calls/references/custom-ui.md +38 -38
  163. package/skills/cometchat-ios-calls/references/group-calls.md +33 -70
  164. package/skills/cometchat-ios-calls/references/idle-timeout.md +24 -25
  165. package/skills/cometchat-ios-calls/references/in-call-chat.md +19 -23
  166. package/skills/cometchat-ios-calls/references/migration-v4-to-v5.md +128 -70
  167. package/skills/cometchat-ios-calls/references/picture-in-picture.md +20 -20
  168. package/skills/cometchat-ios-calls/references/raise-hand.md +14 -227
  169. package/skills/cometchat-ios-calls/references/recording-screen-share.md +35 -122
  170. package/skills/cometchat-ios-calls/references/ringing-integration.md +17 -16
  171. package/skills/cometchat-ios-calls/references/share-invite.md +8 -12
  172. package/skills/cometchat-ios-calls/references/swiftui-uikit-hosting.md +4 -4
  173. package/skills/cometchat-ios-components/SKILL.md +200 -12
  174. package/skills/cometchat-ios-core/SKILL.md +173 -45
  175. package/skills/cometchat-ios-customization/SKILL.md +276 -110
  176. package/skills/cometchat-ios-features/SKILL.md +64 -36
  177. package/skills/cometchat-ios-placement/SKILL.md +15 -12
  178. package/skills/cometchat-ios-production/SKILL.md +12 -4
  179. package/skills/cometchat-ios-push/SKILL.md +53 -19
  180. package/skills/cometchat-ios-testing/SKILL.md +14 -9
  181. package/skills/cometchat-ios-theming/SKILL.md +39 -3
  182. package/skills/cometchat-ios-troubleshooting/SKILL.md +41 -21
  183. package/skills/cometchat-native-bare-patterns/SKILL.md +34 -17
  184. package/skills/cometchat-native-calls/SKILL.md +28 -16
  185. package/skills/cometchat-native-calls/references/add-calls-to-existing-chat.md +2 -2
  186. package/skills/cometchat-native-calls/references/call-layouts.md +15 -14
  187. package/skills/cometchat-native-calls/references/call-session.md +2 -2
  188. package/skills/cometchat-native-calls/references/custom-ui.md +12 -8
  189. package/skills/cometchat-native-calls/references/device-management.md +53 -30
  190. package/skills/cometchat-native-calls/references/group-calls.md +35 -30
  191. package/skills/cometchat-native-calls/references/idle-timeout.md +6 -6
  192. package/skills/cometchat-native-calls/references/in-call-chat.md +10 -8
  193. package/skills/cometchat-native-calls/references/migration-v4-to-v5.md +2 -2
  194. package/skills/cometchat-native-calls/references/raise-hand.md +15 -13
  195. package/skills/cometchat-native-calls/references/recording-screen-share.md +49 -170
  196. package/skills/cometchat-native-calls/references/share-invite.md +7 -5
  197. package/skills/cometchat-native-calls/references/voip-push-end-to-end.md +4 -2
  198. package/skills/cometchat-native-components/SKILL.md +84 -52
  199. package/skills/cometchat-native-core/SKILL.md +101 -32
  200. package/skills/cometchat-native-customization/SKILL.md +150 -28
  201. package/skills/cometchat-native-expo-patterns/SKILL.md +57 -26
  202. package/skills/cometchat-native-features/SKILL.md +23 -16
  203. package/skills/cometchat-native-placement/SKILL.md +19 -10
  204. package/skills/cometchat-native-production/SKILL.md +9 -3
  205. package/skills/cometchat-native-push/SKILL.md +2 -1
  206. package/skills/cometchat-native-testing/SKILL.md +1 -2
  207. package/skills/cometchat-native-theming/SKILL.md +54 -29
  208. package/skills/cometchat-native-troubleshooting/SKILL.md +9 -3
  209. package/skills/cometchat-nextjs-patterns/SKILL.md +20 -6
  210. package/skills/cometchat-placement/SKILL.md +42 -3
  211. package/skills/cometchat-production/SKILL.md +12 -5
  212. package/skills/cometchat-react-calls/SKILL.md +220 -10
  213. package/skills/cometchat-react-calls/references/add-calls-to-existing-chat.md +4 -3
  214. package/skills/cometchat-react-calls/references/call-layouts.md +5 -6
  215. package/skills/cometchat-react-calls/references/call-session.md +1 -1
  216. package/skills/cometchat-react-calls/references/custom-ui.md +61 -15
  217. package/skills/cometchat-react-calls/references/device-management.md +55 -51
  218. package/skills/cometchat-react-calls/references/group-calls.md +18 -23
  219. package/skills/cometchat-react-calls/references/idle-timeout.md +25 -12
  220. package/skills/cometchat-react-calls/references/in-call-chat.md +7 -7
  221. package/skills/cometchat-react-calls/references/migration-v4-to-v5.md +9 -11
  222. package/skills/cometchat-react-calls/references/raise-hand.md +14 -14
  223. package/skills/cometchat-react-calls/references/recording-screen-share.md +39 -38
  224. package/skills/cometchat-react-calls/references/ringing-integration.md +2 -2
  225. package/skills/cometchat-react-calls/references/share-invite.md +4 -5
  226. package/skills/cometchat-react-calls/references/testing-calls-on-web.md +20 -2
  227. package/skills/cometchat-react-calls/references/virtual-background.md +32 -0
  228. package/skills/cometchat-react-patterns/SKILL.md +44 -4
  229. package/skills/cometchat-react-push/SKILL.md +258 -72
  230. package/skills/cometchat-react-router-patterns/SKILL.md +10 -4
  231. package/skills/cometchat-react-testing/SKILL.md +14 -5
  232. package/skills/cometchat-theming/SKILL.md +181 -18
  233. package/skills/cometchat-troubleshooting/SKILL.md +40 -20
@@ -1,234 +1,135 @@
1
1
  ---
2
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.
3
+ description: CometChat Calls integration for Angular UI Kit v5 (@cometchat/chat-uikit-angular@5). Covers enabling calling via UIKitSettingsBuilder().setCallingEnabled(true), the kit's standalone call components (<cometchat-call-buttons>, <cometchat-incoming-call>, <cometchat-outgoing-call>, <cometchat-ongoing-call>, <cometchat-call-logs>), the @Input-callback-vs-@Output binding split, app-wide incoming-call mounting, the @cometchat/calls-sdk-javascript@^5 peer dep, NgZone correctness, getUserMedia handling, and additive-vs-standalone modes.
4
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"
5
+ compatibility: "Angular >=17 <22 (standalone APIs); @cometchat/chat-uikit-angular ^5.0 (5.0.2 verified); @cometchat/calls-sdk-javascript ^5.0 (calls peer); @cometchat/chat-sdk-javascript ^4.1"
7
6
  metadata:
8
7
  author: "CometChat"
9
8
  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"
9
+ tags: "cometchat angular calls voice video webrtc uikit-angular v5 standalone-components setCallingEnabled call-buttons incoming-call outgoing-call ongoing-call call-logs ngzone calls-sdk-javascript"
11
10
  ---
12
11
 
13
12
  ## Purpose
14
13
 
15
- Production-grade voice + video calling for Angular 12-15 apps. Loaded by `cometchat-calls` when `framework === "angular"`. Operates in two modes:
14
+ Production-grade voice + video calling for **Angular UI Kit v5** (`@cometchat/chat-uikit-angular@5`) apps. Loaded by `cometchat-calls` when `framework === "angular"`. Operates in two modes:
16
15
 
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`.
16
+ - **Additive** — calls layered onto an existing CometChat Angular UI Kit v5 chat integration. Enable calling on the `UIKitSettingsBuilder`, drop `<cometchat-call-buttons>` next to a user/group, and mount `<cometchat-incoming-call>` at the root of `AppComponent` so calls ring app-wide.
17
+ - **Standalone** — calls is the product, no chat surface. Same kit init + calling enabled, plus the call components (`<cometchat-ongoing-call>`, `<cometchat-call-logs>`, custom button screens) without `<cometchat-conversations>` / `<cometchat-message-*>`.
18
+
19
+ **v5 is standalone-component-based and targets Angular 17–21.** Import each call component *class* into the consuming standalone component's `imports: []` — there is no NgModule and **no `CUSTOM_ELEMENTS_SCHEMA`** (that was a v4 mental model; v5 components are real Angular components).
19
20
 
20
21
  **Read these other skills first:**
21
22
  - `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
23
+ - `cometchat-angular-core` — `UIKitSettingsBuilder` init, `APP_INITIALIZER` pattern, `login(uid)` (bare string), `loggedInUser$`, `environment.ts`
24
+ - `cometchat-angular-components` — full call-component binding tables (the `@Input`-callback-vs-`@Output` split)
25
+ - `cometchat-angular-patterns` — standalone wiring, route guards, NgZone, change detection
24
26
 
25
27
  **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)
28
+ - Kit types`@cometchat/chat-uikit-angular@5.0.2` → `node_modules/@cometchat/chat-uikit-angular/types/cometchat-chat-uikit-angular.d.ts`. Verify any non-obvious symbol against the installed `.d.ts` before relying on it.
29
+ - Calls SDK`@cometchat/calls-sdk-javascript@^5` (same underlying JS SDK as the React kit; the `CometChatUIKitCalls` namespace ships from this package)
30
+ - Public docshttps://www.cometchat.com/docs/ui-kit/angular and https://www.cometchat.com/docs/calls/javascript/overview
30
31
 
31
32
  ---
32
33
 
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
34
+ ## 1. How calling works in Angular UI Kit v5
61
35
 
62
- Same web shape, wrapped in services:
36
+ ### 1.0 The kit owns calls init — you enable it on the builder
63
37
 
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";
38
+ This is the single biggest difference from the old v4 calls skill. In v5 you do **not** hand-wire `CometChatCalls.init` / `CometChatCalls.login` for the kit path. You **enable calling on the `UIKitSettingsBuilder`** and the kit initializes the Calls SDK for you after `CometChatUIKit.login()` resolves.
70
39
 
71
- @Injectable({ providedIn: "root" })
72
- export class CallInitService {
73
- private initialized = false;
40
+ ```typescript
41
+ import { UIKitSettingsBuilder, CometChatUIKit } from "@cometchat/chat-uikit-angular";
42
+ import { environment } from "../environments/environment";
74
43
 
75
- async init(): Promise<void> {
76
- if (this.initialized) return;
44
+ const settings = new UIKitSettingsBuilder()
45
+ .setAppId(environment.cometchat.appId)
46
+ .setRegion(environment.cometchat.region) // "us" | "eu" | "in"
47
+ .setAuthKey(environment.cometchat.authKey) // dev only — omit in production
48
+ .subscribePresenceForAllUsers()
49
+ .setCallingEnabled(true) // ← turns calling on (verified builder method)
50
+ .build();
77
51
 
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
- }
52
+ await CometChatUIKit.init(settings);
53
+ // ... later, after login:
54
+ await CometChatUIKit.login("cometchat-uid-1"); // kit initializes the Calls SDK internally
95
55
  ```
96
56
 
97
- Wired via `APP_INITIALIZER` in `app.module.ts`:
57
+ - `setCallingEnabled(true)` is a real `UIKitSettingsBuilder` method (verified in the kit `.d.ts`). It is **off by default** — without it the call components render disabled and `CometChatUIKit.isCallingEnabled()` returns `false`.
58
+ - After login, confirm with `CometChatUIKit.isCallingEnabled()` (static, returns `boolean`) before rendering call UI on a custom screen.
59
+ - **Optional advanced config:** to override the Calls SDK app settings, build a `CometChatUIKitCalls.CallAppSettingsBuilder()` and pass it via `.setCallAppSettings(callAppSettings)`. `CometChatUIKitCalls` is re-exported by the UI Kit — import it from `@cometchat/chat-uikit-angular` (the kit wraps the optional `@cometchat/calls-sdk-javascript` dependency; the calls SDK itself exports `CometChatCalls`, not `CometChatUIKitCalls`):
98
60
 
99
- ```ts
100
- {
101
- provide: APP_INITIALIZER,
102
- useFactory: (svc: CallInitService) => () => svc.init(),
103
- deps: [CallInitService],
104
- multi: true,
105
- }
106
- ```
61
+ ```typescript
62
+ import { CometChatUIKitCalls } from "@cometchat/chat-uikit-angular";
107
63
 
108
- ### 1.2 VoIP push — N/A on Angular web (same as React)
64
+ const callAppSettings = new CometChatUIKitCalls.CallAppSettingsBuilder()
65
+ .setAppId(environment.cometchat.appId)
66
+ .setRegion(environment.cometchat.region)
67
+ .build();
109
68
 
110
- Same as `cometchat-react-calls` rule 1.2 — browsers don't have VoIP push. Web Push (Service Worker + `Notification`) is opt-in fallback.
69
+ const settings = new UIKitSettingsBuilder()
70
+ .setAppId(environment.cometchat.appId)
71
+ .setRegion(environment.cometchat.region)
72
+ .setCallingEnabled(true)
73
+ .setCallAppSettings(callAppSettings) // optional — kit builds defaults from appId+region if omitted
74
+ .build();
75
+ ```
111
76
 
112
- ### 1.3 Lifecycle — `getUserMedia` cleanup
77
+ Most integrations do not need `setCallAppSettings` — `setCallingEnabled(true)` is enough; the kit derives defaults from `appId` + `region`.
113
78
 
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.
79
+ ### 1.1 The calls peer dependency
115
80
 
116
- ### 1.4 Server-minted auth tokens
81
+ The Calls SDK is a **separate peer dependency** you must install yourself — the kit declares it as a peer but does not bundle it:
117
82
 
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
- }
83
+ ```bash
84
+ npm install @cometchat/calls-sdk-javascript@^5
147
85
  ```
148
86
 
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:
87
+ Without it, `setCallingEnabled(true)` fails at runtime when the kit tries to load `CometChatUIKitCalls` symptom: "Cannot find module @cometchat/calls-sdk-javascript" or call components that never connect.
154
88
 
155
- #### Pattern ASingle-component, gated by `@if (phase === 'ongoing')`
89
+ ### 1.2 VoIP push N/A on Angular web (same as React)
156
90
 
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:
91
+ Browsers don't have VoIP push. A closed tab cannot ring. Web Push (Service Worker + `Notification` API) is an opt-in fallback to nudge the user to an open tab; it does not bypass tab/page-load. Production web calls UX typically pairs with email/SMS fallback for missed calls.
158
92
 
159
- ```ts
160
- this.phase.set('ongoing');
93
+ ### 1.3 Lifecycle — `getUserMedia` cleanup
161
94
 
162
- // WRONGmicrotask runs before Angular renders the @if block
163
- // await Promise.resolve();
95
+ Browsers don't release the camera/mic until tracks are stopped. The kit's `<cometchat-ongoing-call>` handles this internally when the component is destroyed (`ngOnDestroy` ends the session). If you build a **custom** WebRTC surface with the raw Calls SDK (§4c), you must `getTracks().forEach(t => t.stop())` on hangup yourself.
164
96
 
165
- // RIGHT full task tick gives Angular's change detector time to mount the container
166
- await new Promise((r) => setTimeout(r, 0));
97
+ ### 1.4 Server-minted auth tokens (production)
167
98
 
168
- const container = this.callContainer?.nativeElement;
169
- if (!container) throw new Error('Call container not ready.');
170
- await CometChatCalls.joinSession(callToken, callSettings, container);
171
- ```
99
+ Production login uses `CometChatUIKit.loginWithAuthToken(tokenFromBackend)` — see `cometchat-angular-core` §4 and `cometchat-angular-production`. Because the kit owns calls init/login, the same auth-token login covers calls too on the kit path; there is no separate calls token step. (Raw-SDK custom surfaces in §4c that talk to `CometChatCalls` directly mint a session token via `CometChatCalls.generateToken(sessionId)`.)
172
100
 
173
- Validated 2026-05-13 against a Next.js peer.
101
+ ### 1.5 NgZone correctness for SDK callbacks
174
102
 
175
- #### Pattern B Separate `OngoingCallComponent`, parent-conditional mount (RECOMMENDED)
103
+ When a Calls SDK or Chat SDK callback fires outside Angular's zone, change detection doesn't run and the UI looks frozen until the next user interaction. The kit components run their own handlers inside the zone, but **any handler you write** (e.g. an `onAccept` callback, a raw `CometChat.addCallListener` listener, or the `error` `@Output`) that mutates component state should be safe under change detection. Two correct approaches:
176
104
 
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:
105
+ ```typescript
106
+ import { NgZone, ChangeDetectorRef } from "@angular/core";
178
107
 
179
- ```html
180
- <!-- app.component.html parent gates the whole overlay component -->
181
- <router-outlet />
108
+ // Approach A — wrap UI-mutating work in NgZone.run
109
+ constructor(private zone: NgZone) {}
182
110
 
183
- @if (state.isInCall()) {
184
- <app-ongoing-call />
185
- }
186
- @if (state.isIncoming()) {
187
- <app-incoming-call-overlay />
188
- }
189
- ```
111
+ handleAccept = (call: CometChat.Call) => {
112
+ this.zone.run(() => {
113
+ this.activeSessionId = call.getSessionId();
114
+ this.inCall = true;
115
+ });
116
+ };
190
117
 
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
- }
118
+ // Approach B (recommended for new code) — use signals; reactive readers
119
+ // re-render regardless of which zone the .set() ran in.
120
+ readonly inCall = signal(false);
121
+ handleAccept = (call: CometChat.Call) => { this.inCall.set(true); };
219
122
  ```
220
123
 
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.
124
+ **Rule:** any service/component state a template observes under `OnPush` MUST be a `signal` (or an observable via the `async` pipe / `toSignal`). A plain property set from outside the component's input/event surface never triggers `OnPush` change detection the template stays stuck on the initial value forever. See `cometchat-angular-patterns` for the full signals-vs-plain-property rule.
222
125
 
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.
126
+ ### 1.6 Permissions — the browser handles `getUserMedia`
224
127
 
225
- ### 1.6 Permissions browser handles `getUserMedia`
128
+ The browser prompts for camera/mic automatically when the Calls SDK starts media. Surface `NotAllowedError` (denied) and `NotFoundError` (no device) to a clear message via the `error` `@Output` / `onError` callback. **HTTPS is required** (or `localhost`) — `getUserMedia` returns `NotAllowedError` over plain HTTP. `ng serve --ssl` for local HTTPS.
226
129
 
227
- Same as web. Surface `NotAllowedError` and `NotFoundError` to a clear UI message. HTTPS required (or localhost).
130
+ ### 1.7 `<cometchat-incoming-call>` mounted at app root
228
131
 
229
- ### 1.7 IncomingCall mounted at app root
230
-
231
- `<cometchat-incoming-call>` belongs in `AppComponent`'s template, ABOVE `<router-outlet>`:
132
+ For calls to ring on **every** route, `<cometchat-incoming-call>` must live in a component that **stays mounted across navigation** — `AppComponent` (above `<router-outlet>`) is the simplest place. A **persistent authenticated shell** works equally well: the canonical Angular sample mounts it in its post-login home/shell component (`cometchat-home.component.html`), not literally in `AppComponent`. The rule is "lives in a host that outlives route changes," not "must be AppComponent specifically." Below uses `AppComponent` as the no-shell default:
232
133
 
233
134
  ```html
234
135
  <!-- app.component.html -->
@@ -236,115 +137,48 @@ Same as web. Surface `NotAllowedError` and `NotFoundError` to a clear UI message
236
137
  <router-outlet></router-outlet>
237
138
  ```
238
139
 
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>'
140
+ ```typescript
141
+ // app.component.ts — import the class into imports: []
142
+ import { Component } from "@angular/core";
143
+ import { RouterOutlet } from "@angular/router";
144
+ import { CometChatIncomingCallComponent } from "@cometchat/chat-uikit-angular";
145
+
146
+ @Component({
147
+ selector: "app-root",
148
+ standalone: true,
149
+ imports: [RouterOutlet, CometChatIncomingCallComponent],
150
+ templateUrl: "./app.component.html",
151
+ })
152
+ export class AppComponent {}
250
153
  ```
251
154
 
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.
155
+ Mounting it inside a feature-route component means the listener disappears on navigation calls only ring while that route is active. That is the canonical "calls don't ring" bug. For lazy-loaded features, keep the incoming-call mount in the eagerly-loaded `AppComponent`, not the lazy chunk.
253
156
 
254
- ### 1.8 Signals required for cross-service state under OnPush
157
+ ### 1.8 The `@Input`-callback vs `@Output` binding split (the #1 Angular-v5 calls trap)
255
158
 
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:
159
+ The call components expose accept/decline/error as **`@Input` callback props** (functions passed *into* the component), NOT `@Output` events — but several also expose `@Output` `EventEmitter`s for observing. Bind the form that exists for what you need:
336
160
 
337
161
  ```html
338
- @if (initError(); as err) {
339
- <div class="init-error">Init failed: {{ err }}</div>
340
- }
162
+ <!-- ✓ accept/decline/error are @Input CALLBACK props pass a function reference -->
163
+ <cometchat-incoming-call
164
+ [onAccept]="handleAccept"
165
+ [onDecline]="handleDecline"
166
+ [onError]="handleError">
167
+ </cometchat-incoming-call>
168
+
169
+ <!-- ✓ the SAME component also exposes @Outputs for observation -->
170
+ <cometchat-incoming-call
171
+ (callAccepted)="onAccepted($event)"
172
+ (callDeclined)="onDeclined($event)"
173
+ (error)="onErr($event)">
174
+ </cometchat-incoming-call>
341
175
  ```
342
176
 
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.
177
+ - `[onAccept]="handleAccept"` binds an `@Input` `handleAccept` is a **function reference** (do NOT call it: `[onAccept]="handleAccept()"` is wrong). Prefer the `@Input` callbacks for accept/decline because they carry the kit's built-in call handling.
178
+ - `(callAccepted)="onAccepted($event)"` binds an `@Output` — use `$event` and these for pure observation.
179
+ - **Don't cross them:** binding `(onAccept)` (as if it were an output) or `[callAccepted]` (as if it were an input) silently does nothing.
344
180
 
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.
181
+ See `cometchat-angular-components` for the exact per-component split.
348
182
 
349
183
  ---
350
184
 
@@ -353,159 +187,192 @@ Without this surface, a single bug deep in init causes the dev to spend 20+ minu
353
187
  ### Install
354
188
 
355
189
  ```bash
356
- npm install @cometchat/chat-sdk-javascript @cometchat/calls-sdk-javascript
357
- # additive mode: @cometchat/chat-uikit-angular is already installed
190
+ # additive mode: @cometchat/chat-uikit-angular@^5 is already installed.
191
+ # Always add the calls peer:
192
+ npm install @cometchat/calls-sdk-javascript@^5
358
193
  ```
359
194
 
360
- ### `app.module.ts` (NgModule path)
195
+ The chat SDK (`@cometchat/chat-sdk-javascript@^4.1`) and `dompurify@^3` are pulled in by the kit's peers. Do **not** install `@cometchat/uikit-shared` / `-elements` / `-resources` — they don't exist in v5.
361
196
 
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";
197
+ ### Enable calling at init (standalone bootstrap, Angular 17+)
366
198
 
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
199
+ ```typescript
387
200
  // main.ts
201
+ import { bootstrapApplication } from "@angular/platform-browser";
202
+ import { APP_INITIALIZER } from "@angular/core";
203
+ import { provideRouter } from "@angular/router";
204
+ import { provideAnimations } from "@angular/platform-browser/animations";
205
+ import { UIKitSettingsBuilder, CometChatUIKit } from "@cometchat/chat-uikit-angular";
206
+ import { AppComponent } from "./app/app.component";
207
+ import { routes } from "./app/app.routes";
208
+ import { environment } from "./environments/environment";
209
+
210
+ function initCometChat() {
211
+ return () => {
212
+ const settings = new UIKitSettingsBuilder()
213
+ .setAppId(environment.cometchat.appId)
214
+ .setRegion(environment.cometchat.region)
215
+ .setAuthKey(environment.cometchat.authKey) // dev only
216
+ .subscribePresenceForAllUsers()
217
+ .setCallingEnabled(true) // ← enable calls
218
+ .build();
219
+ return CometChatUIKit.init(settings); // return Promise so bootstrap waits
220
+ };
221
+ }
222
+
388
223
  bootstrapApplication(AppComponent, {
389
224
  providers: [
390
- {
391
- provide: APP_INITIALIZER,
392
- useFactory: (svc: CallInitService) => () => svc.init(),
393
- deps: [CallInitService],
394
- multi: true,
395
- },
225
+ provideRouter(routes),
226
+ provideAnimations(),
227
+ { provide: APP_INITIALIZER, useFactory: initCometChat, multi: true },
396
228
  ],
397
229
  });
398
230
  ```
399
231
 
400
- The standalone-component path skips `CometChatUIKitModule` instead, individual standalone selectors are imported per-component.
232
+ Login (dev user or production token) then runs in a route guard / auth service after init resolves — see `cometchat-angular-core` §4. The kit initializes the Calls SDK on login when `setCallingEnabled(true)` was set.
401
233
 
402
- ---
234
+ > NgModule app (not yet migrated to standalone)? You can still import these standalone component classes into an `@NgModule({ imports: [...] })`. You still do **not** need `CUSTOM_ELEMENTS_SCHEMA`.
235
+
236
+ ### Assets
403
237
 
404
- ## 3. Components catalog
238
+ Calls icons come from the same kit asset bundle as chat — confirm the `angular.json` assets glob from `cometchat-angular-core` §2 is present, or call buttons render without icons.
405
239
 
406
- ### Calls SDK primitives (used in standalone or custom components)
240
+ ---
407
241
 
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).
242
+ ## 3. Call components catalog
409
243
 
410
- ### UI Kit selectors (additive mode `@cometchat/chat-uikit-angular`)
244
+ All are **standalone** import the `*Component` class into the consuming component's `imports: []`. Selectors and bindings below are verified against `@cometchat/chat-uikit-angular@5.0.2` types.
411
245
 
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 |
246
+ | Class (import into `imports: []`) | Selector | Key bindings |
247
+ |---|---|---|
248
+ | `CometChatCallButtonsComponent` | `<cometchat-call-buttons>` | `@Input`: `user`, `group`, `callSettingsBuilder`, `hideVoiceCallButton`, `hideVideoCallButton`, `hideOverlays`, `outgoingCallDisableSoundForCalls`, `outgoingCallCustomSoundForCalls` · `@Input` callbacks: `onVoiceCallClick`, `onVideoCallClick`, `onError` · `@Output`: `error` |
249
+ | `CometChatIncomingCallComponent` | `<cometchat-incoming-call>` | `@Input`: `call`, `disableSoundForCalls`, `customSoundForCalls` · `@Input` callbacks: `onAccept`, `onDecline`, `onError` · `@Output`: `callAccepted`, `callDeclined`, `error` |
250
+ | `CometChatOutgoingCallComponent` | `<cometchat-outgoing-call>` | `@Input`: `call`, `disableSoundForCalls`, `customSoundForCalls` · `@Input` callback: `onError` · `@Output`: `callCanceled`, `error` |
251
+ | `CometChatOngoingCallComponent` | `<cometchat-ongoing-call>` | `@Input`: `sessionID`, `callSettingsBuilder`, `callWorkflow`, `isAudioOnly` · `@Input` callback: `onError` · `@Output`: `callEnded`, `error` |
252
+ | `CometChatCallLogsComponent` | `<cometchat-call-logs>` | `@Input`: `activeCall`, `callLogRequestBuilder`, `callSettingsBuilder`, `showScrollbar`, `callInitiatedDateTimeFormat`, `menuView`, plus template overrides (`itemView`, `leadingView`, `titleView`, `subtitleView`, `trailingView`, `loadingView`, `emptyView`, `errorView`) · `@Input` callback: `onError` · `@Output`: `itemClick`, `callButtonClicked` |
419
253
 
420
- `CUSTOM_ELEMENTS_SCHEMA` (or full module imports) must be in the consuming module — same rule as the chat selectors.
254
+ Notes:
255
+ - `callSettingsBuilder` is typed `typeof CometChatUIKitCalls.CallSettingsBuilder` — pass the **unbuilt builder instance** if you customize it; the kit calls `.build()` internally. Most integrations omit it and let the kit build defaults.
256
+ - **⚠️ Idle timeout is in MILLISECONDS** (Angular uses `@cometchat/calls-sdk-javascript` — the web family). The `SessionSettings` idle fields are **ms, not seconds**: `idleTimeoutPeriodBeforePrompt: 180` means **180 ms**, so a solo session shows the "Are you still there?" prompt and exits almost instantly on join. Use ms — `{ idleTimeoutPeriodBeforePrompt: 180_000, idleTimeoutPeriodAfterPrompt: 60_000 }` (the JS SDK defaults are 60_000 / 120_000; some docs surfaces list 180_000 for the before-prompt — either is fine; the load-bearing point is ms-not-seconds). The timer only runs while you're the **sole** participant. (Native Android/iOS/Flutter use **seconds** here — Angular/web/RN are the ms outliers.)
257
+ - `callWorkflow` on `<cometchat-ongoing-call>` is the `CallWorkflow` enum: `CallWorkflow.defaultCalling` (Chat-SDK signaling, the default) or `CallWorkflow.directCalling` (Calls-SDK direct). Import `CallWorkflow` from `@cometchat/chat-uikit-angular`.
258
+ - `<cometchat-message-header>` auto-renders call buttons when a `user`/`group` is set (it has its own `hideVoiceCallButton` / `hideVideoCallButton` / `voiceCallClick` / `videoCallClick`). Don't add a second `<cometchat-call-buttons>` next to it — see anti-pattern 2.
259
+ - **HMR/dev-server caveat (non-fatal):** on a Vite/webpack hot reload you may see `ERR_ALREADY_LOGGED_IN` in the console — the kit re-runs its calling init against a still-live session. It's harmless; a full page refresh clears it. Do NOT add retry/teardown logic to "fix" it.
260
+ - **Known interop issue — kit caller → custom-UI Angular receiver:** when a kit-initiated 1:1 call rings an Angular app that renders its OWN receiver UI (raw `CometChat.addCallListener`), `onIncomingCallReceived` may not fire (the server routes, but the listener stays silent — suspected stale-session/mixed-version interop). Reverse direction (Angular kit caller → kit receiver) is reliable. If you build a custom receiver surface, verify the listener attaches BEFORE any call can arrive, and prefer the kit's `<cometchat-incoming-call>` over a hand-rolled receiver until this is resolved.
421
261
 
422
262
  ---
423
263
 
424
- ## 4. Standalone integration
264
+ ## 4. Integration shapes
425
265
 
426
- When `product === "voice-video"` and there is no existing UI Kit.
266
+ ### 4a. Additive calls on top of an existing v5 chat integration (most common)
427
267
 
428
- **Split by calling mode these are two different shapes:**
268
+ When `cometchat-angular-core` chat is already wired. The skill:
429
269
 
430
- ### 4a. Standalone — Session mode (meeting-room UX, no ringing)
270
+ 1. Installs `@cometchat/calls-sdk-javascript@^5`.
271
+ 2. Adds `.setCallingEnabled(true)` to the existing `UIKitSettingsBuilder` chain (rule 1.0). Optionally `.setCallAppSettings(...)`.
272
+ 3. Mounts `<cometchat-incoming-call>` in `AppComponent` above `<router-outlet>` (rule 1.7) and imports `CometChatIncomingCallComponent`.
273
+ 4. Lets `<cometchat-message-header>` render the call buttons automatically (a `user`/`group` is already bound on the messages screen), OR — on a custom contact/profile screen with no message header — drops a standalone `<cometchat-call-buttons [user]="user">`.
274
+ 5. Optionally adds a `/calls` route hosting `<cometchat-call-logs>`.
431
275
 
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:
276
+ ```typescript
277
+ // contact-actions.component.ts (custom screen, no message header)
278
+ import { Component, Input } from "@angular/core";
279
+ import { CometChat } from "@cometchat/chat-sdk-javascript";
280
+ import { CometChatCallButtonsComponent } from "@cometchat/chat-uikit-angular";
281
+
282
+ @Component({
283
+ selector: "app-contact-actions",
284
+ standalone: true,
285
+ imports: [CometChatCallButtonsComponent],
286
+ template: `
287
+ <cometchat-call-buttons
288
+ [user]="user"
289
+ [onError]="handleError">
290
+ </cometchat-call-buttons>
291
+ `,
292
+ })
293
+ export class ContactActionsComponent {
294
+ @Input() user!: CometChat.User;
295
+ handleError = (e: CometChat.CometChatException) => console.error("call error", e);
296
+ }
297
+ ```
433
298
 
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.
299
+ ### 4b. Standalone calls is the product (no chat surface)
439
300
 
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`.
301
+ Same kit init + `setCallingEnabled(true)`, but no `<cometchat-conversations>` / `<cometchat-message-*>`. The skill scaffolds:
441
302
 
442
- ### 4b. Standalone Ringing mode (CallButtons + Incoming/Outgoing/Ongoing kit selectors)
303
+ 1. **Init + login** via `APP_INITIALIZER` with `setCallingEnabled(true)` (§2).
304
+ 2. **A user-picker / contact screen** rendering `<cometchat-call-buttons [user]="selectedUser">` to start a call.
305
+ 3. **`<cometchat-incoming-call>` in `AppComponent`** above `<router-outlet>` so the device rings (rule 1.7).
306
+ 4. **`<cometchat-outgoing-call>`** is rendered by the kit's calling flow on initiate; you typically don't mount it manually unless driving a fully custom flow.
307
+ 5. **A `/calls` route** with `<cometchat-call-logs (itemClick)="onLog($event)">` for history.
308
+ 6. **`environment.ts`** credentials block (from `cometchat-angular-core`).
309
+ 7. **HTTPS check** — warn if the dev server is HTTP non-localhost.
443
310
 
444
- Dual-SDK: Chat SDK signaling channel + Calls SDK media channel. The skill scaffolds:
311
+ The kit's incoming/outgoing/ongoing components handle the WebRTC surface end-to-end; you do not call `joinSession` yourself on this path.
445
312
 
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.
313
+ ### 4c. Custom call screen with the raw Calls SDK (advanced)
454
314
 
455
- ## 5. Additive integration
315
+ Only when the user explicitly wants a fully custom in-call UI (custom controls/layout) instead of the kit's `<cometchat-ongoing-call>`. This uses the raw `@cometchat/calls-sdk-javascript` API directly — the **same JS Calls SDK surface documented in `cometchat-react-calls` §3** (`CometChat.initiateCall` for signaling, then `CometChatCalls.generateToken(sessionId)` → `CometChatCalls.joinSession(token, settings, htmlElement)` → `CometChatCalls.leaveSession()`). Angular specifics:
456
316
 
457
- When `cometchat-angular-core` integration already exists. The skill:
317
+ - The container `<div>` must be in the DOM with **non-zero dimensions** when `joinSession` runs. Gate it correctly:
318
+ - **Preferred:** put the container in its own component and let the **parent** decide (via `@if`) whether to instantiate it. `ngAfterViewInit` then fires with the `@ViewChild` resolved — no `setTimeout(0)` needed.
319
+ - If the container lives in the same component gated by an inner `@if (inCall())`, a microtask runs before Angular renders the block, so a `@ViewChild` read is still null — use a **full task tick** (`await new Promise(r => setTimeout(r, 0))`) before reading `nativeElement`.
320
+ - Wrap any Calls-SDK callback that mutates UI in `NgZone.run` (or drive state through signals) — rule 1.5.
321
+ - On hangup: `CometChatCalls.leaveSession()` then stop any custom `MediaStream` tracks (rule 1.3).
322
+ - Audio-only voice calls: set the Chat-SDK call type to audio for signaling AND `setIsAudioOnlyCall(true)` on the Calls-SDK `CallSettingsBuilder` used for `joinSession` — see `cometchat-react-calls` §4c.
458
323
 
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>`.
324
+ Do NOT invent token-mint helpers: the v5 method is `CometChatCalls.generateToken(sessionId)` auth is internal after login (the signature is `generateToken(sessionId, authToken?)`, but the optional second arg is only for explicit-token flows; omit it on the post-login path). There is no `getRTCToken` in v5.
464
325
 
465
- ## 6. Anti-patterns
326
+ ---
466
327
 
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.
328
+ ## 5. Anti-patterns
478
329
 
479
- ## 7. Verification checklist
330
+ 1. **Forgetting `.setCallingEnabled(true)`.** Call components render but stay disabled; `CometChatUIKit.isCallingEnabled()` is `false`. (rule 1.0)
331
+ 2. **Adding `<cometchat-call-buttons>` next to `<cometchat-message-header>`.** The header already renders call buttons when a `user`/`group` is bound — you get a duplicate set. Use the header's own `hideVoiceCallButton`/`hideVideoCallButton` or its `voiceCallClick`/`videoCallClick` instead. (rule 1.8 / §3)
332
+ 3. **Skipping the `@cometchat/calls-sdk-javascript@^5` peer install.** Runtime "cannot find module" / calls never connect. (rule 1.1)
333
+ 4. **Adding `CUSTOM_ELEMENTS_SCHEMA`.** v5 components are real Angular components — the schema is unnecessary and signals a v4 mental model. Import the `*Component` class into `imports: []` instead.
334
+ 5. **Mounting `<cometchat-incoming-call>` inside a feature-route component.** Disappears on navigation; calls only ring on that route. Mount in `AppComponent`. (rule 1.7)
335
+ 6. **Binding a call `@Input` callback as an `@Output`** (`(onAccept)`) **or an `@Output` as an `@Input`** (`[callAccepted]`). Silently does nothing — bind the form that exists. (rule 1.8)
336
+ 7. **Calling the callback in the template** (`[onAccept]="handleAccept()"`). Pass a **reference** (`[onAccept]="handleAccept"`).
337
+ 8. **Plain properties on `OnPush` components/services consumed by the template.** State set from outside the input/event surface never triggers change detection. Use signals. (rule 1.5)
338
+ 9. **Manually calling `CometChatCalls.init`/`CometChatCalls.login` for the kit path.** The kit owns calls init when `setCallingEnabled(true)` is set — don't double-init. Manual `CometChatCalls.*` is only for the raw-SDK custom surface (§4c). (rule 1.0)
339
+ 10. **Running over HTTP (non-localhost).** `getUserMedia` denies. Use HTTPS or `localhost` (`ng serve --ssl`). (rule 1.6)
340
+ 11. **Init inside a lazy-loaded route.** Init must complete before any `<cometchat-*>` renders and before a call can arrive. Use `APP_INITIALIZER` (or gate on an `isReady` flag) — see `cometchat-angular-core` §3.
341
+
342
+ ---
343
+
344
+ ## 6. Verification checklist
480
345
 
481
346
  **Static:**
482
347
 
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
348
+ - [ ] `@cometchat/calls-sdk-javascript@^5` in `package.json` (calls peer)
349
+ - [ ] `@cometchat/chat-uikit-angular@^5` in `package.json`
350
+ - [ ] `.setCallingEnabled(true)` on the `UIKitSettingsBuilder` chain
351
+ - [ ] `<cometchat-incoming-call>` in `AppComponent` template above `<router-outlet>`, and `CometChatIncomingCallComponent` in `AppComponent`'s `imports: []`
352
+ - [ ] Each call component class imported into the consuming standalone component's `imports: []` (no `CUSTOM_ELEMENTS_SCHEMA`)
353
+ - [ ] accept/decline/error bound as `@Input` callbacks (`[onAccept]="fn"`), or `@Output`s (`(callAccepted)="fn($event)"`)the correct form per `cometchat-angular-components`
354
+ - [ ] Callback inputs pass a function **reference**, not a call (`[onAccept]="handleAccept"`)
355
+ - [ ] No second `<cometchat-call-buttons>` next to a `<cometchat-message-header>` that already shows them
356
+ - [ ] Init via `APP_INITIALIZER` (not a lazy route); `<cometchat-*>` gated until init+login resolve
357
+ - [ ] Template-observed state under `OnPush` is a `signal` / `async` pipe (not a plain property)
493
358
  - [ ] `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)
359
+ - [ ] (§4c only) hangup path calls `CometChatCalls.leaveSession()` + stops custom `MediaStream` tracks
360
+ - [ ] Node version ≥ 20.19 or ≥ 22.12 (Angular CLI 17+ requirement)
496
361
 
497
362
  **Runtime (browser):**
498
363
 
499
364
  - [ ] Outgoing call connects, two-way audio + video
500
365
  - [ ] 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
366
+ - [ ] Camera light off within ~2 seconds of hangup
367
+ - [ ] Route navigation during a call cleanly disconnects
368
+ - [ ] HTTPS or localhost only — `getUserMedia` works
369
+
370
+ ## 7. Pointers
371
+
372
+ - `references/virtual-background.md` — blur / custom image / clear (web-only)
373
+ - `cometchat-angular-core` — `UIKitSettingsBuilder`, init/login order, `environment.ts`, theming
374
+ - `cometchat-angular-components` — full call-component binding tables (the `@Input`-callback-vs-`@Output` split)
375
+ - `cometchat-angular-patterns` — standalone wiring, route guards, NgZone, signals-under-OnPush
376
+ - `cometchat-angular-production` — server-minted auth tokens, user management
377
+ - `cometchat-angular-troubleshooting` — runtime failures, zone issues, SSR/Universal
378
+ - `cometchat-react-calls` — raw JS Calls SDK API surface (shared underlying SDK; §4c custom-surface reference)