mirror of
https://gitlab.com/mysocialportal/relatica
synced 2024-10-18 12:23:31 +00:00
Add notification clearing capability (server side not working)
This commit is contained in:
parent
f4dee56650
commit
2c9357741f
4 changed files with 120 additions and 7 deletions
|
@ -46,6 +46,14 @@ class FriendicaClient {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FutureResult<bool, ExecError> clearNotifications() async {
|
||||||
|
final url = 'https://$serverName/api/v1/notifications/clear';
|
||||||
|
final request = Uri.parse(url);
|
||||||
|
_logger.finest(() => 'Clearing unread notifications');
|
||||||
|
final response = await _postUrl(request, {});
|
||||||
|
return response.mapValue((value) => true);
|
||||||
|
}
|
||||||
|
|
||||||
FutureResult<List<TimelineEntry>, ExecError> getUserTimeline(
|
FutureResult<List<TimelineEntry>, ExecError> getUserTimeline(
|
||||||
{String userId = '', int page = 1, int count = 10}) async {
|
{String userId = '', int page = 1, int count = 10}) async {
|
||||||
_logger.finest(() => 'Getting user timeline for $userId');
|
_logger.finest(() => 'Getting user timeline for $userId');
|
||||||
|
|
|
@ -1,6 +1,53 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
final getIt = GetIt.instance;
|
final getIt = GetIt.instance;
|
||||||
|
|
||||||
String randomId() => const Uuid().v4().toString();
|
String randomId() => const Uuid().v4().toString();
|
||||||
|
|
||||||
|
Future<bool?> showConfirmDialog(BuildContext context, String caption) {
|
||||||
|
return showDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: Text(caption),
|
||||||
|
actions: <Widget>[
|
||||||
|
ElevatedButton(
|
||||||
|
child: const Text('OK'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context, true); // showDialog() returns true
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool?> showYesNoDialog(BuildContext context, String caption) {
|
||||||
|
return showDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: Text(caption),
|
||||||
|
actions: <Widget>[
|
||||||
|
ElevatedButton(
|
||||||
|
child: const Text('Yes'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context, true); // showDialog() returns true
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
child: const Text('No'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context, false); // showDialog() returns false
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,9 @@ import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import '../controls/app_bottom_nav_bar.dart';
|
import '../controls/app_bottom_nav_bar.dart';
|
||||||
import '../controls/notifications_control.dart';
|
import '../controls/notifications_control.dart';
|
||||||
|
import '../globals.dart';
|
||||||
import '../services/notifications_manager.dart';
|
import '../services/notifications_manager.dart';
|
||||||
|
import '../utils/snackbar_builder.dart';
|
||||||
|
|
||||||
class NotificationsScreen extends StatelessWidget {
|
class NotificationsScreen extends StatelessWidget {
|
||||||
const NotificationsScreen({super.key});
|
const NotificationsScreen({super.key});
|
||||||
|
@ -12,24 +14,62 @@ class NotificationsScreen extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final manager = context.watch<NotificationsManager>();
|
final manager = context.watch<NotificationsManager>();
|
||||||
final notifications = manager.notifications;
|
final notifications = manager.notifications;
|
||||||
|
late final String title;
|
||||||
|
late final Widget body;
|
||||||
if (notifications.isEmpty) {
|
if (notifications.isEmpty) {
|
||||||
manager.updateNotifications();
|
manager.updateNotifications();
|
||||||
}
|
title = 'Notifications';
|
||||||
return Scaffold(
|
body = Center(
|
||||||
appBar: AppBar(
|
child: Column(
|
||||||
title: Text('Notifications'),
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
),
|
children: [
|
||||||
body: ListView.separated(
|
Text('No notifications'),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
final unreadCount = notifications.where((e) => !e.seen).length;
|
||||||
|
title = 'Notifications ($unreadCount)';
|
||||||
|
body = ListView.separated(
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
return NotificationControl(notification: notifications[index]);
|
return NotificationControl(notification: notifications[index]);
|
||||||
},
|
},
|
||||||
separatorBuilder: (context, index) {
|
separatorBuilder: (context, index) {
|
||||||
return Divider();
|
return Divider();
|
||||||
},
|
},
|
||||||
itemCount: notifications.length),
|
itemCount: notifications.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text(title),
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: () async => _clearAllNotifications(context, manager),
|
||||||
|
icon: Icon(Icons.clear_all),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: RefreshIndicator(
|
||||||
|
onRefresh: () async {
|
||||||
|
await manager.updateNotifications();
|
||||||
|
},
|
||||||
|
child: body,
|
||||||
|
),
|
||||||
bottomNavigationBar: AppBottomNavBar(
|
bottomNavigationBar: AppBottomNavBar(
|
||||||
currentButton: NavBarButtons.notifications,
|
currentButton: NavBarButtons.notifications,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _clearAllNotifications(
|
||||||
|
BuildContext context, NotificationsManager manager) async {
|
||||||
|
final confirmed =
|
||||||
|
await showYesNoDialog(context, 'Clear all notifications?');
|
||||||
|
if (confirmed == true) {
|
||||||
|
final message = (await manager.markAllAsRead()).fold(
|
||||||
|
onSuccess: (_) => 'Marked all notifications as read',
|
||||||
|
onError: (error) => 'Error marking notifications: $error');
|
||||||
|
buildSnackbar(context, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ class NotificationsManager extends ChangeNotifier {
|
||||||
return result.errorCast();
|
return result.errorCast();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_notifications.clear();
|
||||||
for (final n in result.value) {
|
for (final n in result.value) {
|
||||||
_notifications[n.id] = n;
|
_notifications[n.id] = n;
|
||||||
}
|
}
|
||||||
|
@ -71,4 +72,21 @@ class NotificationsManager extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return Result.ok(notifications.first);
|
return Result.ok(notifications.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FutureResult<List<UserNotification>, ExecError> markAllAsRead() async {
|
||||||
|
final auth = getIt<AuthService>();
|
||||||
|
final clientResult = auth.currentClient;
|
||||||
|
if (clientResult.isFailure) {
|
||||||
|
_logger.severe('Error getting Friendica client: ${clientResult.error}');
|
||||||
|
return clientResult.errorCast();
|
||||||
|
}
|
||||||
|
|
||||||
|
final client = clientResult.value;
|
||||||
|
final result = await client.clearNotifications();
|
||||||
|
if (result.isFailure) {
|
||||||
|
return result.errorCast();
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateNotifications();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue