Share post as image on web

This commit is contained in:
LittleSheep 2024-10-14 20:51:56 +08:00
parent a6b17f2c05
commit 1abc65f8fa
8 changed files with 76 additions and 62 deletions

View File

@ -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"
}

View File

@ -480,5 +480,6 @@
"authMaximumAuthStepsDesc": "登陆时最多的验证步数,值越高则越安全,反之则会相对方便;默认设置为 2",
"auditLog": "活动日志",
"shareImage": "分享图片",
"shareImageFooter": "上 Solar Network 看更多有趣帖子"
"shareImageFooter": "上 Solar Network 看更多有趣帖子",
"fileSavedAt": "文件保存于 @path"
}

View File

@ -49,6 +49,7 @@ class _AttachmentListState extends State<AttachmentList> {
bool _isLoading = true;
bool _showMature = false;
// ignore: unused_field
double _aspectRatio = 1;
List<Attachment?> _attachments = List.empty();

View File

@ -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<PostAction> {
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<PostAction> {
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

View File

@ -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);
}
},
);
}

View File

@ -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

View File

@ -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"

View File

@ -111,15 +111,14 @@
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
</head>
<body>
<body oncontextmenu="return false;">
<picture id="splash">
<source srcset="splash/img/light-1x.png 1x, splash/img/light-2x.png 2x, splash/img/light-3x.png 3x, splash/img/light-4x.png 4x" media="(prefers-color-scheme: light)">
<source srcset="splash/img/dark-1x.png 1x, splash/img/dark-2x.png 2x, splash/img/dark-3x.png 3x, splash/img/dark-4x.png 4x" media="(prefers-color-scheme: dark)">
<img class="center" aria-hidden="true" src="splash/img/light-1x.png" alt="">
</picture>
<script src="flutter_bootstrap.js" async=""></script>
<script src="flutter_bootstrap.js" async=""></script>
</body></html>