relatica/lib/screens/notifications_screen.dart

153 wiersze
5.2 KiB
Dart

import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:provider/provider.dart';
import '../controls/app_bottom_nav_bar.dart';
import '../controls/notifications_control.dart';
import '../controls/responsive_max_width.dart';
import '../controls/standard_app_drawer.dart';
import '../controls/standard_appbar.dart';
import '../controls/status_and_refresh_button.dart';
import '../globals.dart';
import '../services/network_status_service.dart';
import '../services/notifications_manager.dart';
import '../utils/active_profile_selector.dart';
import '../utils/snackbar_builder.dart';
class NotificationsScreen extends StatelessWidget {
static final _logger = Logger('$NotificationsScreen');
const NotificationsScreen({super.key});
void update(NotificationsManager manager) {
manager.refreshNotifications();
}
@override
Widget build(BuildContext context) {
_logger.finest('Building');
final nss = getIt<NetworkStatusService>();
final managerResult = context
.watch<ActiveProfileSelector<NotificationsManager>>()
.activeEntry;
late final String title;
late final Widget body;
late final List<Widget> actions;
managerResult.match(onSuccess: (manager) {
final notifications = manager.notifications;
actions = [
StatusAndRefreshButton(
valueListenable: nss.notificationsUpdateStatus,
refreshFunction: () async => update(manager),
),
IconButton(
onPressed: () async => _clearAllNotifications(context, manager),
icon: const Icon(Icons.cleaning_services),
),
];
if (notifications.isEmpty) {
title = 'Notifications';
body = RefreshIndicator(
onRefresh: () async {
update(manager);
return;
},
child: const Center(
child: Column(
children: [
Center(child: Text('No notifications')),
],
)),
);
} else {
title = 'Notifications';
body = RefreshIndicator(
onRefresh: () async {
update(manager);
return;
},
child: ResponsiveMaxWidth(
child: ListView.separated(
physics: const AlwaysScrollableScrollPhysics(),
itemBuilder: (context, index) {
if (index == 0) {
return TextButton(
onPressed: () async {
final result = await manager.loadNewerNotifications();
final noMore = result.fold(
onSuccess: (values) => values.isEmpty,
onError: (_) => true);
if (context.mounted && noMore) {
buildSnackbar(
context, 'No newer notifications to load');
}
},
child: const Text('Load newer notifications'));
}
if (index == notifications.length + 1) {
return TextButton(
onPressed: () async {
final result = await manager.loadOlderNotifications();
final noMore = result.fold(
onSuccess: (values) => values.isEmpty,
onError: (_) => true);
if (context.mounted && noMore) {
buildSnackbar(
context, 'No older notifications to load');
}
},
child: const Text('Load older notifications'));
}
return NotificationControl(
notification: notifications[index - 1]);
},
separatorBuilder: (context, index) {
return const Divider(
color: Colors.black54,
height: 0.0,
);
},
itemCount: notifications.length + 2),
),
);
}
}, onError: (error) {
title = 'Notifications';
actions = [];
body = const Center(
child: Column(
children: [
Center(child: Text('Error getting notifications')),
],
));
});
return Scaffold(
appBar: StandardAppBar.build(
context,
title,
withHome: false,
withDrawer: true,
actions: actions,
),
drawer: const StandardAppDrawer(),
body: body,
bottomNavigationBar: const AppBottomNavBar(
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);
}
}
}