From 2ef59b065196a4aa60d18173ff423f402fb7ceec Mon Sep 17 00:00:00 2001 From: Duan Weiwei Date: Wed, 3 Aug 2022 14:16:08 +0000 Subject: [PATCH] chore: fix group call id mismatch. --- lib/src/voip/group_call.dart | 14 +++++++--- lib/src/voip/voip.dart | 51 ++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/lib/src/voip/group_call.dart b/lib/src/voip/group_call.dart index eb60c7e7..94c88925 100644 --- a/lib/src/voip/group_call.dart +++ b/lib/src/voip/group_call.dart @@ -491,6 +491,7 @@ class GroupCall { ); */ voip.groupCalls.remove(room.id); + voip.groupCalls.remove(groupCallId); if (emitStateEvent) { final existingStateEvent = await getStateEvent( @@ -711,7 +712,7 @@ class GroupCall { if (existingCallIndex != -1) { if (memberCallState != null) { - calls.replaceRange(existingCallIndex, 1, [memberCallState]); + calls[existingCallIndex] = memberCallState; } else { calls.removeAt(existingCallIndex); } @@ -752,8 +753,15 @@ class GroupCall { } // Currently we only support a single call per room. So grab the first call. - final callState = - callsState.calls.isNotEmpty ? callsState.calls.elementAt(0) : null; + IGroupCallRoomMemberCallState? callState; + + if (callsState.calls.isNotEmpty) { + final index = callsState.calls + .indexWhere((element) => element.call_id == groupCallId); + if (index != -1) { + callState = callsState.calls[index]; + } + } if (callState == null) { Logs().w( diff --git a/lib/src/voip/voip.dart b/lib/src/voip/voip.dart index 4d7ee3de..9050d178 100644 --- a/lib/src/voip/voip.dart +++ b/lib/src/voip/voip.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:core'; import 'package:sdp_transform/sdp_transform.dart' as sdp_transform; @@ -37,6 +38,7 @@ class VoIP { String? get localPartyId => client.deviceID; final Client client; final WebRTCDelegate delegate; + final StreamController onIncomingGroupCall = StreamController(); void _handleEvent( Event event, @@ -536,6 +538,10 @@ class VoIP { Future newGroupCall(String roomId, String type, String intent, [bool? dataChannelsEnabled, RTCDataChannelInit? dataChannelOptions]) async { + if (getGroupCallForRoom(roomId) != null) { + Logs().e('[VOIP] [$roomId] already has an existing group call.'); + return null; + } final room = client.getRoomById(roomId); if (room == null) { Logs().v('[VOIP] Invalid room id [$roomId].'); @@ -553,9 +559,53 @@ class VoIP { dataChannelOptions: dataChannelOptions ?? RTCDataChannelInit(), ).create(); groupCalls[groupId] = groupCall; + groupCalls[roomId] = groupCall; return groupCall; } + Future fetchOrCreateGroupCall(String roomId) async { + final groupCall = getGroupCallForRoom(roomId); + if (groupCall != null) return groupCall; + + final room = client.getRoomById(roomId); + + if (room == null) { + Logs().w('Not found room id = $roomId'); + return null; + } + + if (!room.groupCallsEnabled) { + await room.enableGroupCalls(); + } + + if (room.canCreateGroupCall) { + // The call doesn't exist, but we can create it + return await newGroupCall( + roomId, GroupCallType.Video, GroupCallIntent.Prompt); + } + + if (room.canJoinGroupCall) { + Logs().w('No permission to join group calls in room $roomId'); + return null; + } + + final completer = Completer(); + Timer? timer; + final subscription = onIncomingGroupCall.stream.listen((GroupCall call) { + if (call.room.id == roomId) { + timer?.cancel(); + completer.complete(call); + } + }); + + timer = Timer(Duration(seconds: 30), () { + subscription.cancel(); + completer.completeError('timeout'); + }); + + return completer.future; + } + GroupCall? getGroupCallForRoom(String roomId) { return groupCalls[roomId]; } @@ -653,6 +703,7 @@ class VoIP { groupCalls[groupCallId!] = groupCall; groupCalls[room.id] = groupCall; + onIncomingGroupCall.add(groupCall); delegate.handleNewGroupCall(groupCall); return groupCall; }