From 508cba8ed3e01b5912e5d6e36888c18b6b898b83 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sat, 1 Jun 2024 01:25:45 +0800 Subject: [PATCH] :sparkles: Call button --- ios/Podfile | 2 +- ios/Podfile.lock | 32 +++- lib/providers/auth.dart | 7 +- lib/providers/content/channel.dart | 18 ++ lib/screens/channel/channel_chat.dart | 57 +++++- lib/translations.dart | 4 + lib/widgets/chat/call/chat_call_action.dart | 96 ++++++++++ linux/flutter/generated_plugin_registrant.cc | 4 + linux/flutter/generated_plugins.cmake | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 8 + pubspec.lock | 174 ++++++++++++++++-- pubspec.yaml | 2 + .../flutter/generated_plugin_registrant.cc | 9 + windows/flutter/generated_plugins.cmake | 3 + 14 files changed, 393 insertions(+), 24 deletions(-) create mode 100644 lib/widgets/chat/call/chat_call_action.dart diff --git a/ios/Podfile b/ios/Podfile index d97f17e..7f35b81 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '12.0' +platform :ios, '12.1' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 21911c8..52cb95e 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,4 +1,9 @@ PODS: + - connectivity_plus (0.0.1): + - Flutter + - FlutterMacOS + - device_info_plus (0.0.1): + - Flutter - DKImagePickerController/Core (4.3.9): - DKImagePickerController/ImageDataManager - DKImagePickerController/Resource @@ -38,8 +43,14 @@ PODS: - Flutter - flutter_secure_storage (6.0.0): - Flutter + - flutter_webrtc (0.9.36): + - Flutter + - WebRTC-SDK (= 114.5735.10) - image_picker_ios (0.0.1): - Flutter + - livekit_client (2.1.5): + - Flutter + - WebRTC-SDK (= 114.5735.10) - package_info_plus (0.4.5): - Flutter - path_provider_foundation (0.0.1): @@ -58,13 +69,18 @@ PODS: - FlutterMacOS - wakelock_plus (0.0.1): - Flutter + - WebRTC-SDK (114.5735.10) DEPENDENCIES: + - connectivity_plus (from `.symlinks/plugins/connectivity_plus/darwin`) + - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - file_picker (from `.symlinks/plugins/file_picker/ios`) - Flutter (from `Flutter`) - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) + - flutter_webrtc (from `.symlinks/plugins/flutter_webrtc/ios`) - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) + - livekit_client (from `.symlinks/plugins/livekit_client/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) @@ -78,8 +94,13 @@ SPEC REPOS: - DKPhotoGallery - SDWebImage - SwiftyGif + - WebRTC-SDK EXTERNAL SOURCES: + connectivity_plus: + :path: ".symlinks/plugins/connectivity_plus/darwin" + device_info_plus: + :path: ".symlinks/plugins/device_info_plus/ios" file_picker: :path: ".symlinks/plugins/file_picker/ios" Flutter: @@ -88,8 +109,12 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/flutter_local_notifications/ios" flutter_secure_storage: :path: ".symlinks/plugins/flutter_secure_storage/ios" + flutter_webrtc: + :path: ".symlinks/plugins/flutter_webrtc/ios" image_picker_ios: :path: ".symlinks/plugins/image_picker_ios/ios" + livekit_client: + :path: ".symlinks/plugins/livekit_client/ios" package_info_plus: :path: ".symlinks/plugins/package_info_plus/ios" path_provider_foundation: @@ -104,13 +129,17 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/wakelock_plus/ios" SPEC CHECKSUMS: + connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db + device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086 flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12 + flutter_webrtc: b33475c3a57d59ff05bf87b4f5d3feceac63f291 image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1 + livekit_client: e6adadd527ee8e52fff579498467ee89921d99f6 package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2 @@ -119,7 +148,8 @@ SPEC CHECKSUMS: url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3 wakelock_plus: 78ec7c5b202cab7761af8e2b2b3d0671be6c4ae1 + WebRTC-SDK: 8c0edd05b880a39648118192c252667ea06dea51 -PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796 +PODFILE CHECKSUM: f9420bd595da8fbce156b547dcd3368afc5226ff COCOAPODS: 1.15.2 diff --git a/lib/providers/auth.dart b/lib/providers/auth.dart index 54fd9dc..48b0a3b 100644 --- a/lib/providers/auth.dart +++ b/lib/providers/auth.dart @@ -129,7 +129,12 @@ class AuthProvider extends GetConnect { client.httpClient.addAuthenticator(requestAuthenticator); final resp = await client.get('/api/users/me'); - _cacheUserProfileResponse = resp; + if (resp.statusCode != 200) { + throw Exception(resp.bodyString); + } else { + _cacheUserProfileResponse = resp; + } + return resp; } } diff --git a/lib/providers/content/channel.dart b/lib/providers/content/channel.dart index c5b84ee..b54e522 100644 --- a/lib/providers/content/channel.dart +++ b/lib/providers/content/channel.dart @@ -21,6 +21,24 @@ class ChannelProvider extends GetxController { return resp; } + Future getChannelOngoingCall(String alias, + {String realm = 'global'}) async { + final AuthProvider auth = Get.find(); + if (!await auth.isAuthorized) throw Exception('unauthorized'); + + final client = GetConnect(maxAuthRetries: 3); + client.httpClient.baseUrl = ServiceFinder.services['messaging']; + + final resp = await client.get('/api/channels/$realm/$alias/calls/ongoing'); + if (resp.statusCode == 404) { + return null; + } else if (resp.statusCode != 200) { + throw Exception(resp.bodyString); + } + + return resp; + } + Future listChannel({String scope = 'global'}) async { final AuthProvider auth = Get.find(); if (!await auth.isAuthorized) throw Exception('unauthorized'); diff --git a/lib/screens/channel/channel_chat.dart b/lib/screens/channel/channel_chat.dart index 92e662d..e35e899 100644 --- a/lib/screens/channel/channel_chat.dart +++ b/lib/screens/channel/channel_chat.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:solian/exts.dart'; +import 'package:solian/models/call.dart'; import 'package:solian/models/channel.dart'; import 'package:solian/models/message.dart'; import 'package:solian/models/packet.dart'; @@ -14,6 +15,7 @@ import 'package:solian/providers/content/channel.dart'; import 'package:solian/router.dart'; import 'package:solian/services.dart'; import 'package:solian/theme.dart'; +import 'package:solian/widgets/chat/call/chat_call_action.dart'; import 'package:solian/widgets/chat/chat_message.dart'; import 'package:solian/widgets/chat/chat_message_action.dart'; import 'package:solian/widgets/chat/chat_message_input.dart'; @@ -39,6 +41,7 @@ class _ChannelChatScreenState extends State { String? _overrideAlias; Channel? _channel; + Call? _ongoingCall; StreamSubscription? _subscription; final PagingController _pagingController = @@ -72,6 +75,26 @@ class _ChannelChatScreenState extends State { setState(() => _isBusy = false); } + getOngoingCall() async { + final ChannelProvider provider = Get.find(); + + setState(() => _isBusy = true); + + try { + final resp = await provider.getChannelOngoingCall( + _overrideAlias ?? widget.alias, + realm: widget.realm, + ); + if (resp != null) { + setState(() => _ongoingCall = Call.fromJson(resp.body)); + } + } catch (e) { + context.showErrorDialog(e); + } + + setState(() => _isBusy = false); + } + Future getMessages(int pageKey) async { final AuthProvider auth = Get.find(); if (!await auth.isAuthorized) return; @@ -135,6 +158,13 @@ class _ChannelChatScreenState extends State { } } break; + case 'calls.new': + final payload = Call.fromJson(event.payload!); + _ongoingCall = payload; + break; + case 'calls.end': + _ongoingCall = null; + break; } setState(() {}); }); @@ -150,7 +180,7 @@ class _ChannelChatScreenState extends State { Message? _messageToReplying; Message? _messageToEditing; - Widget chatHistoryBuilder(context, item, index) { + Widget buildHistory(context, item, index) { bool isMerged = false, hasMerged = false; if (index > 0) { hasMerged = checkMessageMergeable( @@ -203,6 +233,7 @@ class _ChannelChatScreenState extends State { listenMessages(); _pagingController.addPageRequestListener(getMessages); }); + getOngoingCall(); } @override @@ -231,6 +262,14 @@ class _ChannelChatScreenState extends State { title: Text(title), centerTitle: false, actions: [ + Builder(builder: (context) { + if (_isBusy) return const SizedBox(); + return ChatCallButton( + realm: _channel!.realm, + channel: _channel!, + ongoingCall: _ongoingCall, + ); + }), IconButton( icon: const Icon(Icons.more_vert), onPressed: () { @@ -265,7 +304,7 @@ class _ChannelChatScreenState extends State { clipBehavior: Clip.none, pagingController: _pagingController, builderDelegate: PagedChildBuilderDelegate( - itemBuilder: chatHistoryBuilder, + itemBuilder: buildHistory, noItemsFoundIndicatorBuilder: (_) => Container(), ), ).paddingOnly(bottom: 64), @@ -295,6 +334,20 @@ class _ChannelChatScreenState extends State { }, ), ), + if (_ongoingCall != null) + MaterialBanner( + padding: const EdgeInsets.only(left: 10, right: 20), + leading: const Icon(Icons.call_received), + backgroundColor: Theme.of(context).colorScheme.surfaceContainer, + dividerColor: const Color.fromARGB(1, 0, 0, 0), + content: Text('callOngoing'.tr), + actions: [ + TextButton( + child: Text('callJoin'.tr), + onPressed: () {}, + ), + ], + ), ], ), ); diff --git a/lib/translations.dart b/lib/translations.dart index 5d6e67e..9816008 100644 --- a/lib/translations.dart +++ b/lib/translations.dart @@ -153,6 +153,8 @@ class SolianMessages extends Translations { 'messageDeletionConfirm': 'Confirm message deletion', 'messageDeletionConfirmCaption': 'Are your sure to delete message @id? This action cannot be undone!', + 'callOngoing': 'A call is ongoing...', + 'callJoin': 'Join', }, 'zh_CN': { 'hide': '隐藏', @@ -294,6 +296,8 @@ class SolianMessages extends Translations { 'messageActionList': '消息的操作', 'messageDeletionConfirm': '确认删除消息', 'messageDeletionConfirmCaption': '你确定要删除消息 @id 吗?该操作不可撤销。', + 'callOngoing': '一则通话正在进行中…', + 'callJoin': '加入', } }; } diff --git a/lib/widgets/chat/call/chat_call_action.dart b/lib/widgets/chat/call/chat_call_action.dart new file mode 100644 index 0000000..591a91f --- /dev/null +++ b/lib/widgets/chat/call/chat_call_action.dart @@ -0,0 +1,96 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:solian/exts.dart'; +import 'package:solian/models/call.dart'; +import 'package:solian/models/channel.dart'; +import 'package:solian/models/realm.dart'; +import 'package:solian/providers/auth.dart'; +import 'package:solian/services.dart'; + +class ChatCallButton extends StatefulWidget { + final Realm? realm; + final Channel channel; + final Call? ongoingCall; + final Function? onStarted; + final Function? onEnded; + + const ChatCallButton({ + super.key, + required this.realm, + required this.channel, + required this.ongoingCall, + this.onStarted, + this.onEnded, + }); + + @override + State createState() => _ChatCallButtonState(); +} + +class _ChatCallButtonState extends State { + bool _isBusy = false; + + Future makeCall() async { + final AuthProvider auth = Get.find(); + if (!await auth.isAuthorized) return; + + final client = GetConnect(maxAuthRetries: 3); + client.httpClient.baseUrl = ServiceFinder.services['messaging']; + client.httpClient.addAuthenticator(auth.requestAuthenticator); + + setState(() => _isBusy = true); + + final scope = (widget.realm?.alias.isNotEmpty ?? false) + ? widget.realm?.alias + : 'global'; + final resp = await client.post( + '/api/channels/$scope/${widget.channel.alias}/calls', + {}, + ); + if (resp.statusCode == 200) { + if (widget.onStarted != null) widget.onStarted!(); + } else { + context.showErrorDialog(resp.bodyString); + } + + setState(() => _isBusy = false); + } + + Future endsCall() async { + final AuthProvider auth = Get.find(); + if (!await auth.isAuthorized) return; + + final client = GetConnect(maxAuthRetries: 3); + client.httpClient.baseUrl = ServiceFinder.services['messaging']; + client.httpClient.addAuthenticator(auth.requestAuthenticator); + + setState(() => _isBusy = true); + + final scope = (widget.realm?.alias.isNotEmpty ?? false) + ? widget.realm?.alias + : 'global'; + final resp = await client + .delete('/api/channels/${scope}/${widget.channel.alias}/calls/ongoing'); + if (resp.statusCode == 200) { + if (widget.onEnded != null) widget.onEnded!(); + } else { + context.showErrorDialog(resp.bodyString); + } + + setState(() => _isBusy = false); + } + + @override + Widget build(BuildContext context) { + return IconButton( + onPressed: _isBusy + ? null + : widget.ongoingCall == null + ? makeCall + : endsCall, + icon: widget.ongoingCall == null + ? const Icon(Icons.call) + : const Icon(Icons.call_end), + ); + } +} diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 3ccd551..9d4f68e 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -8,6 +8,7 @@ #include #include +#include #include void fl_register_plugins(FlPluginRegistry* registry) { @@ -17,6 +18,9 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin"); flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar); + g_autoptr(FlPluginRegistrar) flutter_webrtc_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterWebRTCPlugin"); + flutter_web_r_t_c_plugin_register_with_registrar(flutter_webrtc_registrar); g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 9ce94c4..cbd0fef 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -5,6 +5,7 @@ list(APPEND FLUTTER_PLUGIN_LIST file_selector_linux flutter_secure_storage_linux + flutter_webrtc url_launcher_linux ) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 5523396..ab43fc1 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,9 +5,13 @@ import FlutterMacOS import Foundation +import connectivity_plus +import device_info_plus import file_selector_macos import flutter_local_notifications import flutter_secure_storage_macos +import flutter_webrtc +import livekit_client import package_info_plus import path_provider_foundation import url_launcher_macos @@ -15,9 +19,13 @@ import video_player_avfoundation import wakelock_plus func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) + DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) + FlutterWebRTCPlugin.register(with: registry.registrar(forPlugin: "FlutterWebRTCPlugin")) + LiveKitPlugin.register(with: registry.registrar(forPlugin: "LiveKitPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 006cae7..e3a6bc7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -73,6 +73,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" + connectivity_plus: + dependency: transitive + description: + name: connectivity_plus + sha256: db7a4e143dc72cc3cb2044ef9b052a7ebfe729513e6a82943bc3526f784365b8 + url: "https://pub.dev" + source: hosted + version: "6.0.3" + connectivity_plus_platform_interface: + dependency: transitive + description: + name: connectivity_plus_platform_interface + sha256: b6a56efe1e6675be240de39107281d4034b64ac23438026355b4234042a35adb + url: "https://pub.dev" + source: hosted + version: "2.0.0" cross_file: dependency: transitive description: @@ -89,6 +105,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.3" + cryptography: + dependency: transitive + description: + name: cryptography + sha256: d146b76d33d94548cf035233fbc2f4338c1242fa119013bead807d033fc4ae05 + url: "https://pub.dev" + source: hosted + version: "2.7.0" csslib: dependency: transitive description: @@ -105,6 +129,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.8" + dart_webrtc: + dependency: transitive + description: + name: dart_webrtc + sha256: fe4db21dc389b99e04cb7bf43bc927dba2e42768d4c28211b66a4b5a16e4d516 + url: "https://pub.dev" + source: hosted + version: "1.4.5" dbus: dependency: transitive description: @@ -113,6 +145,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.10" + device_info_plus: + dependency: transitive + description: + name: device_info_plus + sha256: eead12d1a1ed83d8283ab4c2f3fca23ac4082f29f25f29dff0f758f57d06ec91 + url: "https://pub.dev" + source: hosted + version: "10.1.0" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + sha256: d3b01d5868b50ae571cd1dc6e502fc94d956b665756180f7b16ead09e836fd64 + url: "https://pub.dev" + source: hosted + version: "7.0.0" dropdown_button2: dependency: "direct main" description: @@ -137,6 +185,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" + file: + dependency: transitive + description: + name: file + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" file_picker: dependency: "direct main" description: @@ -242,10 +298,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "8cf40eebf5dec866a6d1956ad7b4f7016e6c0cc69847ab946833b7d43743809f" + sha256: c6b0b4c05c458e1c01ad9bcc14041dd7b1f6783d487be4386f793f47a8a4d03e url: "https://pub.dev" source: hosted - version: "2.0.19" + version: "2.0.20" flutter_secure_storage: dependency: "direct main" description: @@ -320,6 +376,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_webrtc: + dependency: "direct main" + description: + name: flutter_webrtc + sha256: "1c61bc08d14be57ac28e9e540c44b8b1b9ab1b25bbdb66a8c658e61a3211cc5d" + url: "https://pub.dev" + source: hosted + version: "0.10.7" font_awesome_flutter: dependency: "direct main" description: @@ -340,10 +404,10 @@ packages: dependency: "direct main" description: name: go_router - sha256: "6ad5662b014c06c20fa46ab78715c96b2222a7fe4f87bf77e0289592c2539e86" + sha256: abec47eb8c8c36ebf41d0a4c64dbbe7f956e39a012b3aafc530e951bdc12fe3f url: "https://pub.dev" source: hosted - version: "14.1.3" + version: "14.1.4" html: dependency: transitive description: @@ -380,18 +444,18 @@ packages: dependency: "direct main" description: name: image_picker - sha256: "33974eca2e87e8b4e3727f1b94fa3abcb25afe80b6bc2c4d449a0e150aedf720" + sha256: "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: "0f57fee1e8bfadf8cc41818bbcd7f72e53bb768a54d9496355d5e8a5681a19f1" + sha256: "4161e1f843d8480d2e9025ee22411778c3c9eb7e40076dcf2da23d8242b7b51c" url: "https://pub.dev" source: hosted - version: "0.8.12+1" + version: "0.8.12+3" image_picker_for_web: dependency: transitive description: @@ -496,6 +560,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.0" + livekit_client: + dependency: "direct main" + description: + name: livekit_client + sha256: "3792c4339db035d0320f1be8e2d99f394e5f3fe4215f95b371ce43db44a9d150" + url: "https://pub.dev" + source: hosted + version: "2.1.5" logging: dependency: transitive description: @@ -552,6 +624,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + nm: + dependency: transitive + description: + name: nm + sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" + url: "https://pub.dev" + source: hosted + version: "0.5.0" oauth2: dependency: "direct main" description: @@ -596,10 +676,10 @@ packages: dependency: transitive description: name: path_provider_android - sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d + sha256: "9c96da072b421e98183f9ea7464898428e764bc0ce5567f27ec8693442e72514" url: "https://pub.dev" source: hosted - version: "2.2.4" + version: "2.2.5" path_provider_foundation: dependency: transitive description: @@ -696,6 +776,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.4" + platform_detect: + dependency: transitive + description: + name: platform_detect + sha256: "08f4ee79c0e1c4858d37e06b22352a3ebdef5466b613749a3adb03e703d4f5b0" + url: "https://pub.dev" + source: hosted + version: "2.0.11" plugin_platform_interface: dependency: transitive description: @@ -704,6 +792,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + protobuf: + dependency: transitive + description: + name: protobuf + sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d" + url: "https://pub.dev" + source: hosted + version: "3.1.0" provider: dependency: transitive description: @@ -712,6 +808,22 @@ packages: url: "https://pub.dev" source: hosted version: "6.1.2" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + sdp_transform: + dependency: transitive + description: + name: sdp_transform + sha256: "73e412a5279a5c2de74001535208e20fff88f225c9a4571af0f7146202755e45" + url: "https://pub.dev" + source: hosted + version: "0.3.2" sky_engine: dependency: transitive description: flutter @@ -765,6 +877,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + synchronized: + dependency: transitive + description: + name: synchronized + sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558" + url: "https://pub.dev" + source: hosted + version: "3.1.0+1" term_glyph: dependency: transitive description: @@ -817,10 +937,10 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "17cd5e205ea615e2c6ea7a77323a11712dffa0720a8a90540db57a01347f9ad9" + sha256: ceb2625f0c24ade6ef6778d1de0b2e44f2db71fded235eb52295247feba8c5cf url: "https://pub.dev" source: hosted - version: "6.3.2" + version: "6.3.3" url_launcher_ios: dependency: transitive description: @@ -897,10 +1017,10 @@ packages: dependency: transitive description: name: video_player_android - sha256: "134e1ad410d67e18a19486ed9512c72dfc6d8ffb284d0e8f2e99e903d1ba8fa3" + sha256: "4f77780499ebbdb3a8387f3de7a9d07a7665cfb3a3741177c44a52353fe41d64" url: "https://pub.dev" source: hosted - version: "2.4.14" + version: "2.4.16" video_player_avfoundation: dependency: transitive description: @@ -921,10 +1041,10 @@ packages: dependency: transitive description: name: video_player_web - sha256: "41245cef5ef29c4585dbabcbcbe9b209e34376642c7576cabf11b4ad9289d6e4" + sha256: ff4d69a6614b03f055397c27a71c9d3ddea2b2a23d71b2ba0164f59ca32b8fe2 url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.3.1" video_player_win: dependency: "direct main" description: @@ -969,10 +1089,10 @@ packages: dependency: transitive description: name: web_socket - sha256: "217f49b5213796cb508d6a942a5dc604ce1cb6a0a6b3d8cb3f0c314f0ecea712" + sha256: "24301d8c293ce6fe327ffe6f59d8fd8834735f0ec36e4fd383ec7ff8a64aa078" url: "https://pub.dev" source: hosted - version: "0.1.4" + version: "0.1.5" web_socket_channel: dependency: "direct main" description: @@ -981,6 +1101,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.0" + webrtc_interface: + dependency: transitive + description: + name: webrtc_interface + sha256: abec3ab7956bd5ac539cf34a42fa0c82ea26675847c0966bb85160400eea9388 + url: "https://pub.dev" + source: hosted + version: "1.2.0" win32: dependency: transitive description: @@ -989,6 +1117,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.5.1" + win32_registry: + dependency: transitive + description: + name: win32_registry + sha256: "10589e0d7f4e053f2c61023a31c9ce01146656a70b7b7f0828c0b46d7da2a9bb" + url: "https://pub.dev" + source: hosted + version: "1.1.3" xdg_directories: dependency: transitive description: @@ -1007,4 +1143,4 @@ packages: version: "6.5.0" sdks: dart: ">=3.4.0 <4.0.0" - flutter: ">=3.19.0" + flutter: ">=3.22.0" diff --git a/pubspec.yaml b/pubspec.yaml index 85edd0b..4676d56 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -60,6 +60,8 @@ dependencies: video_player: ^2.8.6 video_player_win: ^2.3.6 chewie: ^1.8.1 + livekit_client: ^2.1.5 + flutter_webrtc: ^0.10.7 dev_dependencies: flutter_test: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 0953d8d..edf0756 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,17 +6,26 @@ #include "generated_plugin_registrant.h" +#include #include #include +#include +#include #include #include #include void RegisterPlugins(flutter::PluginRegistry* registry) { + ConnectivityPlusWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); FileSelectorWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("FileSelectorWindows")); FlutterSecureStorageWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin")); + FlutterWebRTCPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FlutterWebRTCPlugin")); + LiveKitPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("LiveKitPlugin")); PermissionHandlerWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); UrlLauncherWindowsRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 65857b3..7d8d5a4 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,8 +3,11 @@ # list(APPEND FLUTTER_PLUGIN_LIST + connectivity_plus file_selector_windows flutter_secure_storage_windows + flutter_webrtc + livekit_client permission_handler_windows url_launcher_windows video_player_win