import 'package:fluffychat/utils/voip/call_state_proxy.dart'; import 'package:matrix/matrix.dart'; class CallSessionState implements CallStateProxy { final CallSession call; Function()? callback; CallSessionState(this.call) { call.onCallEventChanged.stream.listen((CallEvent event) { if (event == CallEvent.kState || event == CallEvent.kFeedsChanged || event == CallEvent.kLocalHoldUnhold || event == CallEvent.kRemoteHoldUnhold) { if (event == CallEvent.kFeedsChanged) { call.tryRemoveStopedStreams(); } callback?.call(); } }); call.onCallStateChanged.stream.listen((state) { callback?.call(); }); } @override bool get voiceonly => call.type == CallType.kVoice; @override bool get connecting => call.state == CallState.kConnecting; @override bool get connected => call.state == CallState.kConnected; @override bool get ended => call.state == CallState.kEnded; @override bool get isOutgoing => call.isOutgoing; @override bool get ringingPlay => call.state == CallState.kInviteSent; @override void answer() => call.answer(); @override void enter() { // TODO: implement enter } @override void hangup() { if (call.isRinging) { call.reject(); } else { call.hangup(); } } @override bool get isLocalVideoMuted => call.isLocalVideoMuted; @override bool get isMicrophoneMuted => call.isMicrophoneMuted; @override bool get isRemoteOnHold => call.remoteOnHold; @override bool get localHold => call.localHold; @override bool get remoteOnHold => call.remoteOnHold; @override bool get isScreensharingEnabled => call.screensharingEnabled; @override bool get callOnHold => call.localHold || call.remoteOnHold; @override void setLocalVideoMuted(bool muted) { call.setLocalVideoMuted(muted); callback?.call(); } @override void setMicrophoneMuted(bool muted) { call.setMicrophoneMuted(muted); // TODO(Nico): Refactor this to be more granular callback?.call(); } @override void setRemoteOnHold(bool onHold) { call.setRemoteOnHold(onHold); callback?.call(); } @override void setScreensharingEnabled(bool enabled) { call.setScreensharingEnabled(enabled); callback?.call(); } @override String get callState { switch (call.state) { case CallState.kCreateAnswer: case CallState.kFledgling: case CallState.kWaitLocalMedia: case CallState.kCreateOffer: break; case CallState.kRinging: state = 'Ringing'; break; case CallState.kInviteSent: state = 'Invite Sent'; break; case CallState.kConnecting: state = 'Connecting'; break; case CallState.kConnected: state = 'Connected'; break; case CallState.kEnded: state = 'Ended'; break; } return state; } String state = 'New Call'; @override WrappedMediaStream? get localUserMediaStream => call.localUserMediaStream; @override WrappedMediaStream? get localScreenSharingStream => call.localScreenSharingStream; @override List get screenSharingStreams { final streams = []; if (connected) { if (call.remoteScreenSharingStream != null) { streams.add(call.remoteScreenSharingStream!); } if (call.localScreenSharingStream != null) { streams.add(call.localScreenSharingStream!); } } return streams; } @override List get userMediaStreams { final streams = []; if (connected) { if (call.remoteUserMediaStream != null) { streams.add(call.remoteUserMediaStream!); } if (call.localUserMediaStream != null) { streams.add(call.localUserMediaStream!); } } return streams; } @override WrappedMediaStream? get primaryStream { if (screenSharingStreams.isNotEmpty) { return screenSharingStreams.first; } if (userMediaStreams.isNotEmpty) { return userMediaStreams.first; } if (!connected) { return call.localUserMediaStream; } return call.localScreenSharingStream ?? call.localUserMediaStream; } @override String? get displayName => call.displayName; @override void onStateChanged(Function() handler) { callback = handler; } }