@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.
- package/LICENSE +21 -0
- package/bin/install.js +27 -0
- package/package.json +14 -1
- package/skills/cometchat/SKILL.md +233 -69
- package/skills/cometchat/references/asking-questions.md +48 -0
- package/skills/cometchat-a11y/SKILL.md +3 -2
- package/skills/cometchat-android-v5/SKILL.md +2 -1
- package/skills/cometchat-android-v5-calls/SKILL.md +36 -22
- package/skills/cometchat-android-v5-calls/references/README.md +1 -1
- package/skills/cometchat-android-v5-calls/references/add-calls-to-existing-chat.md +7 -5
- package/skills/cometchat-android-v5-calls/references/audio-controls.md +4 -4
- package/skills/cometchat-android-v5-calls/references/call-layouts.md +33 -25
- package/skills/cometchat-android-v5-calls/references/call-session.md +2 -2
- package/skills/cometchat-android-v5-calls/references/custom-ui.md +5 -5
- package/skills/cometchat-android-v5-calls/references/event-listeners.md +2 -2
- package/skills/cometchat-android-v5-calls/references/idle-timeout.md +20 -14
- package/skills/cometchat-android-v5-calls/references/in-call-chat.md +1 -1
- package/skills/cometchat-android-v5-calls/references/migration-v4-to-v5.md +43 -27
- package/skills/cometchat-android-v5-calls/references/participant-management.md +3 -3
- package/skills/cometchat-android-v5-calls/references/raise-hand.md +25 -19
- package/skills/cometchat-android-v5-calls/references/recording.md +2 -2
- package/skills/cometchat-android-v5-calls/references/ringing-integration.md +1 -1
- package/skills/cometchat-android-v5-calls/references/screen-sharing.md +5 -9
- package/skills/cometchat-android-v5-calls/references/session-settings.md +3 -3
- package/skills/cometchat-android-v5-calls/references/setup.md +1 -1
- package/skills/cometchat-android-v5-calls/references/share-invite.md +9 -4
- package/skills/cometchat-android-v5-calls/references/video-controls.md +4 -4
- package/skills/cometchat-android-v5-calls/references/voip-calling.md +2 -2
- package/skills/cometchat-android-v5-components/SKILL.md +4 -3
- package/skills/cometchat-android-v5-core/SKILL.md +5 -3
- package/skills/cometchat-android-v5-customization/SKILL.md +171 -7
- package/skills/cometchat-android-v5-extensions/SKILL.md +7 -4
- package/skills/cometchat-android-v5-features/SKILL.md +5 -4
- package/skills/cometchat-android-v5-placement/SKILL.md +2 -1
- package/skills/cometchat-android-v5-production/SKILL.md +2 -1
- package/skills/cometchat-android-v5-push/SKILL.md +2 -3
- package/skills/cometchat-android-v5-testing/SKILL.md +2 -1
- package/skills/cometchat-android-v5-theming/SKILL.md +2 -1
- package/skills/cometchat-android-v5-troubleshooting/SKILL.md +3 -2
- package/skills/cometchat-android-v6/SKILL.md +2 -1
- package/skills/cometchat-android-v6-builder-settings/SKILL.md +11 -7
- package/skills/cometchat-android-v6-calls/SKILL.md +79 -18
- package/skills/cometchat-android-v6-calls/references/advanced-features.md +87 -0
- package/skills/cometchat-android-v6-calls/references/call-layouts.md +24 -15
- package/skills/cometchat-android-v6-calls/references/call-session.md +2 -2
- package/skills/cometchat-android-v6-calls/references/device-management.md +17 -16
- package/skills/cometchat-android-v6-calls/references/idle-timeout.md +7 -4
- package/skills/cometchat-android-v6-calls/references/in-call-chat.md +13 -8
- package/skills/cometchat-android-v6-calls/references/raise-hand.md +6 -4
- package/skills/cometchat-android-v6-compose-components/SKILL.md +52 -29
- package/skills/cometchat-android-v6-compose-customization/SKILL.md +156 -1
- package/skills/cometchat-android-v6-compose-placement/SKILL.md +129 -40
- package/skills/cometchat-android-v6-compose-theming/SKILL.md +27 -1
- package/skills/cometchat-android-v6-core/SKILL.md +208 -28
- package/skills/cometchat-android-v6-events/SKILL.md +4 -1
- package/skills/cometchat-android-v6-extensions/SKILL.md +2 -1
- package/skills/cometchat-android-v6-features/SKILL.md +26 -2
- package/skills/cometchat-android-v6-kotlin-components/SKILL.md +31 -1
- package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +172 -1
- package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +20 -5
- package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +36 -5
- package/skills/cometchat-android-v6-migration/SKILL.md +44 -42
- package/skills/cometchat-android-v6-production/SKILL.md +6 -3
- package/skills/cometchat-android-v6-push/SKILL.md +43 -2
- package/skills/cometchat-android-v6-testing/SKILL.md +11 -8
- package/skills/cometchat-android-v6-troubleshooting/SKILL.md +26 -5
- package/skills/cometchat-angular-calls/SKILL.md +256 -389
- package/skills/cometchat-angular-calls/references/add-calls-to-existing-chat.md +3 -2
- package/skills/cometchat-angular-calls/references/call-layouts.md +29 -12
- package/skills/cometchat-angular-calls/references/call-session.md +2 -2
- package/skills/cometchat-angular-calls/references/custom-ui.md +18 -10
- package/skills/cometchat-angular-calls/references/device-management.md +53 -34
- package/skills/cometchat-angular-calls/references/group-calls.md +45 -24
- package/skills/cometchat-angular-calls/references/idle-timeout.md +31 -15
- package/skills/cometchat-angular-calls/references/ngzone-and-async-callbacks.md +7 -6
- package/skills/cometchat-angular-calls/references/raise-hand.md +9 -4
- package/skills/cometchat-angular-calls/references/recording-screen-share.md +32 -39
- package/skills/cometchat-angular-calls/references/ringing-integration.md +3 -1
- package/skills/cometchat-angular-calls/references/share-invite.md +11 -5
- package/skills/cometchat-angular-calls/references/virtual-background.md +29 -0
- package/skills/cometchat-angular-components/SKILL.md +149 -620
- package/skills/cometchat-angular-core/SKILL.md +232 -312
- package/skills/cometchat-angular-customization/SKILL.md +415 -223
- package/skills/cometchat-angular-features/SKILL.md +216 -334
- package/skills/cometchat-angular-patterns/SKILL.md +168 -359
- package/skills/cometchat-angular-placement/SKILL.md +189 -560
- package/skills/cometchat-angular-production/SKILL.md +241 -92
- package/skills/cometchat-angular-push/SKILL.md +280 -294
- package/skills/cometchat-angular-testing/SKILL.md +430 -158
- package/skills/cometchat-angular-theming/SKILL.md +190 -265
- package/skills/cometchat-angular-troubleshooting/SKILL.md +192 -157
- package/skills/cometchat-astro-patterns/SKILL.md +2 -1
- package/skills/cometchat-calls/SKILL.md +25 -19
- package/skills/cometchat-calls/references/use-case-broadcast.md +15 -10
- package/skills/cometchat-calls/references/use-case-marketplace.md +2 -3
- package/skills/cometchat-calls/references/use-case-support.md +3 -4
- package/skills/cometchat-calls/references/use-case-team.md +23 -12
- package/skills/cometchat-calls/references/use-case-telehealth.md +3 -4
- package/skills/cometchat-components/SKILL.md +163 -25
- package/skills/cometchat-core/SKILL.md +255 -19
- package/skills/cometchat-customization/SKILL.md +50 -25
- package/skills/cometchat-features/SKILL.md +313 -34
- package/skills/cometchat-flutter-v5/SKILL.md +10 -4
- package/skills/cometchat-flutter-v5-calls/SKILL.md +188 -158
- package/skills/cometchat-flutter-v5-calls/references/add-calls-to-existing-chat.md +48 -24
- package/skills/cometchat-flutter-v5-calls/references/call-layouts.md +20 -15
- package/skills/cometchat-flutter-v5-calls/references/call-session.md +100 -145
- package/skills/cometchat-flutter-v5-calls/references/device-management.md +12 -8
- package/skills/cometchat-flutter-v5-calls/references/group-calls.md +30 -36
- package/skills/cometchat-flutter-v5-calls/references/idle-timeout.md +15 -13
- package/skills/cometchat-flutter-v5-calls/references/in-call-chat.md +12 -9
- package/skills/cometchat-flutter-v5-calls/references/migration-v4-to-v5.md +115 -65
- package/skills/cometchat-flutter-v5-calls/references/raise-hand.md +41 -30
- package/skills/cometchat-flutter-v5-calls/references/ringing-integration.md +17 -14
- package/skills/cometchat-flutter-v5-calls/references/share-invite.md +8 -2
- package/skills/cometchat-flutter-v5-conversations/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-core/SKILL.md +5 -4
- package/skills/cometchat-flutter-v5-customization/SKILL.md +136 -5
- package/skills/cometchat-flutter-v5-events/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-messages/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-production/SKILL.md +15 -6
- package/skills/cometchat-flutter-v5-push/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-testing/SKILL.md +17 -6
- package/skills/cometchat-flutter-v5-theming/SKILL.md +2 -1
- package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +7 -6
- package/skills/cometchat-flutter-v5-users-groups/SKILL.md +3 -2
- package/skills/cometchat-flutter-v6/SKILL.md +17 -16
- package/skills/cometchat-flutter-v6-calls/SKILL.md +72 -57
- package/skills/cometchat-flutter-v6-calls/references/add-calls-to-existing-chat.md +5 -3
- package/skills/cometchat-flutter-v6-calls/references/advanced-features.md +89 -0
- package/skills/cometchat-flutter-v6-calls/references/call-layouts.md +15 -12
- package/skills/cometchat-flutter-v6-calls/references/call-session.md +2 -2
- package/skills/cometchat-flutter-v6-calls/references/device-management.md +9 -3
- package/skills/cometchat-flutter-v6-calls/references/group-calls.md +10 -10
- package/skills/cometchat-flutter-v6-calls/references/idle-timeout.md +15 -7
- package/skills/cometchat-flutter-v6-calls/references/in-call-chat.md +6 -3
- package/skills/cometchat-flutter-v6-calls/references/raise-hand.md +23 -16
- package/skills/cometchat-flutter-v6-components/SKILL.md +32 -11
- package/skills/cometchat-flutter-v6-conversations/SKILL.md +39 -11
- package/skills/cometchat-flutter-v6-core/SKILL.md +182 -21
- package/skills/cometchat-flutter-v6-customization/SKILL.md +97 -25
- package/skills/cometchat-flutter-v6-events/SKILL.md +3 -2
- package/skills/cometchat-flutter-v6-features/SKILL.md +15 -6
- package/skills/cometchat-flutter-v6-messages/SKILL.md +111 -60
- package/skills/cometchat-flutter-v6-migration/SKILL.md +18 -25
- package/skills/cometchat-flutter-v6-placement/SKILL.md +79 -50
- package/skills/cometchat-flutter-v6-production/SKILL.md +13 -12
- package/skills/cometchat-flutter-v6-push/SKILL.md +41 -19
- package/skills/cometchat-flutter-v6-testing/SKILL.md +4 -4
- package/skills/cometchat-flutter-v6-theming/SKILL.md +38 -5
- package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +182 -17
- package/skills/cometchat-flutter-v6-users-groups/SKILL.md +12 -4
- package/skills/cometchat-i18n/SKILL.md +139 -78
- package/skills/cometchat-ios/SKILL.md +4 -2
- package/skills/cometchat-ios-calls/SKILL.md +225 -95
- package/skills/cometchat-ios-calls/references/add-calls-to-existing-chat.md +11 -9
- package/skills/cometchat-ios-calls/references/audio-modes-and-controls.md +45 -0
- package/skills/cometchat-ios-calls/references/avaudiosession-routing.md +6 -7
- package/skills/cometchat-ios-calls/references/call-layouts.md +31 -91
- package/skills/cometchat-ios-calls/references/call-session.md +51 -54
- package/skills/cometchat-ios-calls/references/callkit-and-pushkit.md +33 -29
- package/skills/cometchat-ios-calls/references/custom-ui.md +38 -38
- package/skills/cometchat-ios-calls/references/group-calls.md +33 -70
- package/skills/cometchat-ios-calls/references/idle-timeout.md +24 -25
- package/skills/cometchat-ios-calls/references/in-call-chat.md +19 -23
- package/skills/cometchat-ios-calls/references/migration-v4-to-v5.md +128 -70
- package/skills/cometchat-ios-calls/references/picture-in-picture.md +20 -20
- package/skills/cometchat-ios-calls/references/raise-hand.md +14 -227
- package/skills/cometchat-ios-calls/references/recording-screen-share.md +35 -122
- package/skills/cometchat-ios-calls/references/ringing-integration.md +17 -16
- package/skills/cometchat-ios-calls/references/share-invite.md +8 -12
- package/skills/cometchat-ios-calls/references/swiftui-uikit-hosting.md +4 -4
- package/skills/cometchat-ios-components/SKILL.md +200 -12
- package/skills/cometchat-ios-core/SKILL.md +173 -45
- package/skills/cometchat-ios-customization/SKILL.md +276 -110
- package/skills/cometchat-ios-features/SKILL.md +64 -36
- package/skills/cometchat-ios-placement/SKILL.md +15 -12
- package/skills/cometchat-ios-production/SKILL.md +12 -4
- package/skills/cometchat-ios-push/SKILL.md +53 -19
- package/skills/cometchat-ios-testing/SKILL.md +14 -9
- package/skills/cometchat-ios-theming/SKILL.md +39 -3
- package/skills/cometchat-ios-troubleshooting/SKILL.md +41 -21
- package/skills/cometchat-native-bare-patterns/SKILL.md +34 -17
- package/skills/cometchat-native-calls/SKILL.md +28 -16
- package/skills/cometchat-native-calls/references/add-calls-to-existing-chat.md +2 -2
- package/skills/cometchat-native-calls/references/call-layouts.md +15 -14
- package/skills/cometchat-native-calls/references/call-session.md +2 -2
- package/skills/cometchat-native-calls/references/custom-ui.md +12 -8
- package/skills/cometchat-native-calls/references/device-management.md +53 -30
- package/skills/cometchat-native-calls/references/group-calls.md +35 -30
- package/skills/cometchat-native-calls/references/idle-timeout.md +6 -6
- package/skills/cometchat-native-calls/references/in-call-chat.md +10 -8
- package/skills/cometchat-native-calls/references/migration-v4-to-v5.md +2 -2
- package/skills/cometchat-native-calls/references/raise-hand.md +15 -13
- package/skills/cometchat-native-calls/references/recording-screen-share.md +49 -170
- package/skills/cometchat-native-calls/references/share-invite.md +7 -5
- package/skills/cometchat-native-calls/references/voip-push-end-to-end.md +4 -2
- package/skills/cometchat-native-components/SKILL.md +84 -52
- package/skills/cometchat-native-core/SKILL.md +101 -32
- package/skills/cometchat-native-customization/SKILL.md +150 -28
- package/skills/cometchat-native-expo-patterns/SKILL.md +57 -26
- package/skills/cometchat-native-features/SKILL.md +23 -16
- package/skills/cometchat-native-placement/SKILL.md +19 -10
- package/skills/cometchat-native-production/SKILL.md +9 -3
- package/skills/cometchat-native-push/SKILL.md +2 -1
- package/skills/cometchat-native-testing/SKILL.md +1 -2
- package/skills/cometchat-native-theming/SKILL.md +54 -29
- package/skills/cometchat-native-troubleshooting/SKILL.md +9 -3
- package/skills/cometchat-nextjs-patterns/SKILL.md +20 -6
- package/skills/cometchat-placement/SKILL.md +42 -3
- package/skills/cometchat-production/SKILL.md +12 -5
- package/skills/cometchat-react-calls/SKILL.md +220 -10
- package/skills/cometchat-react-calls/references/add-calls-to-existing-chat.md +4 -3
- package/skills/cometchat-react-calls/references/call-layouts.md +5 -6
- package/skills/cometchat-react-calls/references/call-session.md +1 -1
- package/skills/cometchat-react-calls/references/custom-ui.md +61 -15
- package/skills/cometchat-react-calls/references/device-management.md +55 -51
- package/skills/cometchat-react-calls/references/group-calls.md +18 -23
- package/skills/cometchat-react-calls/references/idle-timeout.md +25 -12
- package/skills/cometchat-react-calls/references/in-call-chat.md +7 -7
- package/skills/cometchat-react-calls/references/migration-v4-to-v5.md +9 -11
- package/skills/cometchat-react-calls/references/raise-hand.md +14 -14
- package/skills/cometchat-react-calls/references/recording-screen-share.md +39 -38
- package/skills/cometchat-react-calls/references/ringing-integration.md +2 -2
- package/skills/cometchat-react-calls/references/share-invite.md +4 -5
- package/skills/cometchat-react-calls/references/testing-calls-on-web.md +20 -2
- package/skills/cometchat-react-calls/references/virtual-background.md +32 -0
- package/skills/cometchat-react-patterns/SKILL.md +44 -4
- package/skills/cometchat-react-push/SKILL.md +258 -72
- package/skills/cometchat-react-router-patterns/SKILL.md +10 -4
- package/skills/cometchat-react-testing/SKILL.md +14 -5
- package/skills/cometchat-theming/SKILL.md +181 -18
- package/skills/cometchat-troubleshooting/SKILL.md +40 -20
|
@@ -34,7 +34,8 @@ In your auth service, after `CometChat.login`:
|
|
|
34
34
|
```ts
|
|
35
35
|
const user = await CometChat.login(uid, env.AUTH_KEY);
|
|
36
36
|
const authToken = user.getAuthToken();
|
|
37
|
-
|
|
37
|
+
// CometChatCalls.login(uid, authKey?) takes a UID; to authenticate with a token use loginWithAuthToken:
|
|
38
|
+
await CometChatCalls.loginWithAuthToken(authToken);
|
|
38
39
|
```
|
|
39
40
|
|
|
40
41
|
---
|
|
@@ -81,7 +82,7 @@ export class CallEventsService {
|
|
|
81
82
|
|
|
82
83
|
- [ ] `@cometchat/calls-sdk-javascript@^5` in package.json
|
|
83
84
|
- [ ] Calls SDK init runs after chat SDK init in `AppInitService`
|
|
84
|
-
- [ ] `CometChatCalls.
|
|
85
|
+
- [ ] `CometChatCalls.loginWithAuthToken(authToken)` after `CometChat.login` (NOT `CometChatCalls.login`, which expects a UID)
|
|
85
86
|
- [ ] `<cometchat-incoming-call>` rendered at app root (sibling of `router-outlet`)
|
|
86
87
|
- [ ] All custom `addEventListener` callbacks wrapped in `NgZone.run`
|
|
87
88
|
- [ ] Run `cometchat verify --calls` — should pass
|
|
@@ -10,26 +10,33 @@ Same SDK API as web. Angular wraps layout state in a service so multiple compone
|
|
|
10
10
|
## Layout service
|
|
11
11
|
|
|
12
12
|
```ts
|
|
13
|
-
import { Injectable, NgZone } from "@angular/core";
|
|
13
|
+
import { Injectable, NgZone, OnDestroy } from "@angular/core";
|
|
14
14
|
import { BehaviorSubject } from "rxjs";
|
|
15
15
|
import { CometChatCalls } from "@cometchat/calls-sdk-javascript";
|
|
16
16
|
|
|
17
17
|
export type CallLayout = "TILE" | "SIDEBAR" | "SPOTLIGHT";
|
|
18
18
|
|
|
19
19
|
@Injectable({ providedIn: "root" })
|
|
20
|
-
export class CallLayoutService {
|
|
20
|
+
export class CallLayoutService implements OnDestroy {
|
|
21
21
|
readonly layout$ = new BehaviorSubject<CallLayout>("TILE");
|
|
22
22
|
|
|
23
|
+
// addEventListener returns an unsubscribe fn — there is NO CometChatCalls.removeEventListener.
|
|
24
|
+
private off: () => void;
|
|
25
|
+
|
|
23
26
|
constructor(private zone: NgZone) {
|
|
24
|
-
CometChatCalls.addEventListener("onCallLayoutChanged", (next: string) => {
|
|
27
|
+
this.off = CometChatCalls.addEventListener("onCallLayoutChanged", (next: string) => {
|
|
25
28
|
this.zone.run(() => this.layout$.next(next as CallLayout));
|
|
26
29
|
});
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
set(layout: CallLayout): void {
|
|
30
|
-
CometChatCalls.setLayout(layout);
|
|
33
|
+
CometChatCalls.setLayout(layout); // static runtime layout switch — valid
|
|
31
34
|
this.layout$.next(layout);
|
|
32
35
|
}
|
|
36
|
+
|
|
37
|
+
ngOnDestroy(): void {
|
|
38
|
+
this.off();
|
|
39
|
+
}
|
|
33
40
|
}
|
|
34
41
|
```
|
|
35
42
|
|
|
@@ -65,17 +72,26 @@ export class LayoutSwitcherComponent {
|
|
|
65
72
|
|
|
66
73
|
---
|
|
67
74
|
|
|
68
|
-
## Pass initial via
|
|
75
|
+
## Pass initial via session settings
|
|
76
|
+
|
|
77
|
+
`joinSession` takes a **`SessionSettings` object**, not a builder result. The initial layout and
|
|
78
|
+
the change-layout button visibility are plain object fields (`layout`, `hideChangeLayoutButton`).
|
|
79
|
+
The builder has NO `setLayout` (its layout setter is the deprecated `setMode`) and NO
|
|
80
|
+
`setHideChangeLayoutButton`, and its output (`CallSettings`) is not accepted by `joinSession`.
|
|
69
81
|
|
|
70
82
|
```ts
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
83
|
+
const sessionSettings = {
|
|
84
|
+
sessionType: "VIDEO",
|
|
85
|
+
layout: "SPOTLIGHT",
|
|
86
|
+
hideChangeLayoutButton: true, // if you ship LayoutSwitcherComponent
|
|
87
|
+
} as const;
|
|
75
88
|
|
|
76
|
-
await CometChatCalls.joinSession(callToken,
|
|
89
|
+
await CometChatCalls.joinSession(callToken, sessionSettings, container.nativeElement);
|
|
77
90
|
```
|
|
78
91
|
|
|
92
|
+
To switch layout at runtime use the static `CometChatCalls.setLayout(layout)` (as the
|
|
93
|
+
`CallLayoutService.set` above does).
|
|
94
|
+
|
|
79
95
|
---
|
|
80
96
|
|
|
81
97
|
## Anti-patterns
|
|
@@ -92,8 +108,9 @@ Web sister rules apply, plus Angular-specific:
|
|
|
92
108
|
|
|
93
109
|
- [ ] `CallLayoutService` provided in root
|
|
94
110
|
- [ ] `NgZone.run` wraps the SDK callback
|
|
95
|
-
- [ ] `mat-button-toggle-group` `(change)` calls `svc.set`
|
|
96
|
-
- [ ] Initial layout via `CallSettingsBuilder
|
|
111
|
+
- [ ] `mat-button-toggle-group` `(change)` calls `svc.set` (which calls static `CometChatCalls.setLayout`)
|
|
112
|
+
- [ ] Initial layout via the `SessionSettings` object `{ layout, hideChangeLayoutButton }` passed to `joinSession` (no `CallSettingsBuilder`)
|
|
113
|
+
- [ ] Listener unsubscribe fn captured + called in `ngOnDestroy` (no `removeEventListener`)
|
|
97
114
|
- [ ] Browser smoke: 3 tabs, each picks a different layout, no cross-talk
|
|
98
115
|
|
|
99
116
|
---
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Call session — joinSession with no ringing (Angular)
|
|
2
2
|
|
|
3
|
-
Same SDK API as web. This file mirrors the upstream Angular sample at
|
|
3
|
+
Same SDK API as web. This file mirrors the upstream Angular sample at `calls-sdk-javascript-5/sample-apps/cometchat-calls-sample-app-angular/src/app/pages/join-session/`. Customer-validated against the v5 SDK as the known-good shape.
|
|
4
4
|
|
|
5
5
|
**Read first:** `cometchat-react-calls/references/call-session.md` — full architecture (sessionId strategies, server-side authorization, token generation), then come back here for Angular specialization.
|
|
6
6
|
|
|
@@ -163,5 +163,5 @@ Read `sessionId` via `ActivatedRoute.snapshot.paramMap.get('sessionId')` in `ngO
|
|
|
163
163
|
- `cometchat-react-calls/references/call-session.md` — full architecture (sessionId strategies, server-side authorization)
|
|
164
164
|
- `cometchat-angular-calls/SKILL.md` — Angular-specific dual-SDK init pattern
|
|
165
165
|
- `references/ngzone-and-async-callbacks.md` — why NgZone.run matters for SDK events
|
|
166
|
-
- Upstream Angular sample —
|
|
166
|
+
- Upstream Angular sample — `calls-sdk-javascript-5/sample-apps/cometchat-calls-sample-app-angular/src/app/pages/join-session/`
|
|
167
167
|
- Canonical docs: https://www.cometchat.com/docs/calls/javascript/join-session
|
|
@@ -7,7 +7,7 @@ Same architecture as React + RN custom UI; Angular-specific because of NgZone, C
|
|
|
7
7
|
## Two paths
|
|
8
8
|
|
|
9
9
|
1. **Style the kit's selectors** — pass Angular `[input]` props + content projection (`<ng-content select="...">`). Cheapest.
|
|
10
|
-
2. **Build your own component on the SDK**
|
|
10
|
+
2. **Build your own component on the SDK** with your own `<video>` elements wrapped in Angular components. ⚠️ Two join APIs by settings type: **hybrid (hide-chrome)** → `SessionSettings` object + `joinSession`; **fully-custom (`enableDefaultLayout(false)`, own tiles)** → `CallSettingsBuilder` + the deprecated `startSession` (joinSession does NOT accept builder output). This reference shows the fully-custom path.
|
|
11
11
|
|
|
12
12
|
This reference covers path 2.
|
|
13
13
|
|
|
@@ -54,6 +54,8 @@ export class OngoingCallComponent implements OnInit, OnDestroy {
|
|
|
54
54
|
constructor(private zone: NgZone) {}
|
|
55
55
|
|
|
56
56
|
async ngOnInit() {
|
|
57
|
+
// ⚠️ CometChatCalls.OngoingCallListener is @deprecated (use addEventListener).
|
|
58
|
+
// It's only here because enableDefaultLayout(false) + startSession require it.
|
|
57
59
|
this.listener = new CometChatCalls.OngoingCallListener({
|
|
58
60
|
onUserListUpdated: (users: unknown) => {
|
|
59
61
|
this.zone.run(() => { /* update roster */ });
|
|
@@ -67,18 +69,23 @@ export class OngoingCallComponent implements OnInit, OnDestroy {
|
|
|
67
69
|
},
|
|
68
70
|
});
|
|
69
71
|
|
|
72
|
+
// CallSettingsBuilder method names (verified vs calls-sdk-javascript@5):
|
|
73
|
+
// - NO .setSessionID() on the builder — sessionId flows via generateToken()
|
|
74
|
+
// - .setIsAudioOnlyCall(bool), not .setIsAudioOnly()
|
|
75
|
+
// - .setCallListener(listener), not .setCallEventListener()
|
|
70
76
|
const settings = new CometChatCalls.CallSettingsBuilder()
|
|
71
|
-
.
|
|
72
|
-
.setIsAudioOnly(false)
|
|
77
|
+
.setIsAudioOnlyCall(false)
|
|
73
78
|
.enableDefaultLayout(false)
|
|
74
|
-
.
|
|
79
|
+
.setCallListener(this.listener)
|
|
75
80
|
.build();
|
|
76
81
|
|
|
77
|
-
//
|
|
82
|
+
// generateToken takes ONLY sessionId. Auth is internal after CometChatCalls.login().
|
|
78
83
|
const tokenRes = await CometChatCalls.generateToken(this.sessionId);
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
|
|
84
|
+
// This fully-custom path uses enableDefaultLayout(false), which builds a CallSettings —
|
|
85
|
+
// consumed ONLY by the deprecated startSession. joinSession takes a SessionSettings
|
|
86
|
+
// OBJECT and will NOT accept CallSettingsBuilder output. startSession is the one place
|
|
87
|
+
// the deprecated call is still required (enableDefaultLayout is builder-only).
|
|
88
|
+
CometChatCalls.startSession(tokenRes.token, settings, this.callContainerRef.nativeElement);
|
|
82
89
|
}
|
|
83
90
|
|
|
84
91
|
ngOnDestroy() {
|
|
@@ -87,12 +94,13 @@ export class OngoingCallComponent implements OnInit, OnDestroy {
|
|
|
87
94
|
|
|
88
95
|
onToggleMute() {
|
|
89
96
|
this.muted = !this.muted;
|
|
90
|
-
|
|
97
|
+
// No-arg methods — muteAudio(bool) ignores the arg. Use the explicit pair.
|
|
98
|
+
this.muted ? CometChatCalls.muteAudio() : CometChatCalls.unmuteAudio();
|
|
91
99
|
}
|
|
92
100
|
|
|
93
101
|
onToggleCamera() {
|
|
94
102
|
this.cameraOff = !this.cameraOff;
|
|
95
|
-
CometChatCalls.pauseVideo(
|
|
103
|
+
this.cameraOff ? CometChatCalls.pauseVideo() : CometChatCalls.resumeVideo();
|
|
96
104
|
}
|
|
97
105
|
|
|
98
106
|
onSwitchCamera() {
|
|
@@ -10,22 +10,34 @@ Same JS SDK as web. Angular wraps device-list state in a service with RxJS obser
|
|
|
10
10
|
## Service-driven device lists
|
|
11
11
|
|
|
12
12
|
```ts
|
|
13
|
-
import { Injectable, NgZone } from "@angular/core";
|
|
13
|
+
import { Injectable, NgZone, OnDestroy } from "@angular/core";
|
|
14
14
|
import { BehaviorSubject } from "rxjs";
|
|
15
15
|
import { CometChatCalls } from "@cometchat/calls-sdk-javascript";
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
// SDK returns standard DOM MediaDeviceInfo objects — use `.deviceId`, NOT `.id`.
|
|
18
18
|
|
|
19
19
|
@Injectable({ providedIn: "root" })
|
|
20
|
-
export class CallDevicesService {
|
|
21
|
-
readonly mics$ = new BehaviorSubject<
|
|
22
|
-
readonly cameras$ = new BehaviorSubject<
|
|
23
|
-
readonly speakers$ = new BehaviorSubject<
|
|
20
|
+
export class CallDevicesService implements OnDestroy {
|
|
21
|
+
readonly mics$ = new BehaviorSubject<MediaDeviceInfo[]>([]);
|
|
22
|
+
readonly cameras$ = new BehaviorSubject<MediaDeviceInfo[]>([]);
|
|
23
|
+
readonly speakers$ = new BehaviorSubject<MediaDeviceInfo[]>([]);
|
|
24
|
+
|
|
25
|
+
// addEventListener returns an unsubscribe fn — there is NO CometChatCalls.removeEventListener.
|
|
26
|
+
private offs: Array<() => void> = [];
|
|
24
27
|
|
|
25
28
|
constructor(private zone: NgZone) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
// Valid device-change event keys (plural = full updated list):
|
|
30
|
+
this.offs.push(
|
|
31
|
+
CometChatCalls.addEventListener("onAudioInputDevicesChanged", () => {
|
|
32
|
+
this.zone.run(() => this.refresh());
|
|
33
|
+
}),
|
|
34
|
+
CometChatCalls.addEventListener("onAudioOutputDevicesChanged", () => {
|
|
35
|
+
this.zone.run(() => this.refresh());
|
|
36
|
+
}),
|
|
37
|
+
CometChatCalls.addEventListener("onVideoInputDevicesChanged", () => {
|
|
38
|
+
this.zone.run(() => this.refresh());
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
29
41
|
}
|
|
30
42
|
|
|
31
43
|
async ensurePermission(): Promise<void> {
|
|
@@ -37,25 +49,27 @@ export class CallDevicesService {
|
|
|
37
49
|
}
|
|
38
50
|
}
|
|
39
51
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
]);
|
|
46
|
-
this.mics$.next(mics);
|
|
47
|
-
this.cameras$.next(cameras);
|
|
48
|
-
this.speakers$.next(speakers);
|
|
52
|
+
// Device getters are SYNCHRONOUS — they return arrays, not Promises. No await / Promise.all.
|
|
53
|
+
refresh(): void {
|
|
54
|
+
this.mics$.next(CometChatCalls.getAudioInputDevices());
|
|
55
|
+
this.cameras$.next(CometChatCalls.getVideoInputDevices());
|
|
56
|
+
this.speakers$.next(CometChatCalls.getAudioOutputDevices());
|
|
49
57
|
}
|
|
50
58
|
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
// Setters are SYNCHRONOUS void — no await. They take the deviceId string.
|
|
60
|
+
selectMic(deviceId: string): void {
|
|
61
|
+
CometChatCalls.setAudioInputDevice(deviceId);
|
|
62
|
+
}
|
|
63
|
+
selectCamera(deviceId: string): void {
|
|
64
|
+
CometChatCalls.setVideoInputDevice(deviceId);
|
|
53
65
|
}
|
|
54
|
-
|
|
55
|
-
|
|
66
|
+
selectSpeaker(deviceId: string): void {
|
|
67
|
+
CometChatCalls.setAudioOutputDevice(deviceId);
|
|
56
68
|
}
|
|
57
|
-
|
|
58
|
-
|
|
69
|
+
|
|
70
|
+
ngOnDestroy(): void {
|
|
71
|
+
this.offs.forEach(off => off()); // call the captured unsubscribe fns
|
|
72
|
+
this.offs = [];
|
|
59
73
|
}
|
|
60
74
|
}
|
|
61
75
|
```
|
|
@@ -71,8 +85,8 @@ export class CallDevicesService {
|
|
|
71
85
|
<form (ngSubmit)="confirm()">
|
|
72
86
|
<label>Microphone
|
|
73
87
|
<select [(ngModel)]="selectedMic" name="mic">
|
|
74
|
-
<option *ngFor="let d of mics$ | async" [value]="d.
|
|
75
|
-
{{ d.label || ('Mic ' + d.
|
|
88
|
+
<option *ngFor="let d of mics$ | async" [value]="d.deviceId">
|
|
89
|
+
{{ d.label || ('Mic ' + d.deviceId.substring(0, 6)) }}
|
|
76
90
|
</option>
|
|
77
91
|
</select>
|
|
78
92
|
</label>
|
|
@@ -92,14 +106,14 @@ export class DevicePickerComponent implements OnInit {
|
|
|
92
106
|
constructor(private devices: CallDevicesService) {}
|
|
93
107
|
|
|
94
108
|
async ngOnInit() {
|
|
95
|
-
await this.devices.ensurePermission();
|
|
96
|
-
|
|
109
|
+
await this.devices.ensurePermission(); // getUserMedia IS async
|
|
110
|
+
this.devices.refresh(); // device list reads are sync
|
|
97
111
|
}
|
|
98
112
|
|
|
99
|
-
|
|
100
|
-
if (this.selectedMic)
|
|
101
|
-
if (this.selectedCamera)
|
|
102
|
-
if (this.selectedSpeaker)
|
|
113
|
+
confirm() {
|
|
114
|
+
if (this.selectedMic) this.devices.selectMic(this.selectedMic);
|
|
115
|
+
if (this.selectedCamera) this.devices.selectCamera(this.selectedCamera);
|
|
116
|
+
if (this.selectedSpeaker) this.devices.selectSpeaker(this.selectedSpeaker);
|
|
103
117
|
}
|
|
104
118
|
}
|
|
105
119
|
```
|
|
@@ -110,16 +124,21 @@ export class DevicePickerComponent implements OnInit {
|
|
|
110
124
|
|
|
111
125
|
Web sister rules apply, plus Angular-specific:
|
|
112
126
|
|
|
113
|
-
1. **No `NgZone.run` wrap on
|
|
127
|
+
1. **No `NgZone.run` wrap on the device-change events.** BehaviorSubject emits but UI doesn't update with OnPush.
|
|
114
128
|
2. **Service NOT provided in `root`.** Lazy-loaded → device events miss.
|
|
115
129
|
3. **`async pipe` not used.** Manual `subscribe` without `unsubscribe` leaks.
|
|
130
|
+
4. **`await`-ing the device getters/setters.** They are synchronous (`getAudioInputDevices()` returns `MediaDeviceInfo[]`; setters return `void`). `await` on them is a no-op that masks the real (sync) signature.
|
|
131
|
+
5. **Reading `device.id`.** The SDK returns DOM `MediaDeviceInfo` — the identifier is `device.deviceId`.
|
|
132
|
+
6. **Expecting `CometChatCalls.removeEventListener`.** It does not exist. `addEventListener` returns a `() => void`; capture and call it to clean up.
|
|
116
133
|
|
|
117
134
|
---
|
|
118
135
|
|
|
119
136
|
## Verification checklist
|
|
120
137
|
|
|
121
138
|
- [ ] `CallDevicesService` provided in root
|
|
122
|
-
- [ ] `NgZone.run` wraps the device-update
|
|
139
|
+
- [ ] `NgZone.run` wraps the device-update events (`onAudioInputDevicesChanged` / `onAudioOutputDevicesChanged` / `onVideoInputDevicesChanged`)
|
|
140
|
+
- [ ] Listener unsubscribe fns captured and called in `ngOnDestroy` (no `removeEventListener`)
|
|
141
|
+
- [ ] Device getters/setters called WITHOUT `await` (they are sync); options use `device.deviceId`
|
|
123
142
|
- [ ] Picker uses `async` pipe (not manual subscribe)
|
|
124
143
|
- [ ] `ensurePermission()` called before `refresh()` (empty-label fix)
|
|
125
144
|
- [ ] Browser smoke: plug/unplug headphones during call → list updates
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Group calls (meetings) on Angular
|
|
2
2
|
|
|
3
|
-
Angular wraps the same JS Calls SDK as React/Vue/Svelte; the SDK semantics are identical. The wiring differences are Angular-specific: NgZone for
|
|
3
|
+
Angular wraps the same JS Calls SDK as React/Vue/Svelte; the SDK semantics are identical. The wiring differences are Angular-specific: NgZone for dominant-speaker updates, `@Input` / `@Output` patterns for participant components, OnPush + `markForCheck` for roster changes.
|
|
4
|
+
|
|
5
|
+
> **v5 event note.** `CometChatCalls.OngoingCallListener` is `@deprecated` in calls-sdk-javascript v5 (use `CometChatCalls.addEventListener(...)`). It still works for roster events (`onUserJoined` / `onUserLeft` / `onUserListUpdated` / `onCallEnded` / `onError`), but there is **no `onActiveSpeakerUpdated` callback on the listener** — the dominant-speaker signal is only available as the `addEventListener` event key `onDominantSpeakerChanged`. The examples below use `addEventListener` for dominant speaker and may keep the listener for roster events.
|
|
4
6
|
|
|
5
7
|
For SDK-level semantics — capacity limits, bandwidth scaling, moderator actions — see `cometchat-native-calls/references/group-calls.md`. This reference covers the Angular-specific patterns.
|
|
6
8
|
|
|
@@ -160,7 +162,10 @@ export class GroupCallComponent implements OnInit, OnDestroy {
|
|
|
160
162
|
|
|
161
163
|
constructor(private zone: NgZone, private cd: ChangeDetectorRef) {}
|
|
162
164
|
|
|
165
|
+
private offSpeaker?: () => void;
|
|
166
|
+
|
|
163
167
|
ngOnInit() {
|
|
168
|
+
// Roster via the (deprecated but functional) OngoingCallListener:
|
|
164
169
|
const listener = new CometChatCalls.OngoingCallListener({
|
|
165
170
|
onUserListUpdated: (users: Participant[]) => {
|
|
166
171
|
this.zone.run(() => {
|
|
@@ -169,14 +174,24 @@ export class GroupCallComponent implements OnInit, OnDestroy {
|
|
|
169
174
|
this.cd.markForCheck(); // OnPush — must mark
|
|
170
175
|
});
|
|
171
176
|
},
|
|
172
|
-
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Dominant speaker is NOT a listener callback — subscribe via addEventListener.
|
|
180
|
+
// addEventListener returns an unsubscribe fn (there is no removeEventListener).
|
|
181
|
+
this.offSpeaker = CometChatCalls.addEventListener(
|
|
182
|
+
"onDominantSpeakerChanged",
|
|
183
|
+
(participant: { uid: string }) => {
|
|
173
184
|
this.zone.run(() => {
|
|
174
|
-
// Debounce — see "Debouncing
|
|
175
|
-
this.scheduleSpeakerSwap(uid);
|
|
185
|
+
// Debounce — see "Debouncing dominant-speaker" below
|
|
186
|
+
this.scheduleSpeakerSwap(participant.uid);
|
|
176
187
|
});
|
|
177
188
|
},
|
|
178
|
-
|
|
179
|
-
// ...
|
|
189
|
+
);
|
|
190
|
+
// ... pass a SessionSettings object + call token to CometChatCalls.joinSession ...
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
ngOnDestroy() {
|
|
194
|
+
this.offSpeaker?.();
|
|
180
195
|
}
|
|
181
196
|
|
|
182
197
|
trackByUid(_: number, p: Participant) {
|
|
@@ -209,9 +224,9 @@ export class GroupCallComponent implements OnInit, OnDestroy {
|
|
|
209
224
|
|
|
210
225
|
---
|
|
211
226
|
|
|
212
|
-
## Debouncing
|
|
227
|
+
## Debouncing dominant-speaker
|
|
213
228
|
|
|
214
|
-
Same rule as RN — `
|
|
229
|
+
Same rule as RN — `onDominantSpeakerChanged` can fire many times per second in a noisy call. Debounce to 500ms minimum:
|
|
215
230
|
|
|
216
231
|
```ts
|
|
217
232
|
private speakerSwapTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
@@ -241,9 +256,11 @@ ngOnInit() {
|
|
|
241
256
|
this.zone.run(() => { this.activeSpeakerUid = uid; this.recomputeLayout(); this.cd.markForCheck(); });
|
|
242
257
|
});
|
|
243
258
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
259
|
+
// Dominant speaker comes from addEventListener, not the listener object:
|
|
260
|
+
this.offSpeaker = CometChatCalls.addEventListener(
|
|
261
|
+
"onDominantSpeakerChanged",
|
|
262
|
+
(participant: { uid: string }) => this.speakerSubject.next(participant.uid),
|
|
263
|
+
);
|
|
247
264
|
}
|
|
248
265
|
```
|
|
249
266
|
|
|
@@ -251,25 +268,28 @@ ngOnInit() {
|
|
|
251
268
|
|
|
252
269
|
## Moderator actions — guarded by group scope
|
|
253
270
|
|
|
271
|
+
The v5 SDK exposes **`CometChatCalls.muteParticipant(participantId)`** (sync, void) — there is
|
|
272
|
+
no `muteUser` / `removeUser`. **There is NO kick/remove-participant API in the JS Calls SDK** —
|
|
273
|
+
removal must be done at the chat layer (e.g. `CometChat.kickGroupMember`), not via the Calls SDK.
|
|
274
|
+
|
|
254
275
|
```ts
|
|
255
276
|
// In your component or a CallControlsService
|
|
256
|
-
|
|
277
|
+
muteParticipant(participantId: string) {
|
|
257
278
|
if (!this.canModerate()) return;
|
|
258
|
-
|
|
279
|
+
CometChatCalls.muteParticipant(participantId); // sync, void — no await
|
|
259
280
|
}
|
|
260
281
|
|
|
261
|
-
|
|
262
|
-
if (!this.canModerate()) return;
|
|
263
|
-
await CometChatCalls.removeUser(uid);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
async muteAll() {
|
|
282
|
+
muteAll() {
|
|
267
283
|
if (!this.canModerate()) return;
|
|
268
284
|
for (const p of this.others) {
|
|
269
|
-
|
|
285
|
+
CometChatCalls.muteParticipant(p.uid);
|
|
270
286
|
}
|
|
271
287
|
}
|
|
272
288
|
|
|
289
|
+
// NOTE: no kick/remove API exists in @cometchat/calls-sdk-javascript.
|
|
290
|
+
// To eject someone, remove them from the group via the Chat SDK
|
|
291
|
+
// (CometChat.kickGroupMember(...)) — they then lose access to the session.
|
|
292
|
+
|
|
273
293
|
private canModerate(): boolean {
|
|
274
294
|
const scope = this.group?.getScope();
|
|
275
295
|
return scope === "admin" || scope === "moderator";
|
|
@@ -281,7 +301,7 @@ Hide the moderator-only buttons in the template:
|
|
|
281
301
|
```html
|
|
282
302
|
<div *ngIf="canModerate()" class="moderator-controls">
|
|
283
303
|
<button (click)="muteAll()">Mute all</button>
|
|
284
|
-
<button (click)="
|
|
304
|
+
<button (click)="muteParticipant(p.uid)" *ngFor="let p of others">Mute</button>
|
|
285
305
|
</div>
|
|
286
306
|
```
|
|
287
307
|
|
|
@@ -321,7 +341,7 @@ async observeBattery() {
|
|
|
321
341
|
const check = () => {
|
|
322
342
|
if (battery.level < 0.2 && this.callActive) {
|
|
323
343
|
this.zone.run(() => {
|
|
324
|
-
CometChatCalls.pauseVideo(
|
|
344
|
+
CometChatCalls.pauseVideo(); // no-arg in v5 (pauses local video)
|
|
325
345
|
this.snackBar.open("Video paused — low battery", "Dismiss", { duration: 5000 });
|
|
326
346
|
});
|
|
327
347
|
}
|
|
@@ -382,8 +402,9 @@ ngOnInit() {
|
|
|
382
402
|
|
|
383
403
|
1. **Roster updates without `trackByUid`** in `*ngFor`. Tiles re-create; video tracks die.
|
|
384
404
|
2. **Skipping `markForCheck`** with OnPush. Roster updates don't render.
|
|
385
|
-
3. **No debounce on
|
|
405
|
+
3. **No debounce on dominant-speaker.** Tiles jitter at 5+ Hz.
|
|
386
406
|
4. **Moderator buttons rendered for non-moderators.** SDK rejects but UI is misleading.
|
|
407
|
+
(Remember: only `muteParticipant` exists — there is no kick/remove in the Calls SDK.)
|
|
387
408
|
5. **`getBattery()` without feature detect.** Firefox/Safari throws.
|
|
388
409
|
6. **Leaving the call doesn't unsubscribe RxJS subjects.** Memory leak across multiple call sessions.
|
|
389
410
|
7. **Group call from a lazy-loaded module.** CallInitService must be eager (cf. `references/lazy-loading-pitfalls.md`).
|
|
@@ -394,7 +415,7 @@ ngOnInit() {
|
|
|
394
415
|
|
|
395
416
|
- [ ] `*ngFor` over participants uses `trackBy: trackByUid`
|
|
396
417
|
- [ ] OnPush components call `cd.markForCheck()` on roster updates
|
|
397
|
-
- [ ]
|
|
418
|
+
- [ ] Dominant-speaker updates (via `addEventListener("onDominantSpeakerChanged", …)`) debounced ≥500ms
|
|
398
419
|
- [ ] All SDK callbacks wrapped in `zone.run`
|
|
399
420
|
- [ ] Moderator controls hidden for non-moderator scopes
|
|
400
421
|
- [ ] Capacity error handled (`ERR_CALL_FULL`) with user-facing snackbar
|
|
@@ -9,19 +9,37 @@ Same SDK API as web. Angular-specific delta: NgZone wrap on the timeout event +
|
|
|
9
9
|
|
|
10
10
|
## SDK API
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
.
|
|
17
|
-
|
|
12
|
+
The idle timeout is configured on the **`SessionSettings` object** passed to
|
|
13
|
+
`joinSession(callToken, sessionSettings, container)`, NOT on the builder.
|
|
14
|
+
|
|
15
|
+
- The builder (`CallSettingsBuilder`) has a single `setIdleTimeoutPeriod(ms)` method — there is
|
|
16
|
+
no `setIdleTimeoutPeriodBeforePrompt` / `setIdleTimeoutPeriodAfterPrompt` on it.
|
|
17
|
+
- The before/after split exists ONLY as `SessionSettings` object fields:
|
|
18
|
+
`idleTimeoutPeriodBeforePrompt` and `idleTimeoutPeriodAfterPrompt`.
|
|
19
|
+
- There is no `setSessionID()` on the builder — the session is identified by the call token
|
|
20
|
+
produced via `CometChatCalls.generateToken(sessionId, authToken)`.
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
```ts
|
|
23
|
+
// 1. token carries the session id
|
|
24
|
+
const { token } = await CometChatCalls.generateToken(sessionId, authToken);
|
|
25
|
+
|
|
26
|
+
// 2. idle timeout lives on the SessionSettings object
|
|
27
|
+
const sessionSettings = {
|
|
28
|
+
sessionType: "VIDEO",
|
|
29
|
+
idleTimeoutPeriodBeforePrompt: 60_000,
|
|
30
|
+
idleTimeoutPeriodAfterPrompt: 120_000,
|
|
31
|
+
} as const;
|
|
32
|
+
|
|
33
|
+
// addEventListener returns an unsubscribe fn — capture it (there is no removeEventListener).
|
|
34
|
+
const off = CometChatCalls.addEventListener("onSessionTimedOut", () => {
|
|
20
35
|
this.zone.run(() => {
|
|
21
36
|
this.router.navigate(["/"]);
|
|
22
37
|
this.snackBar.open("Call ended due to inactivity", "Dismiss", { duration: 5000 });
|
|
23
38
|
});
|
|
24
39
|
});
|
|
40
|
+
|
|
41
|
+
await CometChatCalls.joinSession(token, sessionSettings, container);
|
|
42
|
+
// later: off();
|
|
25
43
|
```
|
|
26
44
|
|
|
27
45
|
`NgZone.run` wrap is mandatory — without it, the navigation + snackbar don't fire because the SDK callback is outside Angular's zone.
|
|
@@ -39,7 +57,8 @@ import { CometChatCalls } from "@cometchat/calls-sdk-javascript";
|
|
|
39
57
|
|
|
40
58
|
@Injectable({ providedIn: "root" })
|
|
41
59
|
export class IdleTimeoutService {
|
|
42
|
-
|
|
60
|
+
// addEventListener returns the unsubscribe fn — there is no CometChatCalls.removeEventListener.
|
|
61
|
+
private off?: () => void;
|
|
43
62
|
|
|
44
63
|
constructor(
|
|
45
64
|
private zone: NgZone,
|
|
@@ -48,20 +67,17 @@ export class IdleTimeoutService {
|
|
|
48
67
|
) {}
|
|
49
68
|
|
|
50
69
|
attachToCallSession() {
|
|
51
|
-
this.
|
|
70
|
+
this.off = CometChatCalls.addEventListener("onSessionTimedOut", () => {
|
|
52
71
|
this.zone.run(() => {
|
|
53
72
|
this.router.navigate(["/"]);
|
|
54
73
|
this.snackBar.open("Call ended due to inactivity", "Dismiss", { duration: 5000 });
|
|
55
74
|
});
|
|
56
|
-
};
|
|
57
|
-
CometChatCalls.addEventListener("onSessionTimedOut", this.listener);
|
|
75
|
+
});
|
|
58
76
|
}
|
|
59
77
|
|
|
60
78
|
detach() {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
this.listener = undefined;
|
|
64
|
-
}
|
|
79
|
+
this.off?.();
|
|
80
|
+
this.off = undefined;
|
|
65
81
|
}
|
|
66
82
|
}
|
|
67
83
|
```
|
|
@@ -56,6 +56,8 @@ All Calls SDK event listeners. The kit's own components handle this internally;
|
|
|
56
56
|
|
|
57
57
|
Conservative rule: **wrap every callback that mutates UI state** in `zone.run`.
|
|
58
58
|
|
|
59
|
+
> `CometChatCalls.OngoingCallListener` is `@deprecated` in calls-sdk-javascript v5 (prefer `CometChatCalls.addEventListener(...)`); the listener pattern below still works and is shown here because this reference is about NgZone-wrapping. Note that the dominant-speaker signal is NOT a listener callback — subscribe to it via `addEventListener("onDominantSpeakerChanged", …)` (also wrap that handler in `zone.run`).
|
|
60
|
+
|
|
59
61
|
```ts
|
|
60
62
|
const listener = new CometChatCalls.OngoingCallListener({
|
|
61
63
|
onUserListUpdated: (userList) => {
|
|
@@ -67,12 +69,11 @@ const listener = new CometChatCalls.OngoingCallListener({
|
|
|
67
69
|
onError: (err) => {
|
|
68
70
|
this.zone.run(() => { this.errorMessage = err.message; });
|
|
69
71
|
},
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
},
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Dominant speaker is an addEventListener event key, not a listener callback:
|
|
75
|
+
const offSpeaker = CometChatCalls.addEventListener("onDominantSpeakerChanged", (p) => {
|
|
76
|
+
this.zone.run(() => { this.activeSpeakerUid = p.uid; });
|
|
76
77
|
});
|
|
77
78
|
```
|
|
78
79
|
|
|
@@ -49,14 +49,19 @@ export class RaiseHandService implements OnDestroy {
|
|
|
49
49
|
});
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
+
// addEventListener returns an unsubscribe fn — there is NO CometChatCalls.removeEventListener.
|
|
53
|
+
private offs: Array<() => void> = [];
|
|
54
|
+
|
|
52
55
|
constructor(private zone: NgZone) {
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
this.offs.push(
|
|
57
|
+
CometChatCalls.addEventListener("onParticipantHandRaised", this.onRaised),
|
|
58
|
+
CometChatCalls.addEventListener("onParticipantHandLowered", this.onLowered),
|
|
59
|
+
);
|
|
55
60
|
}
|
|
56
61
|
|
|
57
62
|
ngOnDestroy() {
|
|
58
|
-
|
|
59
|
-
|
|
63
|
+
this.offs.forEach(off => off());
|
|
64
|
+
this.offs = [];
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
raise() { CometChatCalls.raiseHand(); }
|