mirror of
https://github.com/rzuasti/oott.git
synced 2026-07-08 19:21:54 +02:00
Add mark as unread action to notifications list
Adds a "Mark as unread" option to the notification popup menu (shown only for already-read items) and a swipe-right gesture, mirroring the existing "Mark as read" actions. Swipe/menu actions respect the active filter: items are removed from the list only when filtered to New or Old, and snap back when viewing All. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
c04e76157e
commit
e320d54b38
@@ -47,9 +47,6 @@ class _NotificationListState extends State<NotificationList> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
await BackendAPI.instance.markNotificationAsRead(item.id);
|
await BackendAPI.instance.markNotificationAsRead(item.id);
|
||||||
_pagingController.value = _pagingController.value.filterItems(
|
|
||||||
(n) => n.id != item.id,
|
|
||||||
);
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text('Event marked as read'),
|
content: Text('Event marked as read'),
|
||||||
@@ -57,7 +54,44 @@ class _NotificationListState extends State<NotificationList> {
|
|||||||
showCloseIcon: true,
|
showCloseIcon: true,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
return true;
|
if (_filterChoice != 3) {
|
||||||
|
_pagingController.value = _pagingController.value.filterItems(
|
||||||
|
(n) => n.id != item.id,
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> _markAsNew(
|
||||||
|
BuildContext context,
|
||||||
|
oott_model.Notification item,
|
||||||
|
) async {
|
||||||
|
if (item.isNew) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text('Notification was already marked as unread'),
|
||||||
|
behavior: SnackBarBehavior.floating,
|
||||||
|
showCloseIcon: true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
await BackendAPI.instance.markNotificationAsNew(item.id);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text('Event marked as unread'),
|
||||||
|
behavior: SnackBarBehavior.floating,
|
||||||
|
showCloseIcon: true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (_filterChoice != 3) {
|
||||||
|
_pagingController.value = _pagingController.value.filterItems(
|
||||||
|
(n) => n.id != item.id,
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -116,16 +150,26 @@ class _NotificationListState extends State<NotificationList> {
|
|||||||
Dismissible(
|
Dismissible(
|
||||||
key: UniqueKey(),
|
key: UniqueKey(),
|
||||||
confirmDismiss: (direction) =>
|
confirmDismiss: (direction) =>
|
||||||
_markAsRead(context, item),
|
direction == DismissDirection.startToEnd
|
||||||
|
? _markAsNew(context, item)
|
||||||
|
: _markAsRead(context, item),
|
||||||
background: Container(
|
background: Container(
|
||||||
|
color: Theme.of(
|
||||||
|
context,
|
||||||
|
).colorScheme.tertiaryContainer,
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
padding: const EdgeInsets.only(left: 16),
|
||||||
|
child: Icon(Icons.mark_email_unread),
|
||||||
|
),
|
||||||
|
secondaryBackground: Container(
|
||||||
color: Theme.of(
|
color: Theme.of(
|
||||||
context,
|
context,
|
||||||
).colorScheme.primaryContainer,
|
).colorScheme.primaryContainer,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.centerRight,
|
||||||
|
padding: const EdgeInsets.only(right: 16),
|
||||||
child: Icon(Icons.done),
|
child: Icon(Icons.done),
|
||||||
),
|
),
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
// tileColor: item.isNew ? Colors.amber : null,
|
|
||||||
leading: Icon(item.notificationType.icon),
|
leading: Icon(item.notificationType.icon),
|
||||||
title: Text(
|
title: Text(
|
||||||
'${FriendlyDateFormatter().format(item.createdOn)} - ${item.title}',
|
'${FriendlyDateFormatter().format(item.createdOn)} - ${item.title}',
|
||||||
@@ -136,6 +180,8 @@ class _NotificationListState extends State<NotificationList> {
|
|||||||
onSelected: (value) async {
|
onSelected: (value) async {
|
||||||
if (value == 'mark_read') {
|
if (value == 'mark_read') {
|
||||||
await _markAsRead(context, item);
|
await _markAsRead(context, item);
|
||||||
|
} else if (value == 'mark_new') {
|
||||||
|
await _markAsNew(context, item);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
itemBuilder: (context) => [
|
itemBuilder: (context) => [
|
||||||
@@ -144,6 +190,11 @@ class _NotificationListState extends State<NotificationList> {
|
|||||||
value: 'mark_read',
|
value: 'mark_read',
|
||||||
child: Text('Mark as read'),
|
child: Text('Mark as read'),
|
||||||
),
|
),
|
||||||
|
if (!item.isNew)
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: 'mark_new',
|
||||||
|
child: Text('Mark as unread'),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
onTap: () {},
|
onTap: () {},
|
||||||
|
|||||||
@@ -71,6 +71,11 @@ class BackendAPI {
|
|||||||
await _dio.get('/notifications/$id');
|
await _dio.get('/notifications/$id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> markNotificationAsNew(int id) async {
|
||||||
|
print('About to call /notifications/$id/mark_as_new');
|
||||||
|
await _dio.post('/notifications/$id/mark_as_new');
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<Notification>> listNotifications(bool? isNew, int offset) async {
|
Future<List<Notification>> listNotifications(bool? isNew, int offset) async {
|
||||||
print('About to call /notifications');
|
print('About to call /notifications');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user