diff --git a/calls/android/migration-guide-v5.mdx b/calls/android/migration-guide-v5.mdx new file mode 100644 index 000000000..bd4097312 --- /dev/null +++ b/calls/android/migration-guide-v5.mdx @@ -0,0 +1,464 @@ +--- +title: "Migration Guide" +sidebarTitle: "v4 to v5 Migration" +--- + +This guide covers migrating from Calls SDK v4 to v5 for Android. + +## Drop-in Compatibility + +Calls SDK v5 is a **drop-in replacement** for v4. All v4 APIs are preserved as deprecated methods that internally delegate to the new v5 implementations. You can update the dependency version and your existing code will compile and run without changes. + +```groovy +// Update your dependency version +-implementation "com.cometchat:calls-sdk-android:4.x.x" ++implementation "com.cometchat:calls-sdk-android:5.x.x" +``` + + +If you're using CometChat UI Kits, simply updating the Calls SDK version is sufficient. The UI Kit will continue to work with v5 through the deprecated compatibility layer. + + +## Why Migrate to v5 APIs? + +While v4 APIs will continue to work, migrating to v5 APIs gives you: + +- **Lifecycle-aware listeners** that auto-cleanup when your Activity/Fragment is destroyed — no more manual `removeCallsEventListeners()` calls +- **Granular event listeners** — 5 focused listener interfaces instead of one monolithic `CometChatCallsEventsListener` +- **`CallSession` singleton** for cleaner session control — all actions on a single object instead of scattered static methods +- **Dedicated `login()` method** — the Calls SDK now handles its own authentication instead of depending on the Chat SDK's auth token or REST APIs +- **Strongly-typed enums** — `AudioMode`, `SessionType`, `LayoutType`, `CameraFacing` instead of raw strings + +--- + +## Initialization + +No changes required. The `init()` API is the same in v5. + +```java +CallAppSettings callAppSettings = new CallAppSettings.CallAppSettingBuilder() + .setAppId("APP_ID") + .setRegion("REGION") + .build(); + +CometChatCalls.init(context, callAppSettings, new CometChatCalls.CallbackListener() { + @Override + public void onSuccess(String s) { } + + @Override + public void onError(CometChatException e) { } +}); +``` + +--- + +## Authentication + +In v4, the Calls SDK had no dedicated authentication step. It relied on the Chat SDK's auth token (`CometChat.getUserAuthToken()`) or a REST API to obtain an auth token, which you then passed manually to methods like `generateToken(sessionId, authToken, listener)`. + +v5 introduces its own `login()` method. After calling `login()`, the SDK caches the auth token internally, so you no longer need to pass it around to other API calls. + + + +```java +// No dedicated Calls SDK login — relied on Chat SDK for auth token +String authToken = CometChat.getUserAuthToken(); + +// Had to pass authToken manually to every call that needed it +CometChatCalls.generateToken(sessionId, authToken, new CometChatCalls.CallbackListener() { + @Override + public void onSuccess(GenerateToken generateToken) { + // Use generateToken.getToken() to start a session + } + + @Override + public void onError(CometChatException e) { } +}); +``` + + +```java +// Login to the Calls SDK once (after your Chat SDK login or after obtaining an auth token) +CometChatCalls.login(authToken, new CometChatCalls.CallbackListener() { + @Override + public void onSuccess(CallUser callUser) { + // Calls SDK is now authenticated — auth token is cached internally + } + + @Override + public void onError(CometChatException e) { } +}); +``` + + + + +Call `CometChatCalls.login()` once after your user authenticates (e.g., right after `CometChat.login()` succeeds). The SDK stores the auth token internally, so subsequent calls like `generateToken()` and `joinSession()` use it automatically without you having to pass it. + + +--- + +## Session Settings + +`CallSettings` and `CallSettingsBuilder` are replaced by `SessionSettings` and `SessionSettingsBuilder`. The builder methods have been renamed for clarity. + + + +```java +CallSettings callSettings = new CometChatCalls.CallSettingsBuilder(activity) + .setIsAudioOnly(true) + .setDefaultLayoutEnable(true) + .showEndCallButton(true) + .showMuteAudioButton(true) + .showPauseVideoButton(true) + .showSwitchCameraButton(true) + .showAudioModeButton(true) + .showRecordingButton(true) + .startWithAudioMuted(false) + .startWithVideoMuted(false) + .setDefaultAudioMode("SPEAKER") + .setMode("DEFAULT") + .autoRecordOnCallStart(false) + .build(); +``` + + +```java +SessionSettings sessionSettings = new CometChatCalls.SessionSettingsBuilder() + .setType(SessionType.AUDIO) + .startAudioMuted(false) + .startVideoPaused(false) + .setLayout(LayoutType.TILE) + .setAudioMode(AudioMode.SPEAKER) + .hideLeaveSessionButton(false) + .hideToggleAudioButton(false) + .hideToggleVideoButton(false) + .hideSwitchCameraButton(false) + .hideAudioModeButton(false) + .hideRecordingButton(false) + .hideControlPanel(false) + .hideHeaderPanel(false) + .enableAutoStartRecording(false) + .build(); +``` + + + +### Builder Method Mapping + +| v4 Method | v5 Method | Notes | +|-----------|-----------|-------| +| `setIsAudioOnly(true)` | `setType(SessionType.AUDIO)` | Use `SessionType.VIDEO` for video calls | +| `setDefaultLayoutEnable(bool)` | `hideControlPanel(!bool)` + `hideHeaderPanel(!bool)` | Inverted logic | +| `showEndCallButton(bool)` | `hideLeaveSessionButton(!bool)` | Inverted logic | +| `showMuteAudioButton(bool)` | `hideToggleAudioButton(!bool)` | Inverted logic | +| `showPauseVideoButton(bool)` | `hideToggleVideoButton(!bool)` | Inverted logic | +| `showSwitchCameraButton(bool)` | `hideSwitchCameraButton(!bool)` | Inverted logic | +| `showAudioModeButton(bool)` | `hideAudioModeButton(!bool)` | Inverted logic | +| `showRecordingButton(bool)` | `hideRecordingButton(!bool)` | Inverted logic | +| `startWithAudioMuted(bool)` | `startAudioMuted(bool)` | Same logic | +| `startWithVideoMuted(bool)` | `startVideoPaused(bool)` | Same logic | +| `setDefaultAudioMode("SPEAKER")` | `setAudioMode(AudioMode.SPEAKER)` | Enum instead of string | +| `setMode("DEFAULT")` | `setLayout(LayoutType.TILE)` | Enum instead of string | +| `autoRecordOnCallStart(bool)` | `enableAutoStartRecording(bool)` | Same logic | +| `setAvatarMode(string)` | *Removed* | No longer applicable | +| `setMainVideoContainerSetting(setting)` | *Removed* | No longer applicable | +| `enableVideoTileDrag(bool)` | *Removed* | No longer applicable | +| `enableVideoTileClick(bool)` | *Removed* | No longer applicable | +| `setEventListener(listener)` | Use `CallSession` listeners | See [Events](#event-listeners) section | + +--- + +## Joining a Session + +`startSession()` is replaced by `joinSession()` which returns a `CallSession` object for controlling the call. + + + +```java +// Step 1: Generate token +CometChatCalls.generateToken(sessionId, authToken, new CometChatCalls.CallbackListener() { + @Override + public void onSuccess(GenerateToken generateToken) { + // Step 2: Start session with token string + CometChatCalls.startSession(generateToken.getToken(), callSettings, callView, + new CometChatCalls.CallbackListener() { + @Override + public void onSuccess(String s) { + // Session started + } + + @Override + public void onError(CometChatException e) { } + }); + } + + @Override + public void onError(CometChatException e) { } +}); +``` + + +```java +// Option A: Two-step with GenerateToken object +CometChatCalls.generateToken(sessionId, new CometChatCalls.CallbackListener() { + @Override + public void onSuccess(GenerateToken generateToken) { + CometChatCalls.joinSession(generateToken, sessionSettings, callView, + new CometChatCalls.CallbackListener() { + @Override + public void onSuccess(CallSession callSession) { + // Use callSession for actions and events + } + + @Override + public void onError(CometChatException e) { } + }); + } + + @Override + public void onError(CometChatException e) { } +}); + +// Option B: One-step with session ID (recommended) +CometChatCalls.joinSession(sessionId, sessionSettings, callView, + new CometChatCalls.CallbackListener() { + @Override + public void onSuccess(CallSession callSession) { + // Token generation + join handled internally + } + + @Override + public void onError(CometChatException e) { } + }); +``` + + + +Key differences: +- v5 `joinSession()` returns a `CallSession` object (not a raw `String`) +- v5 accepts the `GenerateToken` object directly (not just the token string) +- v5 offers a convenience overload that takes `sessionId` directly and handles token generation internally + +--- + +## Session Control (Actions) + +In v4, session actions were static methods on `CometChatCalls`. In v5, they're instance methods on `CallSession`. + + + +```java +CometChatCalls.endSession(); +CometChatCalls.switchCamera(); +CometChatCalls.muteAudio(true); +CometChatCalls.pauseVideo(true); +CometChatCalls.setAudioMode("SPEAKER"); +CometChatCalls.enterPIPMode(); +CometChatCalls.exitPIPMode(); +CometChatCalls.startRecording(); +CometChatCalls.stopRecording(); +``` + + +```java +CallSession callSession = CallSession.getInstance(); + +callSession.leaveSession(); +callSession.switchCamera(); +callSession.muteAudio(); // or callSession.unmuteAudio() +callSession.pauseVideo(); // or callSession.resumeVideo() +callSession.setAudioMode(AudioMode.SPEAKER); +callSession.enablePictureInPictureLayout(); +callSession.disablePictureInPictureLayout(); +callSession.startRecording(); +callSession.stopRecording(); +``` + + + +### Action Method Mapping + +| v4 Static Method | v5 CallSession Method | +|---|---| +| `CometChatCalls.endSession()` | `callSession.leaveSession()` | +| `CometChatCalls.switchCamera()` | `callSession.switchCamera()` | +| `CometChatCalls.muteAudio(true)` | `callSession.muteAudio()` | +| `CometChatCalls.muteAudio(false)` | `callSession.unmuteAudio()` | +| `CometChatCalls.pauseVideo(true)` | `callSession.pauseVideo()` | +| `CometChatCalls.pauseVideo(false)` | `callSession.resumeVideo()` | +| `CometChatCalls.setAudioMode("SPEAKER")` | `callSession.setAudioMode(AudioMode.SPEAKER)` | +| `CometChatCalls.enterPIPMode()` | `callSession.enablePictureInPictureLayout()` | +| `CometChatCalls.exitPIPMode()` | `callSession.disablePictureInPictureLayout()` | +| `CometChatCalls.startRecording()` | `callSession.startRecording()` | +| `CometChatCalls.stopRecording()` | `callSession.stopRecording()` | +| `CometChatCalls.switchToVideoCall()` | *Removed* | + +--- + +## Event Listeners + +This is the biggest improvement in v5. The single `CometChatCallsEventsListener` is replaced by 5 focused, lifecycle-aware listeners. + +### v4: Single Monolithic Listener + +```java +CometChatCalls.addCallsEventListeners("LISTENER_ID", new CometChatCallsEventsListener() { + @Override public void onCallEnded() { } + @Override public void onCallEndButtonPressed() { } + @Override public void onUserJoined(RTCUser user) { } + @Override public void onUserLeft(RTCUser user) { } + @Override public void onUserListChanged(ArrayList users) { } + @Override public void onAudioModeChanged(ArrayList devices) { } + @Override public void onCallSwitchedToVideo(CallSwitchRequestInfo info) { } + @Override public void onUserMuted(RTCMutedUser muteObj) { } + @Override public void onRecordingToggled(RTCRecordingInfo info) { } + @Override public void onError(CometChatException e) { } +}); + +// Must manually remove +CometChatCalls.removeCallsEventListeners("LISTENER_ID"); +``` + +### v5: Focused Lifecycle-Aware Listeners + +```java +CallSession callSession = CallSession.getInstance(); + +// Session lifecycle events +callSession.addSessionStatusListener(this, new SessionStatusListener() { + @Override public void onSessionJoined() { } + @Override public void onSessionLeft() { } + @Override public void onSessionTimedOut() { } + @Override public void onConnectionLost() { } + @Override public void onConnectionRestored() { } + @Override public void onConnectionClosed() { } +}); + +// Participant events (replaces onUserJoined, onUserLeft, onUserListChanged, onUserMuted) +callSession.addParticipantEventListener(this, new ParticipantEventListener() { + @Override public void onParticipantJoined(Participant participant) { } + @Override public void onParticipantLeft(Participant participant) { } + @Override public void onParticipantListChanged(List participants) { } + @Override public void onParticipantAudioMuted(Participant participant) { } + @Override public void onParticipantAudioUnmuted(Participant participant) { } + @Override public void onParticipantVideoPaused(Participant participant) { } + @Override public void onParticipantVideoResumed(Participant participant) { } + @Override public void onParticipantHandRaised(Participant participant) { } + @Override public void onParticipantHandLowered(Participant participant) { } + @Override public void onParticipantStartedRecording(Participant participant) { } + @Override public void onParticipantStoppedRecording(Participant participant) { } + @Override public void onDominantSpeakerChanged(Participant participant) { } +}); + +// Media state events (replaces onAudioModeChanged, onRecordingToggled) +callSession.addMediaEventsListener(this, new MediaEventsListener() { + @Override public void onAudioMuted() { } + @Override public void onAudioUnMuted() { } + @Override public void onVideoPaused() { } + @Override public void onVideoResumed() { } + @Override public void onRecordingStarted() { } + @Override public void onRecordingStopped() { } + @Override public void onAudioModeChanged(AudioMode audioMode) { } + @Override public void onCameraFacingChanged(CameraFacing facing) { } +}); + +// Button click events (replaces onCallEndButtonPressed) +callSession.addButtonClickListener(this, new ButtonClickListener() { + @Override public void onLeaveSessionButtonClicked() { } + @Override public void onToggleAudioButtonClicked() { } + @Override public void onToggleVideoButtonClicked() { } + @Override public void onSwitchCameraButtonClicked() { } + @Override public void onRaiseHandButtonClicked() { } + @Override public void onRecordingToggleButtonClicked() { } +}); + +// Layout events +callSession.addLayoutListener(this, new LayoutListener() { + @Override public void onCallLayoutChanged(LayoutType layoutType) { } + @Override public void onPictureInPictureLayoutEnabled() { } + @Override public void onPictureInPictureLayoutDisabled() { } +}); +``` + + +v5 listeners are lifecycle-aware — pass your Activity or Fragment as the first parameter and they'll be automatically removed when the lifecycle owner is destroyed. No need to call `removeCallsEventListeners()`. + + +### Event Mapping + +| v4 Event | v5 Listener | v5 Event | +|----------|-------------|----------| +| `onCallEnded()` | `SessionStatusListener` | `onSessionLeft()` | +| `onCallEndButtonPressed()` | `ButtonClickListener` | `onLeaveSessionButtonClicked()` | +| `onSessionTimeout()` | `SessionStatusListener` | `onSessionTimedOut()` | +| `onUserJoined(RTCUser)` | `ParticipantEventListener` | `onParticipantJoined(Participant)` | +| `onUserLeft(RTCUser)` | `ParticipantEventListener` | `onParticipantLeft(Participant)` | +| `onUserListChanged(ArrayList)` | `ParticipantEventListener` | `onParticipantListChanged(List)` | +| `onAudioModeChanged(ArrayList)` | `MediaEventsListener` | `onAudioModeChanged(AudioMode)` | +| `onCallSwitchedToVideo(CallSwitchRequestInfo)` | *Removed* | — | +| `onUserMuted(RTCMutedUser)` | `ParticipantEventListener` | `onParticipantAudioMuted(Participant)` | +| `onRecordingToggled(RTCRecordingInfo)` | `MediaEventsListener` | `onRecordingStarted()` / `onRecordingStopped()` | +| `onError(CometChatException)` | — | Errors are returned via `CallbackListener.onError()` | + +### New Events in v5 + +These events are only available with the v5 listener APIs: + +| Listener | Event | Description | +|----------|-------|-------------| +| `SessionStatusListener` | `onConnectionLost()` | Network interrupted | +| `SessionStatusListener` | `onConnectionRestored()` | Network restored | +| `SessionStatusListener` | `onConnectionClosed()` | Connection permanently closed | +| `ParticipantEventListener` | `onParticipantVideoResumed()` | Participant turned camera on | +| `ParticipantEventListener` | `onParticipantVideoPaused()` | Participant turned camera off | +| `ParticipantEventListener` | `onParticipantHandRaised()` | Participant raised hand | +| `ParticipantEventListener` | `onParticipantHandLowered()` | Participant lowered hand | +| `ParticipantEventListener` | `onParticipantStartedScreenShare()` | Participant started screen share | +| `ParticipantEventListener` | `onParticipantStoppedScreenShare()` | Participant stopped screen share | +| `ParticipantEventListener` | `onDominantSpeakerChanged()` | Active speaker changed | +| `MediaEventsListener` | `onCameraFacingChanged()` | Camera switched front/back | +| `ButtonClickListener` | Various button events | Individual button click tracking | +| `LayoutListener` | `onCallLayoutChanged()` | Layout type changed | +| `LayoutListener` | `onPictureInPictureLayoutEnabled/Disabled()` | PiP state changed | + +--- + +--- + +## Call Logs + +The `CallLogRequest` API is unchanged. The only deprecated method is `setAuthToken()` — in v5, auth is handled by `CometChatCalls.login()`. + + + +```java +CallLogRequest request = new CallLogRequest.CallLogRequestBuilder() + .setAuthToken(authToken) + .setLimit(30) + .build(); +``` + + +```java +// Auth token is handled by CometChatCalls.login() +CallLogRequest request = new CallLogRequest.CallLogRequestBuilder() + .setLimit(30) + .build(); +``` + + + +--- + +## Deprecated Classes Summary + +These classes still exist in v5 for backward compatibility but are deprecated: + +| Deprecated Class | Replacement | +|-----------------|-------------| +| `CallSettings` | `SessionSettings` | +| `CometChatCalls.CallSettingsBuilder` | `CometChatCalls.SessionSettingsBuilder` | +| `CometChatCallsEventsListener` | 5 focused listeners on `CallSession` | +| `RTCRecordingInfo` | `MediaEventsListener` callbacks | +| `CallSwitchRequestInfo` | *Removed (no replacement)* | diff --git a/calls/ios/migration-guide-v5.mdx b/calls/ios/migration-guide-v5.mdx new file mode 100644 index 000000000..63099f726 --- /dev/null +++ b/calls/ios/migration-guide-v5.mdx @@ -0,0 +1,420 @@ +--- +title: "Migration Guide" +sidebarTitle: "v4 to v5 Migration" +--- + +This guide covers migrating from Calls SDK v4 to v5 for iOS. + +## Drop-in Compatibility + +Calls SDK v5 is a **drop-in replacement** for v4. All v4 APIs are preserved as deprecated methods that internally delegate to the new v5 implementations. You can update the dependency version and your existing code will compile and run without changes. + +```ruby +# CocoaPods — update your Podfile +-pod 'CometChatCallsSDK', '~> 4.0' ++pod 'CometChatCallsSDK', '~> 5.0' +``` + +```swift +// Swift Package Manager — update your package dependency version to 5.x +``` + + +If you're using CometChat UI Kits, simply updating the Calls SDK version is sufficient. The UI Kit will continue to work with v5 through the deprecated compatibility layer. + + +## Why Migrate to v5 APIs? + +While v4 APIs will continue to work, migrating to v5 APIs gives you: + +- **Granular event listeners** — 5 focused listener protocols instead of one monolithic `CallsEventsDelegate` +- **`CallSession` singleton** for cleaner session control — all actions on a single object instead of scattered static methods +- **Dedicated `login()` method** — the Calls SDK now handles its own authentication instead of depending on the Chat SDK's auth token or REST APIs +- **Strongly-typed enums** — `AudioModeType`, `CallType`, `LayoutType`, `CameraFacing` instead of raw strings + +--- + +## Initialization + +No changes required. The `init` API is the same in v5. + +```swift +let callAppSettings = CallAppSettings() +callAppSettings.set(appId: "APP_ID") +callAppSettings.set(region: "REGION") + +CometChatCalls(callsAppSettings: callAppSettings, onSuccess: { success in + // Initialized +}, onError: { error in + // Handle error +}) +``` + +--- + +## Authentication + +In v4, the Calls SDK had no dedicated authentication step. It relied on the Chat SDK's auth token (`CometChat.getUserAuthToken()`) or a REST API to obtain an auth token, which you then passed manually to `generateToken(authToken:sessionID:onSuccess:onError:)`. + +v5 introduces its own `login()` method. After calling `login()`, the SDK caches the auth token internally, so you no longer need to pass it around to other API calls. + + + +```swift +// No dedicated Calls SDK login — relied on Chat SDK for auth token +let authToken = CometChat.getUserAuthToken() + +// Had to pass authToken manually +CometChatCalls.generateToken(authToken: authToken as NSString?, + sessionID: sessionID as NSString?, + onSuccess: { token in + // Use token to start session +}, onError: { error in }) +``` + + +```swift +// Login to the Calls SDK once (after your Chat SDK login) +CometChatCalls.login(authToken: authToken, onSuccess: { callsUser in + // Calls SDK is now authenticated — auth token is cached internally +}, onError: { error in }) +``` + + + + +Call `CometChatCalls.login()` once after your user authenticates (e.g., right after `CometChat.login()` succeeds). The SDK stores the auth token internally, so subsequent calls like `generateToken()` and `joinSession()` use it automatically without you having to pass it. + + +--- + +## Session Settings + +`CallSettingsBuilder` and `PresentationSettingsBuilder` are replaced by `SessionSettingsBuilder`. The builder methods have been renamed for clarity. + + + +```swift +let callSettings = CometChatCalls.callSettingsBuilder + .setIsAudioOnly(true) + .setDefaultLayout(true) + .setEndCallButtonDisable(false) + .setMuteAudioButtonDisable(false) + .setPauseVideoButtonDisable(false) + .setSwitchCameraButtonDisable(false) + .setAudioModeButtonDisable(false) + .setShowRecordingButton(true) + .setStartAudioMuted(false) + .setStartVideoMuted(false) + .setDefaultAudioMode("SPEAKER") + .setMode("DEFAULT") + .setStartRecordingOnCallStart(false) + .setDelegate(self) + .build() +``` + + +```swift +let sessionSettings = CometChatCalls.sessionSettingsBuilder + .setType(.audio) + .startAudioMuted(false) + .startVideoPaused(false) + .setLayout(.tile) + .setAudioMode(.speaker) + .hideLeaveSessionButton(false) + .hideToggleAudioButton(false) + .hideToggleVideoButton(false) + .hideSwitchCameraButton(false) + .hideAudioModeButton(false) + .hideRecordingButton(false) + .hideControlPanel(false) + .hideHeaderPanel(false) + .enableAutoStartRecording(false) + .build() +``` + + + +### Builder Method Mapping + +| v4 Method | v5 Method | Notes | +|-----------|-----------|-------| +| `setIsAudioOnly(true)` | `setType(.audio)` | Use `.video` for video calls | +| `setDefaultLayout(bool)` | `hideControlPanel(!bool)` + `hideHeaderPanel(!bool)` | Inverted logic | +| `setEndCallButtonDisable(bool)` | `hideLeaveSessionButton(bool)` | Same logic | +| `setMuteAudioButtonDisable(bool)` | `hideToggleAudioButton(bool)` | Same logic | +| `setPauseVideoButtonDisable(bool)` | `hideToggleVideoButton(bool)` | Same logic | +| `setSwitchCameraButtonDisable(bool)` | `hideSwitchCameraButton(bool)` | Same logic | +| `setAudioModeButtonDisable(bool)` | `hideAudioModeButton(bool)` | Same logic | +| `setShowRecordingButton(bool)` | `hideRecordingButton(!bool)` | Inverted logic | +| `setStartAudioMuted(bool)` | `startAudioMuted(bool)` | Same logic | +| `setStartVideoMuted(bool)` | `startVideoPaused(bool)` | Same logic | +| `setDefaultAudioMode("SPEAKER")` | `setAudioMode(.speaker)` | Enum instead of string | +| `setMode("DEFAULT")` | `setLayout(.tile)` | Enum instead of string | +| `setStartRecordingOnCallStart(bool)` | `enableAutoStartRecording(bool)` | Same logic | +| `setAvatarMode(string)` | *Removed* | No longer applicable | +| `setEnableVideoTileClick(bool)` | *Removed* | No longer applicable | +| `setEnableDraggableVideoTile(bool)` | *Removed* | No longer applicable | +| `setDelegate(delegate)` | Use `CallSession` listeners | See [Events](#event-listeners) section | + +--- + +## Joining a Session + +`startSession()` is replaced by `joinSession()`. + + + +```swift +// Step 1: Generate token with auth token +CometChatCalls.generateToken(authToken: authToken as NSString?, + sessionID: sessionID as NSString?, + onSuccess: { token in + // Step 2: Start session with token string + CometChatCalls.startSession(callToken: token ?? "", + callSetting: callSettings, + view: callView, + onSuccess: { message in + // Session started + }, onError: { error in }) +}, onError: { error in }) +``` + + +```swift +// Option A: Two-step with token +CometChatCalls.generateToken(sessionID: sessionID, onSuccess: { token in + CometChatCalls.joinSession(callToken: token ?? "", + callSetting: sessionSettings, + container: callView, + onSuccess: { message in + // Session joined + }, onError: { error in }) +}, onError: { error in }) + +// Option B: One-step with session ID (recommended) +CometChatCalls.joinSession(sessionID: sessionID, + callSetting: sessionSettings, + container: callView, + onSuccess: { message in + // Token generation + join handled internally +}, onError: { error in }) +``` + + + +Key differences: +- v5 `generateToken()` no longer requires the `authToken` parameter (uses cached token from `login()`) +- v5 offers a convenience overload that takes `sessionID` directly and handles token generation internally +- Parameter name changed from `view` to `container` + +--- + +## Session Control (Actions) + +In v4, session actions were static methods on `CometChatCalls`. In v5, they're instance methods on `CallSession.shared`. + + + +```swift +CometChatCalls.endSession() +CometChatCalls.switchCamera() +CometChatCalls.audioMuted(true) +CometChatCalls.videoPaused(true) +CometChatCalls.setAudioMode(mode: "SPEAKER") +CometChatCalls.enterPIPMode() +CometChatCalls.exitPIPMode() +CometChatCalls.startRecording() +CometChatCalls.stopRecording() +``` + + +```swift +let callSession = CallSession.shared + +callSession.leaveSession() +callSession.switchCamera() +callSession.muteAudio() // or callSession.unmuteAudio() +callSession.pauseVideo() // or callSession.resumeVideo() +callSession.setAudioMode("SPEAKER") +callSession.enablePictureInPictureLayout() +callSession.disablePictureInPictureLayout() +callSession.startRecording() +callSession.stopRecording() +``` + + + +### Action Method Mapping + +| v4 Static Method | v5 CallSession Method | +|---|---| +| `CometChatCalls.endSession()` | `callSession.leaveSession()` | +| `CometChatCalls.switchCamera()` | `callSession.switchCamera()` | +| `CometChatCalls.audioMuted(true)` | `callSession.muteAudio()` | +| `CometChatCalls.audioMuted(false)` | `callSession.unmuteAudio()` | +| `CometChatCalls.videoPaused(true)` | `callSession.pauseVideo()` | +| `CometChatCalls.videoPaused(false)` | `callSession.resumeVideo()` | +| `CometChatCalls.setAudioMode(mode:)` | `callSession.setAudioMode(_:)` | +| `CometChatCalls.enterPIPMode()` | `callSession.enablePictureInPictureLayout()` | +| `CometChatCalls.exitPIPMode()` | `callSession.disablePictureInPictureLayout()` | +| `CometChatCalls.startRecording()` | `callSession.startRecording()` | +| `CometChatCalls.stopRecording()` | `callSession.stopRecording()` | +| `CometChatCalls.switchToVideoCall()` | *Removed* | + +--- + +## Event Listeners + +This is the biggest improvement in v5. The single `CallsEventsDelegate` protocol is replaced by 5 focused listener protocols. + +### v4: Single Monolithic Delegate + +```swift +class MyViewController: UIViewController, CallsEventsDelegate { + + func setupCallEvents() { + // Set via builder + CometChatCalls.callSettingsBuilder.setDelegate(self).build() + } + + func onCallEnded() { } + func onCallEndButtonPressed() { } + func onSessionTimeout() { } + func onUserJoined(rtcUser: RTCUser) { } + func onUserLeft(rtcUser: RTCUser) { } + func onUserListChanged(rtcUsers: [RTCUser]) { } + func onAudioModeChanged(mode: [CallAudioMode]) { } + func onCallSwitchedToVideo(callSwitchedInfo: CallSwitchRequestInfo) { } + func onUserMuted(rtcMutedUser: RTCMutedUser) { } + func onRecordingToggled(recordingInfo: RTCRecordingInfo) { } +} +``` + +### v5: Focused Listener Protocols + +```swift +let callSession = CallSession.shared + +// Session lifecycle events +class MySessionListener: SessionStatusListener { + func onSessionJoined() { } + func onSessionLeft() { } + func onSessionTimedOut() { } + func onConnectionLost() { } + func onConnectionRestored() { } + func onConnectionClosed() { } +} +callSession.addSessionStatusListener(mySessionListener) + +// Participant events (replaces onUserJoined, onUserLeft, onUserListChanged, onUserMuted) +class MyParticipantListener: ParticipantEventListener { + func onParticipantJoined(participant: Participant) { } + func onParticipantLeft(participant: Participant) { } + func onParticipantListChanged(participants: [Participant]) { } + func onParticipantAudioMuted(participant: Participant) { } + func onParticipantAudioUnmuted(participant: Participant) { } + func onParticipantVideoPaused(participant: Participant) { } + func onParticipantVideoResumed(participant: Participant) { } + func onParticipantHandRaised(participant: Participant) { } + func onParticipantHandLowered(participant: Participant) { } + func onParticipantStartedRecording(participant: Participant) { } + func onParticipantStoppedRecording(participant: Participant) { } + func onDominantSpeakerChanged(participant: Participant) { } +} +callSession.addParticipantEventListener(myParticipantListener) + +// Media state events (replaces onAudioModeChanged, onRecordingToggled) +class MyMediaListener: MediaEventsListener { + func onAudioMuted() { } + func onAudioUnMuted() { } + func onVideoPaused() { } + func onVideoResumed() { } + func onRecordingStarted() { } + func onRecordingStopped() { } + func onAudioModeChanged(audioModeType: AudioModeType) { } + func onCameraFacingChanged(cameraFacing: CameraFacing) { } +} +callSession.addMediaEventsListener(myMediaListener) + +// Button click events (replaces onCallEndButtonPressed) +class MyButtonListener: ButtonClickListener { + func onLeaveSessionButtonClicked() { } + func onToggleAudioButtonClicked() { } + func onToggleVideoButtonClicked() { } + func onSwitchCameraButtonClicked() { } + func onRaiseHandButtonClicked() { } + func onRecordingToggleButtonClicked() { } +} +callSession.addButtonClickListener(myButtonListener) + +// Layout events +class MyLayoutListener: LayoutListener { + func onCallLayoutChanged(layoutType: LayoutType) { } + func onPictureInPictureLayoutEnabled() { } + func onPictureInPictureLayoutDisabled() { } +} +callSession.addLayoutListener(myLayoutListener) +``` + + +v5 listeners use weak references internally, so they are automatically cleaned up when the listener object is deallocated. You can also explicitly remove listeners using `removeSessionStatusListener(_:)`, `removeParticipantEventListener(_:)`, etc. + + +### Event Mapping + +| v4 Event | v5 Listener | v5 Event | +|----------|-------------|----------| +| `onCallEnded()` | `SessionStatusListener` | `onSessionLeft()` | +| `onCallEndButtonPressed()` | `ButtonClickListener` | `onLeaveSessionButtonClicked()` | +| `onSessionTimeout()` | `SessionStatusListener` | `onSessionTimedOut()` | +| `onUserJoined(rtcUser:)` | `ParticipantEventListener` | `onParticipantJoined(participant:)` | +| `onUserLeft(rtcUser:)` | `ParticipantEventListener` | `onParticipantLeft(participant:)` | +| `onUserListChanged(rtcUsers:)` | `ParticipantEventListener` | `onParticipantListChanged(participants:)` | +| `onAudioModeChanged(mode:)` | `MediaEventsListener` | `onAudioModeChanged(audioModeType:)` | +| `onCallSwitchedToVideo(callSwitchedInfo:)` | *Removed* | — | +| `onUserMuted(rtcMutedUser:)` | `ParticipantEventListener` | `onParticipantAudioMuted(participant:)` | +| `onRecordingToggled(recordingInfo:)` | `MediaEventsListener` | `onRecordingStarted()` / `onRecordingStopped()` | + +### New Events in v5 + +These events are only available with the v5 listener APIs: + +| Listener | Event | Description | +|----------|-------|-------------| +| `SessionStatusListener` | `onConnectionLost()` | Network interrupted | +| `SessionStatusListener` | `onConnectionRestored()` | Network restored | +| `SessionStatusListener` | `onConnectionClosed()` | Connection permanently closed | +| `ParticipantEventListener` | `onParticipantVideoResumed()` | Participant turned camera on | +| `ParticipantEventListener` | `onParticipantVideoPaused()` | Participant turned camera off | +| `ParticipantEventListener` | `onParticipantHandRaised()` | Participant raised hand | +| `ParticipantEventListener` | `onParticipantHandLowered()` | Participant lowered hand | +| `ParticipantEventListener` | `onParticipantStartedScreenShare()` | Participant started screen share | +| `ParticipantEventListener` | `onParticipantStoppedScreenShare()` | Participant stopped screen share | +| `ParticipantEventListener` | `onDominantSpeakerChanged()` | Active speaker changed | +| `MediaEventsListener` | `onCameraFacingChanged()` | Camera switched front/back | +| `ButtonClickListener` | Various button events | Individual button click tracking | +| `LayoutListener` | `onCallLayoutChanged()` | Layout type changed | +| `LayoutListener` | `onPictureInPictureLayoutEnabled/Disabled()` | PiP state changed | + +--- + +## Call Logs + +The `CallLogsRequest` API is unchanged. The only difference is that auth is now handled by `CometChatCalls.login()` instead of passing the auth token manually. + +--- + +## Deprecated Classes Summary + +These classes still exist in v5 for backward compatibility but are deprecated: + +| Deprecated Class | Replacement | +|-----------------|-------------| +| `CallSettings` | `SessionSettingsBuilder.SessionSettings` | +| `CallSettingsBuilder` | `SessionSettingsBuilder` | +| `PresentationSettings` | `SessionSettingsBuilder.SessionSettings` | +| `PresentationSettingsBuilder` | `SessionSettingsBuilder` | +| `CallsEventsDelegate` | 5 focused listeners on `CallSession` | +| `RTCRecordingInfo` | `MediaEventsListener` callbacks | +| `CallSwitchRequestInfo` | *Removed (no replacement)* | diff --git a/calls/javascript/migration-guide-v5.mdx b/calls/javascript/migration-guide-v5.mdx new file mode 100644 index 000000000..3431b3e76 --- /dev/null +++ b/calls/javascript/migration-guide-v5.mdx @@ -0,0 +1,323 @@ +--- +title: "Migration Guide" +sidebarTitle: "v4 to v5 Migration" +--- + +This guide covers migrating from Calls SDK v4 to v5 for JavaScript (React, Vue, Angular, etc.). + +## Drop-in Compatibility + +Calls SDK v5 is a **drop-in replacement** for v4. All v4 APIs are preserved as deprecated methods that internally delegate to the new v5 implementations. You can update the package version and your existing code will compile and run without changes. + +```bash +npm install @cometchat/calls-sdk-javascript@5 +``` + + +If you're using CometChat UI Kits, simply updating the Calls SDK version is sufficient. The UI Kit will continue to work with v5 through the deprecated compatibility layer. + + +## Why Migrate to v5 APIs? + +While v4 APIs will continue to work, migrating to v5 APIs gives you: + +- **Granular event listeners** — subscribe to specific events like `onParticipantJoined` or `onSessionLeft` instead of one monolithic `OngoingCallListener` +- **Dedicated `login()` method** — the Calls SDK now handles its own authentication instead of depending on the Chat SDK's auth token or REST APIs +- **Simplified initialization** — pass plain objects to `init()` and `joinSession()` instead of using builder classes +- **Strongly-typed enums** — `LayoutType`, `SessionType` instead of raw strings + +--- + +## Initialization + +v5 accepts a plain object instead of requiring `CallAppSettingsBuilder`. + + + +```javascript +const callAppSettings = new CometChatCalls.CallAppSettingsBuilder() + .setAppId("APP_ID") + .setRegion("REGION") + .build(); + +CometChatCalls.init(callAppSettings).then( + () => { /* initialized */ }, + (error) => { /* handle error */ } +); +``` + + +```javascript +const callAppSettings = { + appId: "APP_ID", + region: "REGION", +}; + +CometChatCalls.init(callAppSettings).then( + () => { /* initialized */ }, + (error) => { /* handle error */ } +); +``` + + + + +`CallAppSettingsBuilder` still works in v5 — it's deprecated but functional. + + +--- + +## Authentication + +In v4, the Calls SDK had no dedicated authentication step. It relied on the Chat SDK's auth token (`CometChat.getUserAuthToken()`) or a REST API to obtain an auth token, which you then passed manually to `generateToken()`. + +v5 introduces its own `login()` method. After calling `login()`, the SDK caches the auth token internally. + + + +```javascript +// No dedicated Calls SDK login — relied on Chat SDK for auth token +const authToken = CometChat.getUserAuthToken(); + +// Had to pass authToken manually +CometChatCalls.generateToken(sessionId, authToken).then( + (token) => { /* use token to start session */ }, + (error) => { } +); +``` + + +```javascript +// Login to the Calls SDK once (after your Chat SDK login) +CometChatCalls.login(authToken).then( + (user) => { /* Calls SDK is now authenticated */ }, + (error) => { } +); + +// generateToken no longer needs the authToken parameter +CometChatCalls.generateToken(sessionId).then( + (token) => { /* use token */ }, + (error) => { } +); +``` + + + + +Call `CometChatCalls.login()` once after your user authenticates. The SDK stores the auth token internally, so subsequent calls like `generateToken()` and `joinSession()` use it automatically. + + +--- + +## Session Settings + +`CallSettingsBuilder` is replaced by passing a plain `SessionSettings` object directly to `joinSession()`. + + + +```javascript +const callSettings = new CometChatCalls.CallSettingsBuilder() + .enableDefaultLayout(true) + .setIsAudioOnlyCall(true) + .showEndCallButton(true) + .showMuteAudioButton(true) + .showPauseVideoButton(true) + .showRecordingButton(true) + .showScreenShareButton(true) + .showSwitchModeButton(true) + .startWithAudioMuted(false) + .startWithVideoMuted(false) + .setMode("DEFAULT") + .setCallListener(new CometChatCalls.OngoingCallListener({ + onCallEnded: () => { }, + onCallEndButtonPressed: () => { }, + onUserJoined: (user) => { }, + onUserLeft: (user) => { }, + onUserListUpdated: (userList) => { }, + onError: (error) => { }, + })) + .build(); +``` + + +```javascript +const sessionSettings = { + sessionType: "VIDEO", // or "VOICE" + layout: "TILE", // or "SPOTLIGHT", "SIDEBAR" + startAudioMuted: false, + startVideoPaused: false, + hideLeaveSessionButton: false, + hideToggleAudioButton: false, + hideToggleVideoButton: false, + hideRecordingButton: false, + hideScreenSharingButton: false, + hideChangeLayoutButton: false, + hideControlPanel: false, + autoStartRecording: false, +}; +``` + + + +### Settings Property Mapping + +| v4 Builder Method | v5 Property | Notes | +|-----------|-----------|-------| +| `setIsAudioOnlyCall(true)` | `sessionType: "VOICE"` | Use `"VIDEO"` for video calls | +| `enableDefaultLayout(bool)` | `hideControlPanel: !bool` | Inverted logic | +| `showEndCallButton(bool)` | `hideLeaveSessionButton: !bool` | Inverted logic | +| `showMuteAudioButton(bool)` | `hideToggleAudioButton: !bool` | Inverted logic | +| `showPauseVideoButton(bool)` | `hideToggleVideoButton: !bool` | Inverted logic | +| `showRecordingButton(bool)` | `hideRecordingButton: !bool` | Inverted logic | +| `showScreenShareButton(bool)` | `hideScreenSharingButton: !bool` | Inverted logic | +| `showSwitchModeButton(bool)` | `hideChangeLayoutButton: !bool` | Inverted logic | +| `startWithAudioMuted(bool)` | `startAudioMuted: bool` | Same logic | +| `startWithVideoMuted(bool)` | `startVideoPaused: bool` | Same logic | +| `setMode("DEFAULT")` | `layout: "SIDEBAR"` | `"DEFAULT"` maps to `"SIDEBAR"` | +| `startRecordingOnCallStart(bool)` | `autoStartRecording: bool` | Same logic | +| `setCallListener(listener)` | Use `addEventListener()` | See [Events](#event-listeners) section | + +--- + +## Joining a Session + +`startSession()` is replaced by `joinSession()`. + + + +```javascript +CometChatCalls.generateToken(sessionId, authToken).then((token) => { + CometChatCalls.startSession(token, callSettings, document.getElementById("callContainer")); +}); +``` + + +```javascript +// Option A: With token +CometChatCalls.generateToken(sessionId).then((token) => { + CometChatCalls.joinSession(token, sessionSettings, document.getElementById("callContainer")); +}); + +// Option B: With session ID (recommended) +CometChatCalls.joinSession(sessionId, sessionSettings, document.getElementById("callContainer")); +``` + + + +--- + +## Session Control (Actions) + +Static methods remain on `CometChatCalls` but some have been renamed. + +| v4 Method | v5 Method | +|---|---| +| `CometChatCalls.endSession()` | `CometChatCalls.leaveSession()` | +| `CometChatCalls.switchCamera()` | `CometChatCalls.switchCamera()` | +| `CometChatCalls.muteAudio(true)` | `CometChatCalls.muteAudio()` | +| `CometChatCalls.muteAudio(false)` | `CometChatCalls.unmuteAudio()` | +| `CometChatCalls.pauseVideo(true)` | `CometChatCalls.pauseVideo()` | +| `CometChatCalls.pauseVideo(false)` | `CometChatCalls.resumeVideo()` | +| `CometChatCalls.setMode(mode)` | `CometChatCalls.setLayout(layout)` | +| `CometChatCalls.startScreenShare()` | `CometChatCalls.startScreenSharing()` | +| `CometChatCalls.stopScreenShare()` | `CometChatCalls.stopScreenSharing()` | +| `CometChatCalls.enterPIPMode()` | `CometChatCalls.enablePictureInPictureLayout()` | +| `CometChatCalls.exitPIPMode()` | `CometChatCalls.disablePictureInPictureLayout()` | +| `CometChatCalls.openVirtualBackground()` | `CometChatCalls.showVirtualBackgroundDialog()` | +| `CometChatCalls.closeVirtualBackground()` | `CometChatCalls.hideVirtualBackgroundDialog()` | +| `CometChatCalls.setBackgroundBlur(level)` | `CometChatCalls.setVirtualBackgroundBlurLevel(level)` | +| `CometChatCalls.setBackgroundImage(url)` | `CometChatCalls.setVirtualBackgroundImage(url)` | +| `CometChatCalls.startRecording()` | `CometChatCalls.startRecording()` | +| `CometChatCalls.stopRecording()` | `CometChatCalls.stopRecording()` | +| `CometChatCalls.switchToVideoCall()` | *Removed* | +| `CometChatCalls.getCallDetails()` | *Removed* | + +--- + +## Event Listeners + +The single `OngoingCallListener` is replaced by `addEventListener()` with specific event types. + +### v4: Single Listener Object + +```javascript +const callSettings = new CometChatCalls.CallSettingsBuilder() + .setCallListener(new CometChatCalls.OngoingCallListener({ + onCallEnded: () => { }, + onCallEndButtonPressed: () => { }, + onUserJoined: (user) => { }, + onUserLeft: (user) => { }, + onUserListUpdated: (userList) => { }, + onAudioModeChanged: (audioModeList) => { }, + onUserMuted: (muteInfo) => { }, + onRecordingToggled: (recordingInfo) => { }, + onError: (error) => { }, + })) + .build(); +``` + +### v5: Granular Event Subscriptions + +```javascript +// Session events +CometChatCalls.addEventListener("onSessionJoined", () => { }); +CometChatCalls.addEventListener("onSessionLeft", () => { }); +CometChatCalls.addEventListener("onSessionTimedOut", () => { }); +CometChatCalls.addEventListener("onConnectionLost", () => { }); +CometChatCalls.addEventListener("onConnectionRestored", () => { }); + +// Participant events +CometChatCalls.addEventListener("onParticipantJoined", (participant) => { }); +CometChatCalls.addEventListener("onParticipantLeft", (participant) => { }); +CometChatCalls.addEventListener("onParticipantListChanged", (participants) => { }); +CometChatCalls.addEventListener("onParticipantAudioMuted", (participant) => { }); +CometChatCalls.addEventListener("onParticipantAudioUnmuted", (participant) => { }); + +// Media events +CometChatCalls.addEventListener("onAudioMuted", () => { }); +CometChatCalls.addEventListener("onAudioUnMuted", () => { }); +CometChatCalls.addEventListener("onRecordingStarted", () => { }); +CometChatCalls.addEventListener("onRecordingStopped", () => { }); + +// Button click events +CometChatCalls.addEventListener("onLeaveSessionButtonClicked", () => { }); +CometChatCalls.addEventListener("onToggleAudioButtonClicked", () => { }); +CometChatCalls.addEventListener("onToggleVideoButtonClicked", () => { }); + +// Layout events +CometChatCalls.addEventListener("onCallLayoutChanged", (layoutType) => { }); +CometChatCalls.addEventListener("onPictureInPictureLayoutEnabled", () => { }); +CometChatCalls.addEventListener("onPictureInPictureLayoutDisabled", () => { }); +``` + + +`addEventListener()` returns an unsubscribe function. Call it to remove the listener. You can also pass an `AbortSignal` for cleanup. + + +### Event Mapping + +| v4 Event | v5 Event | +|----------|----------| +| `onCallEnded` | `onSessionLeft` | +| `onCallEndButtonPressed` | `onLeaveSessionButtonClicked` | +| `onUserJoined(user)` | `onParticipantJoined(participant)` | +| `onUserLeft(user)` | `onParticipantLeft(participant)` | +| `onUserListUpdated(userList)` | `onParticipantListChanged(participants)` | +| `onAudioModeChanged(list)` | `onAudioModeChanged(audioMode)` | +| `onUserMuted(info)` | `onParticipantAudioMuted(participant)` | +| `onRecordingToggled(info)` | `onRecordingStarted` / `onRecordingStopped` | +| `onError(error)` | Errors returned via Promise rejection | + +--- + +## Deprecated Classes Summary + +| Deprecated | Replacement | +|------------|-------------| +| `CometChatCalls.CallAppSettingsBuilder` | Pass plain object to `init()` | +| `CometChatCalls.CallSettingsBuilder` | Pass plain `SessionSettings` object to `joinSession()` | +| `CometChatCalls.OngoingCallListener` | `CometChatCalls.addEventListener()` | +| `CometChatCalls.startSession()` | `CometChatCalls.joinSession()` | +| `CometChatCalls.endSession()` | `CometChatCalls.leaveSession()` | +| `RTCRecordingInfo` | `onRecordingStarted` / `onRecordingStopped` events | +| `CallSwitchRequestInfo` | *Removed (no replacement)* | diff --git a/calls/react-native/migration-guide-v5.mdx b/calls/react-native/migration-guide-v5.mdx new file mode 100644 index 000000000..160d70ed0 --- /dev/null +++ b/calls/react-native/migration-guide-v5.mdx @@ -0,0 +1,314 @@ +--- +title: "Migration Guide" +sidebarTitle: "v4 to v5 Migration" +--- + +This guide covers migrating from Calls SDK v4 to v5 for React Native. + +## Drop-in Compatibility + +Calls SDK v5 is a **drop-in replacement** for v4. All v4 APIs are preserved as deprecated methods that internally delegate to the new v5 implementations. You can update the package version and your existing code will compile and run without changes. + +```bash +npm install @cometchat/calls-sdk-react-native@5 +``` + + +If you're using CometChat UI Kits, simply updating the Calls SDK version is sufficient. The UI Kit will continue to work with v5 through the deprecated compatibility layer. + + +## Why Migrate to v5 APIs? + +While v4 APIs will continue to work, migrating to v5 APIs gives you: + +- **Granular event listeners** — subscribe to specific events like `onParticipantJoined` or `onSessionLeft` instead of one monolithic `OngoingCallListener` +- **Dedicated `login()` method** — the Calls SDK now handles its own authentication instead of depending on the Chat SDK's auth token or REST APIs +- **Simplified initialization** — pass plain objects to `init()` and `joinSession()` instead of using builder classes +- **Strongly-typed enums** — `LayoutType`, `SessionType` instead of raw strings + +--- + +## Initialization + +v5 accepts a plain object instead of requiring `CallAppSettingsBuilder`. + + + +```javascript +const callAppSettings = new CometChatCalls.CallAppSettingsBuilder() + .setAppId("APP_ID") + .setRegion("REGION") + .build(); + +CometChatCalls.init(callAppSettings).then( + () => { /* initialized */ }, + (error) => { /* handle error */ } +); +``` + + +```javascript +const callAppSettings = { + appId: "APP_ID", + region: "REGION", +}; + +CometChatCalls.init(callAppSettings).then( + () => { /* initialized */ }, + (error) => { /* handle error */ } +); +``` + + + + +`CallAppSettingsBuilder` still works in v5 — it's deprecated but functional. + + +--- + +## Authentication + +In v4, the Calls SDK had no dedicated authentication step. It relied on the Chat SDK's auth token (`CometChat.getUserAuthToken()`) or a REST API to obtain an auth token, which you then passed manually to `generateToken()`. + +v5 introduces its own `login()` method. After calling `login()`, the SDK caches the auth token internally. + + + +```javascript +// No dedicated Calls SDK login — relied on Chat SDK for auth token +const authToken = CometChat.getUserAuthToken(); + +// Had to pass authToken manually +CometChatCalls.generateToken(sessionId, authToken).then( + (token) => { /* use token to start session */ }, + (error) => { } +); +``` + + +```javascript +// Login to the Calls SDK once (after your Chat SDK login) +CometChatCalls.login(authToken).then( + (user) => { /* Calls SDK is now authenticated */ }, + (error) => { } +); + +// generateToken no longer needs the authToken parameter +CometChatCalls.generateToken(sessionId).then( + (token) => { /* use token */ }, + (error) => { } +); +``` + + + + +Call `CometChatCalls.login()` once after your user authenticates. The SDK stores the auth token internally, so subsequent calls like `generateToken()` and `joinSession()` use it automatically. + + +--- + +## Session Settings + +`CallSettingsBuilder` is replaced by passing a plain `SessionSettings` object directly. + + + +```javascript +const callSettings = new CometChatCalls.CallSettingsBuilder() + .enableDefaultLayout(true) + .setIsAudioOnlyCall(true) + .showEndCallButton(true) + .showMuteAudioButton(true) + .showPauseVideoButton(true) + .showRecordingButton(true) + .showSwitchModeButton(true) + .startWithAudioMuted(false) + .startWithVideoMuted(false) + .setMode(CometChatCalls.CALL_MODE.DEFAULT) + .setCallListener(new CometChatCalls.OngoingCallListener({ + onCallEnded: () => { }, + onCallEndButtonPressed: () => { }, + onUserJoined: (user) => { }, + onUserLeft: (user) => { }, + onUserListUpdated: (userList) => { }, + onError: (error) => { }, + })) + .build(); +``` + + +```javascript +const sessionSettings = { + sessionType: "VIDEO", // or "VOICE" + layout: "TILE", // or "SPOTLIGHT" + startAudioMuted: false, + startVideoPaused: false, + hideLeaveSessionButton: false, + hideToggleAudioButton: false, + hideToggleVideoButton: false, + hideRecordingButton: false, + hideScreenSharingButton: false, + hideChangeLayoutButton: false, + hideControlPanel: false, + autoStartRecording: false, +}; +``` + + + +### Settings Property Mapping + +| v4 Builder Method | v5 Property | Notes | +|-----------|-----------|-------| +| `setIsAudioOnlyCall(true)` | `sessionType: "VOICE"` | Use `"VIDEO"` for video calls | +| `enableDefaultLayout(bool)` | `hideControlPanel: !bool` | Inverted logic | +| `showEndCallButton(bool)` | `hideLeaveSessionButton: !bool` | Inverted logic | +| `showMuteAudioButton(bool)` | `hideToggleAudioButton: !bool` | Inverted logic | +| `showPauseVideoButton(bool)` | `hideToggleVideoButton: !bool` | Inverted logic | +| `showRecordingButton(bool)` | `hideRecordingButton: !bool` | Inverted logic | +| `showSwitchModeButton(bool)` | `hideChangeLayoutButton: !bool` | Inverted logic | +| `startWithAudioMuted(bool)` | `startAudioMuted: bool` | Same logic | +| `startWithVideoMuted(bool)` | `startVideoPaused: bool` | Same logic | +| `setMode(CALL_MODE.DEFAULT)` | `layout: "TILE"` | Enum instead of constant | +| `startRecordingOnCallStart(bool)` | `autoStartRecording: bool` | Same logic | +| `setCallListener(listener)` | Use `addEventListener()` | See [Events](#event-listeners) section | + +--- + +## Joining a Session + +`startSession()` is replaced by `joinSession()`. + + + +```javascript +CometChatCalls.generateToken(sessionId, authToken).then((token) => { + CometChatCalls.startSession(token, callSettings); +}); +``` + + +```javascript +// Option A: With token +CometChatCalls.generateToken(sessionId).then((token) => { + CometChatCalls.joinSession(token, sessionSettings); +}); + +// Option B: With session ID (recommended) +CometChatCalls.joinSession(sessionId, sessionSettings); +``` + + + +--- + +## Session Control (Actions) + +Static methods remain on `CometChatCalls` but some have been renamed. + +| v4 Method | v5 Method | +|---|---| +| `CometChatCalls.endSession()` | `CometChatCalls.leaveSession()` | +| `CometChatCalls.switchCamera()` | `CometChatCalls.switchCamera()` | +| `CometChatCalls.muteAudio(true)` | `CometChatCalls.muteAudio()` | +| `CometChatCalls.muteAudio(false)` | `CometChatCalls.unmuteAudio()` | +| `CometChatCalls.pauseVideo(true)` | `CometChatCalls.pauseVideo()` | +| `CometChatCalls.pauseVideo(false)` | `CometChatCalls.resumeVideo()` | +| `CometChatCalls.setMode(mode)` | `CometChatCalls.setLayout(layout)` | +| `CometChatCalls.enterPIPMode()` | `CometChatCalls.enablePictureInPictureLayout()` | +| `CometChatCalls.exitPIPMode()` | `CometChatCalls.disablePictureInPictureLayout()` | +| `CometChatCalls.startRecording()` | `CometChatCalls.startRecording()` | +| `CometChatCalls.stopRecording()` | `CometChatCalls.stopRecording()` | +| `CometChatCalls.switchToVideoCall()` | *Removed* | + +--- + +## Event Listeners + +The single `OngoingCallListener` is replaced by `addEventListener()` with specific event types. + +### v4: Single Listener Object + +```javascript +const callSettings = new CometChatCalls.CallSettingsBuilder() + .setCallListener(new CometChatCalls.OngoingCallListener({ + onCallEnded: () => { }, + onCallEndButtonPressed: () => { }, + onUserJoined: (user) => { }, + onUserLeft: (user) => { }, + onUserListUpdated: (userList) => { }, + onAudioModeChanged: (audioModeList) => { }, + onUserMuted: (muteInfo) => { }, + onRecordingToggled: (recordingInfo) => { }, + onError: (error) => { }, + })) + .build(); +``` + +### v5: Granular Event Subscriptions + +```javascript +// Session events +CometChatCalls.addEventListener("onSessionJoined", () => { }); +CometChatCalls.addEventListener("onSessionLeft", () => { }); +CometChatCalls.addEventListener("onSessionTimedOut", () => { }); +CometChatCalls.addEventListener("onConnectionLost", () => { }); +CometChatCalls.addEventListener("onConnectionRestored", () => { }); + +// Participant events +CometChatCalls.addEventListener("onParticipantJoined", (participant) => { }); +CometChatCalls.addEventListener("onParticipantLeft", (participant) => { }); +CometChatCalls.addEventListener("onParticipantListChanged", (participants) => { }); +CometChatCalls.addEventListener("onParticipantAudioMuted", (participant) => { }); +CometChatCalls.addEventListener("onParticipantAudioUnmuted", (participant) => { }); + +// Media events +CometChatCalls.addEventListener("onAudioMuted", () => { }); +CometChatCalls.addEventListener("onAudioUnMuted", () => { }); +CometChatCalls.addEventListener("onRecordingStarted", () => { }); +CometChatCalls.addEventListener("onRecordingStopped", () => { }); + +// Button click events +CometChatCalls.addEventListener("onLeaveSessionButtonClicked", () => { }); +CometChatCalls.addEventListener("onToggleAudioButtonClicked", () => { }); +CometChatCalls.addEventListener("onToggleVideoButtonClicked", () => { }); + +// Layout events +CometChatCalls.addEventListener("onCallLayoutChanged", (layoutType) => { }); +CometChatCalls.addEventListener("onPictureInPictureLayoutEnabled", () => { }); +CometChatCalls.addEventListener("onPictureInPictureLayoutDisabled", () => { }); +``` + + +`addEventListener()` returns an unsubscribe function. Call it to remove the listener. + + +### Event Mapping + +| v4 Event | v5 Event | +|----------|----------| +| `onCallEnded` | `onSessionLeft` | +| `onCallEndButtonPressed` | `onLeaveSessionButtonClicked` | +| `onUserJoined(user)` | `onParticipantJoined(participant)` | +| `onUserLeft(user)` | `onParticipantLeft(participant)` | +| `onUserListUpdated(userList)` | `onParticipantListChanged(participants)` | +| `onAudioModeChanged(list)` | `onAudioModeChanged(audioMode)` | +| `onUserMuted(info)` | `onParticipantAudioMuted(participant)` | +| `onRecordingToggled(info)` | `onRecordingStarted` / `onRecordingStopped` | +| `onError(error)` | Errors returned via Promise rejection | + +--- + +## Deprecated Classes Summary + +| Deprecated | Replacement | +|------------|-------------| +| `CometChatCalls.CallAppSettingsBuilder` | Pass plain object to `init()` | +| `CometChatCalls.CallSettingsBuilder` | Pass plain `SessionSettings` object to `joinSession()` | +| `CometChatCalls.OngoingCallListener` | `CometChatCalls.addEventListener()` | +| `CometChatCalls.startSession()` | `CometChatCalls.joinSession()` | +| `CometChatCalls.endSession()` | `CometChatCalls.leaveSession()` | +| `RTCRecordingInfo` | `onRecordingStarted` / `onRecordingStopped` events | +| `CallSwitchRequestInfo` | *Removed (no replacement)* | diff --git a/chat-call.mdx b/chat-call.mdx index df16c41e4..82330b640 100644 --- a/chat-call.mdx +++ b/chat-call.mdx @@ -14,7 +14,7 @@ canonical: "https://cometchat.com/docs"
-

Chat & Calling

+

Chat & Messaging

Add real-time chat and calls to your app in minutes. Choose the approach that fits your needs.

diff --git a/docs.json b/docs.json index 813c17df3..bca0aa32f 100644 --- a/docs.json +++ b/docs.json @@ -110,10 +110,8 @@ "product": "Chat & Messaging", "tabs": [ { - "tab": "Chat & Calling", - "pages": [ - "chat-call" - ] + "tab": "Chat & Messaging", + "pages": ["chat-call"] }, { "tab": "Platform", @@ -5353,6 +5351,12 @@ "calls/javascript/share-invite" ] }, + { + "group": "Migration Guide", + "pages": [ + "calls/javascript/migration-guide-v5" + ] + }, { "group": "Resources", "pages": [ @@ -5417,6 +5421,12 @@ "calls/react-native/share-invite" ] }, + { + "group": "Migration Guide", + "pages": [ + "calls/react-native/migration-guide-v5" + ] + }, { "group": "Resources", "pages": [ @@ -5480,6 +5490,12 @@ "calls/ios/share-invite" ] }, + { + "group": "Migration Guide", + "pages": [ + "calls/ios/migration-guide-v5" + ] + }, { "group": "Resources", "pages": [ @@ -5543,6 +5559,12 @@ "calls/android/share-invite" ] }, + { + "group": "Migration Guide", + "pages": [ + "calls/android/migration-guide-v5" + ] + }, { "group": "Resources", "pages": [ @@ -5606,6 +5628,12 @@ "calls/flutter/share-invite" ] }, + { + "group": "Migration Guide", + "pages": [ + "calls/flutter/migration-guide-v5" + ] + }, { "group": "Resources", "pages": [ diff --git a/notifications.mdx b/notifications.mdx index a04f9e9f9..c4d041b9b 100644 --- a/notifications.mdx +++ b/notifications.mdx @@ -139,7 +139,7 @@ canonical: "https://cometchat.com/docs"

- Show working experiences just like Chat & Calling: clones, payloads, and end-to-end journeys. + Show working experiences just like Chat & Messaging: clones, payloads, and end-to-end journeys.

diff --git a/sdk/flutter/overview.mdx b/sdk/flutter/overview.mdx index 7d60a459a..de98dc63e 100644 --- a/sdk/flutter/overview.mdx +++ b/sdk/flutter/overview.mdx @@ -2,7 +2,9 @@ title: "Overview" --- - + +🚀 **v5 Beta Available** — The Flutter Chat SDK v5 is now available in beta with significant improvements. [Check out the v5 Overview →](/sdk/flutter/v5/overview) + This guide demonstrates how to add chat to a Flutter application. Before you begin, we strongly recommend you read the [Key Concepts](/sdk/flutter/key-concepts) guide. diff --git a/sdk/flutter/setup.mdx b/sdk/flutter/setup.mdx index 77e8f1402..81ff39409 100644 --- a/sdk/flutter/setup.mdx +++ b/sdk/flutter/setup.mdx @@ -2,7 +2,9 @@ title: "Setup" --- - + +🚀 **v5 Beta Available** — The Flutter Chat SDK v5 is now available in beta with significant improvements. [Check out the v5 Overview →](/sdk/flutter/v5/overview) + ### Get your Application Keys