✨ Post share card
This commit is contained in:
@@ -23,7 +23,6 @@ import 'package:island/widgets/safety/abuse_report_helper.dart';
|
||||
import 'package:island/widgets/share/share_sheet.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:path_provider/path_provider.dart' show getTemporaryDirectory;
|
||||
import 'package:relative_time/relative_time.dart';
|
||||
import 'package:screenshot/screenshot.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
@@ -103,13 +102,13 @@ class PostActionableItem extends HookConsumerWidget {
|
||||
textDirection: TextDirection.ltr,
|
||||
child: SizedBox(
|
||||
width: 520,
|
||||
height: 640,
|
||||
child: PostItemScreenshot(item: item, isFullPost: isFullPost),
|
||||
),
|
||||
),
|
||||
),
|
||||
context: context,
|
||||
pixelRatio: MediaQuery.of(context).devicePixelRatio,
|
||||
delay: const Duration(seconds: 1),
|
||||
)
|
||||
.then((Uint8List? image) async {
|
||||
if (image == null) return;
|
||||
@@ -468,7 +467,8 @@ class PostItem extends HookConsumerWidget {
|
||||
translationSection: translationSection,
|
||||
renderingPadding: renderingPadding,
|
||||
),
|
||||
if (isShowReference) ReferencedPostWidget(item: item),
|
||||
if (isShowReference)
|
||||
ReferencedPostWidget(item: item, renderingPadding: renderingPadding),
|
||||
if (item.repliesCount > 0 && isEmbedReply)
|
||||
PostReplyPreview(
|
||||
parent: item,
|
||||
|
@@ -1,9 +1,12 @@
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:island/models/post.dart';
|
||||
import 'package:island/widgets/post/post_shared.dart';
|
||||
import 'package:qr_flutter/qr_flutter.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
class PostItemScreenshot extends ConsumerWidget {
|
||||
final SnPost item;
|
||||
@@ -31,42 +34,102 @@ class PostItemScreenshot extends ConsumerWidget {
|
||||
.map((e) => e.key)
|
||||
.last;
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
PostHeader(
|
||||
item: item,
|
||||
isFullPost: isFullPost,
|
||||
isInteractive: false,
|
||||
renderingPadding: renderingPadding,
|
||||
trailing:
|
||||
mostReaction != null
|
||||
? Row(
|
||||
final isDark = MediaQuery.of(context).platformBrightness == Brightness.dark;
|
||||
|
||||
return Material(
|
||||
elevation: 0,
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Gap(renderingPadding.vertical),
|
||||
PostHeader(
|
||||
item: item,
|
||||
isFullPost: isFullPost,
|
||||
isInteractive: false,
|
||||
renderingPadding: renderingPadding,
|
||||
isRelativeTime: false,
|
||||
trailing:
|
||||
mostReaction != null
|
||||
? Row(
|
||||
children: [
|
||||
Text(
|
||||
kReactionTemplates[mostReaction]?.icon ?? '',
|
||||
style: const TextStyle(fontSize: 20),
|
||||
),
|
||||
const Gap(4),
|
||||
Text(
|
||||
'x${item.reactionsCount[mostReaction]}',
|
||||
style: const TextStyle(fontSize: 11),
|
||||
),
|
||||
],
|
||||
)
|
||||
: null,
|
||||
),
|
||||
PostBody(
|
||||
item: item,
|
||||
renderingPadding: renderingPadding,
|
||||
isFullPost: isFullPost,
|
||||
isTextSelectable: false,
|
||||
isInteractive: false,
|
||||
),
|
||||
if (isShowReference)
|
||||
ReferencedPostWidget(
|
||||
item: item,
|
||||
isInteractive: false,
|
||||
renderingPadding: renderingPadding,
|
||||
),
|
||||
Container(
|
||||
color: Theme.of(context).colorScheme.surfaceContainerLow,
|
||||
margin: const EdgeInsets.only(top: 8),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: renderingPadding.horizontal,
|
||||
vertical: 4,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 44,
|
||||
height: 44,
|
||||
child: Image.asset(
|
||||
'assets/icons/icon${isDark ? '-dark' : ''}.png',
|
||||
width: 40,
|
||||
height: 40,
|
||||
),
|
||||
).padding(vertical: 8, right: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
kReactionTemplates[mostReaction]?.icon ?? '',
|
||||
style: const TextStyle(fontSize: 20),
|
||||
),
|
||||
const Gap(4),
|
||||
Text(
|
||||
'x${item.reactionsCount[mostReaction]}',
|
||||
style: const TextStyle(fontSize: 11),
|
||||
const Text(
|
||||
'Solar Network',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const Text(
|
||||
'sharePostSlogan',
|
||||
style: TextStyle(fontSize: 12),
|
||||
).tr().opacity(0.9),
|
||||
],
|
||||
)
|
||||
: null,
|
||||
),
|
||||
PostBody(
|
||||
item: item,
|
||||
renderingPadding: renderingPadding,
|
||||
isFullPost: isFullPost,
|
||||
isTextSelectable: false,
|
||||
isInteractive: false,
|
||||
),
|
||||
if (isShowReference)
|
||||
ReferencedPostWidget(item: item, isInteractive: false),
|
||||
],
|
||||
),
|
||||
),
|
||||
QrImageView(
|
||||
data: 'https://solian.app/posts/${item.id}',
|
||||
version: QrVersions.auto,
|
||||
size: 60,
|
||||
errorCorrectionLevel: QrErrorCorrectLevel.M,
|
||||
backgroundColor: Colors.transparent,
|
||||
foregroundColor: Theme.of(context).colorScheme.onSurface,
|
||||
padding: const EdgeInsets.all(8),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -348,11 +348,13 @@ class PostTruncateHint extends StatelessWidget {
|
||||
class ReferencedPostWidget extends StatelessWidget {
|
||||
final SnPost item;
|
||||
final bool isInteractive;
|
||||
final EdgeInsets renderingPadding;
|
||||
|
||||
const ReferencedPostWidget({
|
||||
super.key,
|
||||
required this.item,
|
||||
this.isInteractive = true,
|
||||
this.renderingPadding = EdgeInsets.zero,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -363,8 +365,15 @@ class ReferencedPostWidget extends StatelessWidget {
|
||||
final isReply = item.repliedPost != null;
|
||||
|
||||
final content = Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
margin: const EdgeInsets.only(top: 8),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: renderingPadding.horizontal,
|
||||
vertical: 8,
|
||||
),
|
||||
margin: EdgeInsets.only(
|
||||
top: 8,
|
||||
left: renderingPadding.vertical,
|
||||
right: renderingPadding.vertical,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.5),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
@@ -522,6 +531,7 @@ class PostHeader extends StatelessWidget {
|
||||
final Widget? trailing;
|
||||
final bool isInteractive;
|
||||
final EdgeInsets renderingPadding;
|
||||
final bool isRelativeTime;
|
||||
|
||||
const PostHeader({
|
||||
super.key,
|
||||
@@ -530,6 +540,7 @@ class PostHeader extends StatelessWidget {
|
||||
this.trailing,
|
||||
this.isInteractive = true,
|
||||
this.renderingPadding = EdgeInsets.zero,
|
||||
this.isRelativeTime = true,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -569,15 +580,21 @@ class PostHeader extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
isFullPost
|
||||
? (item.publishedAt ?? item.createdAt)!.formatSystem()
|
||||
: (item.publishedAt ?? item.createdAt)!.formatRelative(
|
||||
!isFullPost && isRelativeTime
|
||||
? (item.publishedAt ?? item.createdAt)!.formatRelative(
|
||||
context,
|
||||
),
|
||||
)
|
||||
: (item.publishedAt ?? item.createdAt)!.formatSystem(),
|
||||
).fontSize(10),
|
||||
if (item.editedAt != null)
|
||||
Text(
|
||||
'editedAt'.tr(args: [item.editedAt!.formatSystem()]),
|
||||
'editedAt'.tr(
|
||||
args: [
|
||||
!isFullPost && isRelativeTime
|
||||
? item.editedAt!.formatRelative(context)
|
||||
: item.editedAt!.formatSystem(),
|
||||
],
|
||||
),
|
||||
).fontSize(10),
|
||||
if (item.visibility != 0)
|
||||
Text(
|
||||
@@ -711,6 +728,7 @@ class PostBody extends ConsumerWidget {
|
||||
if (item.attachments.isNotEmpty && item.type != 1)
|
||||
CloudFileList(
|
||||
files: item.attachments,
|
||||
isColumn: !isInteractive,
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: renderingPadding.horizontal,
|
||||
vertical: 4,
|
||||
|
Reference in New Issue
Block a user