💄 Optimize post metadata

This commit is contained in:
2025-10-23 01:27:40 +08:00
parent 8bec18813d
commit 126048b4fa
4 changed files with 116 additions and 84 deletions

View File

@@ -871,6 +871,7 @@
"pollShortTextAnswerPreview": "Short text answer (preview)", "pollShortTextAnswerPreview": "Short text answer (preview)",
"award": "Award", "award": "Award",
"awardPost": "Award Post", "awardPost": "Award Post",
"awardPoints": "Awarded {} points",
"awardMessage": "Message", "awardMessage": "Message",
"awardMessageHint": "Enter your award message...", "awardMessageHint": "Enter your award message...",
"awardAttitude": "Attitude", "awardAttitude": "Attitude",

View File

@@ -237,7 +237,7 @@ class PostCategoryDetailScreen extends HookConsumerWidget {
loading: () => ResponseLoadingWidget(), loading: () => ResponseLoadingWidget(),
), ),
), ),
), ).padding(horizontal: 8),
), ),
), ),
const SliverGap(4), const SliverGap(4),

View File

@@ -289,7 +289,7 @@ class PostActionButtons extends HookConsumerWidget {
builder: (context) => PostAwardHistorySheet(postId: post.id), builder: (context) => PostAwardHistorySheet(postId: post.id),
); );
}, },
icon: const Icon(Symbols.star), icon: const Icon(Symbols.emoji_events),
label: label:
post.awardedScore > 0 post.awardedScore > 0
? Text('${formatScore(post.awardedScore)} pts') ? Text('${formatScore(post.awardedScore)} pts')

View File

@@ -647,35 +647,13 @@ class PostHeader extends StatelessWidget {
]), ]),
], ],
), ),
Row( Text(
spacing: 6, !isFullPost && isRelativeTime
crossAxisAlignment: CrossAxisAlignment.end, ? (item.publishedAt ?? item.createdAt)!.formatRelative(
children: [ context,
Text( )
!isFullPost && isRelativeTime : (item.publishedAt ?? item.createdAt)!.formatSystem(),
? (item.publishedAt ?? item.createdAt)! ).fontSize(10),
.formatRelative(context)
: (item.publishedAt ?? item.createdAt)!
.formatSystem(),
).fontSize(10),
if (item.editedAt != null)
Text(
'editedAt'.tr(
args: [
!isFullPost && isRelativeTime
? item.editedAt!.formatRelative(context)
: item.editedAt!.formatSystem(),
],
),
).fontSize(10),
if (item.visibility != 0)
Text(
PostVisibilityHelpers.getVisibilityText(
item.visibility,
).tr(),
).fontSize(10),
],
),
], ],
), ),
), ),
@@ -694,6 +672,7 @@ class PostBody extends ConsumerWidget {
final Widget? translationSection; final Widget? translationSection;
final bool isInteractive; final bool isInteractive;
final EdgeInsets renderingPadding; final EdgeInsets renderingPadding;
final bool isRelativeTime;
const PostBody({ const PostBody({
super.key, super.key,
@@ -703,10 +682,113 @@ class PostBody extends ConsumerWidget {
this.translationSection, this.translationSection,
this.isInteractive = true, this.isInteractive = true,
this.renderingPadding = EdgeInsets.zero, this.renderingPadding = EdgeInsets.zero,
this.isRelativeTime = true,
}); });
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final metadataChildren = <Widget>[];
if (item.tags.isNotEmpty) {
metadataChildren.add(
Wrap(
runAlignment: WrapAlignment.center,
spacing: 8,
children: [
const Icon(Symbols.label, size: 16).padding(top: 2),
for (final tag in isFullPost ? item.tags : item.tags.take(3))
InkWell(
onTap:
isInteractive
? () {
GoRouter.of(context).pushNamed(
'postTagDetail',
pathParameters: {'slug': tag.slug},
);
}
: null,
child: Text('#${tag.name ?? tag.slug}'),
),
if (!isFullPost && item.tags.length > 3)
Text('+${item.tags.length - 3}').opacity(0.6),
],
),
);
}
if (item.categories.isNotEmpty) {
metadataChildren.add(
Wrap(
runAlignment: WrapAlignment.center,
spacing: 8,
children: [
const Icon(Symbols.category, size: 16).padding(top: 2),
for (final category
in isFullPost ? item.categories : item.categories.take(2))
InkWell(
onTap:
isInteractive
? () {
GoRouter.of(context).pushNamed(
'postCategoryDetail',
pathParameters: {'slug': category.slug},
);
}
: null,
child: Text(category.categoryDisplayTitle),
),
if (!isFullPost && item.categories.length > 2)
Text('+${item.categories.length - 2}').opacity(0.6),
],
),
);
}
if (item.editedAt != null) {
metadataChildren.add(
Row(
spacing: 8,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(Symbols.edit, size: 16),
Text(
'editedAt'.tr(
args: [
!isFullPost && isRelativeTime
? item.editedAt!.formatRelative(context)
: item.editedAt!.formatSystem(),
],
),
).fontSize(13),
],
),
);
}
if (item.visibility != 0) {
metadataChildren.add(
Row(
spacing: 8,
children: [
const Icon(Symbols.visibility_lock, size: 16).padding(top: 2),
Text(
PostVisibilityHelpers.getVisibilityText(item.visibility).tr(),
).fontSize(13),
],
),
);
}
if (item.awardedScore != 0) {
metadataChildren.add(
Row(
spacing: 8,
children: [
const Icon(Symbols.emoji_events, size: 16).padding(top: 2),
Text(
'awardPoints'.tr(args: [item.awardedScore.toString()]),
).fontSize(13),
],
),
);
}
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@@ -819,63 +901,12 @@ class PostBody extends ConsumerWidget {
vertical: 4, vertical: 4,
), ),
), ),
if (item.tags.isNotEmpty || item.categories.isNotEmpty) if (metadataChildren.isNotEmpty)
Column( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
spacing: 2, spacing: 2,
children: [ children: metadataChildren,
if (item.tags.isNotEmpty)
Wrap(
runAlignment: WrapAlignment.center,
spacing: 8,
children: [
const Icon(Symbols.label, size: 16).padding(top: 2),
for (final tag
in isFullPost ? item.tags : item.tags.take(3))
InkWell(
onTap:
isInteractive
? () {
GoRouter.of(context).pushNamed(
'postTagDetail',
pathParameters: {'slug': tag.slug},
);
}
: null,
child: Text('#${tag.name ?? tag.slug}'),
),
if (!isFullPost && item.tags.length > 3)
Text('+${item.tags.length - 3}').opacity(0.6),
],
),
if (item.categories.isNotEmpty)
Wrap(
runAlignment: WrapAlignment.center,
spacing: 8,
children: [
const Icon(Symbols.category, size: 16).padding(top: 2),
for (final category
in isFullPost
? item.categories
: item.categories.take(2))
InkWell(
onTap:
isInteractive
? () {
GoRouter.of(context).pushNamed(
'postCategoryDetail',
pathParameters: {'slug': category.slug},
);
}
: null,
child: Text(category.categoryDisplayTitle),
),
if (!isFullPost && item.categories.length > 2)
Text('+${item.categories.length - 2}').opacity(0.6),
],
),
],
).padding(horizontal: renderingPadding.horizontal + 4, top: 4), ).padding(horizontal: renderingPadding.horizontal + 4, top: 4),
if (item.meta?['embeds'] != null) if (item.meta?['embeds'] != null)
EmbedListWidget( EmbedListWidget(