Components and utilities for voice/video calling.
Package Structure
Calls are in a separate package: cometchat_calls_uikit.
dependencies:
cometchat_calls_uikit: ^5.0.15
Import everything from:
import 'package:cometchat_calls_uikit/cometchat_calls_uikit.dart';
This re-exports cometchat_uikit_shared, cometchat_sdk, and cometchat_calls_sdk.
Rule: CALLS_INIT_ORDER
Chat SDK must be initialized BEFORE Calls SDK. The calling extension handles this automatically when configured via UIKitSettingsBuilder.callingExtension.
// ✅ CORRECT — enable calling via UIKitSettings
final settings = (UIKitSettingsBuilder()
..appId = 'APP_ID'
..region = 'us'
..authKey = 'AUTH_KEY'
..subscriptionType = CometChatSubscriptionType.allUsers
..callingExtension = CometChatCallingExtension())
.build();
CometChatUIKit.init(uiKitSettings: settings);
CometChatCallingExtension extends ExtensionsDataSource and uses ChatConfigurator.enable() to register the calling decorator.
Rule: CALL_NAVIGATION_CONTEXT
CallNavigationContext.navigatorKey must be set on MaterialApp for call overlays to navigate:
MaterialApp(
navigatorKey: CallNavigationContext.navigatorKey,
)
CometChatCallButtons
Voice and video call buttons for a user or group.
CometChatCallButtons(user: user)
CometChatCallButtons(group: group, hideVoiceCallButton: true)
Key props: user, group, callButtonsStyle, hideVoiceCallButton, hideVideoCallButton, outgoingCallConfiguration, callSettingsBuilder, onError.
CometChatCallLogs
Call history list.
CometChatCallLogs(
onItemClick: (callLog) {
// CometChatCallLogDetails is NOT a UIKit export — copy the
// sample-app pattern from `sample_app/lib/call_log_details/` into
// your own project and route to it here.
Navigator.push(context, MaterialPageRoute(
builder: (_) => YourCallLogDetailsScreen(callLog: callLog),
));
},
)
Key props: callLogsRequestBuilder, callLogsStyle, onItemClick, listItemView, subTitleView, trailingView, onError.
CometChatIncomingCall / CometChatOutgoingCall / CometChatOngoingCall
These are typically managed automatically by CometChatCallingExtension. Manual usage is rare.
CometChatIncomingCall(call: call, onAccept: (BuildContext, Call)? ..., onDecline: (BuildContext, Call)? ...)— callbacks take(BuildContext, Call), NOT(Call)alone.CometChatOutgoingCall(call: returnedCall, user: user OR group: group, onCancelled: (BuildContext, Call)? ...)— takes the activeCallobject plus theUserorGroupit's directed at. Thecall:param holds the result ofCometChatUIKitCalls.initiateCall(...). Callbacks are(BuildContext, Call)?, NOT(Call)?alone.CometChatOngoingCall(callSettingsBuilder: ..., sessionId: ...)
Call Flow — Outgoing
- User taps call button →
CometChatUIKitCalls.initiateCall(call) CometChatOutgoingCallscreen pushed- Recipient accepts →
CometChatOngoingCallreplaces outgoing - Call ends → screens pop back
Call Flow — Incoming
CometChatCallingExtensionlistens via SDK listenerCometChatIncomingCalloverlay displayed viaCallNavigationContext.navigatorKey- Accept →
CometChatUIKitCalls.acceptCall(sessionId)→CometChatOngoingCall - Decline →
CometChatUIKitCalls.rejectCall(sessionId, status)
Incoming Call Handling (Global)
Handle incoming calls at the app level (dashboard/home), not per-screen:
class _DashboardState extends State<Dashboard>
with CallListener, CometChatCallEventListener {
@override
void initState() {
super.initState();
_listenerId = 'calls_${DateTime.now().millisecondsSinceEpoch}';
CometChat.addCallListener(_listenerId, this);
CometChatCallEvents.addCallEventsListener(_listenerId, this);
}
@override
void dispose() {
CometChat.removeCallListener(_listenerId);
CometChatCallEvents.removeCallEventsListener(_listenerId);
super.dispose();
}
@override
void onIncomingCallReceived(Call call) {
// Handle incoming call globally
}
}
Permissions
Request camera and microphone permissions before calls:
await [Permission.camera, Permission.microphone].request();
Golden Path — Enable Calling
// 1. Configure calling extension
final settings = (UIKitSettingsBuilder()
..appId = 'APP_ID'
..region = 'us'
..authKey = 'AUTH_KEY'
..subscriptionType = CometChatSubscriptionType.allUsers
..callingExtension = CometChatCallingExtension())
.build();
// 2. Init
CometChatUIKit.init(uiKitSettings: settings);
// 3. Set navigator key
MaterialApp(navigatorKey: CallNavigationContext.navigatorKey)
// 4. Call buttons appear automatically in CometChatMessageHeader
Anti-Patterns
// ❌ WRONG — forgetting navigatorKey
MaterialApp(/* missing navigatorKey */)
// ❌ WRONG — not enabling calling extension
UIKitSettingsBuilder()..appId = 'APP_ID'..region = 'us'
// Missing: ..callingExtension = CometChatCallingExtension()
// ❌ WRONG — handling incoming calls per-screen instead of globally
Checklist — Calls
-
CometChatCallingExtension()set onUIKitSettingsBuilder.callingExtension -
CallNavigationContext.navigatorKeyset onMaterialApp.navigatorKey - Incoming call handling is global (dashboard level)
- Camera/microphone permissions requested
- Import from
package:cometchat_calls_uikit/cometchat_calls_uikit.dart