Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fix for accepting second call when already in a call #834

Merged
merged 3 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion dogfooding/lib/app/app_content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,20 @@ class _StreamDogFoodingAppContentState
@override
void initState() {
super.initState();
initPushNotificationManagerIfAvailable();

if (_userAuthController.currentUser != null) {
initPushNotificationManagerIfAvailable();
}

_userAuthController.addListener(() {
if (_userAuthController.currentUser != null) {
_compositeSubscription.clear();
initPushNotificationManagerIfAvailable();
} else {
_compositeSubscription.clear();
}
});

_tryConsumingIncomingCallFromTerminatedState();
}

Expand Down
6 changes: 3 additions & 3 deletions packages/stream_video/lib/src/call/call.dart
Original file line number Diff line number Diff line change
Expand Up @@ -501,15 +501,13 @@ class Call {
if (outgoingCall != null && outgoingCall.callCid != callCid) {
_logger.i(() => '[accept] canceling outgoing call: $outgoingCall');
await outgoingCall.reject(reason: CallRejectReason.cancel());

await _streamVideo.state.setOutgoingCall(null);
}

final activeCall = _streamVideo.state.activeCall.valueOrNull;
if (activeCall != null && activeCall.callCid != callCid) {
_logger.i(() => '[accept] canceling another active call: $activeCall');
await activeCall.reject(reason: CallRejectReason.cancel());

await activeCall.leave(reason: DisconnectReason.ended());
await _streamVideo.state.setActiveCall(null);
}

Expand Down Expand Up @@ -1006,6 +1004,8 @@ class Call {

Future<void> _onSfuEvent(SfuEvent sfuEvent) async {
if (sfuEvent is SfuParticipantLeftEvent) {
if (sfuEvent.callCid != callCid.value) return;

final callParticipants = [...state.value.callParticipants]..removeWhere(
(participant) =>
participant.userId == sfuEvent.participant.userId &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ class CoordinatorClientOpenApi extends CoordinatorClient {
return const Result.success(none);
}

_logger.d(() => '[waitUntilConnected] user.id: ${_user?.id}');
_logger.d(() =>
'[waitUntilConnected] user.id: ${_user?.id}, current state: ${_connectionState.value},');
return _connectionState
.firstWhere(
(it) => it.isConnected,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ abstract class PushNotificationManager {
/// [uuid] is the unique identifier for the call.
Future<void> endCall(String uuid);

/// Ends the call.
///
/// [cid] is the call id for the call.
Future<void> endCallByCid(String cid);

/// Ends all ongoing calls.
Future<void> endAllCalls();

Expand Down
4 changes: 3 additions & 1 deletion packages/stream_video/lib/src/stream_video.dart
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ class StreamVideo extends Disposable {

Future<void> _onActiveCall(Call? activeCall) async {
if (activeCall == null) {
await pushNotificationManager?.endAllCalls();
await pushNotificationManager?.endCallByCid(activeCall!.callCid.value);
}
}

Expand Down Expand Up @@ -676,6 +676,8 @@ class StreamVideo extends Disposable {
}

Future<void> _onCallEnded(ActionCallEnded event) async {
_logger.d(() => '[onCallEnded] event: $event');

final uuid = event.data.uuid;
final cid = event.data.callCid;
if (uuid == null || cid == null) return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ import 'stream_video_push_params.dart';
part 'stream_video_push_provider.dart';

const _idToken = 1;
const _idCallKitIncoming = 2;
const _idCallKit = 2;
const _idCallEnded = 3;
const _idCallAccepted = 4;
const _idCallKitAcceptDecline = 5;
const _idCallRejected = 6;
const _idCallParticipantCount = 7;

Expand Down Expand Up @@ -127,16 +126,16 @@ class StreamVideoPushNotificationManager implements PushNotificationManager {
'[subscribeToEvents] Call accepted event: ${event.callCid}, accepted by: ${event.acceptedByUserId}');
if (event.acceptedByUserId != streamVideo.currentUser.id) return;

// end CallKit call on other devices if the call was accepted on one of them
// End the CallKit call on this device if the call was accepted on another device
if (streamVideo.activeCall?.state.value.status
is! CallStatusActive) {
_logger.v(() =>
'[subscribeToEvents] Call accepted on other device, ending call: ${event.callCid}');
await endCallByCid(event.callCid.toString());
}

// if the call was accepted on the same device, end the CallKit call silently
// (in case it was accepted from the app and not from the CallKit UI)
// If the call was accepted on this device, end the CallKit call silently
// (useful if the call was accepted via the app instead of the CallKit UI)
else {
_logger.v(() =>
'[subscribeToEvents] Call accepted on the same device, ending CallKit silently: ${event.callCid}');
Expand All @@ -158,29 +157,24 @@ class StreamVideoPushNotificationManager implements PushNotificationManager {
});

_subscriptions.add(
_idCallKitIncoming,
onCallEvent.whereType<ActionCallIncoming>().listen(
(_) {
if (!client.isConnected) {
client.openConnection();
}

subscribeToEvents();
},
),
);

_subscriptions.add(
_idCallKitAcceptDecline,
onCallEvent.whereType<ActionCallAccept>().map((_) => null).mergeWith([
onCallEvent.whereType<ActionCallDecline>().map((_) => null),
onCallEvent.whereType<ActionCallTimeout>().map((_) => null),
]).listen(
_idCallKit,
onCallEvent.listen(
(event) {
_subscriptions.cancel(_idCallAccepted);
_subscriptions.cancel(_idCallEnded);
_subscriptions.cancel(_idCallRejected);
_subscriptions.cancel(_idCallParticipantCount);
if (event is ActionCallIncoming) {
if (!client.isConnected) {
client.openConnection();
}

subscribeToEvents();
} else if (event is ActionCallAccept ||
event is ActionCallDecline ||
event is ActionCallTimeout ||
event is ActionCallEnded) {
Brazol marked this conversation as resolved.
Show resolved Hide resolved
_subscriptions.cancel(_idCallAccepted);
_subscriptions.cancel(_idCallEnded);
_subscriptions.cancel(_idCallRejected);
_subscriptions.cancel(_idCallParticipantCount);
}
},
),
);
Expand Down Expand Up @@ -375,6 +369,7 @@ class StreamVideoPushNotificationManager implements PushNotificationManager {
@override
Future<void> endCall(String uuid) => FlutterCallkitIncoming.endCall(uuid);

@override
Future<void> endCallByCid(String cid) async {
final activeCalls = await this.activeCalls();
final calls =
Expand Down
Loading