💄 Optimization of sharing post via image
This commit is contained in:
parent
240ad7dc7e
commit
d7c1ffe3cc
@ -439,5 +439,7 @@
|
|||||||
"userUnblocked": "{} has been unblocked.",
|
"userUnblocked": "{} has been unblocked.",
|
||||||
"userBlocked": "{} has been blocked.",
|
"userBlocked": "{} has been blocked.",
|
||||||
"postSharingViaPicture": "Capturing post as picture, please stand by...",
|
"postSharingViaPicture": "Capturing post as picture, please stand by...",
|
||||||
"postImageShareAds": "Explore posts on the Solar Network"
|
"postImageShareAds": "Explore posts on the Solar Network",
|
||||||
|
"postShare": "Share",
|
||||||
|
"postShareImage": "Share via Image"
|
||||||
}
|
}
|
||||||
|
@ -437,5 +437,7 @@
|
|||||||
"userUnblocked": "已解除屏蔽用户 {}",
|
"userUnblocked": "已解除屏蔽用户 {}",
|
||||||
"userBlocked": "已屏蔽用户 {}",
|
"userBlocked": "已屏蔽用户 {}",
|
||||||
"postSharingViaPicture": "正在生成帖子截图,请稍等片刻……",
|
"postSharingViaPicture": "正在生成帖子截图,请稍等片刻……",
|
||||||
"postImageShareAds": "来 Solar Network 探索更多有趣帖子"
|
"postImageShareAds": "来 Solar Network 探索更多有趣帖子",
|
||||||
|
"postShare": "分享",
|
||||||
|
"postShareImage": "分享帖图"
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,59 @@ class PostItem extends StatelessWidget {
|
|||||||
if (onChanged != null) onChanged!(data);
|
if (onChanged != null) onChanged!(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _doShare(BuildContext context) {
|
||||||
|
final box = context.findRenderObject() as RenderBox?;
|
||||||
|
final url = 'https://solsynth.dev/posts/${data.id}';
|
||||||
|
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
||||||
|
Share.shareUri(Uri.parse(url), sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
|
||||||
|
} else {
|
||||||
|
Share.share(url, sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _doShareViaPicture(BuildContext context) async {
|
||||||
|
final box = context.findRenderObject() as RenderBox?;
|
||||||
|
context.showSnackbar('postSharingViaPicture'.tr());
|
||||||
|
|
||||||
|
final controller = ScreenshotController();
|
||||||
|
final capturedImage = await controller.captureFromLongWidget(
|
||||||
|
InheritedTheme.captureAll(
|
||||||
|
context,
|
||||||
|
MediaQuery(
|
||||||
|
data: MediaQuery.of(context),
|
||||||
|
child: Material(
|
||||||
|
child: MultiProvider(
|
||||||
|
providers: [
|
||||||
|
Provider<SnNetworkProvider>(create: (_) => context.read()),
|
||||||
|
],
|
||||||
|
child: ResponsiveBreakpoints.builder(
|
||||||
|
breakpoints: ResponsiveBreakpoints.of(context).breakpoints,
|
||||||
|
child: PostShareImage(data: data),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pixelRatio: 3,
|
||||||
|
context: context,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (kIsWeb) return;
|
||||||
|
|
||||||
|
final directory = await getTemporaryDirectory();
|
||||||
|
final imagePath = await File(
|
||||||
|
'${directory.path}/sn-share-via-image-${DateTime.now().millisecondsSinceEpoch}.png',
|
||||||
|
).create();
|
||||||
|
await imagePath.writeAsBytes(capturedImage);
|
||||||
|
|
||||||
|
await Share.shareXFiles(
|
||||||
|
[XFile(imagePath.path)],
|
||||||
|
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
|
||||||
|
);
|
||||||
|
|
||||||
|
await imagePath.delete();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
@ -74,6 +127,8 @@ class PostItem extends StatelessWidget {
|
|||||||
_PostContentHeader(
|
_PostContentHeader(
|
||||||
data: data,
|
data: data,
|
||||||
isAuthor: isAuthor,
|
isAuthor: isAuthor,
|
||||||
|
onShare: () => _doShare(context),
|
||||||
|
onShareImage: () => _doShareViaPicture(context),
|
||||||
onDeleted: () {
|
onDeleted: () {
|
||||||
if (onDeleted != null) {}
|
if (onDeleted != null) {}
|
||||||
},
|
},
|
||||||
@ -125,6 +180,8 @@ class PostItem extends StatelessWidget {
|
|||||||
data: data,
|
data: data,
|
||||||
showComments: showComments,
|
showComments: showComments,
|
||||||
showReactions: showReactions,
|
showReactions: showReactions,
|
||||||
|
onShare: () => _doShare(context),
|
||||||
|
onShareImage: () => _doShareViaPicture(context),
|
||||||
onChanged: _onChanged,
|
onChanged: _onChanged,
|
||||||
).padding(left: 8, right: 14),
|
).padding(left: 8, right: 14),
|
||||||
],
|
],
|
||||||
@ -143,6 +200,8 @@ class PostItem extends StatelessWidget {
|
|||||||
_PostContentHeader(
|
_PostContentHeader(
|
||||||
data: data,
|
data: data,
|
||||||
showMenu: showMenu,
|
showMenu: showMenu,
|
||||||
|
onShare: () => _doShare(context),
|
||||||
|
onShareImage: () => _doShareViaPicture(context),
|
||||||
onDeleted: () {
|
onDeleted: () {
|
||||||
if (onDeleted != null) onDeleted!();
|
if (onDeleted != null) onDeleted!();
|
||||||
},
|
},
|
||||||
@ -190,6 +249,8 @@ class PostItem extends StatelessWidget {
|
|||||||
data: data,
|
data: data,
|
||||||
showComments: showComments,
|
showComments: showComments,
|
||||||
showReactions: showReactions,
|
showReactions: showReactions,
|
||||||
|
onShare: () => _doShare(context),
|
||||||
|
onShareImage: () => _doShareViaPicture(context),
|
||||||
onChanged: _onChanged,
|
onChanged: _onChanged,
|
||||||
).padding(left: 8, right: 14),
|
).padding(left: 8, right: 14),
|
||||||
],
|
],
|
||||||
@ -219,6 +280,8 @@ class PostShareImage extends StatelessWidget {
|
|||||||
_PostContentHeader(
|
_PostContentHeader(
|
||||||
data: data,
|
data: data,
|
||||||
onDeleted: () {},
|
onDeleted: () {},
|
||||||
|
onShare: () {},
|
||||||
|
onShareImage: () {},
|
||||||
showMenu: false,
|
showMenu: false,
|
||||||
isRelativeDate: false,
|
isRelativeDate: false,
|
||||||
).padding(horizontal: 16, bottom: 8),
|
).padding(horizontal: 16, bottom: 8),
|
||||||
@ -241,10 +304,19 @@ class PostShareImage extends StatelessWidget {
|
|||||||
data: data.preload!.attachments!,
|
data: data.preload!.attachments!,
|
||||||
isFlatted: true,
|
isFlatted: true,
|
||||||
).padding(horizontal: 16, bottom: 8),
|
).padding(horizontal: 16, bottom: 8),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if (data.visibility > 0) _PostVisibilityHint(data: data),
|
||||||
|
if (data.body['content_truncated'] == true) _PostTruncatedHint(data: data),
|
||||||
|
],
|
||||||
|
).padding(horizontal: 16),
|
||||||
_PostBottomAction(
|
_PostBottomAction(
|
||||||
data: data,
|
data: data,
|
||||||
showComments: true,
|
showComments: true,
|
||||||
showReactions: true,
|
showReactions: true,
|
||||||
|
onShare: () {},
|
||||||
|
onShareImage: () {},
|
||||||
onChanged: (SnPost data) {},
|
onChanged: (SnPost data) {},
|
||||||
).padding(left: 8, right: 14),
|
).padding(left: 8, right: 14),
|
||||||
const Divider(height: 1),
|
const Divider(height: 1),
|
||||||
@ -317,67 +389,17 @@ class _PostBottomAction extends StatelessWidget {
|
|||||||
final bool showComments;
|
final bool showComments;
|
||||||
final bool showReactions;
|
final bool showReactions;
|
||||||
final Function(SnPost data) onChanged;
|
final Function(SnPost data) onChanged;
|
||||||
|
final Function() onShare, onShareImage;
|
||||||
|
|
||||||
const _PostBottomAction({
|
const _PostBottomAction({
|
||||||
required this.data,
|
required this.data,
|
||||||
required this.showComments,
|
required this.showComments,
|
||||||
required this.showReactions,
|
required this.showReactions,
|
||||||
required this.onChanged,
|
required this.onChanged,
|
||||||
|
required this.onShare,
|
||||||
|
required this.onShareImage,
|
||||||
});
|
});
|
||||||
|
|
||||||
void _doShare(BuildContext context) {
|
|
||||||
final box = context.findRenderObject() as RenderBox?;
|
|
||||||
final url = 'https://solsynth.dev/posts/${data.id}';
|
|
||||||
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
|
||||||
Share.shareUri(Uri.parse(url), sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
|
|
||||||
} else {
|
|
||||||
Share.share(url, sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _doShareViaPicture(BuildContext context) async {
|
|
||||||
final box = context.findRenderObject() as RenderBox?;
|
|
||||||
context.showSnackbar('postSharingViaPicture'.tr());
|
|
||||||
|
|
||||||
final controller = ScreenshotController();
|
|
||||||
final capturedImage = await controller.captureFromLongWidget(
|
|
||||||
InheritedTheme.captureAll(
|
|
||||||
context,
|
|
||||||
MediaQuery(
|
|
||||||
data: MediaQuery.of(context),
|
|
||||||
child: Material(
|
|
||||||
child: MultiProvider(
|
|
||||||
providers: [
|
|
||||||
Provider<SnNetworkProvider>(create: (_) => context.read()),
|
|
||||||
],
|
|
||||||
child: ResponsiveBreakpoints.builder(
|
|
||||||
breakpoints: ResponsiveBreakpoints.of(context).breakpoints,
|
|
||||||
child: PostShareImage(data: data),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
pixelRatio: 3,
|
|
||||||
context: context,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (kIsWeb) return;
|
|
||||||
|
|
||||||
final directory = await getTemporaryDirectory();
|
|
||||||
final imagePath = await File(
|
|
||||||
'${directory.path}/sn-share-via-image-${DateTime.now().millisecondsSinceEpoch}.png',
|
|
||||||
).create();
|
|
||||||
await imagePath.writeAsBytes(capturedImage);
|
|
||||||
|
|
||||||
await Share.shareXFiles(
|
|
||||||
[XFile(imagePath.path)],
|
|
||||||
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
|
|
||||||
);
|
|
||||||
|
|
||||||
await imagePath.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final iconColor = Theme.of(context).colorScheme.onSurface.withAlpha(
|
final iconColor = Theme.of(context).colorScheme.onSurface.withAlpha(
|
||||||
@ -462,8 +484,8 @@ class _PostBottomAction extends StatelessWidget {
|
|||||||
..removeLast(),
|
..removeLast(),
|
||||||
),
|
),
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () => _doShare(context),
|
onTap: onShare,
|
||||||
onLongPress: () => _doShareViaPicture(context),
|
onLongPress: onShareImage,
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Symbols.share,
|
Symbols.share,
|
||||||
size: 20,
|
size: 20,
|
||||||
@ -576,6 +598,7 @@ class _PostContentHeader extends StatelessWidget {
|
|||||||
final bool isRelativeDate;
|
final bool isRelativeDate;
|
||||||
final bool showMenu;
|
final bool showMenu;
|
||||||
final Function onDeleted;
|
final Function onDeleted;
|
||||||
|
final Function() onShare, onShareImage;
|
||||||
|
|
||||||
const _PostContentHeader({
|
const _PostContentHeader({
|
||||||
required this.data,
|
required this.data,
|
||||||
@ -584,6 +607,8 @@ class _PostContentHeader extends StatelessWidget {
|
|||||||
this.isRelativeDate = true,
|
this.isRelativeDate = true,
|
||||||
this.showMenu = true,
|
this.showMenu = true,
|
||||||
required this.onDeleted,
|
required this.onDeleted,
|
||||||
|
required this.onShare,
|
||||||
|
required this.onShareImage,
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<void> _deletePost(BuildContext context) async {
|
Future<void> _deletePost(BuildContext context) async {
|
||||||
@ -744,6 +769,27 @@ class _PostContentHeader extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
const PopupMenuDivider(),
|
const PopupMenuDivider(),
|
||||||
|
PopupMenuItem(
|
||||||
|
onTap: onShare,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Symbols.share),
|
||||||
|
const Gap(16),
|
||||||
|
Text('postShare').tr(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PopupMenuItem(
|
||||||
|
onTap: onShareImage,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Symbols.share_reviews),
|
||||||
|
const Gap(16),
|
||||||
|
Text('postShareImage').tr(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const PopupMenuDivider(),
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
@ -825,6 +871,8 @@ class _PostQuoteContent extends StatelessWidget {
|
|||||||
isCompact: true,
|
isCompact: true,
|
||||||
isRelativeDate: isRelativeDate,
|
isRelativeDate: isRelativeDate,
|
||||||
showMenu: false,
|
showMenu: false,
|
||||||
|
onShare: () {},
|
||||||
|
onShareImage: () {},
|
||||||
onDeleted: () {},
|
onDeleted: () {},
|
||||||
).padding(bottom: 4),
|
).padding(bottom: 4),
|
||||||
_PostContentBody(data: child),
|
_PostContentBody(data: child),
|
||||||
|
Loading…
Reference in New Issue
Block a user