From 1abc65f8fae53197a6598d001a83ba315820aada Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Mon, 14 Oct 2024 20:51:56 +0800 Subject: [PATCH] :wheelchair: Share post as image on web --- assets/locales/en_us.json | 3 +- assets/locales/zh_cn.json | 3 +- lib/widgets/attachments/attachment_list.dart | 1 + lib/widgets/posts/post_action.dart | 28 +++--- lib/widgets/posts/post_list.dart | 90 +++++++++++--------- macos/Podfile.lock | 6 ++ pubspec.yaml | 2 +- web/index.html | 5 +- 8 files changed, 76 insertions(+), 62 deletions(-) diff --git a/assets/locales/en_us.json b/assets/locales/en_us.json index 3735921..e827f65 100644 --- a/assets/locales/en_us.json +++ b/assets/locales/en_us.json @@ -484,5 +484,6 @@ "authMaximumAuthStepsDesc": "The maximum number of authentication steps when logging in, higher value is more secure, lower value is more convenient; default is 2", "auditLog": "Audit log", "shareImage": "Share as image", - "shareImageFooter": "Only on the Solar Network" + "shareImageFooter": "Only on the Solar Network", + "fileSavedAt": "File saved at @path" } diff --git a/assets/locales/zh_cn.json b/assets/locales/zh_cn.json index 5083ef5..63ef445 100644 --- a/assets/locales/zh_cn.json +++ b/assets/locales/zh_cn.json @@ -480,5 +480,6 @@ "authMaximumAuthStepsDesc": "登陆时最多的验证步数,值越高则越安全,反之则会相对方便;默认设置为 2", "auditLog": "活动日志", "shareImage": "分享图片", - "shareImageFooter": "上 Solar Network 看更多有趣帖子" + "shareImageFooter": "上 Solar Network 看更多有趣帖子", + "fileSavedAt": "文件保存于 @path" } diff --git a/lib/widgets/attachments/attachment_list.dart b/lib/widgets/attachments/attachment_list.dart index b0e1da6..dedc16c 100644 --- a/lib/widgets/attachments/attachment_list.dart +++ b/lib/widgets/attachments/attachment_list.dart @@ -49,6 +49,7 @@ class _AttachmentListState extends State { bool _isLoading = true; bool _showMature = false; + // ignore: unused_field double _aspectRatio = 1; List _attachments = List.empty(); diff --git a/lib/widgets/posts/post_action.dart b/lib/widgets/posts/post_action.dart index 473bde9..e6eb651 100644 --- a/lib/widgets/posts/post_action.dart +++ b/lib/widgets/posts/post_action.dart @@ -1,4 +1,3 @@ -import 'dart:io'; import 'dart:math'; import 'package:file_saver/file_saver.dart'; @@ -7,9 +6,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_animate/flutter_animate.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:get/get.dart'; -import 'package:intl/intl.dart'; -import 'package:path/path.dart' as path; -import 'package:path_provider/path_provider.dart'; import 'package:screenshot/screenshot.dart'; import 'package:share_plus/share_plus.dart'; import 'package:solian/exts.dart'; @@ -113,16 +109,17 @@ class _PostActionState extends State { maxHeight: double.infinity, ), ); - final directory = await getApplicationDocumentsDirectory(); - final imageFile = await File( - '${directory.path}/share_image_${DateFormat('yyyy-MM-dd-HH-mm-ss').format(DateTime.now())}.png', - ).create(); - await imageFile.writeAsBytes(image); + + final filename = 'share_post#${widget.item.id}'; if (PlatformInfo.isAndroid || PlatformInfo.isIOS) { final box = context.findRenderObject() as RenderBox?; - final file = XFile(imageFile.path); + final file = XFile.fromData( + image, + mimeType: 'image/png', + name: filename, + ); await Share.shareXFiles( [file], subject: 'postShareSubject'.trParams({ @@ -132,15 +129,14 @@ class _PostActionState extends State { sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size, ); } else { - await FileSaver.instance.saveAs( - name: path.basename(imageFile.path), - ext: path.extension(imageFile.path), + final filepath = await FileSaver.instance.saveFile( + name: filename, + ext: 'png', mimeType: MimeType.png, - file: imageFile, + bytes: image, ); + context.showSnackbar('fileSavedAt'.trParams({'path': filepath})); } - - await imageFile.delete(); } @override diff --git a/lib/widgets/posts/post_list.dart b/lib/widgets/posts/post_list.dart index e8d716c..f5349af 100644 --- a/lib/widgets/posts/post_list.dart +++ b/lib/widgets/posts/post_list.dart @@ -1,3 +1,4 @@ +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; @@ -73,50 +74,59 @@ class PostListEntryWidget extends StatelessWidget { required this.onUpdate, }); + void _openActions(BuildContext context) { + final AuthProvider auth = Get.find(); + if (auth.isAuthorized.isFalse) return; + + showModalBottomSheet( + useRootNavigator: true, + context: context, + builder: (context) => PostAction(item: item), + ).then((value) { + if (value is Future) { + value.then((_) { + onUpdate(); + }); + } else if (value != null) { + onUpdate(); + } + }); + } + @override Widget build(BuildContext context) { - return GestureDetector( - child: PostItem( - key: Key('p${item.id}'), - item: item, - isShowEmbed: isShowEmbed, - isClickable: isNestedClickable, - showFeaturedReply: showFeaturedReply, - padding: padding, - onComment: () { - AppRouter.instance - .pushNamed( - 'postEditor', - extra: PostPublishArguments(reply: item), - ) - .then((value) { - if (value is Future) { - value.then((_) { + return TapRegion( + child: GestureDetector( + onLongPress: () => _openActions(context), + child: PostItem( + key: Key('p${item.id}'), + item: item, + isShowEmbed: isShowEmbed, + isClickable: isNestedClickable, + showFeaturedReply: showFeaturedReply, + padding: padding, + onComment: () { + AppRouter.instance + .pushNamed( + 'postEditor', + extra: PostPublishArguments(reply: item), + ) + .then((value) { + if (value is Future) { + value.then((_) { + onUpdate(); + }); + } else if (value != null) { onUpdate(); - }); - } else if (value != null) { - onUpdate(); - } - }); - }, - ).paddingSymmetric(vertical: 8), - onLongPress: () { - final AuthProvider auth = Get.find(); - if (auth.isAuthorized.isFalse) return; - - showModalBottomSheet( - useRootNavigator: true, - context: context, - builder: (context) => PostAction(item: item), - ).then((value) { - if (value is Future) { - value.then((_) { - onUpdate(); + } }); - } else if (value != null) { - onUpdate(); - } - }); + }, + ).paddingSymmetric(vertical: 8), + ), + onTapInside: (event) { + if (event.buttons == kSecondaryMouseButton) { + _openActions(context); + } }, ); } diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 7ef866a..07b68bf 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -6,6 +6,8 @@ PODS: - FlutterMacOS - device_info_plus (0.0.1): - FlutterMacOS + - file_saver (0.0.1): + - FlutterMacOS - file_selector_macos (0.0.1): - FlutterMacOS - Firebase/Analytics (11.2.0): @@ -230,6 +232,7 @@ DEPENDENCIES: - connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/darwin`) - desktop_drop (from `Flutter/ephemeral/.symlinks/plugins/desktop_drop/macos`) - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) + - file_saver (from `Flutter/ephemeral/.symlinks/plugins/file_saver/macos`) - file_selector_macos (from `Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos`) - firebase_analytics (from `Flutter/ephemeral/.symlinks/plugins/firebase_analytics/macos`) - firebase_core (from `Flutter/ephemeral/.symlinks/plugins/firebase_core/macos`) @@ -288,6 +291,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/desktop_drop/macos device_info_plus: :path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos + file_saver: + :path: Flutter/ephemeral/.symlinks/plugins/file_saver/macos file_selector_macos: :path: Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos firebase_analytics: @@ -349,6 +354,7 @@ SPEC CHECKSUMS: connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db desktop_drop: 69eeff437544aa619c8db7f4481b3a65f7696898 device_info_plus: f1aae8670672f75c4c8850ecbe0b2ddef62b0a22 + file_saver: 44e6fbf666677faf097302460e214e977fdd977b file_selector_macos: cc3858c981fe6889f364731200d6232dac1d812d Firebase: 98e6bf5278170668a7983e12971a66b2cd57fc8c firebase_analytics: 30ff72f6d4847ff0b479d8edd92fc8582e719072 diff --git a/pubspec.yaml b/pubspec.yaml index a050e0b..49064da 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: solian description: "The Solar Network App" publish_to: "none" -version: 1.3.7+12 +version: 1.3.8+12 environment: sdk: ">=3.3.4 <4.0.0" diff --git a/web/index.html b/web/index.html index ebbe679..de9a2b3 100644 --- a/web/index.html +++ b/web/index.html @@ -111,15 +111,14 @@ - + - - + \ No newline at end of file