💄 Optimize in-app notification style

This commit is contained in:
2025-11-02 21:55:42 +08:00
parent c0ab3837ac
commit beeb28abf2
2 changed files with 72 additions and 62 deletions

View File

@@ -106,20 +106,6 @@ StreamSubscription<WebSocketPacket> setupNotificationListener(
child: NotificationCard(notification: notification), child: NotificationCard(notification: notification),
), ),
), ),
onTap: () {
if (notification.meta['action_uri'] != null) {
var uri = notification.meta['action_uri'] as String;
if (uri.startsWith('/')) {
// In-app routes
rootNavigatorKey.currentContext?.push(
notification.meta['action_uri'],
);
} else {
// External URLs
launchUrlString(uri);
}
}
},
onDismissed: () {}, onDismissed: () {},
dismissType: DismissType.onSwipe, dismissType: DismissType.onSwipe,
displayDuration: const Duration(seconds: 5), displayDuration: const Duration(seconds: 5),

View File

@@ -1,9 +1,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/account.dart'; import 'package:island/models/account.dart';
import 'package:island/route.dart';
import 'package:island/widgets/content/cloud_files.dart'; import 'package:island/widgets/content/cloud_files.dart';
import 'package:material_symbols_icons/material_symbols_icons.dart'; import 'package:material_symbols_icons/material_symbols_icons.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
import 'package:url_launcher/url_launcher_string.dart';
class NotificationCard extends HookConsumerWidget { class NotificationCard extends HookConsumerWidget {
final SnNotification notification; final SnNotification notification;
@@ -14,58 +17,79 @@ class NotificationCard extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final icon = Symbols.info; final icon = Symbols.info;
return Card( return InkWell(
elevation: 4, borderRadius: BorderRadius.all(Radius.circular(8)),
margin: const EdgeInsets.only(bottom: 8), onTap: () {
shape: const RoundedRectangleBorder( if (notification.meta['action_uri'] != null) {
borderRadius: BorderRadius.all(Radius.circular(8)), var uri = notification.meta['action_uri'] as String;
), if (uri.startsWith('solian://')) {
child: Column( uri = uri.replaceFirst('solian://', '');
crossAxisAlignment: CrossAxisAlignment.start, }
mainAxisSize: MainAxisSize.min, if (uri.startsWith('/')) {
children: [ // In-app routes
Padding( rootNavigatorKey.currentContext?.push(
padding: const EdgeInsets.all(12), notification.meta['action_uri'],
child: Row( );
crossAxisAlignment: CrossAxisAlignment.start, } else {
children: [ // External URLs
if (notification.meta['pfp'] != null) launchUrlString(uri);
ProfilePictureWidget( }
fileId: notification.meta['pfp'], }
radius: 12, },
).padding(right: 12, top: 2) child: Card(
else elevation: 4,
Icon( margin: const EdgeInsets.only(bottom: 8),
icon, color: Theme.of(context).colorScheme.surfaceContainer,
color: Theme.of(context).colorScheme.primary, shape: const RoundedRectangleBorder(
size: 24, borderRadius: BorderRadius.all(Radius.circular(8)),
).padding(right: 12), ),
Expanded( child: Column(
child: Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text( Padding(
notification.title, padding: const EdgeInsets.all(12),
style: Theme.of(context).textTheme.titleMedium child: Row(
?.copyWith(fontWeight: FontWeight.bold), crossAxisAlignment: CrossAxisAlignment.start,
), children: [
if (notification.content.isNotEmpty) if (notification.meta['pfp'] != null)
ProfilePictureWidget(
fileId: notification.meta['pfp'],
radius: 12,
).padding(right: 12, top: 2)
else
Icon(
icon,
color: Theme.of(context).colorScheme.primary,
size: 24,
).padding(right: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text( Text(
notification.content, notification.title,
style: Theme.of(context).textTheme.bodyMedium, style: Theme.of(context).textTheme.titleMedium
?.copyWith(fontWeight: FontWeight.bold),
), ),
if (notification.subtitle.isNotEmpty) if (notification.content.isNotEmpty)
Text( Text(
notification.subtitle, notification.content,
style: Theme.of(context).textTheme.bodySmall, style: Theme.of(context).textTheme.bodyMedium,
), ),
], if (notification.subtitle.isNotEmpty)
Text(
notification.subtitle,
style: Theme.of(context).textTheme.bodySmall,
),
],
),
), ),
), ],
], ),
), ),
), ],
], ),
), ),
); );
} }