mirror of
https://github.com/krille-chan/fluffychat
synced 2024-09-10 04:25:15 +00:00
fix: voip code breaking from 0.28
have not tested it but should mostly be fine, rewrite should get in someday anyway :p
This commit is contained in:
parent
57f0962921
commit
4095560412
10 changed files with 124 additions and 115 deletions
|
@ -1269,25 +1269,12 @@ class ChatController extends State<ChatPageWithRoom>
|
||||||
);
|
);
|
||||||
if (callType == null) return;
|
if (callType == null) return;
|
||||||
|
|
||||||
final success = await showFutureLoadingDialog(
|
final voipPlugin = Matrix.of(context).voipPlugin;
|
||||||
context: context,
|
try {
|
||||||
future: () =>
|
await voipPlugin!.voip.inviteToCall(room, callType);
|
||||||
Matrix.of(context).voipPlugin!.voip.requestTurnServerCredentials(),
|
} catch (e) {
|
||||||
);
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
if (success.result != null) {
|
SnackBar(content: Text(e.toLocalizedString(context))),
|
||||||
final voipPlugin = Matrix.of(context).voipPlugin;
|
|
||||||
try {
|
|
||||||
await voipPlugin!.voip.inviteToCall(room.id, callType);
|
|
||||||
} catch (e) {
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
SnackBar(content: Text(e.toLocalizedString(context))),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
await showOkAlertDialog(
|
|
||||||
context: context,
|
|
||||||
title: L10n.of(context)!.unavailable,
|
|
||||||
okLabel: L10n.of(context)!.next,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,7 @@ class _SpaceViewState extends State<SpaceView> {
|
||||||
icon: Icons.send_outlined,
|
icon: Icons.send_outlined,
|
||||||
),
|
),
|
||||||
if (spaceChild != null &&
|
if (spaceChild != null &&
|
||||||
(activeSpace?.canChangeStateEvent(EventTypes.spaceChild) ?? false))
|
(activeSpace?.canChangeStateEvent(EventTypes.SpaceChild) ?? false))
|
||||||
SheetAction(
|
SheetAction(
|
||||||
key: SpaceChildContextAction.removeFromSpace,
|
key: SpaceChildContextAction.removeFromSpace,
|
||||||
label: L10n.of(context)!.removeFromSpace,
|
label: L10n.of(context)!.removeFromSpace,
|
||||||
|
@ -474,7 +474,7 @@ class _SpaceViewState extends State<SpaceView> {
|
||||||
onTap: () => _onJoinSpaceChild(spaceChild),
|
onTap: () => _onJoinSpaceChild(spaceChild),
|
||||||
),
|
),
|
||||||
if (activeSpace?.canChangeStateEvent(
|
if (activeSpace?.canChangeStateEvent(
|
||||||
EventTypes.spaceChild,
|
EventTypes.SpaceChild,
|
||||||
) ==
|
) ==
|
||||||
true)
|
true)
|
||||||
Material(
|
Material(
|
||||||
|
|
|
@ -25,13 +25,14 @@ import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'package:flutter_foreground_task/flutter_foreground_task.dart';
|
import 'package:flutter_foreground_task/flutter_foreground_task.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
import 'package:flutter_webrtc/flutter_webrtc.dart' hide VideoRenderer;
|
||||||
import 'package:just_audio/just_audio.dart';
|
import 'package:just_audio/just_audio.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:wakelock_plus/wakelock_plus.dart';
|
import 'package:wakelock_plus/wakelock_plus.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||||
import 'package:fluffychat/utils/platform_infos.dart';
|
import 'package:fluffychat/utils/platform_infos.dart';
|
||||||
|
import 'package:fluffychat/utils/voip/video_renderer.dart';
|
||||||
import 'package:fluffychat/widgets/avatar.dart';
|
import 'package:fluffychat/widgets/avatar.dart';
|
||||||
import 'pip/pip_view.dart';
|
import 'pip/pip_view.dart';
|
||||||
|
|
||||||
|
@ -75,19 +76,13 @@ class _StreamView extends StatelessWidget {
|
||||||
child: Stack(
|
child: Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
if (videoMuted)
|
VideoRenderer(
|
||||||
Container(
|
wrappedStream,
|
||||||
color: Colors.transparent,
|
mirror: mirrored,
|
||||||
),
|
fit: RTCVideoViewObjectFit.RTCVideoViewObjectFitContain,
|
||||||
if (!videoMuted)
|
),
|
||||||
RTCVideoView(
|
if (videoMuted) ...[
|
||||||
// yes, it must explicitly be casted even though I do not feel
|
Container(color: Colors.black54),
|
||||||
// comfortable with it...
|
|
||||||
wrappedStream.renderer as RTCVideoRenderer,
|
|
||||||
mirror: mirrored,
|
|
||||||
objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitContain,
|
|
||||||
),
|
|
||||||
if (videoMuted)
|
|
||||||
Positioned(
|
Positioned(
|
||||||
child: Avatar(
|
child: Avatar(
|
||||||
mxContent: avatarUrl,
|
mxContent: avatarUrl,
|
||||||
|
@ -98,6 +93,7 @@ class _StreamView extends StatelessWidget {
|
||||||
// matrixClient: matrixClient,
|
// matrixClient: matrixClient,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
],
|
||||||
if (!isScreenSharing)
|
if (!isScreenSharing)
|
||||||
Positioned(
|
Positioned(
|
||||||
left: 4.0,
|
left: 4.0,
|
||||||
|
@ -159,8 +155,6 @@ class MyCallingPage extends State<Calling> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get speakerOn => call.speakerOn;
|
|
||||||
|
|
||||||
bool get isMicrophoneMuted => call.isMicrophoneMuted;
|
bool get isMicrophoneMuted => call.isMicrophoneMuted;
|
||||||
|
|
||||||
bool get isLocalVideoMuted => call.isLocalVideoMuted;
|
bool get isLocalVideoMuted => call.isLocalVideoMuted;
|
||||||
|
@ -175,9 +169,6 @@ class MyCallingPage extends State<Calling> {
|
||||||
|
|
||||||
bool get connected => call.state == CallState.kConnected;
|
bool get connected => call.state == CallState.kConnected;
|
||||||
|
|
||||||
bool get mirrored => call.facingMode == 'user';
|
|
||||||
|
|
||||||
List<WrappedMediaStream> get streams => call.streams;
|
|
||||||
double? _localVideoHeight;
|
double? _localVideoHeight;
|
||||||
double? _localVideoWidth;
|
double? _localVideoWidth;
|
||||||
EdgeInsetsGeometry? _localVideoMargin;
|
EdgeInsetsGeometry? _localVideoMargin;
|
||||||
|
@ -205,12 +196,12 @@ class MyCallingPage extends State<Calling> {
|
||||||
final call = this.call;
|
final call = this.call;
|
||||||
call.onCallStateChanged.stream.listen(_handleCallState);
|
call.onCallStateChanged.stream.listen(_handleCallState);
|
||||||
call.onCallEventChanged.stream.listen((event) {
|
call.onCallEventChanged.stream.listen((event) {
|
||||||
if (event == CallEvent.kFeedsChanged) {
|
if (event == CallStateChange.kFeedsChanged) {
|
||||||
setState(() {
|
setState(() {
|
||||||
call.tryRemoveStopedStreams();
|
call.tryRemoveStopedStreams();
|
||||||
});
|
});
|
||||||
} else if (event == CallEvent.kLocalHoldUnhold ||
|
} else if (event == CallStateChange.kLocalHoldUnhold ||
|
||||||
event == CallEvent.kRemoteHoldUnhold) {
|
event == CallStateChange.kRemoteHoldUnhold) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
Logs().i(
|
Logs().i(
|
||||||
'Call hold event: local ${call.localHold}, remote ${call.remoteOnHold}',
|
'Call hold event: local ${call.localHold}, remote ${call.remoteOnHold}',
|
||||||
|
@ -286,7 +277,7 @@ class MyCallingPage extends State<Calling> {
|
||||||
if (call.isRinging) {
|
if (call.isRinging) {
|
||||||
call.reject();
|
call.reject();
|
||||||
} else {
|
} else {
|
||||||
call.hangup();
|
call.hangup(reason: CallErrorCode.userHangup);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -341,11 +332,6 @@ class MyCallingPage extends State<Calling> {
|
||||||
await Helper.switchCamera(
|
await Helper.switchCamera(
|
||||||
call.localUserMediaStream!.stream!.getVideoTracks()[0],
|
call.localUserMediaStream!.stream!.getVideoTracks()[0],
|
||||||
);
|
);
|
||||||
if (PlatformInfos.isMobile) {
|
|
||||||
call.facingMode == 'user'
|
|
||||||
? call.facingMode = 'environment'
|
|
||||||
: call.facingMode = 'user';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
@ -450,16 +436,10 @@ class MyCallingPage extends State<Calling> {
|
||||||
hangupButton,
|
hangupButton,
|
||||||
];
|
];
|
||||||
case CallState.kFledgling:
|
case CallState.kFledgling:
|
||||||
// TODO: Handle this case.
|
|
||||||
break;
|
|
||||||
case CallState.kWaitLocalMedia:
|
case CallState.kWaitLocalMedia:
|
||||||
// TODO: Handle this case.
|
|
||||||
break;
|
|
||||||
case CallState.kCreateOffer:
|
case CallState.kCreateOffer:
|
||||||
// TODO: Handle this case.
|
case CallState.kEnding:
|
||||||
break;
|
|
||||||
case null:
|
case null:
|
||||||
// TODO: Handle this case.
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return <Widget>[];
|
return <Widget>[];
|
||||||
|
|
|
@ -299,7 +299,7 @@ class UserBottomSheetView extends StatelessWidget {
|
||||||
BorderRadius.circular(AppConfig.borderRadius / 2),
|
BorderRadius.circular(AppConfig.borderRadius / 2),
|
||||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||||
child: DropdownButton<int>(
|
child: DropdownButton<int>(
|
||||||
onChanged: user.canChangePowerLevel ||
|
onChanged: user.canChangeUserPowerLevel ||
|
||||||
// Workaround until https://github.com/famedly/matrix-dart-sdk/pull/1765
|
// Workaround until https://github.com/famedly/matrix-dart-sdk/pull/1765
|
||||||
(user.room.canChangePowerLevel &&
|
(user.room.canChangePowerLevel &&
|
||||||
user.id == user.room.client.userID)
|
user.id == user.room.client.userID)
|
||||||
|
|
|
@ -8,8 +8,6 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/utils/voip_plugin.dart';
|
|
||||||
|
|
||||||
class CallKeeper {
|
class CallKeeper {
|
||||||
CallKeeper(this.callKeepManager, this.call) {
|
CallKeeper(this.callKeepManager, this.call) {
|
||||||
call.onCallStateChanged.stream.listen(_handleCallState);
|
call.onCallStateChanged.stream.listen(_handleCallState);
|
||||||
|
@ -40,31 +38,14 @@ class CallKeeper {
|
||||||
case CallState.kEnded:
|
case CallState.kEnded:
|
||||||
callKeepManager.hangup(call.callId);
|
callKeepManager.hangup(call.callId);
|
||||||
break;
|
break;
|
||||||
/* TODO:
|
|
||||||
case CallState.kMuted:
|
|
||||||
callKeepManager.setMutedCall(uuid, true);
|
|
||||||
break;
|
|
||||||
case CallState.kHeld:
|
|
||||||
callKeepManager.setOnHold(uuid, true);
|
|
||||||
break;
|
|
||||||
*/
|
|
||||||
case CallState.kFledgling:
|
case CallState.kFledgling:
|
||||||
// TODO: Handle this case.
|
|
||||||
break;
|
|
||||||
case CallState.kInviteSent:
|
case CallState.kInviteSent:
|
||||||
// TODO: Handle this case.
|
|
||||||
break;
|
|
||||||
case CallState.kWaitLocalMedia:
|
case CallState.kWaitLocalMedia:
|
||||||
// TODO: Handle this case.
|
|
||||||
break;
|
|
||||||
case CallState.kCreateOffer:
|
case CallState.kCreateOffer:
|
||||||
// TODO: Handle this case.
|
|
||||||
break;
|
|
||||||
case CallState.kCreateAnswer:
|
case CallState.kCreateAnswer:
|
||||||
// TODO: Handle this case.
|
|
||||||
break;
|
|
||||||
case CallState.kRinging:
|
case CallState.kRinging:
|
||||||
// TODO: Handle this case.
|
case CallState.kEnding:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +65,6 @@ class CallKeepManager {
|
||||||
static final CallKeepManager _instance = CallKeepManager._internal();
|
static final CallKeepManager _instance = CallKeepManager._internal();
|
||||||
|
|
||||||
late FlutterCallkeep _callKeep;
|
late FlutterCallkeep _callKeep;
|
||||||
VoipPlugin? _voipPlugin;
|
|
||||||
|
|
||||||
String get appName => 'FluffyChat';
|
String get appName => 'FluffyChat';
|
||||||
|
|
||||||
|
@ -130,7 +110,7 @@ class CallKeepManager {
|
||||||
});
|
});
|
||||||
call.onCallEventChanged.stream.listen(
|
call.onCallEventChanged.stream.listen(
|
||||||
(event) {
|
(event) {
|
||||||
if (event == CallEvent.kLocalHoldUnhold) {
|
if (event == CallStateChange.kLocalHoldUnhold) {
|
||||||
Logs().i(
|
Logs().i(
|
||||||
'Call hold event: local ${call.localHold}, remote ${call.remoteOnHold}',
|
'Call hold event: local ${call.localHold}, remote ${call.remoteOnHold}',
|
||||||
);
|
);
|
||||||
|
@ -170,10 +150,7 @@ class CallKeepManager {
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
_callKeep.on(CallKeepPerformAnswerCallAction(), answerCall);
|
_callKeep.on(CallKeepPerformAnswerCallAction(), answerCall);
|
||||||
_callKeep.on(CallKeepDidPerformDTMFAction(), didPerformDTMFAction);
|
_callKeep.on(CallKeepDidPerformDTMFAction(), didPerformDTMFAction);
|
||||||
_callKeep.on(
|
|
||||||
CallKeepDidReceiveStartCallAction(),
|
|
||||||
didReceiveStartCallAction,
|
|
||||||
);
|
|
||||||
_callKeep.on(CallKeepDidToggleHoldAction(), didToggleHoldCallAction);
|
_callKeep.on(CallKeepDidToggleHoldAction(), didToggleHoldCallAction);
|
||||||
_callKeep.on(
|
_callKeep.on(
|
||||||
CallKeepDidPerformSetMutedCallAction(),
|
CallKeepDidPerformSetMutedCallAction(),
|
||||||
|
@ -313,7 +290,7 @@ class CallKeepManager {
|
||||||
|
|
||||||
Future<void> endCall(CallKeepPerformEndCallAction event) async {
|
Future<void> endCall(CallKeepPerformEndCallAction event) async {
|
||||||
final keeper = calls[event.callUUID];
|
final keeper = calls[event.callUUID];
|
||||||
keeper?.call.hangup();
|
keeper?.call.hangup(reason: CallErrorCode.userHangup);
|
||||||
removeCall(event.callUUID);
|
removeCall(event.callUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,25 +299,6 @@ class CallKeepManager {
|
||||||
keeper.call.sendDTMF(event.digits!);
|
keeper.call.sendDTMF(event.digits!);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> didReceiveStartCallAction(
|
|
||||||
CallKeepDidReceiveStartCallAction event,
|
|
||||||
) async {
|
|
||||||
if (event.handle == null) {
|
|
||||||
// @TODO: sometime we receive `didReceiveStartCallAction` with handle` undefined`
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final callUUID = event.callUUID!;
|
|
||||||
if (event.callUUID == null) {
|
|
||||||
final call =
|
|
||||||
await _voipPlugin!.voip.inviteToCall(event.handle!, CallType.kVideo);
|
|
||||||
addCall(callUUID, CallKeeper(this, call));
|
|
||||||
}
|
|
||||||
await _callKeep.startCall(callUUID, event.handle!, event.handle!);
|
|
||||||
Timer(const Duration(seconds: 1), () {
|
|
||||||
_callKeep.setCurrentCallActive(callUUID);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> didPerformSetMutedCallAction(
|
Future<void> didPerformSetMutedCallAction(
|
||||||
CallKeepDidPerformSetMutedCallAction event,
|
CallKeepDidPerformSetMutedCallAction event,
|
||||||
) async {
|
) async {
|
||||||
|
|
86
lib/utils/voip/video_renderer.dart
Normal file
86
lib/utils/voip/video_renderer.dart
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
||||||
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
|
class VideoRenderer extends StatefulWidget {
|
||||||
|
final WrappedMediaStream? stream;
|
||||||
|
final bool mirror;
|
||||||
|
final RTCVideoViewObjectFit fit;
|
||||||
|
|
||||||
|
const VideoRenderer(
|
||||||
|
this.stream, {
|
||||||
|
this.mirror = false,
|
||||||
|
this.fit = RTCVideoViewObjectFit.RTCVideoViewObjectFitContain,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => _VideoRendererState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _VideoRendererState extends State<VideoRenderer> {
|
||||||
|
RTCVideoRenderer? _renderer;
|
||||||
|
bool _rendererReady = false;
|
||||||
|
MediaStream? get mediaStream => widget.stream?.stream;
|
||||||
|
StreamSubscription? _streamChangeSubscription;
|
||||||
|
|
||||||
|
Future<RTCVideoRenderer> _initializeRenderer() async {
|
||||||
|
_renderer ??= RTCVideoRenderer();
|
||||||
|
await _renderer!.initialize();
|
||||||
|
_renderer!.srcObject = mediaStream;
|
||||||
|
return _renderer!;
|
||||||
|
}
|
||||||
|
|
||||||
|
void disposeRenderer() {
|
||||||
|
try {
|
||||||
|
_renderer?.srcObject = null;
|
||||||
|
_renderer?.dispose();
|
||||||
|
_renderer = null;
|
||||||
|
// ignore: empty_catches
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_streamChangeSubscription =
|
||||||
|
widget.stream?.onStreamChanged.stream.listen((stream) {
|
||||||
|
setState(() {
|
||||||
|
_renderer?.srcObject = stream;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
setupRenderer();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> setupRenderer() async {
|
||||||
|
await _initializeRenderer();
|
||||||
|
setState(() => _rendererReady = true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_streamChangeSubscription?.cancel();
|
||||||
|
disposeRenderer();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => !_rendererReady
|
||||||
|
? Container()
|
||||||
|
: Builder(
|
||||||
|
key: widget.key,
|
||||||
|
builder: (ctx) {
|
||||||
|
return RTCVideoView(
|
||||||
|
_renderer!,
|
||||||
|
mirror: widget.mirror,
|
||||||
|
filterQuality: FilterQuality.medium,
|
||||||
|
objectFit: widget.fit,
|
||||||
|
placeholderBuilder: (_) =>
|
||||||
|
Container(color: Colors.white.withOpacity(0.18)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
|
@ -90,11 +90,6 @@ class VoipPlugin with WidgetsBindingObserver implements WebRTCDelegate {
|
||||||
]) =>
|
]) =>
|
||||||
webrtc_impl.createPeerConnection(configuration, constraints);
|
webrtc_impl.createPeerConnection(configuration, constraints);
|
||||||
|
|
||||||
@override
|
|
||||||
VideoRenderer createRenderer() {
|
|
||||||
return webrtc_impl.RTCVideoRenderer();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> get hasCallingAccount async =>
|
Future<bool> get hasCallingAccount async =>
|
||||||
kIsWeb ? false : await CallKeepManager().hasPhoneAccountEnabled;
|
kIsWeb ? false : await CallKeepManager().hasPhoneAccountEnabled;
|
||||||
|
|
||||||
|
@ -179,12 +174,12 @@ class VoipPlugin with WidgetsBindingObserver implements WebRTCDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> handleGroupCallEnded(GroupCall groupCall) async {
|
Future<void> handleGroupCallEnded(GroupCallSession groupCall) async {
|
||||||
// TODO: implement handleGroupCallEnded
|
// TODO: implement handleGroupCallEnded
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> handleNewGroupCall(GroupCall groupCall) async {
|
Future<void> handleNewGroupCall(GroupCallSession groupCall) async {
|
||||||
// TODO: implement handleNewGroupCall
|
// TODO: implement handleNewGroupCall
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,4 +192,8 @@ class VoipPlugin with WidgetsBindingObserver implements WebRTCDelegate {
|
||||||
Future<void> handleMissedCall(CallSession session) async {
|
Future<void> handleMissedCall(CallSession session) async {
|
||||||
// TODO: implement handleMissedCall
|
// TODO: implement handleMissedCall
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
// TODO: implement keyProvider
|
||||||
|
EncryptionKeyProvider? get keyProvider => throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1210,10 +1210,10 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: matrix
|
name: matrix
|
||||||
sha256: "36c7e13d5d7420898f2597d6f5f0611a9da8114a0fde11f41b9e54cd1140b05f"
|
sha256: "32c21a2ac2c221ce887b00a87f965bd8df1a3a4ba8794bbe86be8b56214051fb"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.27.0"
|
version: "0.28.1"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -64,7 +64,7 @@ dependencies:
|
||||||
keyboard_shortcuts: ^0.1.4
|
keyboard_shortcuts: ^0.1.4
|
||||||
latlong2: ^0.9.1
|
latlong2: ^0.9.1
|
||||||
linkify: ^5.0.0
|
linkify: ^5.0.0
|
||||||
matrix: ^0.27.0
|
matrix: ^0.28.1
|
||||||
native_imaging: ^0.1.0
|
native_imaging: ^0.1.0
|
||||||
package_info_plus: ^6.0.0
|
package_info_plus: ^6.0.0
|
||||||
pasteboard: ^0.2.0
|
pasteboard: ^0.2.0
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// ignore_for_file: depend_on_referenced_packages
|
// ignore_for_file: depend_on_referenced_packages
|
||||||
|
|
||||||
import 'package:matrix/encryption/utils/key_verification.dart';
|
import 'package:matrix/encryption/utils/key_verification.dart';
|
||||||
import 'package:matrix/fake_matrix_api.dart';
|
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart';
|
||||||
|
|
Loading…
Reference in a new issue