💄 Optimize fediverse mention rendering, etc

This commit is contained in:
2026-01-02 14:04:16 +08:00
parent 81d69ce10f
commit 3b13a63e7b
6 changed files with 95 additions and 11 deletions

View File

@@ -21,6 +21,7 @@ import 'package:island/widgets/app_scaffold.dart';
import 'package:island/widgets/notification_tile.dart'; import 'package:island/widgets/notification_tile.dart';
import 'package:island/widgets/post/post_featured.dart'; import 'package:island/widgets/post/post_featured.dart';
import 'package:island/widgets/check_in.dart'; import 'package:island/widgets/check_in.dart';
import 'package:island/screens/auth/login_modal.dart';
import 'package:island/models/activity.dart'; import 'package:island/models/activity.dart';
import 'package:island/screens/notification.dart'; import 'package:island/screens/notification.dart';
import 'package:material_symbols_icons/material_symbols_icons.dart'; import 'package:material_symbols_icons/material_symbols_icons.dart';
@@ -116,7 +117,11 @@ class DashboardGrid extends HookConsumerWidget {
topRight: isWide ? 0 : 12, topRight: isWide ? 0 : 12,
) )
.padding(horizontal: isWide ? 0 : 16), .padding(horizontal: isWide ? 0 : 16),
), )
else
Center(
child: _UnauthorizedCard(isWide: isWide),
).padding(horizontal: isWide ? 24 : 16),
], ],
), ),
); );
@@ -303,7 +308,9 @@ class ClockCard extends HookConsumerWidget {
spacing: 5, spacing: 5,
children: [ children: [
notableDay.when( notableDay.when(
data: (day) => _buildNotableDayText(context, day!), data: (day) => day == null
? Text('unauthorized').tr()
: _buildNotableDayText(context, day),
error: (err, _) => error: (err, _) =>
Text(err.toString()).fontSize(12), Text(err.toString()).fontSize(12),
loading: () => loading: () =>
@@ -555,3 +562,64 @@ class FortuneCard extends HookConsumerWidget {
).height(48); ).height(48);
} }
} }
class _UnauthorizedCard extends HookConsumerWidget {
final bool isWide;
const _UnauthorizedCard({required this.isWide});
@override
Widget build(BuildContext context, WidgetRef ref) {
return Card(
margin: EdgeInsets.zero,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: isWide ? 48 : 32,
vertical: 32,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
const Gap(16),
Icon(
Symbols.dashboard_rounded,
size: 64,
color: Theme.of(context).colorScheme.primary,
fill: 1,
),
const Gap(16),
Text(
'Welcome to\nthe Solar Network',
style: Theme.of(
context,
).textTheme.headlineSmall?.copyWith(fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
const Gap(8),
Text(
'Login to access your personalized dashboard with friends, notifications, chats, and more!',
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
textAlign: TextAlign.center,
),
const Gap(12),
FilledButton.icon(
onPressed: () {
showModalBottomSheet(
context: context,
useRootNavigator: true,
isScrollControlled: true,
builder: (context) => const LoginModal(),
);
},
icon: const Icon(Symbols.login),
label: Text('login').tr(),
),
],
),
),
);
}
}

View File

@@ -584,6 +584,10 @@ class _WebSocketIndicator extends HookConsumerWidget {
isInteractive = false; isInteractive = false;
} }
if (user.value == null) {
opacity = 0.0;
}
return Positioned( return Positioned(
top: devicePadding.top + (isDesktop ? 27.5 : 25), top: devicePadding.top + (isDesktop ? 27.5 : 25),
left: 0, left: 0,

View File

@@ -39,6 +39,7 @@ class MarkdownTextContent extends HookConsumerWidget {
final List<markdown.InlineSyntax> extraInlineSyntaxList; final List<markdown.InlineSyntax> extraInlineSyntaxList;
final List<markdown.BlockSyntax> extraBlockSyntaxList; final List<markdown.BlockSyntax> extraBlockSyntaxList;
final List<dynamic> extraGenerators; final List<dynamic> extraGenerators;
final bool noMentionChip;
const MarkdownTextContent({ const MarkdownTextContent({
super.key, super.key,
@@ -53,6 +54,7 @@ class MarkdownTextContent extends HookConsumerWidget {
this.extraInlineSyntaxList = const [], this.extraInlineSyntaxList = const [],
this.extraBlockSyntaxList = const [], this.extraBlockSyntaxList = const [],
this.extraGenerators = const [], this.extraGenerators = const [],
this.noMentionChip = false,
}); });
@override @override
@@ -224,7 +226,7 @@ class MarkdownTextContent extends HookConsumerWidget {
isDark: isDark, isDark: isDark,
linesMargin: linesMargin, linesMargin: linesMargin,
generators: [ generators: [
mentionGenerator, if (!noMentionChip) mentionGenerator,
highlightGenerator, highlightGenerator,
spoilerGenerator, spoilerGenerator,
stickerGenerator, stickerGenerator,
@@ -431,11 +433,13 @@ class MentionChipSpanNode extends SpanNode {
fallbackIcon: Symbols.person_rounded, fallbackIcon: Symbols.person_rounded,
radius: 9, radius: 9,
), ),
error: (_, _) => const Icon(Symbols.close), error: (_, _) => const Icon(Symbols.close, size: 20),
loading: () => const SizedBox( loading: () => const SizedBox(
width: 9, width: 20,
height: 9, height: 20,
child: CircularProgressIndicator(), child: CircularProgressIndicator(
padding: EdgeInsets.zero,
),
), ),
); );
}, },
@@ -449,11 +453,13 @@ class MentionChipSpanNode extends SpanNode {
fallbackIcon: Symbols.design_services_rounded, fallbackIcon: Symbols.design_services_rounded,
radius: 9, radius: 9,
), ),
error: (_, _) => const Icon(Symbols.close), error: (_, _) => const Icon(Symbols.close, size: 20),
loading: () => const SizedBox( loading: () => const SizedBox(
width: 9, width: 20,
height: 9, height: 20,
child: CircularProgressIndicator(), child: CircularProgressIndicator(
padding: EdgeInsets.zero,
),
), ),
); );
}, },

View File

@@ -425,6 +425,7 @@ class PostItem extends HookConsumerWidget {
content: translatedText.value!, content: translatedText.value!,
isSelectable: isTextSelectable, isSelectable: isTextSelectable,
attachments: item.attachments, attachments: item.attachments,
noMentionChip: item.fediverseUri != null,
), ),
], ],
) )

View File

@@ -205,6 +205,7 @@ class PostItemScreenshot extends ConsumerWidget {
child: MarkdownTextContent( child: MarkdownTextContent(
content: post.content!, content: post.content!,
attachments: post.attachments, attachments: post.attachments,
noMentionChip: item.fediverseUri != null,
).padding(top: 2), ).padding(top: 2),
) )
else else

View File

@@ -199,6 +199,7 @@ class PostReplyPreview extends HookConsumerWidget {
child: MarkdownTextContent( child: MarkdownTextContent(
content: _convertContentToMarkdown(post), content: _convertContentToMarkdown(post),
attachments: post.attachments, attachments: post.attachments,
noMentionChip: post.fediverseUri != null,
).padding(top: 2), ).padding(top: 2),
) )
else else
@@ -607,6 +608,7 @@ class ReferencedPostWidget extends StatelessWidget {
? const EdgeInsets.only(bottom: 4) ? const EdgeInsets.only(bottom: 4)
: null, : null,
attachments: item.attachments, attachments: item.attachments,
noMentionChip: item.fediverseUri != null,
).padding(bottom: 4), ).padding(bottom: 4),
if (referencePost.isTruncated) if (referencePost.isTruncated)
const PostTruncateHint( const PostTruncateHint(
@@ -1070,6 +1072,7 @@ class PostBody extends ConsumerWidget {
MarkdownTextContent( MarkdownTextContent(
content: '${_convertContentToMarkdown(item)}...', content: '${_convertContentToMarkdown(item)}...',
attachments: item.attachments, attachments: item.attachments,
noMentionChip: item.fediverseUri != null,
), ),
], ],
), ),
@@ -1109,6 +1112,7 @@ class PostBody extends ConsumerWidget {
: _convertContentToMarkdown(item), : _convertContentToMarkdown(item),
isSelectable: isTextSelectable, isSelectable: isTextSelectable,
attachments: item.attachments, attachments: item.attachments,
noMentionChip: item.fediverseUri != null,
), ),
if (translationSection != null) translationSection!, if (translationSection != null) translationSection!,
], ],