Skip to main content

cometchat_calls_sdk 5.1.0 copy "cometchat_calls_sdk: ^5.1.0" to clipboard
cometchat_calls_sdk: ^5.1.0 copied to clipboard

Integrate voice & video calling into your Flutter app with CometChat's Calls SDK. Create real-time communication for better user engagement.

example/lib/main.dart

// A minimal CometChat Calls app: initialise the SDK, log a user in and join a
// call session. Open the same session ID on a second device (or in the web
// sample) as another user to talk to each other.
//
// Credentials come from your CometChat dashboard. Pass them at build time,
//   flutter run --dart-define=APP_ID=... --dart-define=REGION=us --dart-define=AUTH_KEY=...
// or type them into the first screen. The Auth Key is for development only;
// production apps log in with an auth token minted by their server.

import 'dart:async';

import 'package:cometchat_calls_sdk/cometchat_calls_sdk.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';

void main() => runApp(const CallsExampleApp());

class CallsExampleApp extends StatelessWidget {
  const CallsExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'CometChat Calls',
      theme: ThemeData(colorSchemeSeed: const Color(0xFF6852D6)),
      home: const JoinScreen(),
    );
  }
}

class JoinScreen extends StatefulWidget {
  const JoinScreen({super.key});

  @override
  State<JoinScreen> createState() => _JoinScreenState();
}

class _JoinScreenState extends State<JoinScreen> {
  final _appId = TextEditingController(
    text: const String.fromEnvironment('APP_ID'),
  );
  final _region = TextEditingController(
    text: const String.fromEnvironment('REGION', defaultValue: 'us'),
  );
  final _authKey = TextEditingController(
    text: const String.fromEnvironment('AUTH_KEY'),
  );
  final _uid = TextEditingController(text: 'cometchat-uid-1');
  final _sessionId = TextEditingController(text: 'example-session');
  bool _video = true;
  bool _busy = false;
  String? _error;

  Future<void> _join() async {
    setState(() {
      _busy = true;
      _error = null;
    });
    try {
      if (defaultTargetPlatform == TargetPlatform.android) {
        // iOS asks for the camera and microphone itself on first use.
        await [Permission.microphone, if (_video) Permission.camera].request();
      }
      await _initAndLogin();
      final settings =
          (SessionSettingsBuilder()
                ..setTitle(_sessionId.text.trim())
                ..setType(_video ? SessionType.video : SessionType.audio))
              .build();
      await CometChatCalls.joinSession(
        sessionId: _sessionId.text.trim(),
        sessionSettings: settings,
        onSuccess: (callView) {
          if (!mounted) return;
          if (callView == null) {
            _fail('Joined, but the SDK returned no call view');
            return;
          }
          Navigator.of(context).push(
            MaterialPageRoute(builder: (_) => CallScreen(callView: callView)),
          );
          setState(() => _busy = false);
        },
        onError: (e) => _fail(e.message),
      );
    } catch (e) {
      _fail('$e');
    }
  }

  /// Initialises the SDK and logs the user in, unless that user already is.
  Future<void> _initAndLogin() async {
    final appSettings =
        (CallAppSettingBuilder()
              ..appId = _appId.text.trim()
              ..region = _region.text.trim().toLowerCase())
            .build();
    await _await<String>(
      (ok, err) =>
          CometChatCalls.init(appSettings, onSuccess: ok, onError: err),
    );

    final uid = _uid.text.trim();
    final current = await CometChatCalls.getLoggedInUser();
    if (current?.uid == uid) return;
    if (current != null) {
      await _await<String>(
        (ok, err) => CometChatCalls.logout(onSuccess: ok, onError: err),
      );
    }
    await _await<User?>(
      (ok, err) => CometChatCalls.login(
        uid: uid,
        authKey: _authKey.text.trim(),
        onSuccess: ok,
        onError: err,
      ),
    );
  }

  /// Turns a callback-style SDK call into a Future.
  Future<T> _await<T>(
    void Function(
      void Function(T) ok,
      void Function(CometChatCallsException) err,
    )
    call,
  ) {
    final done = Completer<T>();
    call(done.complete, (e) => done.completeError(e.message ?? e.code));
    return done.future;
  }

  void _fail(String? message) {
    if (!mounted) return;
    setState(() {
      _busy = false;
      _error = message ?? 'Unknown error';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('CometChat Calls')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          TextField(
            controller: _appId,
            decoration: const InputDecoration(labelText: 'App ID'),
          ),
          TextField(
            controller: _region,
            decoration: const InputDecoration(
              labelText: 'Region (us, eu or in)',
            ),
          ),
          TextField(
            controller: _authKey,
            decoration: const InputDecoration(labelText: 'Auth Key'),
            obscureText: true,
          ),
          TextField(
            controller: _uid,
            decoration: const InputDecoration(labelText: 'User ID'),
          ),
          TextField(
            controller: _sessionId,
            decoration: const InputDecoration(labelText: 'Session ID'),
          ),
          SwitchListTile(
            contentPadding: EdgeInsets.zero,
            title: const Text('Video'),
            value: _video,
            onChanged: (value) => setState(() => _video = value),
          ),
          const SizedBox(height: 8),
          FilledButton(
            onPressed: _busy ? null : _join,
            child: Text(_busy ? 'Joining…' : 'Join session'),
          ),
          if (_error != null) ...[
            const SizedBox(height: 12),
            Text(
              _error!,
              style: TextStyle(color: Theme.of(context).colorScheme.error),
            ),
          ],
        ],
      ),
    );
  }

  @override
  void dispose() {
    for (final controller in [_appId, _region, _authKey, _uid, _sessionId]) {
      controller.dispose();
    }
    super.dispose();
  }
}

/// Shows the call. The view holds the running call, so it stays mounted until
/// the user leaves with the end-call button.
class CallScreen extends StatefulWidget {
  const CallScreen({super.key, required this.callView});

  final Widget callView;

  @override
  State<CallScreen> createState() => _CallScreenState();
}

class _CallScreenState extends State<CallScreen> {
  late final _listener = _SessionLeftListener(() {
    if (mounted) Navigator.of(context).pop();
  });

  @override
  void initState() {
    super.initState();
    CallSession.getInstance()?.addSessionStatusListener(_listener);
  }

  @override
  void dispose() {
    CallSession.getInstance()?.removeSessionStatusListener(_listener);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return PopScope(
      canPop: false,
      child: Scaffold(
        backgroundColor: Colors.black,
        body: SafeArea(child: SizedBox.expand(child: widget.callView)),
      ),
    );
  }
}

class _SessionLeftListener extends SessionStatusListeners {
  _SessionLeftListener(this.onLeft);

  final VoidCallback onLeft;

  @override
  void onSessionLeft() => onLeft();
}
4
likes
140
points
1.48k
downloads

Documentation

API reference

Publisher

verified publishercometchat.com

Weekly Downloads

Integrate voice & video calling into your Flutter app with CometChat's Calls SDK. Create real-time communication for better user engagement.

Homepage

License

MIT (license)

Dependencies

connectivity_plus, crypto, flutter, http, path, plugin_platform_interface, shared_preferences, sqflite, web

More

Packages that depend on cometchat_calls_sdk

Packages that implement cometchat_calls_sdk