From 9aca6eb6742b9e97755f8826b83c8035e40fb35b Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Mon, 2 Jun 2025 02:43:57 +0800 Subject: [PATCH] :sparkles: Post show replies / forwareded --- assets/i18n/en-US.json | 10 +++ assets/i18n/zh-CN.json | 8 +++ assets/i18n/zh-TW.json | 8 +++ ios/Runner.xcodeproj/project.pbxproj | 10 +-- ios/Runner/AppDelegate.swift | 2 - lib/widgets/post/post_item.dart | 102 +++++++++++++++++++++++++++ lib/widgets/post/post_replies.dart | 1 + 7 files changed, 130 insertions(+), 11 deletions(-) diff --git a/assets/i18n/en-US.json b/assets/i18n/en-US.json index 7055611..e19fbfc 100644 --- a/assets/i18n/en-US.json +++ b/assets/i18n/en-US.json @@ -99,6 +99,16 @@ "permissionMember": "Member", "reply": "Reply", "forward": "Forward", + "repliedTo": "Replied to", + "forwarded": "Forwarded", + "hasAttachments": { + "one": "{} attachment", + "other": "{} attachments" + }, + "postHasAttachments": { + "one": "{} attachment", + "other": "{} attachments" + }, "edited": "Edited", "addVideo": "Add video", "addPhoto": "Add photo", diff --git a/assets/i18n/zh-CN.json b/assets/i18n/zh-CN.json index 328552f..8477495 100644 --- a/assets/i18n/zh-CN.json +++ b/assets/i18n/zh-CN.json @@ -99,6 +99,14 @@ "permissionMember": "成员", "reply": "回复", "forward": "转发", + "repliedTo": "回复了", + "forwarded": "转发了", + "hasAttachments": { + "other": "{}个附件" + }, + "postHasAttachments": { + "other": "{}个附件" + }, "edited": "已编辑", "addVideo": "添加视频", "addPhoto": "添加照片", diff --git a/assets/i18n/zh-TW.json b/assets/i18n/zh-TW.json index d172cfb..831c19b 100644 --- a/assets/i18n/zh-TW.json +++ b/assets/i18n/zh-TW.json @@ -99,6 +99,14 @@ "permissionMember": "成員", "reply": "回覆", "forward": "轉發", + "repliedTo": "回覆了", + "forwarded": "轉發了", + "hasAttachments": { + "other": "{}個附件" + }, + "postHasAttachments": { + "other": "{}個附件" + }, "edited": "已編輯", "addVideo": "新增影片", "addPhoto": "新增照片", diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index d03e7fc..4166bc2 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 77; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -448,14 +448,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; @@ -491,14 +487,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index ffe8a23..eae3471 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -1,8 +1,6 @@ import Flutter import UIKit -import shared_preferences_foundation - @main @objc class AppDelegate: FlutterAppDelegate { let notifyDelegate = NotifyDelegate() diff --git a/lib/widgets/post/post_item.dart b/lib/widgets/post/post_item.dart index 18eec7e..4d3a03a 100644 --- a/lib/widgets/post/post_item.dart +++ b/lib/widgets/post/post_item.dart @@ -25,6 +25,7 @@ class PostItem extends HookConsumerWidget { final SnPost item; final EdgeInsets? padding; final bool isOpenable; + final bool showReferencePost; final Function? onRefresh; final Function(SnPost)? onUpdate; const PostItem({ @@ -33,6 +34,7 @@ class PostItem extends HookConsumerWidget { this.backgroundColor, this.padding, this.isOpenable = true, + this.showReferencePost = true, this.onRefresh, this.onUpdate, }); @@ -134,6 +136,10 @@ class PostItem extends HookConsumerWidget { Text(item.publisher.nick).bold(), if (item.content?.isNotEmpty ?? false) MarkdownTextContent(content: item.content!), + if ((item.repliedPost != null || + item.forwardedPost != null) && + showReferencePost) + _buildReferencePost(context, item), if (item.attachments.isNotEmpty) CloudFileList( files: item.attachments, @@ -178,6 +184,102 @@ class PostItem extends HookConsumerWidget { } } +Widget _buildReferencePost(BuildContext context, SnPost item) { + final referencePost = item.repliedPost ?? item.forwardedPost; + if (referencePost == null) return const SizedBox.shrink(); + + final isReply = item.repliedPost != null; + + return Container( + margin: const EdgeInsets.only(top: 8, bottom: 8), + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.5), + borderRadius: BorderRadius.circular(12), + border: Border.all( + color: Theme.of(context).colorScheme.outline.withOpacity(0.3), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + isReply ? Symbols.reply : Symbols.forward, + size: 16, + color: Theme.of(context).colorScheme.secondary, + ), + const SizedBox(width: 6), + Text( + isReply ? 'repliedTo'.tr() : 'forwarded'.tr(), + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.w500, + fontSize: 12, + ), + ), + ], + ), + const SizedBox(height: 8), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ProfilePictureWidget( + fileId: referencePost.publisher.picture?.id, + radius: 16, + ), + const SizedBox(width: 8), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + referencePost.publisher.nick, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + ), + ), + if (referencePost.content?.isNotEmpty ?? false) + MarkdownTextContent( + content: referencePost.content!, + textStyle: const TextStyle(fontSize: 14), + isSelectable: false, + ).padding(bottom: 4), + if (referencePost.attachments.isNotEmpty) + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + Symbols.attach_file, + size: 12, + color: Theme.of(context).colorScheme.secondary, + ), + const SizedBox(width: 4), + Text( + 'postHasAttachments'.plural( + referencePost.attachments.length, + ), + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontSize: 12, + ), + ), + ], + ).padding(vertical: 2), + ], + ), + ), + ], + ), + ], + ), + ).gestures( + onTap: () => context.router.push(PostDetailRoute(id: referencePost.id)), + ); +} + class PostReactionList extends HookConsumerWidget { final String parentId; final Map reactions; diff --git a/lib/widgets/post/post_replies.dart b/lib/widgets/post/post_replies.dart index 630cbfa..6b97619 100644 --- a/lib/widgets/post/post_replies.dart +++ b/lib/widgets/post/post_replies.dart @@ -94,6 +94,7 @@ class PostRepliesList extends HookConsumerWidget { PostItem( item: data.items[index], backgroundColor: isWide ? Colors.transparent : null, + showReferencePost: false, ), const Divider(height: 1), ],