fix: display WebRTC call overlay in web

This commit is contained in:
Lanna Michalke 2022-02-19 08:27:03 +00:00 committed by Krille Fear
commit e46307cd82
7 changed files with 99 additions and 29 deletions

View file

@ -175,6 +175,7 @@ class ChatListController extends State<ChatList> {
scrollController.addListener(_onScroll);
_waitForFirstSync();
_hackyWebRTCFixForWeb();
super.initState();
}
@ -576,6 +577,10 @@ class ChatListController extends State<ChatList> {
Matrix.of(context).navigatorContext = context;
return ChatListView(this);
}
void _hackyWebRTCFixForWeb() {
Matrix.of(context).voipPlugin?.context = context;
}
}
enum EditBundleAction { addToBundle, removeFromBundle }

View file

@ -1,12 +1,12 @@
import 'dart:core';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart' as webrtc_impl;
import 'package:matrix/matrix.dart';
import 'package:webrtc_interface/webrtc_interface.dart';
import 'package:webrtc_interface/webrtc_interface.dart' hide Navigator;
import 'package:fluffychat/pages/dialer/dialer.dart';
import '../../utils/voip/user_media_manager.dart';
@ -14,10 +14,14 @@ import '../../utils/voip/user_media_manager.dart';
class VoipPlugin extends WidgetsBindingObserver implements WebRTCDelegate {
VoipPlugin({required this.client, required this.context}) {
voip = VoIP(client, this);
Connectivity()
.onConnectivityChanged
.listen(_handleNetworkChanged)
.onError((e) => _currentConnectivity = ConnectivityResult.none);
try {
Connectivity()
.onConnectivityChanged
.listen(_handleNetworkChanged)
.onError((e) => _currentConnectivity = ConnectivityResult.none);
} catch (e, s) {
Logs().w('Could not subscribe network updates', e, s);
}
Connectivity()
.checkConnectivity()
.then((result) => _currentConnectivity = result)
@ -39,7 +43,11 @@ class VoipPlugin extends WidgetsBindingObserver implements WebRTCDelegate {
ValueChanged<CallSession>? onIncomingCall;
OverlayEntry? overlayEntry;
final BuildContext context;
// hacky workaround: in order to have [Overlay.of] working on web, the context
// mus explicitly be re-assigned
//
// hours wasted: 5
BuildContext context;
void _handleNetworkChanged(ConnectivityResult result) async {
/// Got a new connectivity status!
@ -64,18 +72,33 @@ class VoipPlugin extends WidgetsBindingObserver implements WebRTCDelegate {
Logs().w('[VOIP] addCallingOverlay: The call session already exists?');
overlayEntry?.remove();
}
overlayEntry = OverlayEntry(
builder: (_) => Calling(
// Overlay.of(context) is broken on web
// falling back on a dialog
if (kIsWeb) {
showDialog(
context: context,
builder: (context) => Calling(
context: context,
client: client,
callId: callId,
call: call,
onClear: () {
overlayEntry?.remove();
overlayEntry = null;
}),
);
Overlay.of(context)!.insert(overlayEntry!);
onClear: () => Navigator.of(context).pop(),
),
);
} else {
overlayEntry = OverlayEntry(
builder: (_) => Calling(
context: context,
client: client,
callId: callId,
call: call,
onClear: () {
overlayEntry?.remove();
overlayEntry = null;
}),
);
Overlay.of(context)!.insert(overlayEntry!);
}
}
@override

View file

@ -83,10 +83,13 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
return widget.clients[_activeClient];
}
bool get webrtcIsSupported => PlatformInfos.isMobile;
bool get webrtcIsSupported =>
kIsWeb ||
PlatformInfos.isMobile ||
PlatformInfos.isWindows ||
PlatformInfos.isMacOS;
VoipPlugin? get voipPlugin =>
webrtcIsSupported ? VoipPlugin(client: client, context: context) : null;
VoipPlugin? voipPlugin;
bool get isMultiAccount => widget.clients.length > 1;
@ -100,6 +103,8 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
final i = widget.clients.indexWhere((c) => c == cl);
if (i != -1) {
_activeClient = i;
// TODO: Multi-client VoiP support
createVoipPlugin();
} else {
Logs().w('Tried to set an unknown client ${cl!.userID} as active');
}
@ -172,6 +177,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
widget.clients.firstWhereOrNull((c) => c.clientName == name);
Map<String, dynamic>? get shareContent => _shareContent;
set shareContent(Map<String, dynamic>? content) {
_shareContent = content;
onShareContentChanged.add(_shareContent);
@ -216,6 +222,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
String? _cachedPassword;
Timer? _cachedPasswordClearTimer;
String? get cachedPassword => _cachedPassword;
set cachedPassword(String? p) {
@ -420,6 +427,13 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
),
);
}
createVoipPlugin();
}
void createVoipPlugin() {
voipPlugin =
webrtcIsSupported ? VoipPlugin(client: client, context: context) : null;
}
bool _firstStartup = true;
@ -534,5 +548,6 @@ class FixedThreepidCreds extends ThreepidCreds {
class _AccountBundleWithClient {
final Client? client;
final AccountBundle? bundle;
_AccountBundleWithClient({this.client, this.bundle});
}