call method
Starts an OngoingCall in a Chat with the given chatId
.
Implementation
Future<void> call(
ChatId chatId, {
bool withAudio = true,
bool withVideo = false,
bool withScreen = false,
}) async {
Log.debug(
'call($chatId, $withAudio, $withVideo, $withScreen)',
'$runtimeType',
);
final Rx<OngoingCall>? stored = _callRepository[chatId];
final WebStoredCall? webStored = WebUtils.getCall(chatId);
final ChatCallDeviceId? webDevice = webStored?.deviceId;
if (webDevice != null) {
// Call seems to already exist in the Web, thus try to leave and remove
// the existing one.
WebUtils.removeCall(chatId);
await _callRepository.leave(chatId, webDevice);
} else if (stored != null &&
stored.value.state.value != OngoingCallState.ended) {
// No-op, as already exists.
return;
}
try {
final Rx<OngoingCall> call = await _callRepository.start(
chatId,
withAudio: withAudio,
withVideo: withVideo,
withScreen: withScreen,
);
if (isClosed) {
call.value.dispose();
} else {
call.value.connect(this);
}
} on StartChatCallException catch (e) {
switch (e.code) {
case StartChatCallErrorCode.blocked:
rethrow;
case StartChatCallErrorCode.unknownChat:
case StartChatCallErrorCode.unknownUser:
onChatRemoved?.call(chatId);
return;
case StartChatCallErrorCode.artemisUnknown:
_callRepository.remove(chatId);
rethrow;
}
} on CallAlreadyJoinedException catch (e) {
await _callRepository.leave(chatId, e.deviceId);
return await join(
chatId,
withAudio: withAudio,
withVideo: withVideo,
withScreen: withScreen,
);
} catch (e) {
// If any other error occurs, it's guaranteed that the broken call will be
// removed.
_callRepository.remove(chatId);
rethrow;
}
}