mirror of
https://github.com/Iconica-Development/flutter_notification_center.git
synced 2025-05-19 00:53:44 +02:00
refactor: change notification service
This commit is contained in:
parent
af5726a822
commit
66c1def101
6 changed files with 222 additions and 55 deletions
|
@ -21,31 +21,19 @@ class NotificationCenterDemo extends StatelessWidget {
|
||||||
),
|
),
|
||||||
body: NotificationCenter(
|
body: NotificationCenter(
|
||||||
key: key,
|
key: key,
|
||||||
notificationCenterService: NotificationService(listOfNotifications: [
|
notificationCenterService:
|
||||||
|
LocalNotificationService(listOfActiveNotifications: [
|
||||||
NotificationModel(
|
NotificationModel(
|
||||||
|
id: 1,
|
||||||
title: 'Notification title 1',
|
title: 'Notification title 1',
|
||||||
body: 'Notification body 1',
|
body: 'Notification body 1',
|
||||||
dateTime: DateTime.now(),
|
dateTimePushed: DateTime.now(),
|
||||||
isRead: false,
|
|
||||||
),
|
|
||||||
NotificationModel(
|
|
||||||
title: 'RECURRING',
|
|
||||||
body: 'RECURRING',
|
|
||||||
dateTime: DateTime.now(),
|
|
||||||
isRead: false,
|
|
||||||
isScheduled: true,
|
|
||||||
),
|
),
|
||||||
NotificationModel(
|
NotificationModel(
|
||||||
|
id: 2,
|
||||||
title: 'Notification title 2',
|
title: 'Notification title 2',
|
||||||
body: 'Notification body 2',
|
body: 'Notification body 2',
|
||||||
dateTime: DateTime.now(),
|
dateTimePushed: DateTime.now(),
|
||||||
isRead: false,
|
|
||||||
),
|
|
||||||
NotificationModel(
|
|
||||||
title: 'Notification title 3',
|
|
||||||
body: 'Notification body 3',
|
|
||||||
dateTime: DateTime.now(),
|
|
||||||
isRead: false,
|
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
notificationTheme: const NotificationStyle(
|
notificationTheme: const NotificationStyle(
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
library notification_center;
|
library notification_center;
|
||||||
|
|
||||||
export 'package:flutter_notification_center/src/services/notification_service.dart';
|
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/notification_center.dart';
|
||||||
export 'package:flutter_notification_center/src/models/notification.dart';
|
export 'package:flutter_notification_center/src/models/notification.dart';
|
||||||
export 'package:flutter_notification_center/src/models/notification_theme.dart';
|
export 'package:flutter_notification_center/src/models/notification_theme.dart';
|
||||||
|
|
|
@ -1,26 +1,32 @@
|
||||||
enum ScheduleType {
|
enum OcurringInterval {
|
||||||
minute,
|
|
||||||
daily,
|
daily,
|
||||||
weekly,
|
weekly,
|
||||||
monthly,
|
monthly,
|
||||||
|
debug
|
||||||
}
|
}
|
||||||
|
|
||||||
class NotificationModel {
|
class NotificationModel {
|
||||||
NotificationModel({
|
NotificationModel({
|
||||||
this.id,
|
required this.id,
|
||||||
required this.title,
|
required this.title,
|
||||||
required this.body,
|
required this.body,
|
||||||
required this.dateTime,
|
this.dateTimePushed,
|
||||||
required this.isRead,
|
|
||||||
this.isScheduled = false,
|
|
||||||
this.scheduledFor,
|
this.scheduledFor,
|
||||||
|
this.recurring = false,
|
||||||
|
this.occuringInterval,
|
||||||
});
|
});
|
||||||
|
|
||||||
int? id;
|
int id;
|
||||||
String title;
|
String title;
|
||||||
String body;
|
String body;
|
||||||
DateTime dateTime;
|
DateTime? dateTimePushed;
|
||||||
bool isRead;
|
DateTime? scheduledFor;
|
||||||
bool isScheduled;
|
bool recurring;
|
||||||
ScheduleType? scheduledFor;
|
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}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,30 +9,27 @@ class NotificationCenter extends StatefulWidget {
|
||||||
final NotificationStyle? notificationTheme;
|
final NotificationStyle? notificationTheme;
|
||||||
|
|
||||||
const NotificationCenter({
|
const NotificationCenter({
|
||||||
super.key,
|
Key? key,
|
||||||
required this.notificationCenterService,
|
required this.notificationCenterService,
|
||||||
this.notificationTheme,
|
this.notificationTheme,
|
||||||
});
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_NotificationCenterState createState() => _NotificationCenterState();
|
_NotificationCenterState createState() => _NotificationCenterState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _NotificationCenterState extends State<NotificationCenter> {
|
class _NotificationCenterState extends State<NotificationCenter> {
|
||||||
late List<NotificationModel> listOfNotifications;
|
late Future<List<NotificationModel>> _notificationsFuture;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
listOfNotifications = widget.notificationCenterService.getNotifications();
|
_notificationsFuture =
|
||||||
|
widget.notificationCenterService.getActiveNotifications();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final unreadNotifications = listOfNotifications
|
|
||||||
.where((notification) => !notification.isRead)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Notification Center'),
|
title: const Text('Notification Center'),
|
||||||
|
@ -44,16 +41,27 @@ class _NotificationCenterState extends State<NotificationCenter> {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
body: unreadNotifications.isEmpty
|
body: FutureBuilder<List<NotificationModel>>(
|
||||||
? const Center(
|
future: _notificationsFuture,
|
||||||
child: Text('No unread notifications available.'),
|
builder: (context, snapshot) {
|
||||||
)
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||||
: ListView.builder(
|
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,
|
itemCount: unreadNotifications.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final notification = unreadNotifications[index];
|
final notification = unreadNotifications[index];
|
||||||
final formattedDateTime = DateFormat('yyyy-MM-dd HH:mm')
|
final formattedDateTime = notification.dateTimePushed != null
|
||||||
.format(notification.dateTime);
|
? DateFormat('yyyy-MM-dd HH:mm')
|
||||||
|
.format(notification.dateTimePushed!)
|
||||||
|
: 'Pending';
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Column(
|
title: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
@ -81,13 +89,32 @@ class _NotificationCenterState extends State<NotificationCenter> {
|
||||||
icon: const Icon(Icons.clear),
|
icon: const Icon(Icons.clear),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
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),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
136
lib/src/services/local_notification_service.dart
Normal file
136
lib/src/services/local_notification_service.dart
Normal file
|
@ -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<NotificationModel> listOfActiveNotifications;
|
||||||
|
@override
|
||||||
|
List<NotificationModel> 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<List<NotificationModel>> 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<void> 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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,24 @@
|
||||||
import 'package:flutter_notification_center/src/models/notification.dart';
|
import 'package:flutter_notification_center/src/models/notification.dart';
|
||||||
|
|
||||||
class NotificationService {
|
abstract class NotificationService {
|
||||||
List<NotificationModel> listOfNotifications;
|
List<NotificationModel> listOfActiveNotifications;
|
||||||
|
List<NotificationModel> listOfPlannedNotifications;
|
||||||
|
|
||||||
NotificationService({this.listOfNotifications = const []});
|
NotificationService(
|
||||||
|
{this.listOfActiveNotifications = const [],
|
||||||
|
this.listOfPlannedNotifications = const []});
|
||||||
|
|
||||||
void addNotification(NotificationModel notification) {
|
Future pushNotification(NotificationModel notification);
|
||||||
listOfNotifications.add(notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<NotificationModel> getNotifications() {
|
Future<List<NotificationModel>> getActiveNotifications();
|
||||||
return listOfNotifications;
|
|
||||||
}
|
Future createScheduledNotification(NotificationModel notification);
|
||||||
|
|
||||||
|
Future createRecurringNotification(NotificationModel notification);
|
||||||
|
|
||||||
|
Future deleteScheduledNotification(NotificationModel notificationId);
|
||||||
|
|
||||||
|
Future dismissActiveNotification(NotificationModel notificationId);
|
||||||
|
|
||||||
|
Future checkForScheduledNotifications();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue