Share via image

This commit is contained in:
2024-10-13 23:12:23 +08:00
parent 6c32d76f78
commit ad7a34ec18
12 changed files with 165 additions and 19 deletions

View File

@ -1,3 +1,4 @@
import 'dart:io';
import 'dart:math';
import 'package:firebase_analytics/firebase_analytics.dart';
@ -5,6 +6,8 @@ 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:path_provider/path_provider.dart';
import 'package:screenshot/screenshot.dart';
import 'package:share_plus/share_plus.dart';
import 'package:solian/exts.dart';
import 'package:solian/models/post.dart';
@ -12,6 +15,7 @@ import 'package:solian/platform.dart';
import 'package:solian/providers/auth.dart';
import 'package:solian/router.dart';
import 'package:solian/screens/posts/post_editor.dart';
import 'package:solian/widgets/posts/post_share.dart';
import 'package:solian/widgets/reports/abuse_report.dart';
class PostAction extends StatefulWidget {
@ -84,6 +88,24 @@ class _PostActionState extends State<PostAction> {
}
}
Future<void> _shareImage() async {
final screenshot = ScreenshotController();
final image = await screenshot.captureFromWidget(
PostShareImage(item: widget.item),
context: context,
);
final directory = await getApplicationDocumentsDirectory();
final imageFile = await File(
'${directory.path}/temporary_share_image.png',
).create();
await imageFile.writeAsBytes(image);
final file = XFile(imageFile.path);
await Share.shareXFiles([file]);
await imageFile.delete();
}
@override
void initState() {
super.initState();
@ -135,16 +157,29 @@ class _PostActionState extends State<PostAction> {
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
leading: const Icon(Icons.share),
title: Text('share'.tr),
trailing: PlatformInfo.isIOS || PlatformInfo.isAndroid
? IconButton(
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (PlatformInfo.isIOS || PlatformInfo.isAndroid)
IconButton(
icon: const Icon(Icons.link_off),
tooltip: 'shareNoUri'.tr,
onPressed: () async {
await _doShare(noUri: true);
Navigator.pop(context);
},
)
: null,
),
if (PlatformInfo.isIOS || PlatformInfo.isAndroid)
IconButton(
icon: const Icon(Icons.image),
tooltip: 'shareImage'.tr,
onPressed: () async {
await _shareImage();
Navigator.pop(context);
},
),
],
),
onTap: () async {
await _doShare();
Navigator.pop(context);

View File

@ -41,7 +41,6 @@ class PostListWidget extends StatelessWidget {
isClickable: isClickable,
showFeaturedReply: true,
item: item,
backgroundColor: backgroundColor,
onUpdate: () {
controller.refresh();
},
@ -60,7 +59,6 @@ class PostListEntryWidget extends StatelessWidget {
final bool isClickable;
final bool showFeaturedReply;
final Post item;
final Color? backgroundColor;
final EdgeInsets? padding;
final Function onUpdate;
@ -71,7 +69,6 @@ class PostListEntryWidget extends StatelessWidget {
required this.isClickable,
required this.showFeaturedReply,
required this.item,
this.backgroundColor,
this.padding,
required this.onUpdate,
});

View File

@ -0,0 +1,92 @@
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:get/get.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'package:solian/models/post.dart';
import 'package:solian/widgets/posts/post_item.dart';
import 'package:solian/widgets/root_container.dart';
class PostShareImage extends StatelessWidget {
final Post item;
const PostShareImage({super.key, required this.item});
@override
Widget build(BuildContext context) {
final textColor = Theme.of(context).colorScheme.onSurface.withOpacity(0.3);
return RootContainer(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Gap(8),
Material(
color: Colors.transparent,
child: Card(
child: PostItem(
item: item,
isShowEmbed: true,
isClickable: false,
showFeaturedReply: false,
isReactable: false,
isShowReply: false,
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 8),
onComment: () {},
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(8)),
child: Image.asset(
'assets/logo.png',
width: 48,
height: 48,
),
),
const Gap(16),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'shareImageFooter'.tr,
style: TextStyle(
fontSize: 13,
color: textColor,
),
),
Text(
'Solsynth LLC © ${DateTime.now().year}',
style: TextStyle(
fontSize: 11,
color: textColor,
),
),
],
),
],
),
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(8)),
child: Material(
color: Theme.of(context).colorScheme.surface,
child: QrImageView(
data: 'https://solsynth.dev/posts/${item.id}',
version: QrVersions.auto,
padding: const EdgeInsets.all(4),
size: 48,
),
),
),
],
),
],
).paddingSymmetric(horizontal: 36, vertical: 24),
);
}
}

View File

@ -25,7 +25,6 @@ class PostSingleDisplay extends StatelessWidget {
isNestedClickable: true,
showFeaturedReply: true,
onUpdate: onUpdate,
backgroundColor: Theme.of(context).colorScheme.surfaceContainerLow,
),
),
),