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