From b85c89e805701f71899e9daa29b50acc88af749f Mon Sep 17 00:00:00 2001 From: guozhigq Date: Fri, 28 Apr 2023 17:36:47 +0800 Subject: [PATCH] =?UTF-8?q?mod:=20=E5=9B=BE=E7=89=87=E9=A2=84=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Podfile.lock | 44 ++++ lib/common/widgets/appbar.dart | 33 +++ lib/pages/preview/controller.dart | 77 +++++++ lib/pages/preview/index.dart | 4 + lib/pages/preview/view.dart | 188 +++++++++++++++++ .../detail/reply/widgets/reply_item.dart | 74 +++++-- lib/router/app_pages.dart | 3 + lib/utils/utils.dart | 21 ++ linux/flutter/generated_plugin_registrant.cc | 4 + linux/flutter/generated_plugins.cmake | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 6 + pubspec.lock | 196 +++++++++++++++++- pubspec.yaml | 14 +- .../flutter/generated_plugin_registrant.cc | 9 + windows/flutter/generated_plugins.cmake | 3 + 15 files changed, 658 insertions(+), 19 deletions(-) create mode 100644 lib/common/widgets/appbar.dart create mode 100644 lib/pages/preview/controller.dart create mode 100644 lib/pages/preview/index.dart create mode 100644 lib/pages/preview/view.dart diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e467820a..8576a625 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2,46 +2,90 @@ PODS: - connectivity_plus (0.0.1): - Flutter - ReachabilitySwift + - device_info_plus (0.0.1): + - Flutter - Flutter (1.0.0) + - flutter_inappwebview (0.0.1): + - Flutter + - flutter_inappwebview/Core (= 0.0.1) + - OrderedSet (~> 5.0) + - flutter_inappwebview/Core (0.0.1): + - Flutter + - OrderedSet (~> 5.0) - FMDB (2.7.5): - FMDB/standard (= 2.7.5) - FMDB/standard (2.7.5) + - image_gallery_saver (1.5.0): + - Flutter + - OrderedSet (5.0.0) - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS + - permission_handler_apple (9.0.4): + - Flutter - ReachabilitySwift (5.0.0) + - share_plus (0.0.1): + - Flutter - sqflite (0.0.2): - Flutter - FMDB (>= 2.7.5) + - url_launcher_ios (0.0.1): + - Flutter DEPENDENCIES: - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) + - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - Flutter (from `Flutter`) + - flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`) + - image_gallery_saver (from `.symlinks/plugins/image_gallery_saver/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`) + - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) + - share_plus (from `.symlinks/plugins/share_plus/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) SPEC REPOS: trunk: - FMDB + - OrderedSet - ReachabilitySwift EXTERNAL SOURCES: connectivity_plus: :path: ".symlinks/plugins/connectivity_plus/ios" + device_info_plus: + :path: ".symlinks/plugins/device_info_plus/ios" Flutter: :path: Flutter + flutter_inappwebview: + :path: ".symlinks/plugins/flutter_inappwebview/ios" + image_gallery_saver: + :path: ".symlinks/plugins/image_gallery_saver/ios" path_provider_foundation: :path: ".symlinks/plugins/path_provider_foundation/ios" + permission_handler_apple: + :path: ".symlinks/plugins/permission_handler_apple/ios" + share_plus: + :path: ".symlinks/plugins/share_plus/ios" sqflite: :path: ".symlinks/plugins/sqflite/ios" + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" SPEC CHECKSUMS: connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e + device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721 FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a + image_gallery_saver: 259eab68fb271cfd57d599904f7acdc7832e7ef2 + OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9 + permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 + share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68 sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 + url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4 PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 diff --git a/lib/common/widgets/appbar.dart b/lib/common/widgets/appbar.dart new file mode 100644 index 00000000..ad2b0e3b --- /dev/null +++ b/lib/common/widgets/appbar.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; + +class AppBarWidget extends StatelessWidget implements PreferredSizeWidget { + const AppBarWidget({ + required this.child, + required this.controller, + required this.visible, + Key? key, + }) : super(key: key); + + final PreferredSizeWidget child; + final AnimationController controller; + final bool visible; + + @override + // TODO: implement preferredSize + Size get preferredSize => child.preferredSize; + + @override + Widget build(BuildContext context) { + visible ? controller.reverse() : controller.forward(); + return SlideTransition( + position: Tween( + begin: Offset.zero, + end: const Offset(0, -1), + ).animate(CurvedAnimation( + parent: controller, + curve: Curves.easeInOutBack, + )), + child: child, + ); + } +} diff --git a/lib/pages/preview/controller.dart b/lib/pages/preview/controller.dart new file mode 100644 index 00000000..f2af8b9c --- /dev/null +++ b/lib/pages/preview/controller.dart @@ -0,0 +1,77 @@ +import 'dart:io'; + +import 'package:device_info_plus/device_info_plus.dart'; +import 'package:get/get.dart'; +import 'dart:typed_data'; +import 'package:dio/dio.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:image_gallery_saver/image_gallery_saver.dart'; +import 'package:pilipala/utils/utils.dart'; +import 'package:share_plus/share_plus.dart'; + +class PreviewController extends GetxController { + DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); + RxInt initialPage = 0.obs; + RxInt currentPage = 1.obs; + RxList imgList = [].obs; + bool storage = true; + bool videos = true; + bool photos = true; + bool visiable = true; + + @override + void onInit() { + super.onInit(); + if (Get.arguments != null) { + initialPage.value = Get.arguments['initialPage']!; + currentPage.value = Get.arguments['initialPage']! + 1; + imgList.value = Get.arguments['imgList']; + } + } + + requestPermission() async { + Map statuses = await [ + Permission.storage, + // Permission.photos + ].request(); + + final info = statuses[Permission.storage].toString(); + // final photosInfo = statuses[Permission.photos].toString(); + + print('授权状态:$info'); + } + + // 图片保存 + void onSaveImg() async { + var response = await Dio().get(imgList[initialPage.value], + options: Options(responseType: ResponseType.bytes)); + final result = await ImageGallerySaver.saveImage( + Uint8List.fromList(response.data), + quality: 100, + name: "pic_vvex${DateTime.now().toString().split('-').join()}"); + if (result != null) { + if (result['isSuccess']) { + print('已保存到相册'); + } + } + } + + // 图片分享 + void onShareImg() async { + requestPermission(); + var response = await Dio().get(imgList[initialPage.value], + options: Options(responseType: ResponseType.bytes)); + final temp = await getTemporaryDirectory(); + String imgName = + "pic_vvex${DateTime.now().toString().split('-').join()}.jpg"; + var path = '${temp.path}/$imgName'; + File(path).writeAsBytesSync(response.data); + Share.shareXFiles([XFile(path)], subject: imgList[initialPage.value]); + } + + // 浏览器中查看 + void onBrowserImg() async { + Utils.openURL(imgList[initialPage.value]); + } +} diff --git a/lib/pages/preview/index.dart b/lib/pages/preview/index.dart new file mode 100644 index 00000000..9fb82e8d --- /dev/null +++ b/lib/pages/preview/index.dart @@ -0,0 +1,4 @@ +library preview; + +export './controller.dart'; +export './view.dart'; diff --git a/lib/pages/preview/view.dart b/lib/pages/preview/view.dart new file mode 100644 index 00000000..d82cd45e --- /dev/null +++ b/lib/pages/preview/view.dart @@ -0,0 +1,188 @@ +import 'package:get/get.dart'; +import 'package:flutter/material.dart'; +import 'package:extended_image/extended_image.dart'; +import 'package:pilipala/common/widgets/appbar.dart'; +import 'controller.dart'; + +typedef DoubleClickAnimationListener = void Function(); + +class ImagePreview extends StatefulWidget { + const ImagePreview({Key? key}) : super(key: key); + + @override + _ImagePreviewState createState() => _ImagePreviewState(); +} + +class _ImagePreviewState extends State + with TickerProviderStateMixin { + final PreviewController _previewController = Get.put(PreviewController()); + late AnimationController animationController; + late AnimationController _doubleClickAnimationController; + Animation? _doubleClickAnimation; + late DoubleClickAnimationListener _doubleClickAnimationListener; + List doubleTapScales = [1.0, 2.0]; + + @override + void initState() { + super.initState(); + animationController = AnimationController( + vsync: this, duration: const Duration(milliseconds: 400)); + _doubleClickAnimationController = AnimationController( + duration: const Duration(milliseconds: 250), vsync: this); + } + + @override + void dispose() { + animationController.dispose(); + _doubleClickAnimationController.dispose(); + clearGestureDetailsCache(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + extendBodyBehindAppBar: true, + appBar: AppBarWidget( + controller: animationController, + visible: _previewController.visiable, + child: AppBar( + backgroundColor: Theme.of(context).colorScheme.background, + elevation: 0, + centerTitle: false, + title: Obx( + () => Text.rich( + TextSpan(children: [ + TextSpan(text: _previewController.currentPage.toString()), + const TextSpan(text: ' / '), + TextSpan(text: _previewController.imgList.length.toString()), + ]), + ), + ), + actions: [ + PopupMenuButton( + icon: const Icon(Icons.more_vert), + tooltip: 'action', + itemBuilder: (BuildContext context) => [ + PopupMenuItem( + value: 'share', + onTap: _previewController.onShareImg, + child: const Text('分享'), + ), + PopupMenuItem( + value: 'save', + onTap: _previewController.onSaveImg, + child: const Text('保存'), + ), + PopupMenuItem( + value: 'browser', + onTap: _previewController.onBrowserImg, + child: const Text('浏览器中查看'), + ), + ], + ), + ], + ), + ), + body: GestureDetector( + onTap: () { + _previewController.visiable = !_previewController.visiable; + setState(() {}); + }, + child: ExtendedImageGesturePageView.builder( + controller: ExtendedPageController( + initialPage: _previewController.initialPage.value, + pageSpacing: 0, + ), + onPageChanged: (int index) { + _previewController.initialPage.value = index; + _previewController.currentPage.value = index + 1; + }, + canScrollPage: (GestureDetails? gestureDetails) => + gestureDetails!.totalScale! <= 1.0, + preloadPagesCount: 2, + itemCount: _previewController.imgList.length, + itemBuilder: (BuildContext context, int index) { + return ExtendedImage.network( + _previewController.imgList[index], + fit: BoxFit.contain, + mode: ExtendedImageMode.gesture, + onDoubleTap: (ExtendedImageGestureState state) { + final Offset? pointerDownPosition = state.pointerDownPosition; + final double? begin = state.gestureDetails!.totalScale; + double end; + + //remove old + _doubleClickAnimation + ?.removeListener(_doubleClickAnimationListener); + + //stop pre + _doubleClickAnimationController.stop(); + + //reset to use + _doubleClickAnimationController.reset(); + + if (begin == doubleTapScales[0]) { + end = doubleTapScales[1]; + } else { + end = doubleTapScales[0]; + } + + _doubleClickAnimationListener = () { + state.handleDoubleTap( + scale: _doubleClickAnimation!.value, + doubleTapPosition: pointerDownPosition); + }; + _doubleClickAnimation = _doubleClickAnimationController + .drive(Tween(begin: begin, end: end)); + + _doubleClickAnimation! + .addListener(_doubleClickAnimationListener); + + _doubleClickAnimationController.forward(); + }, + loadStateChanged: (ExtendedImageState state) { + if (state.extendedImageLoadState == LoadState.loading) { + final ImageChunkEvent? loadingProgress = + state.loadingProgress; + final double? progress = + loadingProgress?.expectedTotalBytes != null + ? loadingProgress!.cumulativeBytesLoaded / + loadingProgress.expectedTotalBytes! + : null; + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + width: 150.0, + child: LinearProgressIndicator(value: progress), + ), + const SizedBox(height: 10.0), + Text('${((progress ?? 0.0) * 100).toInt()}%'), + ], + ), + ); + } + }, + initGestureConfigHandler: (ExtendedImageState state) { + return GestureConfig( + inPageView: true, + initialScale: 1.0, + maxScale: 5.0, + animationMaxScale: 6.0, + initialAlignment: InitialAlignment.center, + ); + }, + ); + }, + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: () => _previewController.onSaveImg(), + child: const Icon(Icons.save_alt_rounded), + ), + ); + } +} diff --git a/lib/pages/video/detail/reply/widgets/reply_item.dart b/lib/pages/video/detail/reply/widgets/reply_item.dart index b5b78747..93ca58d1 100644 --- a/lib/pages/video/detail/reply/widgets/reply_item.dart +++ b/lib/pages/video/detail/reply/widgets/reply_item.dart @@ -1,5 +1,6 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; +import 'package:get/get.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart'; import 'package:pilipala/models/video/reply/item.dart'; import 'package:pilipala/utils/utils.dart'; @@ -367,25 +368,66 @@ InlineSpan buildContent(BuildContext context, content) { // 图片渲染 if (content.pictures.isNotEmpty) { - spanChilds.add( - const TextSpan(text: '\n'), - ); - for (var i = 0; i < content.pictures.length; i++) { - spanChilds.add( - WidgetSpan( - child: SizedBox( - height: 180, - child: NetworkImgLayer( - src: content.pictures[i]['img_src'], - width: 200, - height: 200 * - content.pictures[i]['img_height'] / - content.pictures[i]['img_width'], - ), - ), + List list = []; + List picList = []; + int len = content.pictures.length; + for (var i = 0; i < len; i++) { + picList.add(content.pictures[i]['img_src']); + list.add( + LayoutBuilder( + builder: (context, BoxConstraints box) { + return GestureDetector( + onTap: () { + Get.toNamed('/preview', + arguments: {'initialPage': i, 'imgList': picList}); + }, + child: NetworkImgLayer( + src: content.pictures[i]['img_src'], + width: box.maxWidth, + height: box.maxWidth, + ), + ); + }, ), ); } + spanChilds.add( + WidgetSpan( + child: LayoutBuilder( + builder: (context, BoxConstraints box) { + double maxWidth = box.maxWidth; + double crossCount = len < 3 ? 2 : 3; + double height = maxWidth / + crossCount * + (len % crossCount == 0 + ? len ~/ crossCount + : len ~/ crossCount + 1) + + 6; + return Container( + padding: const EdgeInsets.only(top: 6), + height: height, + child: GridView( + padding: EdgeInsets.zero, + physics: const NeverScrollableScrollPhysics(), + // 子Item排列规则 + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + //横轴元素个数 + crossAxisCount: crossCount.toInt(), + //纵轴间距 + mainAxisSpacing: 4.0, + //横轴间距 + crossAxisSpacing: 4.0, + //子组件宽高长度比例 + // childAspectRatio: 1, + ), + //GridView中使用的子Widegt + children: list, + ), + ); + }, + ), + ), + ); } // spanChilds.add(TextSpan(text: matchMember)); return TextSpan(children: spanChilds); diff --git a/lib/router/app_pages.dart b/lib/router/app_pages.dart index 9ec967f8..0a0bd88b 100644 --- a/lib/router/app_pages.dart +++ b/lib/router/app_pages.dart @@ -1,6 +1,7 @@ import 'package:get/get.dart'; import 'package:pilipala/pages/home/index.dart'; import 'package:pilipala/pages/hot/index.dart'; +import 'package:pilipala/pages/preview/index.dart'; import 'package:pilipala/pages/video/detail/index.dart'; class Routes { @@ -11,5 +12,7 @@ class Routes { GetPage(name: '/hot', page: () => const HotPage()), // 视频详情 GetPage(name: '/video', page: () => const VideoDetailPage()), + // 图片预览 + GetPage(name: '/preview', page: () => const ImagePreview()) ]; } diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 084a6e6f..03d30181 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -1,10 +1,13 @@ // 工具函数 import 'dart:io'; import 'dart:math'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:get/get_utils/get_utils.dart'; import 'package:path_provider/path_provider.dart'; class Utils { + final ChromeSafariBrowser browser = ChromeSafariBrowser(); + static Future getCookiePath() async { Directory tempDir = await getApplicationSupportDirectory(); String tempPath = "${tempDir.path}/.plpl/"; @@ -135,4 +138,22 @@ class Utils { static String makeHeroTag(v) { return v.toString() + Random().nextInt(9999).toString(); } + + static openURL(aUrl) async { + try { + await Utils().browser.open( + url: Uri.parse(aUrl), + options: ChromeSafariBrowserClassOptions( + android: AndroidChromeCustomTabsOptions( + shareState: CustomTabsShareState.SHARE_STATE_OFF, + isSingleInstance: false, + isTrustedWebActivity: false, + keepAliveEnabled: true, + ), + ), + ); + } catch (err) { + await InAppBrowser.openWithSystemBrowser(url: Uri.parse(aUrl)); + } + } } diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 675b7194..fe56f8d8 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -7,9 +7,13 @@ #include "generated_plugin_registrant.h" #include +#include void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) dynamic_color_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin"); dynamic_color_plugin_register_with_registrar(dynamic_color_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 3e303c15..18366213 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST dynamic_color + url_launcher_linux ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 65feaf20..bb5265fd 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,13 +6,19 @@ import FlutterMacOS import Foundation import connectivity_plus +import device_info_plus import dynamic_color import path_provider_foundation +import share_plus import sqflite +import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) + DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) + SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 24787131..9f021f27 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -97,6 +97,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.1" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9" + url: "https://pub.dev" + source: hosted + version: "0.3.3+4" crypto: dependency: transitive description: @@ -121,6 +129,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.8" + device_info_plus: + dependency: "direct main" + description: + name: device_info_plus + sha256: f52ab3b76b36ede4d135aab80194df8925b553686f0fa12226b4e2d658e45903 + url: "https://pub.dev" + source: hosted + version: "8.2.2" + 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" dio: dependency: "direct main" description: @@ -153,6 +177,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.6.3" + extended_image: + dependency: "direct main" + description: + name: extended_image + sha256: "75e4b0ad0f8f63eed7935ff2506c809a670f5e6dd0f61304525879d53fc41a17" + url: "https://pub.dev" + source: hosted + version: "7.0.2" + extended_image_library: + dependency: transitive + description: + name: extended_image_library + sha256: "550743b43ab093aed35ef234500fcc7a304cbac1eca47b0cc991e07e88750758" + url: "https://pub.dev" + source: hosted + version: "3.4.2" extended_nested_scroll_view: dependency: "direct main" description: @@ -206,6 +246,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.3.0" + flutter_inappwebview: + dependency: "direct main" + description: + name: flutter_inappwebview + sha256: "1c370ac07de80a579a0047c94c5bb586128d4ef50c0f3f501d6e77010374a319" + url: "https://pub.dev" + source: hosted + version: "5.4.4" flutter_lints: dependency: "direct dev" description: @@ -248,6 +296,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + http_client_helper: + dependency: transitive + description: + name: http_client_helper + sha256: "1f32359bd07a064ad256d1f84ae5f973f69bc972e7287223fa198abe1d969c28" + url: "https://pub.dev" + source: hosted + version: "2.0.3" http_parser: dependency: transitive description: @@ -256,6 +312,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + image_gallery_saver: + dependency: "direct main" + description: + name: image_gallery_saver + sha256: be812580c7a320d3bf583af89cac6b376f170d48000aca75215a73285a3223a0 + url: "https://pub.dev" + source: hosted + version: "1.7.1" js: dependency: transitive description: @@ -296,6 +360,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.8.0" + mime: + dependency: transitive + description: + name: mime + sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + url: "https://pub.dev" + source: hosted + version: "1.0.4" nm: dependency: transitive description: @@ -376,6 +448,46 @@ packages: url: "https://pub.dev" source: hosted version: "1.11.1" + permission_handler: + dependency: "direct main" + description: + name: permission_handler + sha256: "33c6a1253d1f95fd06fa74b65b7ba907ae9811f9d5c1d3150e51417d04b8d6a8" + url: "https://pub.dev" + source: hosted + version: "10.2.0" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + sha256: "8028362b40c4a45298f1cbfccd227c8dd6caf0e27088a69f2ba2ab15464159e2" + url: "https://pub.dev" + source: hosted + version: "10.2.0" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + sha256: ee96ac32f5a8e6f80756e25b25b9f8e535816c8e6665a96b6d70681f8c4f7e85 + url: "https://pub.dev" + source: hosted + version: "9.0.8" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + sha256: "68abbc472002b5e6dfce47fe9898c6b7d8328d58b5d2524f75e277c07a97eb84" + url: "https://pub.dev" + source: hosted + version: "3.9.0" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + sha256: f67cab14b4328574938ecea2db3475dad7af7ead6afab6338772c5f88963e38b + url: "https://pub.dev" + source: hosted + version: "0.1.2" petitparser: dependency: transitive description: @@ -416,6 +528,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.27.7" + share_plus: + dependency: "direct main" + description: + name: share_plus + sha256: b1f15232d41e9701ab2f04181f21610c36c83a12ae426b79b4bd011c567934b1 + url: "https://pub.dev" + source: hosted + version: "6.3.4" + share_plus_platform_interface: + dependency: transitive + description: + name: share_plus_platform_interface + sha256: "0c6e61471bd71b04a138b8b588fa388e66d8b005e6f2deda63371c5c505a0981" + url: "https://pub.dev" + source: hosted + version: "3.2.1" sky_engine: dependency: transitive description: flutter @@ -501,6 +629,70 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + sha256: "75f2846facd11168d007529d6cd8fcb2b750186bea046af9711f10b907e1587e" + url: "https://pub.dev" + source: hosted + version: "6.1.10" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: "22f8db4a72be26e9e3a4aa3f194b1f7afbc76d20ec141f84be1d787db2155cbd" + url: "https://pub.dev" + source: hosted + version: "6.0.31" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2" + url: "https://pub.dev" + source: hosted + version: "6.1.4" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: "207f4ddda99b95b4d4868320a352d374b0b7e05eefad95a4a26f57da413443f5" + url: "https://pub.dev" + source: hosted + version: "3.0.5" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: "91ee3e75ea9dadf38036200c5d3743518f4a5eb77a8d13fda1ee5764373f185e" + url: "https://pub.dev" + source: hosted + version: "3.0.5" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "6c9ca697a5ae218ce56cece69d46128169a58aa8653c1b01d26fcd4aad8c4370" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: "81fe91b6c4f84f222d186a9d23c73157dc4c8e1c71489c4d08be1ad3b228f1aa" + url: "https://pub.dev" + source: hosted + version: "2.0.16" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "254708f17f7c20a9c8c471f67d86d76d4a3f9c1591aad1e15292008aceb82771" + url: "https://pub.dev" + source: hosted + version: "3.0.6" uuid: dependency: transitive description: @@ -529,10 +721,10 @@ packages: dependency: transitive description: name: win32 - sha256: dd8f9344bc305ae2923e3d11a2a911d9a4e2c7dd6fe0ed10626d63211a69676e + sha256: a6f0236dbda0f63aa9a25ad1ff9a9d8a4eaaa5012da0dc59d21afdb1dc361ca4 url: "https://pub.dev" source: hosted - version: "4.1.3" + version: "3.1.4" xdg_directories: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 45b193f6..efadde4b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -48,10 +48,22 @@ dependencies: # 图片 cached_network_image: ^3.2.3 - + extended_image: ^7.0.2 + image_gallery_saver: ^1.7.1 + # 存储 path_provider: ^2.0.14 + # 设备信息 + device_info_plus: ^8.2.0 + # 权限 + permission_handler: ^10.2.0 + # 分享 + share_plus: ^6.3.1 + # webView + url_launcher: ^6.1.9 + flutter_inappwebview: 5.4.4 + extended_nested_scroll_view: ^6.0.0 dev_dependencies: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index ae0cf3ff..efd465a4 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -8,10 +8,19 @@ #include #include +#include +#include +#include void RegisterPlugins(flutter::PluginRegistry* registry) { ConnectivityPlusWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); DynamicColorPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("DynamicColorPluginCApi")); + PermissionHandlerWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); + SharePlusWindowsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); + UrlLauncherWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("UrlLauncherWindows")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index e47678f2..afce192f 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -5,6 +5,9 @@ list(APPEND FLUTTER_PLUGIN_LIST connectivity_plus dynamic_color + permission_handler_windows + share_plus + url_launcher_windows ) list(APPEND FLUTTER_FFI_PLUGIN_LIST