diff --git a/example/lib/main.dart b/example/lib/main.dart index cd07b01..a2d1563 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -21,31 +21,19 @@ class NotificationCenterDemo extends StatelessWidget { ), body: NotificationCenter( key: key, - notificationCenterService: NotificationService(listOfNotifications: [ + notificationCenterService: + LocalNotificationService(listOfActiveNotifications: [ NotificationModel( + id: 1, title: 'Notification title 1', body: 'Notification body 1', - dateTime: DateTime.now(), - isRead: false, - ), - NotificationModel( - title: 'RECURRING', - body: 'RECURRING', - dateTime: DateTime.now(), - isRead: false, - isScheduled: true, + dateTimePushed: DateTime.now(), ), NotificationModel( + id: 2, title: 'Notification title 2', body: 'Notification body 2', - dateTime: DateTime.now(), - isRead: false, - ), - NotificationModel( - title: 'Notification title 3', - body: 'Notification body 3', - dateTime: DateTime.now(), - isRead: false, + dateTimePushed: DateTime.now(), ), ]), notificationTheme: const NotificationStyle( diff --git a/lib/flutter_notification_center.dart b/lib/flutter_notification_center.dart index 2fe8aaf..fd3daff 100644 --- a/lib/flutter_notification_center.dart +++ b/lib/flutter_notification_center.dart @@ -5,6 +5,7 @@ library notification_center; export 'package:flutter_notification_center/src/services/notification_service.dart'; +export 'package:flutter_notification_center/src/services/local_notification_service.dart'; export 'package:flutter_notification_center/src/notification_center.dart'; export 'package:flutter_notification_center/src/models/notification.dart'; export 'package:flutter_notification_center/src/models/notification_theme.dart'; diff --git a/lib/src/models/notification.dart b/lib/src/models/notification.dart index b0414ab..2f236e2 100644 --- a/lib/src/models/notification.dart +++ b/lib/src/models/notification.dart @@ -1,26 +1,32 @@ -enum ScheduleType { - minute, +enum OcurringInterval { daily, weekly, monthly, + debug } class NotificationModel { NotificationModel({ - this.id, + required this.id, required this.title, required this.body, - required this.dateTime, - required this.isRead, - this.isScheduled = false, + this.dateTimePushed, this.scheduledFor, + this.recurring = false, + this.occuringInterval, }); - int? id; + int id; String title; String body; - DateTime dateTime; - bool isRead; - bool isScheduled; - ScheduleType? scheduledFor; + DateTime? dateTimePushed; + DateTime? scheduledFor; + bool recurring; + OcurringInterval? occuringInterval; + + // Override toString() to provide custom string representation + @override + String toString() { + return 'NotificationModel{id: $id, title: $title, body: $body, dateTimePushed: $dateTimePushed, scheduledFor: $scheduledFor, recurring: $recurring, occuringInterval: $occuringInterval}'; + } } diff --git a/lib/src/notification_center.dart b/lib/src/notification_center.dart index 0674485..cff5370 100644 --- a/lib/src/notification_center.dart +++ b/lib/src/notification_center.dart @@ -9,30 +9,27 @@ class NotificationCenter extends StatefulWidget { final NotificationStyle? notificationTheme; const NotificationCenter({ - super.key, + Key? key, required this.notificationCenterService, this.notificationTheme, - }); + }) : super(key: key); @override _NotificationCenterState createState() => _NotificationCenterState(); } class _NotificationCenterState extends State { - late List listOfNotifications; + late Future> _notificationsFuture; @override void initState() { super.initState(); - listOfNotifications = widget.notificationCenterService.getNotifications(); + _notificationsFuture = + widget.notificationCenterService.getActiveNotifications(); } @override Widget build(BuildContext context) { - final unreadNotifications = listOfNotifications - .where((notification) => !notification.isRead) - .toList(); - return Scaffold( appBar: AppBar( title: const Text('Notification Center'), @@ -44,16 +41,27 @@ class _NotificationCenterState extends State { }, ), ), - body: unreadNotifications.isEmpty - ? const Center( - child: Text('No unread notifications available.'), - ) - : ListView.builder( + body: FutureBuilder>( + future: _notificationsFuture, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } else if (snapshot.hasError) { + return Center(child: Text('Error: ${snapshot.error}')); + } else if (snapshot.data == null || snapshot.data!.isEmpty) { + return const Center( + child: Text('No unread notifications available.')); + } else { + final unreadNotifications = snapshot.data!.toList(); + + return ListView.builder( itemCount: unreadNotifications.length, itemBuilder: (context, index) { final notification = unreadNotifications[index]; - final formattedDateTime = DateFormat('yyyy-MM-dd HH:mm') - .format(notification.dateTime); + final formattedDateTime = notification.dateTimePushed != null + ? DateFormat('yyyy-MM-dd HH:mm') + .format(notification.dateTimePushed!) + : 'Pending'; return ListTile( title: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -81,13 +89,32 @@ class _NotificationCenterState extends State { icon: const Icon(Icons.clear), onPressed: () { setState(() { - notification.isRead = true; + widget.notificationCenterService + .dismissActiveNotification(notification); + print('Notification dismissed: $notification'); }); }, ), ); }, - ), + ); + } + }, + ), + floatingActionButton: FloatingActionButton( + onPressed: () async { + await widget.notificationCenterService.createRecurringNotification( + NotificationModel( + id: 3, + title: 'HALLO', + body: 'DIT IS DE BODY', + recurring: true, + occuringInterval: OcurringInterval.debug, + scheduledFor: DateTime.now().add(const Duration(seconds: 5))), + ); + }, + child: const Icon(Icons.add), + ), ); } } diff --git a/lib/src/services/local_notification_service.dart b/lib/src/services/local_notification_service.dart new file mode 100644 index 0000000..2a2c22f --- /dev/null +++ b/lib/src/services/local_notification_service.dart @@ -0,0 +1,136 @@ +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:flutter_notification_center/src/models/notification.dart'; +import 'package:flutter_notification_center/src/services/notification_service.dart'; + +class LocalNotificationService implements NotificationService { + @override + List listOfActiveNotifications; + @override + List listOfPlannedNotifications; + + late Timer _timer; + + LocalNotificationService( + {this.listOfActiveNotifications = const [], + this.listOfPlannedNotifications = const []}) { + _startTimer(); + } + + void _startTimer() { + _timer = Timer.periodic(const Duration(seconds: 5), (timer) { + debugPrint('Checking for scheduled notifications...'); + checkForScheduledNotifications(); + }); + } + + void _cancelTimer() { + _timer.cancel(); + } + + @override + Future pushNotification(NotificationModel notification) async { + notification.dateTimePushed = DateTime.now(); + listOfActiveNotifications.add(notification); + } + + @override + Future> getActiveNotifications() async { + print('Getting all active notifications...'); + return listOfActiveNotifications; + } + + @override + Future createScheduledNotification(NotificationModel notification) async { + listOfPlannedNotifications = [...listOfPlannedNotifications, notification]; + print('Creating scheduled notification: $notification'); + } + + @override + Future createRecurringNotification(NotificationModel notification) async { + // If recurring, update the scheduled date for the next occurrence + notification.title = notification.id.toString(); + await pushNotification(notification); + if (notification.recurring) { + switch (notification.occuringInterval) { + case OcurringInterval.daily: + notification.scheduledFor = + notification.scheduledFor!.add(const Duration(days: 1)); + break; + case OcurringInterval.weekly: + notification.scheduledFor = + notification.scheduledFor!.add(const Duration(days: 7)); + break; + case OcurringInterval.monthly: + // Add logic for monthly recurrence, e.g., adding 1 month to the scheduled date + break; + case OcurringInterval.debug: + notification.scheduledFor = + notification.scheduledFor!.add(const Duration(seconds: 5)); + break; + case null: + // TODO: Handle this case. + } + + // Create the next recurring notification + listOfPlannedNotifications = [ + ...listOfPlannedNotifications, + notification + ]; + print('Created recurring notification for: ${notification.scheduledFor}'); + } + } + + @override + Future deleteScheduledNotification(NotificationModel notification) async { + listOfPlannedNotifications = + listOfPlannedNotifications.where((n) => n != notification).toList(); + print('Notification deleted: $notification'); + } + + @override + Future dismissActiveNotification(NotificationModel notification) async { + int id = notification.id; + listOfActiveNotifications.removeWhere((n) => n.id == id); + print('Notification with ID $id dismissed'); + print('List of active notifications: $listOfActiveNotifications'); + } + + @override + Future checkForScheduledNotifications() async { + DateTime currentTime = DateTime.now(); + + if (listOfPlannedNotifications.isEmpty) { + print('There are no scheduled notifications to be pushed'); + return; + } + + for (NotificationModel notification + in listOfPlannedNotifications.toList()) { + // Check if scheduledFor is not null + if (notification.scheduledFor != null) { + // Check if the scheduled date and time is before or equal to the current date and time + if (notification.scheduledFor!.isBefore(currentTime) || + notification.scheduledFor!.isAtSameMomentAs(currentTime)) { + // Push the notification if it's due + await pushNotification(notification); + print('Scheduled notification pushed: $notification'); + + // If recurring, update the scheduled date for the next occurrence + if (notification.recurring) { + // Increment the ID for recurring notifications + notification.id += 1; + notification.title = notification.id.toString(); + print('New RECURRING ID IS: ${notification.id}'); + + // Create the next recurring notification + await createRecurringNotification(notification); + } else { + // Delete the notification if not recurring + print('Non-recurring notification removed: $notification'); + } + } + } + } + } +} diff --git a/lib/src/services/notification_service.dart b/lib/src/services/notification_service.dart index add0781..a7d82d3 100644 --- a/lib/src/services/notification_service.dart +++ b/lib/src/services/notification_service.dart @@ -1,15 +1,24 @@ import 'package:flutter_notification_center/src/models/notification.dart'; -class NotificationService { - List listOfNotifications; +abstract class NotificationService { + List listOfActiveNotifications; + List listOfPlannedNotifications; - NotificationService({this.listOfNotifications = const []}); + NotificationService( + {this.listOfActiveNotifications = const [], + this.listOfPlannedNotifications = const []}); - void addNotification(NotificationModel notification) { - listOfNotifications.add(notification); - } + Future pushNotification(NotificationModel notification); - List getNotifications() { - return listOfNotifications; - } + Future> getActiveNotifications(); + + Future createScheduledNotification(NotificationModel notification); + + Future createRecurringNotification(NotificationModel notification); + + Future deleteScheduledNotification(NotificationModel notificationId); + + Future dismissActiveNotification(NotificationModel notificationId); + + Future checkForScheduledNotifications(); }