From e207b26008fa5a608b1e91479f4f2de6c95119e7 Mon Sep 17 00:00:00 2001 From: Lanna Michalke Date: Sat, 19 Feb 2022 08:27:03 +0000 Subject: [PATCH] fix: display WebRTC call overlay in web --- lib/pages/chat_list/chat_list.dart | 5 +++ lib/utils/voip_plugin.dart | 53 ++++++++++++++++++------- lib/widgets/matrix.dart | 21 ++++++++-- linux/flutter/generated_plugins.cmake | 8 ++++ pubspec.lock | 24 ++++++----- pubspec.yaml | 9 +++++ windows/flutter/generated_plugins.cmake | 8 ++++ 7 files changed, 99 insertions(+), 29 deletions(-) diff --git a/lib/pages/chat_list/chat_list.dart b/lib/pages/chat_list/chat_list.dart index f5518b89..9580becb 100644 --- a/lib/pages/chat_list/chat_list.dart +++ b/lib/pages/chat_list/chat_list.dart @@ -175,6 +175,7 @@ class ChatListController extends State { scrollController.addListener(_onScroll); _waitForFirstSync(); + _hackyWebRTCFixForWeb(); super.initState(); } @@ -576,6 +577,10 @@ class ChatListController extends State { Matrix.of(context).navigatorContext = context; return ChatListView(this); } + + void _hackyWebRTCFixForWeb() { + Matrix.of(context).voipPlugin?.context = context; + } } enum EditBundleAction { addToBundle, removeFromBundle } diff --git a/lib/utils/voip_plugin.dart b/lib/utils/voip_plugin.dart index 5b56aa86..c529de9e 100644 --- a/lib/utils/voip_plugin.dart +++ b/lib/utils/voip_plugin.dart @@ -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? 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 diff --git a/lib/widgets/matrix.dart b/lib/widgets/matrix.dart index f8d82665..bb5a5c01 100644 --- a/lib/widgets/matrix.dart +++ b/lib/widgets/matrix.dart @@ -83,10 +83,13 @@ class MatrixState extends State 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 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 with WidgetsBindingObserver { widget.clients.firstWhereOrNull((c) => c.clientName == name); Map? get shareContent => _shareContent; + set shareContent(Map? content) { _shareContent = content; onShareContentChanged.add(_shareContent); @@ -216,6 +222,7 @@ class MatrixState extends State with WidgetsBindingObserver { String? _cachedPassword; Timer? _cachedPasswordClearTimer; + String? get cachedPassword => _cachedPassword; set cachedPassword(String? p) { @@ -420,6 +427,13 @@ class MatrixState extends State 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}); } diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 818fa7f6..43424f5e 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -10,6 +10,9 @@ list(APPEND FLUTTER_PLUGIN_LIST url_launcher_linux ) +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + set(PLUGIN_BUNDLED_LIBRARIES) foreach(plugin ${FLUTTER_PLUGIN_LIST}) @@ -18,3 +21,8 @@ foreach(plugin ${FLUTTER_PLUGIN_LIST}) list(APPEND PLUGIN_BUNDLED_LIBRARIES $) list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/pubspec.lock b/pubspec.lock index 5385352e..24b8740a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -226,12 +226,14 @@ packages: source: hosted version: "1.2.0" connectivity_plus_web: - dependency: transitive + dependency: "direct overridden" description: - name: connectivity_plus_web - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" + path: "packages/connectivity_plus/connectivity_plus_web" + ref: a04401cb48abe92d138c0e9288b360739994a9e9 + resolved-ref: a04401cb48abe92d138c0e9288b360739994a9e9 + url: "https://github.com/TheOneWithTheBraid/plus_plugins.git" + source: git + version: "1.2.1" connectivity_plus_windows: dependency: transitive description: @@ -888,7 +890,7 @@ packages: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.3" + version: "0.6.4" latlong2: dependency: transitive description: @@ -1105,7 +1107,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.8.1" path_drawing: dependency: transitive description: @@ -1558,21 +1560,21 @@ packages: name: test url: "https://pub.dartlang.org" source: hosted - version: "1.19.5" + version: "1.20.1" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.8" + version: "0.4.9" test_core: dependency: transitive description: name: test_core url: "https://pub.dartlang.org" source: hosted - version: "0.4.9" + version: "0.4.11" timezone: dependency: transitive description: @@ -1896,5 +1898,5 @@ packages: source: hosted version: "3.1.0" sdks: - dart: ">=2.15.1 <3.0.0" + dart: ">=2.16.0-100.0.dev <3.0.0" flutter: ">=2.8.0" diff --git a/pubspec.yaml b/pubspec.yaml index 5ea48afb..9f1254e7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -121,6 +121,15 @@ flutter: - asset: fonts/NotoEmoji/NotoColorEmoji.ttf dependency_overrides: + # Necessary for webRTC on web. + # Fix for stream fallback for unsupported browsers: + # https://github.com/fluttercommunity/plus_plugins/pull/746 + # Upstream pull request: https://github.com/fluttercommunity/plus_plugins/pull/746 + connectivity_plus_web: + git: + url: https://github.com/TheOneWithTheBraid/plus_plugins.git + ref: a04401cb48abe92d138c0e9288b360739994a9e9 + path: packages/connectivity_plus/connectivity_plus_web dbus: ^0.7.1 geolocator_android: hosted: diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index b18dd536..cd2a6cc0 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -12,6 +12,9 @@ list(APPEND FLUTTER_PLUGIN_LIST url_launcher_windows ) +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + set(PLUGIN_BUNDLED_LIBRARIES) foreach(plugin ${FLUTTER_PLUGIN_LIST}) @@ -20,3 +23,8 @@ foreach(plugin ${FLUTTER_PLUGIN_LIST}) list(APPEND PLUGIN_BUNDLED_LIBRARIES $) list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin)