✨ Post headline, and read est
This commit is contained in:
parent
a59de65130
commit
731ab97209
@ -55,6 +55,13 @@
|
||||
"untitled": "Untitled",
|
||||
"postDetail": "Post detail",
|
||||
"postNoun": "Post",
|
||||
"postReadMore": "Read more",
|
||||
"postReadEstimate": "Est read time {}",
|
||||
"postTotalLength": {
|
||||
"zero": "No character",
|
||||
"one": "{} character",
|
||||
"other": "{} characters"
|
||||
},
|
||||
"fieldUsername": "Username",
|
||||
"fieldNickname": "Nickname",
|
||||
"fieldEmail": "Email address",
|
||||
|
@ -55,6 +55,13 @@
|
||||
"untitled": "无题",
|
||||
"postDetail": "帖子详情",
|
||||
"postNoun": "帖子",
|
||||
"postReadMore": "阅读更多",
|
||||
"postReadEstimate": "预计花费 {} 阅读",
|
||||
"postTotalLength": {
|
||||
"zero": "没有内容",
|
||||
"one": "总计 {} 字",
|
||||
"other": "总计 {} 字"
|
||||
},
|
||||
"fieldUsername": "用户名",
|
||||
"fieldNickname": "显示名",
|
||||
"fieldEmail": "电子邮箱地址",
|
||||
|
@ -109,35 +109,38 @@ class _AttachmentItemSensitiveBlurState
|
||||
child: Container(
|
||||
color: Colors.black.withOpacity(0.5),
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Symbols.visibility_off,
|
||||
color: Colors.white,
|
||||
size: 32,
|
||||
),
|
||||
const Gap(8),
|
||||
Text('sensitiveContent')
|
||||
.tr()
|
||||
.fontSize(20)
|
||||
.textColor(Colors.white)
|
||||
.bold(),
|
||||
Text('sensitiveContentDescription')
|
||||
.tr()
|
||||
.fontSize(14)
|
||||
.textColor(Colors.white.withOpacity(0.8)),
|
||||
const Gap(16),
|
||||
InkWell(
|
||||
child: Text('sensitiveContentReveal')
|
||||
child: Container(
|
||||
constraints: const BoxConstraints(maxWidth: 280),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Symbols.visibility_off,
|
||||
color: Colors.white,
|
||||
size: 32,
|
||||
),
|
||||
const Gap(8),
|
||||
Text('sensitiveContent')
|
||||
.tr()
|
||||
.textColor(Colors.white),
|
||||
onTap: () {
|
||||
setState(() => _doesShow = !_doesShow);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
.fontSize(20)
|
||||
.textColor(Colors.white)
|
||||
.bold(),
|
||||
Text('sensitiveContentDescription')
|
||||
.tr()
|
||||
.fontSize(14)
|
||||
.textColor(Colors.white.withOpacity(0.8)),
|
||||
const Gap(16),
|
||||
InkWell(
|
||||
child: Text('sensitiveContentReveal')
|
||||
.tr()
|
||||
.textColor(Colors.white),
|
||||
onTap: () {
|
||||
setState(() => _doesShow = !_doesShow);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
).center(),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
@ -41,15 +41,24 @@ class PostItem extends StatelessWidget {
|
||||
Container(
|
||||
constraints: BoxConstraints(maxWidth: maxWidth ?? double.infinity),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_PostContentHeader(data: data)
|
||||
.padding(horizontal: 12, vertical: 8),
|
||||
if (data.body['title'] != null ||
|
||||
data.body['description'] != null)
|
||||
_PostHeadline(data: data).padding(horizontal: 16, bottom: 8),
|
||||
_PostContentBody(data: data.body)
|
||||
.padding(horizontal: 16, bottom: 6),
|
||||
if (data.repostTo != null)
|
||||
_PostQuoteContent(child: data.repostTo!).padding(
|
||||
horizontal: 12,
|
||||
),
|
||||
if (data.body['content_truncated'] == true)
|
||||
_PostTruncatedHint(data: data).padding(
|
||||
horizontal: 16,
|
||||
vertical: 4,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -69,7 +78,7 @@ class PostItem extends StatelessWidget {
|
||||
showComments: showComments,
|
||||
showReactions: showReactions,
|
||||
onChanged: _onChanged,
|
||||
).padding(left: 12, right: 18),
|
||||
).padding(left: 8, right: 14),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -175,6 +184,30 @@ class _PostBottomAction extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _PostHeadline extends StatelessWidget {
|
||||
final SnPost data;
|
||||
const _PostHeadline({super.key, required this.data});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (data.body['title'] != null)
|
||||
Text(
|
||||
data.body['title'],
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
if (data.body['description'] != null)
|
||||
Text(
|
||||
data.body['description'],
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _PostContentHeader extends StatelessWidget {
|
||||
final SnPost data;
|
||||
final bool isCompact;
|
||||
@ -351,3 +384,49 @@ class _PostQuoteContent extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _PostTruncatedHint extends StatelessWidget {
|
||||
final SnPost data;
|
||||
const _PostTruncatedHint({super.key, required this.data});
|
||||
|
||||
static const int kHumanReadSpeed = 238;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
if (data.body['content_length'] != null)
|
||||
Row(
|
||||
children: [
|
||||
const Icon(Symbols.timer, size: 20),
|
||||
const Gap(4),
|
||||
Text('postReadEstimate').tr(args: [
|
||||
'${Duration(
|
||||
seconds: ((data.body['content_length'] as num).toDouble() /
|
||||
kHumanReadSpeed)
|
||||
.round(),
|
||||
).inSeconds}s',
|
||||
]),
|
||||
],
|
||||
).padding(right: 12),
|
||||
if (data.body['content_length'] != null)
|
||||
Row(
|
||||
children: [
|
||||
const Icon(Symbols.height, size: 20),
|
||||
const Gap(4),
|
||||
Text(
|
||||
'postTotalLength'.plural(data.body['content_length']),
|
||||
).padding(right: 12)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
const Icon(Symbols.unfold_more, size: 20),
|
||||
const Gap(4),
|
||||
Text('postReadMore').tr(),
|
||||
],
|
||||
)
|
||||
],
|
||||
).opacity(0.75);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user