💄 Bunch of optimization

This commit is contained in:
2025-03-17 00:36:20 +08:00
parent b492db90ca
commit 5976d61997
11 changed files with 567 additions and 223 deletions

View File

@ -63,7 +63,10 @@ class _NotificationScreenState extends State<NotificationScreen> {
queryParameters: {'take': 10, 'offset': _notifications.length},
);
_totalCount = resp.data['count'];
_notifications.addAll(resp.data['data']?.map((e) => SnNotification.fromJson(e)).cast<SnNotification>() ?? []);
_notifications.addAll(resp.data['data']
?.map((e) => SnNotification.fromJson(e))
.cast<SnNotification>() ??
[]);
nty.updateTray();
} catch (err) {
if (!mounted) return;
@ -98,7 +101,8 @@ class _NotificationScreenState extends State<NotificationScreen> {
nty.clear();
if (!mounted) return;
context.showSnackbar('notificationMarkAllReadPrompt'.plural(resp.data['count']));
context.showSnackbar(
'notificationMarkAllReadPrompt'.plural(resp.data['count']));
} catch (err) {
if (!mounted) return;
context.showErrorDialog(err);
@ -122,7 +126,8 @@ class _NotificationScreenState extends State<NotificationScreen> {
_fetchNotifications();
if (!mounted) return;
context.showSnackbar('notificationMarkOneReadPrompt'.tr(args: ['#${notification.id}']));
context.showSnackbar(
'notificationMarkOneReadPrompt'.tr(args: ['#${notification.id}']));
} catch (err) {
if (!mounted) return;
context.showErrorDialog(err);
@ -143,7 +148,9 @@ class _NotificationScreenState extends State<NotificationScreen> {
if (!ua.isAuthorized) {
return AppScaffold(
appBar: AppBar(leading: AutoAppBarLeading(), title: Text('screenNotification').tr()),
appBar: AppBar(
leading: AutoAppBarLeading(),
title: Text('screenNotification').tr()),
body: Center(child: UnauthorizedHint()),
);
}
@ -153,7 +160,9 @@ class _NotificationScreenState extends State<NotificationScreen> {
leading: AutoAppBarLeading(),
title: Text('screenNotification').tr(),
actions: [
IconButton(icon: const Icon(Symbols.checklist), onPressed: _isSubmitting ? null : _markAllAsRead),
IconButton(
icon: const Icon(Symbols.checklist),
onPressed: _isSubmitting ? null : _markAllAsRead),
const Gap(8),
],
),
@ -167,13 +176,17 @@ class _NotificationScreenState extends State<NotificationScreen> {
return _fetchNotifications();
},
child: InfiniteList(
padding: EdgeInsets.only(top: 16, bottom: math.max(MediaQuery.of(context).padding.bottom, 16)),
padding: EdgeInsets.only(
top: 16,
bottom:
math.max(MediaQuery.of(context).padding.bottom, 16)),
itemCount: _notifications.length,
onFetchData: () {
_fetchNotifications();
},
isLoading: _isBusy,
hasReachedMax: _totalCount != null && _notifications.length >= _totalCount!,
hasReachedMax: _totalCount != null &&
_notifications.length >= _totalCount!,
itemBuilder: (context, idx) {
final nty = _notifications[idx];
return Row(
@ -186,12 +199,19 @@ class _NotificationScreenState extends State<NotificationScreen> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (nty.readAt == null)
StyledWidget(Badge(label: Text('notificationUnread').tr())).padding(bottom: 4),
Text(nty.title, style: Theme.of(context).textTheme.titleMedium),
StyledWidget(Badge(
label: Text('notificationUnread').tr()))
.padding(bottom: 4),
Text(nty.title,
style: Theme.of(context).textTheme.titleMedium),
if (nty.subtitle != null)
Text(nty.subtitle!, style: Theme.of(context).textTheme.titleSmall),
Text(nty.subtitle!,
style:
Theme.of(context).textTheme.titleSmall),
if (nty.subtitle != null) const Gap(4),
SelectionArea(child: MarkdownTextContent(content: nty.body, isAutoWarp: true)),
SelectionArea(
child: MarkdownTextContent(
content: nty.body, isAutoWarp: true)),
if ([
'interactive.reply',
'interactive.feedback',
@ -201,31 +221,43 @@ class _NotificationScreenState extends State<NotificationScreen> {
GestureDetector(
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(8)),
border: Border.all(color: Theme.of(context).dividerColor, width: 1),
borderRadius: const BorderRadius.all(
Radius.circular(8)),
border: Border.all(
color: Theme.of(context).dividerColor,
width: 1),
),
child: PostItem(
data: SnPost.fromJson(nty.metadata['related_post']!),
data: SnPost.fromJson(
nty.metadata['related_post']!),
showComments: false,
showReactions: false,
showMenu: false,
),
).padding(vertical: 4),
),
onTap: () {
GoRouter.of(context).pushNamed(
'postDetail',
pathParameters: {'slug': nty.metadata['related_post']!['id'].toString()},
pathParameters: {
'slug': nty
.metadata['related_post']!['id']
.toString()
},
);
},
).padding(top: 8),
const Gap(8),
Row(
children: [
Text(DateFormat('yy/MM/dd').format(nty.createdAt)).fontSize(12),
Text(DateFormat('yy/MM/dd')
.format(nty.createdAt))
.fontSize(12),
const Gap(4),
Text('·', style: TextStyle(fontSize: 12)),
const Gap(4),
Text(RelativeTime(context).format(nty.createdAt)).fontSize(12),
Text(RelativeTime(context)
.format(nty.createdAt))
.fontSize(12),
],
).opacity(0.75),
],
@ -235,8 +267,10 @@ class _NotificationScreenState extends State<NotificationScreen> {
IconButton(
icon: const Icon(Symbols.check),
padding: EdgeInsets.all(0),
visualDensity: const VisualDensity(horizontal: -4, vertical: -4),
onPressed: _isSubmitting ? null : () => _markOneAsRead(nty),
visualDensity:
const VisualDensity(horizontal: -4, vertical: -4),
onPressed:
_isSubmitting ? null : () => _markOneAsRead(nty),
),
],
).padding(horizontal: 16);