diff --git a/assets/translations/zh.json b/assets/translations/zh.json index 758c97e..736317d 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -377,7 +377,7 @@ "accountJoinedAt": "加入于 {}", "accountBirthday": "出生于 {}", "accountBadge": "徽章", - "badgeCompanyStaff": "索尔辛茨士大夫 · Staff", + "badgeCompanyStaff": "索尔辛茨士大夫 · 员工", "badgeSiteMigration": "Solar Network 原住民", "accountStatus": "状态", "accountStatusOnline": "在线", diff --git a/lib/screens/account/pfp.dart b/lib/screens/account/pfp.dart index d91c72e..fe9e1e7 100644 --- a/lib/screens/account/pfp.dart +++ b/lib/screens/account/pfp.dart @@ -6,6 +6,7 @@ import 'package:gap/gap.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:material_symbols_icons/symbols.dart'; import 'package:provider/provider.dart'; +import 'package:relative_time/relative_time.dart'; import 'package:styled_widget/styled_widget.dart'; import 'package:surface/providers/sn_network.dart'; import 'package:surface/types/account.dart'; @@ -28,14 +29,14 @@ const Map kBadgesMeta = { class UserScreen extends StatefulWidget { final String name; + const UserScreen({super.key, required this.name}); @override State createState() => _UserScreenState(); } -class _UserScreenState extends State - with SingleTickerProviderStateMixin { +class _UserScreenState extends State with SingleTickerProviderStateMixin { late final ScrollController _scrollController = ScrollController(); SnAccount? _account; @@ -75,14 +76,12 @@ class _UserScreenState extends State double _appBarBlur = 0.0; late final _appBarWidth = MediaQuery.of(context).size.width; - late final _appBarHeight = - (_appBarWidth * kBannerAspectRatio).roundToDouble(); + late final _appBarHeight = (_appBarWidth * kBannerAspectRatio).roundToDouble(); void _updateAppBarBlur() { if (_scrollController.offset > _appBarHeight) return; setState(() { - _appBarBlur = - (_scrollController.offset / _appBarHeight * 10).clamp(0.0, 10.0); + _appBarBlur = (_scrollController.offset / _appBarHeight * 10).clamp(0.0, 10.0); }); } @@ -218,9 +217,7 @@ class _UserScreenState extends State Symbols.circle, fill: 1, size: 16, - color: (_status?.isOnline ?? false) - ? Colors.green - : Colors.grey, + color: (_status?.isOnline ?? false) ? Colors.green : Colors.grey, ).padding(all: 4), const Gap(8), Text( @@ -230,19 +227,55 @@ class _UserScreenState extends State : 'accountStatusOffline'.tr() : 'loading'.tr(), ), + if (_status != null && !_status!.isOnline && _status!.lastSeenAt != null) + Text( + 'accountStatusLastSeen'.tr(args: [ + _status!.lastSeenAt != null + ? RelativeTime(context).format( + _status!.lastSeenAt!.toLocal(), + ) + : 'unknown', + ]), + ).padding(left: 6).opacity(0.75), ], ).padding(vertical: 8, horizontal: 12), ), const Gap(8), + Wrap( + children: _account!.badges + .map( + (ele) => Tooltip( + richMessage: TextSpan( + children: [ + TextSpan(text: kBadgesMeta[ele.type]?.$1.tr() ?? 'unknown'.tr()), + if (ele.metadata['title'] != null) + TextSpan( + text: '\n${ele.metadata['title']}', + style: const TextStyle(fontWeight: FontWeight.bold), + ), + TextSpan(text: '\n'), + TextSpan( + text: DateFormat.yMEd().format(ele.createdAt), + ), + ], + ), + child: Icon( + kBadgesMeta[ele.type]?.$2 ?? Symbols.question_mark, + color: kBadgesMeta[ele.type]?.$3, + fill: 1, + ), + ), + ) + .toList(), + ).padding(horizontal: 8), + const Gap(8), Column( children: [ Row( children: [ const Icon(Symbols.calendar_add_on), const Gap(8), - Text('publisherJoinedAt').tr(args: [ - DateFormat('y/M/d').format(_account!.createdAt) - ]), + Text('publisherJoinedAt').tr(args: [DateFormat('y/M/d').format(_account!.createdAt)]), ], ), Row( @@ -279,11 +312,7 @@ class _UserScreenState extends State child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text('accountBadge') - .bold() - .fontSize(17) - .tr() - .padding(horizontal: 20, bottom: 4), + Text('accountBadge').bold().fontSize(17).tr().padding(horizontal: 20, bottom: 4), SizedBox( height: 80, width: double.infinity, @@ -297,8 +326,7 @@ class _UserScreenState extends State child: Card( child: ListTile( leading: Icon( - kBadgesMeta[badge.type]?.$2 ?? - Symbols.question_mark, + kBadgesMeta[badge.type]?.$2 ?? Symbols.question_mark, color: kBadgesMeta[badge.type]?.$3, fill: 1, ), @@ -308,8 +336,7 @@ class _UserScreenState extends State subtitle: badge.metadata['title'] != null ? Text(badge.metadata['title']) : Text( - DateFormat('y/M/d') - .format(badge.createdAt), + DateFormat('y/M/d').format(badge.createdAt), ), ), ), diff --git a/lib/widgets/markdown_content.dart b/lib/widgets/markdown_content.dart index 558dd01..6eb0e02 100644 --- a/lib/widgets/markdown_content.dart +++ b/lib/widgets/markdown_content.dart @@ -73,7 +73,6 @@ class MarkdownTextContent extends StatelessWidget { extensionSet: markdown.ExtensionSet( [ markdown.CodeBlockSyntax(), - ...markdown.ExtensionSet.commonMark.blockSyntaxes, ...markdown.ExtensionSet.gitHubFlavored.blockSyntaxes, ], [ @@ -82,7 +81,6 @@ class MarkdownTextContent extends StatelessWidget { markdown.AutolinkSyntax(), markdown.AutolinkExtensionSyntax(), markdown.CodeSyntax(), - ...markdown.ExtensionSet.commonMark.inlineSyntaxes, ...markdown.ExtensionSet.gitHubFlavored.inlineSyntaxes ], ), @@ -93,7 +91,7 @@ class MarkdownTextContent extends StatelessWidget { final segments = uri.split('/'); switch (segments[0]) { default: - GoRouter.of(context).push(uri); + GoRouter.of(context).push('/$uri'); } return; } @@ -188,7 +186,7 @@ class _UserNameCardInlineSyntax extends markdown.InlineSyntax { final alias = match[0]!; final anchor = markdown.Element.text('a', alias) ..attributes['href'] = Uri.encodeFull( - 'solink://users/${alias.substring(1)}', + 'solink://account/${alias.substring(1)}', ); parser.addNode(anchor);