Skip to content

Commit 6d543d0

Browse files
authored
FVS-84: fix duplicate participant, dateTime parsing, reset StreamVideo on uregister (#491)
1 parent 9fec1b8 commit 6d543d0

File tree

5 files changed

+45
-10
lines changed

5 files changed

+45
-10
lines changed

dogfooding/lib/di/injector.dart

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
// 📦 Package imports:
22
import 'package:flutter/foundation.dart';
3+
// 🌎 Project imports:
4+
import 'package:flutter_dogfooding/core/repos/app_preferences.dart';
5+
import 'package:flutter_dogfooding/core/repos/user_chat_repository.dart';
36
import 'package:get_it/get_it.dart';
47
import 'package:google_sign_in/google_sign_in.dart';
58
import 'package:share_plus/share_plus.dart';
69
import 'package:shared_preferences/shared_preferences.dart';
710
import 'package:stream_chat_flutter/stream_chat_flutter.dart' hide User;
811
import 'package:stream_video_flutter/stream_video_flutter.dart';
9-
10-
// 🌎 Project imports:
11-
import 'package:flutter_dogfooding/core/repos/app_preferences.dart';
12-
import 'package:flutter_dogfooding/core/repos/user_chat_repository.dart';
1312
import 'package:stream_video_push_notification/stream_video_push_notification.dart';
13+
1414
import '../app/user_auth_controller.dart';
1515
import '../core/repos/token_service.dart';
1616
import '../core/repos/user_auth_repository.dart';
@@ -69,6 +69,7 @@ class AppInjector {
6969
static StreamVideo registerStreamVideo(User user) {
7070
_setupLogger();
7171
return locator.registerSingleton(
72+
dispose: (_) => StreamVideo.reset(),
7273
_initStreamVideo(
7374
user,
7475
tokenLoader: switch (user.type) {

packages/stream_video/lib/open_api/video/coordinator/api_helper.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,17 @@ DateTime? mapDateTime(dynamic map, String key, [String? pattern]) {
102102
}
103103
return null;
104104
}
105+
106+
extension on Map<String, String> {
107+
Map<String, DateTime> convertValueToDateTime() {
108+
final Map<String, DateTime> output = {};
109+
for (var key in keys) {
110+
final value = this[key];
111+
if (value == null) continue;
112+
final dateTime = DateTime.tryParse(value);
113+
if (dateTime == null) continue;
114+
output[key] = dateTime;
115+
}
116+
return output;
117+
}
118+
}

packages/stream_video/lib/open_api/video/coordinator/model/call_session_response.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,16 +141,17 @@ class CallSessionResponse {
141141
});
142142
return true;
143143
}());
144-
145144
return CallSessionResponse(
146-
acceptedBy: mapCastOfType<String, DateTime>(json, r'accepted_by')!,
145+
acceptedBy: mapCastOfType<String, String>(json, r'accepted_by')!
146+
.convertValueToDateTime(),
147147
endedAt: mapDateTime(json, r'ended_at', ''),
148148
id: mapValueOfType<String>(json, r'id')!,
149149
liveEndedAt: mapDateTime(json, r'live_ended_at', ''),
150150
liveStartedAt: mapDateTime(json, r'live_started_at', ''),
151151
participants: CallParticipantResponse.listFromJson(json[r'participants']),
152152
participantsCountByRole: mapCastOfType<String, int>(json, r'participants_count_by_role')!,
153-
rejectedBy: mapCastOfType<String, DateTime>(json, r'rejected_by')!,
153+
rejectedBy: mapCastOfType<String, String>(json, r'rejected_by')!
154+
.convertValueToDateTime(),
154155
startedAt: mapDateTime(json, r'started_at', ''),
155156
);
156157
}

packages/stream_video/lib/src/call/state/call_state_notifier.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:state_notifier/state_notifier.dart';
22

33
import '../../call_state.dart';
4+
import '../../logger/impl/tagged_logger.dart';
45
import '../../models/call_preferences.dart';
56
import '../../state_emitter.dart';
67
import 'mixins/state_call_actions_mixin.dart';
@@ -24,6 +25,8 @@ class CallStateNotifier extends StateNotifier<CallState>
2425
MutableStateEmitterImpl<CallState>(initialState, sync: true);
2526
}
2627

28+
final _logger = taggedLogger(tag: 'CallStateNotifier');
29+
2730
@override
2831
final CallPreferences callPreferences;
2932

@@ -32,6 +35,11 @@ class CallStateNotifier extends StateNotifier<CallState>
3235

3336
@override
3437
set state(CallState value) {
38+
_logger.v(() => '[setState] ${value.status} <= ${super.state.status}');
39+
_logger.v(() => '[setState] ${value.callParticipants.map((it) {
40+
return (it.sessionId, it.userId);
41+
})}',);
42+
3543
super.state = value;
3644
callStateStream.value = value;
3745
}

packages/stream_video/lib/src/call/state/mixins/state_sfu_mixin.dart

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ mixin StateSfuMixin on StateNotifier<CallState> {
4848
final participants = event.callState.participants.map((aParticipant) {
4949
final isLocal = aParticipant.userId == state.currentUserId;
5050
final existing = state.callParticipants.firstWhereOrNull(
51-
(it) => it.userId == aParticipant.userId,
51+
(it) => it.userId == aParticipant.userId
52+
&& it.sessionId == aParticipant.sessionId,
5253
);
5354
final existingName = existing?.name ?? '';
5455
final existingRole = existing?.role ?? '';
@@ -212,10 +213,20 @@ mixin StateSfuMixin on StateNotifier<CallState> {
212213
isLocal: isLocal,
213214
isOnline: !isLocal,
214215
);
216+
var isExisting = false;
217+
final participants = state.callParticipants.map((it) {
218+
if (it.userId == participant.userId &&
219+
it.sessionId == participant.sessionId) {
220+
isExisting = true;
221+
return participant;
222+
} else {
223+
return it;
224+
}
225+
});
215226
state = state.copyWith(
216227
callParticipants: [
217-
...state.callParticipants,
218-
participant,
228+
...participants,
229+
if (!isExisting) participant,
219230
],
220231
);
221232
}

0 commit comments

Comments
 (0)