From 4a9ccc7c7a5618268bc964ea47665ada2b90b373 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sun, 8 Dec 2024 00:25:53 +0800 Subject: [PATCH] :sparkles: Save attachment to album --- android/app/src/main/AndroidManifest.xml | 4 +- assets/translations/en.json | 4 +- assets/translations/zh.json | 5 +- ios/Podfile.lock | 19 +- ios/Runner/Info.plist | 2 + lib/widgets/attachment/attachment_zoom.dart | 445 ++++++++++-------- lib/widgets/post/post_item.dart | 2 - macos/Flutter/GeneratedPluginRegistrant.swift | 2 + macos/Runner/Info.plist | 2 + pubspec.lock | 68 +-- pubspec.yaml | 1 + .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + 13 files changed, 332 insertions(+), 226 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 361f833..c7010c3 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -9,11 +9,13 @@ + + android:icon="@mipmap/ic_launcher" + android:requestLegacyExternalStorage="true"> 11.4.0) - - firebase_analytics (11.3.5): + - firebase_analytics (11.3.6): - Firebase/Analytics (= 11.4.0) - firebase_core - Flutter - - firebase_core (3.8.0): + - firebase_core (3.8.1): - Firebase/CoreOnly (= 11.4.0) - Flutter - - firebase_messaging (15.1.5): + - firebase_messaging (15.1.6): - Firebase/Messaging (= 11.4.0) - firebase_core - Flutter @@ -110,6 +110,9 @@ PODS: - flutter_webrtc (0.12.2): - Flutter - WebRTC-SDK (= 125.6422.06) + - gal (1.0.0): + - Flutter + - FlutterMacOS - GoogleAppMeasurement (11.4.0): - GoogleAppMeasurement/AdIdSupport (= 11.4.0) - GoogleUtilities/AppDelegateSwizzler (~> 8.0) @@ -225,6 +228,7 @@ DEPENDENCIES: - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) - flutter_udid (from `.symlinks/plugins/flutter_udid/ios`) - flutter_webrtc (from `.symlinks/plugins/flutter_webrtc/ios`) + - gal (from `.symlinks/plugins/gal/darwin`) - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) - livekit_client (from `.symlinks/plugins/livekit_client/ios`) - media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`) @@ -288,6 +292,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/flutter_udid/ios" flutter_webrtc: :path: ".symlinks/plugins/flutter_webrtc/ios" + gal: + :path: ".symlinks/plugins/gal/darwin" image_picker_ios: :path: ".symlinks/plugins/image_picker_ios/ios" livekit_client: @@ -330,9 +336,9 @@ SPEC CHECKSUMS: DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655 Firebase: cf1b19f21410b029b6786a54e9764a0cacad3c99 - firebase_analytics: fa7e5b20c2b58042e3301f5112a473d365bd490c - firebase_core: 9efc3ecf689cdbc90f13f4dc58108c83ea46b266 - firebase_messaging: 6bf60adb4b33a848d135e16bc363fb4924f98fba + firebase_analytics: 2815af29d49c1a994652abd37a5b001a88bc7b75 + firebase_core: 418aed674e9a0b8b6088aec16cde82a811f6261f + firebase_messaging: 98619a0572d82cfb3668e78859ba9f1110e268c9 FirebaseAnalytics: 3feef9ae8733c567866342a1000691baaa7cad49 FirebaseCore: e0510f1523bc0eb21653cac00792e1e2bd6f1771 FirebaseCoreInternal: f47dd28ae7782e6a4738aad3106071a8fe0af604 @@ -342,6 +348,7 @@ SPEC CHECKSUMS: flutter_native_splash: e8a1e01082d97a8099d973f919f57904c925008a flutter_udid: a2482c67a61b9c806ef59dd82ed8d007f1b7ac04 flutter_webrtc: 1a53bd24f97bcfeff512f13699e721897f261563 + gal: 61e868295d28fe67ffa297fae6dacebf56fd53e1 GoogleAppMeasurement: 987769c4ca6b968f2479fbcc9fe3ce34af454b8e GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 3b03791..c860a2d 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -39,6 +39,8 @@ Grant access to Photo Library will allow Solian record audio for your post. NSPhotoLibraryUsageDescription Grant access to Photo Library will allow Solian upload photo or video for your post. + NSPhotoLibraryAddUsageDescription + Grant access to Photo Library will allow Solian download photo to album for you. UIApplicationSupportsIndirectInputEvents UIBackgroundModes diff --git a/lib/widgets/attachment/attachment_zoom.dart b/lib/widgets/attachment/attachment_zoom.dart index 7fe3bfa..a2670c2 100644 --- a/lib/widgets/attachment/attachment_zoom.dart +++ b/lib/widgets/attachment/attachment_zoom.dart @@ -1,8 +1,15 @@ +import 'dart:io'; + +import 'package:dio/dio.dart'; import 'package:dismissible_page/dismissible_page.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:gal/gal.dart'; import 'package:gap/gap.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:material_symbols_icons/symbols.dart'; +import 'package:path/path.dart' show extension; import 'package:photo_view/photo_view.dart'; import 'package:photo_view/photo_view_gallery.dart'; import 'package:provider/provider.dart'; @@ -11,13 +18,16 @@ import 'package:surface/providers/sn_network.dart'; import 'package:surface/providers/user_directory.dart'; import 'package:surface/types/attachment.dart'; import 'package:surface/widgets/account/account_image.dart'; +import 'package:surface/widgets/dialog.dart'; import 'package:surface/widgets/universal_image.dart'; +import 'package:url_launcher/url_launcher_string.dart'; import 'package:uuid/uuid.dart'; class AttachmentZoomView extends StatefulWidget { final Iterable data; final int? initialIndex; final List? heroTags; + const AttachmentZoomView({ super.key, required this.data, @@ -30,11 +40,68 @@ class AttachmentZoomView extends StatefulWidget { } class _AttachmentZoomViewState extends State { - late final PageController _pageController = - PageController(initialPage: widget.initialIndex ?? 0); + late final PageController _pageController = PageController(initialPage: widget.initialIndex ?? 0); void _updatePage() { - setState(() {}); + setState(() { + if (_isCompletedDownload) { + setState(() => _isCompletedDownload = false); + } + }); + } + + bool _isDownloading = false; + bool _isCompletedDownload = false; + double? _progressOfDownload = 0; + + Future _saveToAlbum(int idx) async { + final sn = context.read(); + final item = widget.data.elementAt(idx); + final url = sn.getAttachmentUrl(item.rid); + + if (kIsWeb || Platform.isLinux) { + await launchUrlString(url); + return; + } + + if (!await Gal.hasAccess(toAlbum: true)) { + if (!await Gal.requestAccess(toAlbum: true)) return; + } + + setState(() => _isDownloading = true); + + var extName = extension(item.name); + if (extName.isEmpty) extName = '.png'; + final imagePath = '${Directory.systemTemp.path}/${item.uuid}$extName'; + await Dio().download( + url, + imagePath, + onReceiveProgress: (count, total) { + setState(() => _progressOfDownload = count / total); + }, + ); + + bool isSuccess = false; + try { + await Gal.putImage(imagePath, album: 'Solar Network'); + setState(() { + isSuccess = true; + _isDownloading = false; + _isCompletedDownload = isSuccess; + }); + } catch (e) { + if (!mounted) return; + context.showErrorDialog(e); + } + + if (!mounted) return; + context.showSnackbar( + 'attachmentSaved'.tr(), + action: SnackBarAction( + label: 'openInAlbum'.tr(), + onPressed: () async => Gal.open(), + ), + ); } @override @@ -51,8 +118,7 @@ class _AttachmentZoomViewState extends State { super.dispose(); } - Color get _unFocusColor => - Theme.of(context).colorScheme.onSurface.withOpacity(0.75); + Color get _unFocusColor => Theme.of(context).colorScheme.onSurface.withOpacity(0.75); @override Widget build(BuildContext context) { @@ -72,207 +138,218 @@ class _AttachmentZoomViewState extends State { direction: DismissiblePageDismissDirection.down, backgroundColor: Colors.transparent, isFullScreen: true, - child: Stack( - children: [ - Builder(builder: (context) { - if (widget.data.length == 1) { - final heroTag = widget.heroTags?.first ?? uuid.v4(); - return Hero( - tag: 'attachment-${widget.data.first.rid}-$heroTag', - child: PhotoView( - key: Key( - 'attachment-detail-${widget.data.first.rid}-$heroTag'), - backgroundDecoration: - BoxDecoration(color: Colors.transparent), - imageProvider: UniversalImage.provider( - sn.getAttachmentUrl(widget.data.first.rid), - ), - ), - ); - } - - return PhotoViewGallery.builder( - pageController: _pageController, - scrollPhysics: const BouncingScrollPhysics(), - builder: (context, idx) { - final heroTag = widget.heroTags?.elementAt(idx) ?? uuid.v4(); - return PhotoViewGalleryPageOptions( - imageProvider: UniversalImage.provider( - sn.getAttachmentUrl(widget.data.elementAt(idx).rid), - ), - heroAttributes: PhotoViewHeroAttributes( - tag: 'attachment-${widget.data.first.rid}-$heroTag', + child: Scaffold( + body: Stack( + children: [ + Builder(builder: (context) { + if (widget.data.length == 1) { + final heroTag = widget.heroTags?.first ?? uuid.v4(); + return Hero( + tag: 'attachment-${widget.data.first.rid}-$heroTag', + child: PhotoView( + key: Key('attachment-detail-${widget.data.first.rid}-$heroTag'), + backgroundDecoration: BoxDecoration(color: Colors.transparent), + imageProvider: UniversalImage.provider( + sn.getAttachmentUrl(widget.data.first.rid), + ), ), ); - }, - itemCount: widget.data.length, - loadingBuilder: (context, event) => Center( - child: SizedBox( - width: 20.0, - height: 20.0, - child: CircularProgressIndicator( - value: event == null - ? 0 - : event.cumulativeBytesLoaded / - (event.expectedTotalBytes ?? 1), + } + + return PhotoViewGallery.builder( + pageController: _pageController, + scrollPhysics: const BouncingScrollPhysics(), + builder: (context, idx) { + final heroTag = widget.heroTags?.elementAt(idx) ?? uuid.v4(); + return PhotoViewGalleryPageOptions( + imageProvider: UniversalImage.provider( + sn.getAttachmentUrl(widget.data.elementAt(idx).rid), + ), + heroAttributes: PhotoViewHeroAttributes( + tag: 'attachment-${widget.data.first.rid}-$heroTag', + ), + ); + }, + itemCount: widget.data.length, + loadingBuilder: (context, event) => Center( + child: SizedBox( + width: 20.0, + height: 20.0, + child: CircularProgressIndicator( + value: event == null ? 0 : event.cumulativeBytesLoaded / (event.expectedTotalBytes ?? 1), + ), ), ), - ), - backgroundDecoration: BoxDecoration(color: Colors.transparent), - ); - }), - Align( - alignment: Alignment.bottomCenter, - child: IgnorePointer( - child: Container( - height: 300, - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.bottomCenter, - end: Alignment.topCenter, - colors: [ - Theme.of(context).colorScheme.surface, - Colors.transparent, - ], + backgroundDecoration: BoxDecoration(color: Colors.transparent), + ); + }), + Align( + alignment: Alignment.bottomCenter, + child: IgnorePointer( + child: Container( + height: 300, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.bottomCenter, + end: Alignment.topCenter, + colors: [ + Theme.of(context).colorScheme.surface, + Colors.transparent, + ], + ), ), ), ), ), - ), - Positioned( - left: 16, - right: 16, - bottom: 16 + MediaQuery.of(context).padding.bottom, - child: Material( - color: Colors.transparent, - child: Builder(builder: (context) { - final ud = context.read(); - final item = widget.data.elementAt( - widget.data.length > 1 - ? _pageController.page?.round() ?? 0 - : 0, - ); - final account = ud.getAccountFromCache(item.accountId); + Positioned( + left: 16, + right: 16, + bottom: 16 + MediaQuery.of(context).padding.bottom, + child: Material( + color: Colors.transparent, + child: Builder(builder: (context) { + final ud = context.read(); + final item = widget.data.elementAt( + widget.data.length > 1 ? _pageController.page?.round() ?? 0 : 0, + ); + final account = ud.getAccountFromCache(item.accountId); - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (item.accountId > 0) - Row( - children: [ - IgnorePointer( - child: AccountImage( - content: account!.avatar, - radius: 19, - ), - ), - const Gap(8), - Expanded( - child: IgnorePointer( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'attachmentUploadBy'.tr(), - style: - Theme.of(context).textTheme.bodySmall, - ), - Text( - account.nick, - style: - Theme.of(context).textTheme.bodyMedium, - ), - ], + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (item.accountId > 0) + Row( + children: [ + IgnorePointer( + child: AccountImage( + content: account!.avatar, + radius: 19, ), ), - ), - if (widget.data.length > 1) - IgnorePointer( - child: Text( - '${(_pageController.page?.round() ?? 0) + 1}/${widget.data.length}', - style: GoogleFonts.robotoMono(fontSize: 13), - ).padding(right: 8), + const Gap(8), + Expanded( + child: IgnorePointer( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'attachmentUploadBy'.tr(), + style: Theme.of(context).textTheme.bodySmall, + ), + Text( + account.nick, + style: Theme.of(context).textTheme.bodyMedium, + ), + ], + ), + ), ), - ], - ), - const Gap(4), - IgnorePointer( - child: Text( - item.alt, - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: const TextStyle( - fontSize: 15, - fontWeight: FontWeight.w500, + if (widget.data.length > 1) + IgnorePointer( + child: Text( + '${(_pageController.page?.round() ?? 0) + 1}/${widget.data.length}', + style: GoogleFonts.robotoMono(fontSize: 13), + ).padding(right: 8), + ), + InkWell( + onTap: _isDownloading + ? null + : () => _saveToAlbum(widget.data.length > 1 ? _pageController.page?.round() ?? 0 : 0), + child: Container( + padding: const EdgeInsets.all(6), + child: !_isDownloading + ? !_isCompletedDownload + ? const Icon(Symbols.save_alt) + : const Icon(Symbols.download_done) + : SizedBox( + width: 24, + height: 24, + child: CircularProgressIndicator( + value: _progressOfDownload, + strokeWidth: 3, + ), + ), + ), + ), + ], + ), + const Gap(4), + IgnorePointer( + child: Text( + item.alt, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontSize: 15, + fontWeight: FontWeight.w500, + ), ), ), - ), - const Gap(2), - IgnorePointer( - child: Wrap( - spacing: 6, - children: [ - if (item.metadata['exif'] == null) + const Gap(2), + IgnorePointer( + child: Wrap( + spacing: 6, + children: [ + if (item.metadata['exif'] == null) + Text( + '#${item.rid}', + style: metaTextStyle, + ), + if (item.metadata['exif']?['Model'] != null) + Text( + 'attachmentShotOn'.tr(args: [ + item.metadata['exif']?['Model'], + ]), + style: metaTextStyle, + ).padding(right: 2), + if (item.metadata['exif']?['ShutterSpeed'] != null) + Text( + item.metadata['exif']?['ShutterSpeed'], + style: metaTextStyle, + ).padding(right: 2), + if (item.metadata['exif']?['ISO'] != null) + Text( + 'ISO${item.metadata['exif']?['ISO']}', + style: metaTextStyle, + ).padding(right: 2), + if (item.metadata['exif']?['Aperture'] != null) + Text( + 'f/${item.metadata['exif']?['Aperture']}', + style: metaTextStyle, + ).padding(right: 2), + if (item.metadata['exif']?['Megapixels'] != null && item.metadata['exif']?['Model'] != null) + Text( + '${item.metadata['exif']?['Megapixels']}MP', + style: metaTextStyle, + ) + else + Text( + '${item.size} Bytes', + style: metaTextStyle, + ), Text( - '#${item.rid}', + '${item.metadata['width']}x${item.metadata['height']}', style: metaTextStyle, ), - if (item.metadata['exif']?['Model'] != null) + if (item.metadata['ratio'] != null) + Text( + (item.metadata['ratio'] as num).toStringAsFixed(2), + style: metaTextStyle, + ), Text( - 'attachmentShotOn'.tr(args: [ - item.metadata['exif']?['Model'], - ]), - style: metaTextStyle, - ).padding(right: 2), - if (item.metadata['exif']?['ShutterSpeed'] != null) - Text( - item.metadata['exif']?['ShutterSpeed'], - style: metaTextStyle, - ).padding(right: 2), - if (item.metadata['exif']?['ISO'] != null) - Text( - 'ISO${item.metadata['exif']?['ISO']}', - style: metaTextStyle, - ).padding(right: 2), - if (item.metadata['exif']?['Aperture'] != null) - Text( - 'f/${item.metadata['exif']?['Aperture']}', - style: metaTextStyle, - ).padding(right: 2), - if (item.metadata['exif']?['Megapixels'] != null && - item.metadata['exif']?['Model'] != null) - Text( - '${item.metadata['exif']?['Megapixels']}MP', - style: metaTextStyle, - ) - else - Text( - '${item.size} Bytes', + item.mimetype, style: metaTextStyle, ), - Text( - '${item.metadata['width']}x${item.metadata['height']}', - style: metaTextStyle, - ), - if (item.metadata['ratio'] != null) - Text( - (item.metadata['ratio'] as num) - .toStringAsFixed(2), - style: metaTextStyle, - ), - Text( - item.mimetype, - style: metaTextStyle, - ), - ], + ], + ), ), - ), - ], - ); - }), + ], + ); + }), + ), ), - ), - ], + ], + ), ), ); } diff --git a/lib/widgets/post/post_item.dart b/lib/widgets/post/post_item.dart index bd7d116..9615896 100644 --- a/lib/widgets/post/post_item.dart +++ b/lib/widgets/post/post_item.dart @@ -311,8 +311,6 @@ class _PostHeadline extends StatelessWidget { Widget build(BuildContext context) { if (isEnlarge) { final sn = context.read(); - final textScaler = TextScaler.linear(1.5); - return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index ef449b6..3916e41 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -14,6 +14,7 @@ import firebase_core import firebase_messaging import flutter_udid import flutter_webrtc +import gal import livekit_client import media_kit_libs_macos_video import media_kit_video @@ -37,6 +38,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) FlutterUdidPlugin.register(with: registry.registrar(forPlugin: "FlutterUdidPlugin")) FlutterWebRTCPlugin.register(with: registry.registrar(forPlugin: "FlutterWebRTCPlugin")) + GalPlugin.register(with: registry.registrar(forPlugin: "GalPlugin")) LiveKitPlugin.register(with: registry.registrar(forPlugin: "LiveKitPlugin")) MediaKitLibsMacosVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitLibsMacosVideoPlugin")) MediaKitVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitVideoPlugin")) diff --git a/macos/Runner/Info.plist b/macos/Runner/Info.plist index 8e80858..a3a6092 100644 --- a/macos/Runner/Info.plist +++ b/macos/Runner/Info.plist @@ -36,5 +36,7 @@ Grant access to Photo Library will allow Solian record audio for your post. NSPhotoLibraryUsageDescription Grant access to Photo Library will allow Solian upload photo or video for your post. + NSPhotoLibraryAddUsageDescription + Grant access to Photo Library will allow Solian download photo to album for you. diff --git a/pubspec.lock b/pubspec.lock index e1acca2..921d8ec 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "71c01c1998c40b3af1944ad0a5f374b4e6fef7f3d2df487f3970dbeadaeb25a1" + sha256: eae3133cbb06de9205899b822e3897fc6a8bc278ad4c944b4ce612689369694b url: "https://pub.dev" source: hosted - version: "1.3.46" + version: "1.3.47" _macros: dependency: transitive description: dart @@ -530,74 +530,74 @@ packages: dependency: "direct main" description: name: firebase_analytics - sha256: "8be7c45091f01cc15130edf8201ed4f4b7b022a38424ed9aac6b9a6d7c45bb09" + sha256: "366140abb55418ea23060b779893fa997c2d8e1974a4d1cc4d9590933b65c5fd" url: "https://pub.dev" source: hosted - version: "11.3.5" + version: "11.3.6" firebase_analytics_platform_interface: dependency: transitive description: name: firebase_analytics_platform_interface - sha256: "111e288dd332ce13e1ec96b54f5dca0601fe6e75bc251f74fd6f70096f3fbf09" + sha256: "8e987cf977c0c8f4ad02d9950a9b25b1a9606899f37b66a322a43af05be0246b" url: "https://pub.dev" source: hosted - version: "4.2.7" + version: "4.2.8" firebase_analytics_web: dependency: transitive description: name: firebase_analytics_web - sha256: "7c3c80b4e223565ddbda3eaacc42712ba6de53410f8ae18738c807aa8af6b910" + sha256: "0b64ef9060d394bba3d3b4777f49ee098efeeea7b0afb04663c956de6a3da170" url: "https://pub.dev" source: hosted - version: "0.5.10+4" + version: "0.5.10+5" firebase_core: dependency: "direct main" description: name: firebase_core - sha256: "2438a75ad803e818ad3bd5df49137ee619c46b6fc7101f4dbc23da07305ce553" + sha256: fef81a53ba1ca618def1f8bef4361df07968434e62cb204c1fb90bb880a03da2 url: "https://pub.dev" source: hosted - version: "3.8.0" + version: "3.8.1" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface - sha256: e30da58198a6d4b49d5bce4e852f985c32cb10db329ebef9473db2b9f09ce810 + sha256: b94b217e3ad745e784960603d33d99471621ecca151c99c670869b76e50ad2a6 url: "https://pub.dev" source: hosted - version: "5.3.0" + version: "5.3.1" firebase_core_web: dependency: transitive description: name: firebase_core_web - sha256: f967a7138f5d2ffb1ce15950e2a382924239eaa521150a8f144af34e68b3b3e5 + sha256: "9e69806bb3d905aeec3c1242e0e1475de6ea6d48f456af29d598fb229a2b4e5e" url: "https://pub.dev" source: hosted - version: "2.18.1" + version: "2.18.2" firebase_messaging: dependency: "direct main" description: name: firebase_messaging - sha256: "4d0968ecb860d7baa15a6e2af3469ec5b0d959e51c59ce84a52b0f7632a4aa5a" + sha256: "151a3ee68736abf293aab66d1317ade53c88abe1db09c75a0460aebf7767bbdf" url: "https://pub.dev" source: hosted - version: "15.1.5" + version: "15.1.6" firebase_messaging_platform_interface: dependency: transitive description: name: firebase_messaging_platform_interface - sha256: a2cb3e7d71d40b6612e2d4e0daa0ae759f6a9d07f693f904d14d22aadf70be10 + sha256: f331ee51e40c243f90cc7bc059222dfec4e5df53125b08d31fb28961b00d2a9d url: "https://pub.dev" source: hosted - version: "4.5.48" + version: "4.5.49" firebase_messaging_web: dependency: transitive description: name: firebase_messaging_web - sha256: "1554e190f0cd9d6fe59f61ae0275ac12006fdb78b07669f1a260d1a9e6de3a1f" + sha256: efaf3fdc54cd77e0eedb8e75f7f01c808828c64d052ddbf94d3009974e47d30f url: "https://pub.dev" source: hosted - version: "3.9.4" + version: "3.9.5" fixnum: dependency: transitive description: @@ -647,10 +647,10 @@ packages: dependency: "direct dev" description: name: flutter_launcher_icons - sha256: "619817c4b65b322b5104b6bb6dfe6cda62d9729bd7ad4303ecc8b4e690a67a77" + sha256: "31cd0885738e87c72d6f055564d37fabcdacee743b396b78c7636c169cac64f5" url: "https://pub.dev" source: hosted - version: "0.14.1" + version: "0.14.2" flutter_lints: dependency: "direct dev" description: @@ -754,6 +754,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.0" + gal: + dependency: "direct main" + description: + name: gal + sha256: "54c9b72528efce7c66234f3b6dd01cb0304fd8af8196de15571d7bdddb940977" + url: "https://pub.dev" + source: hosted + version: "2.3.0" gap: dependency: "direct main" description: @@ -1078,10 +1086,10 @@ packages: dependency: "direct main" description: name: material_symbols_icons - sha256: a783133f87c58e10b1cc19797f7c3192ff9c2bab301c4ade90312d8f2aed01b2 + sha256: "64404f47f8e0a9d20478468e5decef867a688660bad7173adcd20418d7f892c9" url: "https://pub.dev" source: hosted - version: "4.2800.2" + version: "4.2801.0" media_kit: dependency: "direct main" description: @@ -1262,10 +1270,10 @@ packages: dependency: transitive description: name: path_provider_foundation - sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 + sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.1" path_provider_linux: dependency: transitive description: @@ -1827,10 +1835,10 @@ packages: dependency: transitive description: name: url_launcher_ios - sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e + sha256: "16a513b6c12bb419304e72ea0ae2ab4fed569920d1c7cb850263fe3acc824626" url: "https://pub.dev" source: hosted - version: "6.3.1" + version: "6.3.2" url_launcher_linux: dependency: transitive description: @@ -1843,10 +1851,10 @@ packages: dependency: transitive description: name: url_launcher_macos - sha256: "769549c999acdb42b8bcfa7c43d72bf79a382ca7441ab18a808e101149daf672" + sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2" url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "3.2.2" url_launcher_platform_interface: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 4ee5c61..2aa092d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -95,6 +95,7 @@ dependencies: popover: ^0.3.1 sliver_tools: ^0.2.12 bitsdojo_window: ^0.1.6 + gal: ^2.3.0 dev_dependencies: flutter_test: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 28a74a5..9495a88 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("FlutterUdidPluginCApi")); FlutterWebRTCPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("FlutterWebRTCPlugin")); + GalPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("GalPluginCApi")); LiveKitPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("LiveKitPlugin")); MediaKitLibsWindowsVideoPluginCApiRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index fee9a31..e8a8b84 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -9,6 +9,7 @@ list(APPEND FLUTTER_PLUGIN_LIST firebase_core flutter_udid flutter_webrtc + gal livekit_client media_kit_libs_windows_video media_kit_video