💄 Optimized notification list
This commit is contained in:
parent
6e00a99803
commit
9012566dbf
@ -487,5 +487,6 @@
|
|||||||
"shareImageFooter": "Only on the Solar Network",
|
"shareImageFooter": "Only on the Solar Network",
|
||||||
"fileSavedAt": "File saved at @path",
|
"fileSavedAt": "File saved at @path",
|
||||||
"showIp": "Show IP Address",
|
"showIp": "Show IP Address",
|
||||||
"shotOn": "Shot on @device"
|
"shotOn": "Shot on @device",
|
||||||
|
"unread": "Unread"
|
||||||
}
|
}
|
||||||
|
@ -483,5 +483,6 @@
|
|||||||
"shareImageFooter": "上 Solar Network 看更多有趣帖子",
|
"shareImageFooter": "上 Solar Network 看更多有趣帖子",
|
||||||
"fileSavedAt": "文件保存于 @path",
|
"fileSavedAt": "文件保存于 @path",
|
||||||
"showIp": "显示 IP 地址",
|
"showIp": "显示 IP 地址",
|
||||||
"shotOn": "由 @device 拍摄"
|
"shotOn": "由 @device 拍摄",
|
||||||
|
"unread": "未读"
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,9 @@ part 'notification.g.dart';
|
|||||||
|
|
||||||
const Map<String, IconData> NotificationTopicIcons = {
|
const Map<String, IconData> NotificationTopicIcons = {
|
||||||
'passport.security.alert': Icons.gpp_maybe,
|
'passport.security.alert': Icons.gpp_maybe,
|
||||||
|
'interactive.subscription': Icons.subscriptions,
|
||||||
|
'interactive.feedback': Icons.add_reaction,
|
||||||
|
'messaging.callStart': Icons.call_received,
|
||||||
};
|
};
|
||||||
|
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
@ -55,7 +55,11 @@ class NotificationProvider extends GetxController {
|
|||||||
await client.put('/notifications/read', {'messages': markList});
|
await client.put('/notifications/read', {'messages': markList});
|
||||||
}
|
}
|
||||||
|
|
||||||
nty.notifications.clear();
|
nty.notifications.value = nty.notifications.map((x) {
|
||||||
|
x.readAt = DateTime.now();
|
||||||
|
return x;
|
||||||
|
}).toList();
|
||||||
|
nty.notifications.refresh();
|
||||||
|
|
||||||
isBusy.value = false;
|
isBusy.value = false;
|
||||||
}
|
}
|
||||||
@ -79,7 +83,8 @@ class NotificationProvider extends GetxController {
|
|||||||
|
|
||||||
await client.put('/notifications/read/${element.id}', {});
|
await client.put('/notifications/read/${element.id}', {});
|
||||||
|
|
||||||
nty.notifications.removeAt(index);
|
nty.notifications[0].readAt = DateTime.now();
|
||||||
|
nty.notifications.refresh();
|
||||||
|
|
||||||
isBusy.value = false;
|
isBusy.value = false;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import 'package:solian/models/notification.dart';
|
|||||||
import 'package:solian/providers/notifications.dart';
|
import 'package:solian/providers/notifications.dart';
|
||||||
import 'package:solian/widgets/loading_indicator.dart';
|
import 'package:solian/widgets/loading_indicator.dart';
|
||||||
import 'package:solian/widgets/markdown_text_content.dart';
|
import 'package:solian/widgets/markdown_text_content.dart';
|
||||||
|
import 'package:solian/widgets/relative_date.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
class NotificationScreen extends StatefulWidget {
|
class NotificationScreen extends StatefulWidget {
|
||||||
@ -107,12 +108,26 @@ class _NotificationScreenState extends State<NotificationScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Icon(NotificationTopicIcons[element.topic]),
|
Icon(NotificationTopicIcons[element.topic]),
|
||||||
const Gap(12),
|
const Gap(16),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment:
|
crossAxisAlignment:
|
||||||
CrossAxisAlignment.start,
|
CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
if (element.readAt == null)
|
||||||
|
Badge(
|
||||||
|
label: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(
|
||||||
|
Icons.new_releases_outlined,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 12,
|
||||||
|
),
|
||||||
|
const Gap(4),
|
||||||
|
Text('unread'.tr),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
).paddingOnly(bottom: 4),
|
||||||
Text(
|
Text(
|
||||||
element.title,
|
element.title,
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
@ -126,6 +141,7 @@ class _NotificationScreenState extends State<NotificationScreen> {
|
|||||||
.textTheme
|
.textTheme
|
||||||
.titleSmall,
|
.titleSmall,
|
||||||
),
|
),
|
||||||
|
if (element.subtitle != null)
|
||||||
const Gap(4),
|
const Gap(4),
|
||||||
MarkdownTextContent(
|
MarkdownTextContent(
|
||||||
content: element.body,
|
content: element.body,
|
||||||
@ -134,6 +150,29 @@ class _NotificationScreenState extends State<NotificationScreen> {
|
|||||||
parentId:
|
parentId:
|
||||||
'notification-${element.id}',
|
'notification-${element.id}',
|
||||||
),
|
),
|
||||||
|
const Gap(8),
|
||||||
|
Opacity(
|
||||||
|
opacity: 0.75,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
RelativeDate(
|
||||||
|
element.createdAt,
|
||||||
|
style: TextStyle(fontSize: 12),
|
||||||
|
),
|
||||||
|
const Gap(4),
|
||||||
|
Text(
|
||||||
|
'·',
|
||||||
|
style: TextStyle(fontSize: 12),
|
||||||
|
),
|
||||||
|
const Gap(4),
|
||||||
|
RelativeDate(
|
||||||
|
element.createdAt,
|
||||||
|
style: TextStyle(fontSize: 12),
|
||||||
|
isFull: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -4,20 +4,25 @@ import 'package:timeago/timeago.dart';
|
|||||||
|
|
||||||
class RelativeDate extends StatelessWidget {
|
class RelativeDate extends StatelessWidget {
|
||||||
final DateTime date;
|
final DateTime date;
|
||||||
|
final TextStyle? style;
|
||||||
final bool isFull;
|
final bool isFull;
|
||||||
|
|
||||||
const RelativeDate(this.date, {super.key, this.isFull = false});
|
const RelativeDate(this.date, {super.key, this.style, this.isFull = false});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (isFull) {
|
if (isFull) {
|
||||||
return Text(DateFormat('y/M/d HH:mm').format(date));
|
return Text(
|
||||||
|
DateFormat('y/M/d HH:mm').format(date),
|
||||||
|
style: style,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return Text(
|
return Text(
|
||||||
format(
|
format(
|
||||||
date,
|
date,
|
||||||
locale: 'en_short',
|
locale: 'en_short',
|
||||||
),
|
),
|
||||||
|
style: style,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user