refactor: merge onGroupCallState and onGroupCallEvent into matrixRTCEventStream with proper types

This commit is contained in:
Karthikeyan S 2025-10-13 07:43:54 +05:30
parent 9c574b5958
commit 9df13a02ea
No known key found for this signature in database
GPG Key ID: 28BA6AEE539ECE2E
5 changed files with 154 additions and 9 deletions

View File

@ -2753,6 +2753,14 @@ class FakeMatrixApi extends BaseClient {
(var reqI) => { (var reqI) => {
'event_id': '42', 'event_id': '42',
}, },
'/client/v3/rooms/!calls%3Aexample.com/state/com.famedly.call.member/%40test%3AfakeServer.notExisting':
(var reqI) => {
'event_id': 'call_member_42',
},
'/client/v3/rooms/!calls%3Aexample.com/state/com.famedly.call.member/%40remoteuser%3Aexample.com':
(var reqI) => {
'event_id': 'call_member_remote_42',
},
'/client/v3/directory/list/room/!localpart%3Aexample.com': (var req) => '/client/v3/directory/list/room/!localpart%3Aexample.com': (var req) =>
{}, {},
'/client/v3/room_keys/version/5': (var req) => {}, '/client/v3/room_keys/version/5': (var req) => {},

View File

@ -133,7 +133,9 @@ class MeshBackend extends CallBackend {
Future<void> _addCall(GroupCallSession groupCall, CallSession call) async { Future<void> _addCall(GroupCallSession groupCall, CallSession call) async {
_callSessions.add(call); _callSessions.add(call);
_initCall(groupCall, call); _initCall(groupCall, call);
// ignore: deprecated_member_use_from_same_package
groupCall.onGroupCallEvent.add(GroupCallStateChange.callsChanged); groupCall.onGroupCallEvent.add(GroupCallStateChange.callsChanged);
groupCall.matrixRTCEventStream.add(CallAddedEvent(call));
} }
/// init a peer call from group calls. /// init a peer call from group calls.
@ -183,7 +185,10 @@ class MeshBackend extends CallBackend {
_registerListenersBeforeCallAdd(replacementCall); _registerListenersBeforeCallAdd(replacementCall);
_initCall(groupCall, replacementCall); _initCall(groupCall, replacementCall);
// ignore: deprecated_member_use_from_same_package
groupCall.onGroupCallEvent.add(GroupCallStateChange.callsChanged); groupCall.onGroupCallEvent.add(GroupCallStateChange.callsChanged);
groupCall.matrixRTCEventStream
.add(CallReplacedEvent(existingCall, replacementCall));
} }
/// Removes a peer call from group calls. /// Removes a peer call from group calls.
@ -196,7 +201,9 @@ class MeshBackend extends CallBackend {
_callSessions.removeWhere((element) => call.callId == element.callId); _callSessions.removeWhere((element) => call.callId == element.callId);
// ignore: deprecated_member_use_from_same_package
groupCall.onGroupCallEvent.add(GroupCallStateChange.callsChanged); groupCall.onGroupCallEvent.add(GroupCallStateChange.callsChanged);
groupCall.matrixRTCEventStream.add(CallRemovedEvent(call));
} }
Future<void> _disposeCall( Future<void> _disposeCall(
@ -375,7 +382,10 @@ class MeshBackend extends CallBackend {
if (nextActiveSpeaker != null && _activeSpeaker != nextActiveSpeaker) { if (nextActiveSpeaker != null && _activeSpeaker != nextActiveSpeaker) {
_activeSpeaker = nextActiveSpeaker; _activeSpeaker = nextActiveSpeaker;
// ignore: deprecated_member_use_from_same_package
groupCall.onGroupCallEvent.add(GroupCallStateChange.activeSpeakerChanged); groupCall.onGroupCallEvent.add(GroupCallStateChange.activeSpeakerChanged);
groupCall.matrixRTCEventStream
.add(GroupCallActiveSpeakerChanged(_activeSpeaker!));
} }
_activeSpeakerLoopTimeout?.cancel(); _activeSpeakerLoopTimeout?.cancel();
_activeSpeakerLoopTimeout = Timer( _activeSpeakerLoopTimeout = Timer(
@ -401,8 +411,12 @@ class MeshBackend extends CallBackend {
) { ) {
_screenshareStreams.add(stream); _screenshareStreams.add(stream);
onStreamAdd.add(stream); onStreamAdd.add(stream);
// ignore: deprecated_member_use_from_same_package
groupCall.onGroupCallEvent groupCall.onGroupCallEvent
// ignore: deprecated_member_use_from_same_package
.add(GroupCallStateChange.screenshareStreamsChanged); .add(GroupCallStateChange.screenshareStreamsChanged);
groupCall.matrixRTCEventStream
.add(GroupCallStreamAdded(GroupCallStreamType.screenshare));
} }
Future<void> _replaceScreenshareStream( Future<void> _replaceScreenshareStream(
@ -423,8 +437,12 @@ class MeshBackend extends CallBackend {
_screenshareStreams.replaceRange(streamIndex, 1, [replacementStream]); _screenshareStreams.replaceRange(streamIndex, 1, [replacementStream]);
await existingStream.dispose(); await existingStream.dispose();
// ignore: deprecated_member_use_from_same_package
groupCall.onGroupCallEvent groupCall.onGroupCallEvent
// ignore: deprecated_member_use_from_same_package
.add(GroupCallStateChange.screenshareStreamsChanged); .add(GroupCallStateChange.screenshareStreamsChanged);
groupCall.matrixRTCEventStream
.add(GroupCallStreamReplaced(GroupCallStreamType.screenshare));
} }
Future<void> _removeScreenshareStream( Future<void> _removeScreenshareStream(
@ -450,8 +468,12 @@ class MeshBackend extends CallBackend {
await stopMediaStream(stream.stream); await stopMediaStream(stream.stream);
} }
// ignore: deprecated_member_use_from_same_package
groupCall.onGroupCallEvent groupCall.onGroupCallEvent
// ignore: deprecated_member_use_from_same_package
.add(GroupCallStateChange.screenshareStreamsChanged); .add(GroupCallStateChange.screenshareStreamsChanged);
groupCall.matrixRTCEventStream
.add(GroupCallStreamRemoved(GroupCallStreamType.screenshare));
} }
Future<void> _onCallStateChanged(CallSession call, CallState state) async { Future<void> _onCallStateChanged(CallSession call, CallState state) async {
@ -486,8 +508,12 @@ class MeshBackend extends CallBackend {
) async { ) async {
_userMediaStreams.add(stream); _userMediaStreams.add(stream);
onStreamAdd.add(stream); onStreamAdd.add(stream);
// ignore: deprecated_member_use_from_same_package
groupCall.onGroupCallEvent groupCall.onGroupCallEvent
// ignore: deprecated_member_use_from_same_package
.add(GroupCallStateChange.userMediaStreamsChanged); .add(GroupCallStateChange.userMediaStreamsChanged);
groupCall.matrixRTCEventStream
.add(GroupCallStreamAdded(GroupCallStreamType.userMedia));
} }
Future<void> _replaceUserMediaStream( Future<void> _replaceUserMediaStream(
@ -508,8 +534,12 @@ class MeshBackend extends CallBackend {
_userMediaStreams.replaceRange(streamIndex, 1, [replacementStream]); _userMediaStreams.replaceRange(streamIndex, 1, [replacementStream]);
await existingStream.dispose(); await existingStream.dispose();
// ignore: deprecated_member_use_from_same_package
groupCall.onGroupCallEvent groupCall.onGroupCallEvent
// ignore: deprecated_member_use_from_same_package
.add(GroupCallStateChange.userMediaStreamsChanged); .add(GroupCallStateChange.userMediaStreamsChanged);
groupCall.matrixRTCEventStream
.add(GroupCallStreamReplaced(GroupCallStreamType.userMedia));
} }
Future<void> _removeUserMediaStream( Future<void> _removeUserMediaStream(
@ -536,12 +566,19 @@ class MeshBackend extends CallBackend {
await stopMediaStream(stream.stream); await stopMediaStream(stream.stream);
} }
// ignore: deprecated_member_use_from_same_package
groupCall.onGroupCallEvent groupCall.onGroupCallEvent
// ignore: deprecated_member_use_from_same_package
.add(GroupCallStateChange.userMediaStreamsChanged); .add(GroupCallStateChange.userMediaStreamsChanged);
groupCall.matrixRTCEventStream
.add(GroupCallStreamRemoved(GroupCallStreamType.userMedia));
if (_activeSpeaker == stream.participant && _userMediaStreams.isNotEmpty) { if (_activeSpeaker == stream.participant && _userMediaStreams.isNotEmpty) {
_activeSpeaker = _userMediaStreams[0].participant; _activeSpeaker = _userMediaStreams[0].participant;
// ignore: deprecated_member_use_from_same_package
groupCall.onGroupCallEvent.add(GroupCallStateChange.activeSpeakerChanged); groupCall.onGroupCallEvent.add(GroupCallStateChange.activeSpeakerChanged);
groupCall.matrixRTCEventStream
.add(GroupCallActiveSpeakerChanged(_activeSpeaker!));
} }
} }
@ -663,7 +700,9 @@ class MeshBackend extends CallBackend {
} }
} }
// ignore: deprecated_member_use_from_same_package
groupCall.onGroupCallEvent.add(GroupCallStateChange.localMuteStateChanged); groupCall.onGroupCallEvent.add(GroupCallStateChange.localMuteStateChanged);
groupCall.matrixRTCEventStream.add(GroupCallLocalMutedChanged(muted, kind));
return; return;
} }
@ -799,8 +838,12 @@ class MeshBackend extends CallBackend {
_addScreenshareStream(groupCall, localScreenshareStream!); _addScreenshareStream(groupCall, localScreenshareStream!);
// ignore: deprecated_member_use_from_same_package
groupCall.onGroupCallEvent groupCall.onGroupCallEvent
// ignore: deprecated_member_use_from_same_package
.add(GroupCallStateChange.localScreenshareStateChanged); .add(GroupCallStateChange.localScreenshareStateChanged);
groupCall.matrixRTCEventStream
.add(GroupCallLocalScreenshareStateChanged(true));
for (final call in _callSessions) { for (final call in _callSessions) {
await call.addLocalStream( await call.addLocalStream(
await localScreenshareStream!.stream!.clone(), await localScreenshareStream!.stream!.clone(),
@ -813,7 +856,10 @@ class MeshBackend extends CallBackend {
return; return;
} catch (e, s) { } catch (e, s) {
Logs().e('[VOIP] Enabling screensharing error', e, s); Logs().e('[VOIP] Enabling screensharing error', e, s);
// ignore: deprecated_member_use_from_same_package
groupCall.onGroupCallEvent.add(GroupCallStateChange.error); groupCall.onGroupCallEvent.add(GroupCallStateChange.error);
groupCall.matrixRTCEventStream
.add(GroupCallStateError(e.toString(), s));
return; return;
} }
} else { } else {
@ -826,8 +872,12 @@ class MeshBackend extends CallBackend {
await groupCall.sendMemberStateEvent(); await groupCall.sendMemberStateEvent();
// ignore: deprecated_member_use_from_same_package
groupCall.onGroupCallEvent groupCall.onGroupCallEvent
// ignore: deprecated_member_use_from_same_package
.add(GroupCallStateChange.localMuteStateChanged); .add(GroupCallStateChange.localMuteStateChanged);
groupCall.matrixRTCEventStream
.add(GroupCallLocalScreenshareStateChanged(false));
return; return;
} }
} }

View File

@ -54,9 +54,11 @@ class GroupCallSession {
String groupCallId; String groupCallId;
@Deprecated('Use matrixRTCEventStream instead')
final CachedStreamController<GroupCallState> onGroupCallState = final CachedStreamController<GroupCallState> onGroupCallState =
CachedStreamController(); CachedStreamController();
@Deprecated('Use matrixRTCEventStream instead')
final CachedStreamController<GroupCallStateChange> onGroupCallEvent = final CachedStreamController<GroupCallStateChange> onGroupCallEvent =
CachedStreamController(); CachedStreamController();
@ -105,8 +107,11 @@ class GroupCallSession {
void setState(GroupCallState newState) { void setState(GroupCallState newState) {
state = newState; state = newState;
// ignore: deprecated_member_use_from_same_package
onGroupCallState.add(newState); onGroupCallState.add(newState);
// ignore: deprecated_member_use_from_same_package
onGroupCallEvent.add(GroupCallStateChange.groupCallStateChanged); onGroupCallEvent.add(GroupCallStateChange.groupCallStateChanged);
matrixRTCEventStream.add(GroupCallStateChanged(newState));
} }
bool hasLocalParticipant() { bool hasLocalParticipant() {
@ -313,6 +318,7 @@ class GroupCallSession {
.add(ParticipantsLeftEvent(participants: anyLeft.toList())); .add(ParticipantsLeftEvent(participants: anyLeft.toList()));
} }
// ignore: deprecated_member_use_from_same_package
onGroupCallEvent.add(GroupCallStateChange.participantsChanged); onGroupCallEvent.add(GroupCallStateChange.participantsChanged);
} }
} }

View File

@ -5,15 +5,18 @@ import 'package:matrix/matrix.dart';
/// often. /// often.
sealed class MatrixRTCCallEvent {} sealed class MatrixRTCCallEvent {}
/// Event type for participants change
sealed class ParticipantsChangeEvent implements MatrixRTCCallEvent {} sealed class ParticipantsChangeEvent implements MatrixRTCCallEvent {}
final class ParticipantsJoinEvent implements ParticipantsChangeEvent { final class ParticipantsJoinEvent implements ParticipantsChangeEvent {
/// The participants who joined the call
final List<CallParticipant> participants; final List<CallParticipant> participants;
ParticipantsJoinEvent({required this.participants}); ParticipantsJoinEvent({required this.participants});
} }
final class ParticipantsLeftEvent implements ParticipantsChangeEvent { final class ParticipantsLeftEvent implements ParticipantsChangeEvent {
/// The participants who left the call
final List<CallParticipant> participants; final List<CallParticipant> participants;
ParticipantsLeftEvent({required this.participants}); ParticipantsLeftEvent({required this.participants});
@ -46,3 +49,89 @@ final class CallReactionRemovedEvent implements CallReactionEvent {
required this.redactedEventId, required this.redactedEventId,
}); });
} }
/// Group call active speaker changed event
final class GroupCallActiveSpeakerChanged implements MatrixRTCCallEvent {
final CallParticipant participant;
GroupCallActiveSpeakerChanged(this.participant);
}
/// Group calls changed event type
sealed class GroupCallChanged implements MatrixRTCCallEvent {}
/// Group call, call added event
final class CallAddedEvent implements GroupCallChanged {
final CallSession call;
CallAddedEvent(this.call);
}
/// Group call, call removed event
final class CallRemovedEvent implements GroupCallChanged {
final CallSession call;
CallRemovedEvent(this.call);
}
/// Group call, call replaced event
final class CallReplacedEvent extends GroupCallChanged {
final CallSession existingCall, replacementCall;
CallReplacedEvent(this.existingCall, this.replacementCall);
}
enum GroupCallStreamType {
userMedia,
screenshare,
}
/// Group call stream added event
final class GroupCallStreamAdded implements MatrixRTCCallEvent {
final GroupCallStreamType type;
GroupCallStreamAdded(this.type);
}
/// Group call stream removed event
final class GroupCallStreamRemoved implements MatrixRTCCallEvent {
final GroupCallStreamType type;
GroupCallStreamRemoved(this.type);
}
/// Group call stream replaced event
final class GroupCallStreamReplaced implements MatrixRTCCallEvent {
final GroupCallStreamType type;
GroupCallStreamReplaced(this.type);
}
/// Group call local screenshare state changed event
final class GroupCallLocalScreenshareStateChanged
implements MatrixRTCCallEvent {
final bool screensharing;
GroupCallLocalScreenshareStateChanged(this.screensharing);
}
/// Group call local muted changed event
final class GroupCallLocalMutedChanged implements MatrixRTCCallEvent {
final bool muted;
final MediaInputKind kind;
GroupCallLocalMutedChanged(this.muted, this.kind);
}
enum GroupCallState {
localCallFeedUninitialized,
initializingLocalCallFeed,
localCallFeedInitialized,
entering,
entered,
ended
}
/// Group call state changed event
final class GroupCallStateChanged implements MatrixRTCCallEvent {
final GroupCallState state;
GroupCallStateChanged(this.state);
}
/// Group call error event
final class GroupCallStateError implements MatrixRTCCallEvent {
final String msg;
final dynamic err;
GroupCallStateError(this.msg, this.err);
}

View File

@ -165,6 +165,7 @@ class GroupCallError extends Error {
} }
} }
@Deprecated('Use the events implementing MatrixRTCCallEvent instead')
enum GroupCallStateChange { enum GroupCallStateChange {
groupCallStateChanged, groupCallStateChanged,
activeSpeakerChanged, activeSpeakerChanged,
@ -176,12 +177,3 @@ enum GroupCallStateChange {
participantsChanged, participantsChanged,
error error
} }
enum GroupCallState {
localCallFeedUninitialized,
initializingLocalCallFeed,
localCallFeedInitialized,
entering,
entered,
ended
}