join method

Future<void> join(
  1. ChatId chatId, {
  2. bool withAudio = true,
  3. bool withVideo = false,
  4. bool withScreen = false,
})

Joins an OngoingCall identified by the given chatId.

Implementation

Future<void> join(
  ChatId chatId, {
  bool withAudio = true,
  bool withVideo = false,
  bool withScreen = false,
}) async {
  Log.debug(
    'join($chatId, $withAudio, $withVideo, $withScreen)',
    '$runtimeType',
  );

  if (WebUtils.containsCall(chatId) && !WebUtils.isPopup) {
    throw CallIsInPopupException();
  }

  try {
    final FutureOr<RxChat?> chatOrFuture = _chatService.get(chatId);
    final RxChat? chat =
        chatOrFuture is RxChat? ? chatOrFuture : await chatOrFuture;

    final ChatCall? chatCall = chat?.chat.value.ongoingCall;

    Rx<OngoingCall>? call;

    try {
      call = await _callsRepo.join(
        chatId,
        chatCall,
        withAudio: withAudio,
        withVideo: withVideo,
        withScreen: withScreen,
      );
    } on CallAlreadyJoinedException catch (e) {
      await _callsRepo.leave(chatId, e.deviceId);
      call = await _callsRepo.join(
        chatId,
        chatCall,
        withAudio: withAudio,
        withVideo: withVideo,
        withScreen: withScreen,
      );
    }

    if (isClosed) {
      call?.value.dispose();
    } else {
      call?.value.connect(this);
    }
  } on CallAlreadyJoinedException catch (e) {
    _callsRepo.leave(chatId, e.deviceId);
    _callsRepo.remove(chatId);

    // TODO: Try joining the [OngoingCall] again, instead of throwing the
    //       exception here.
    rethrow;
  } catch (e) {
    // If any other error occurs, it's guaranteed that the broken call will be
    // removed.
    _callsRepo.remove(chatId);
    rethrow;
  }
}