mirror of
https://github.com/Iconica-Development/flutter_notification_center.git
synced 2025-05-18 16:43:44 +02:00
refactor: make changes based on review comments
This commit is contained in:
parent
718395fb53
commit
a29ecba146
10 changed files with 222 additions and 70 deletions
68
README.md
68
README.md
|
@ -1,16 +1,66 @@
|
|||
# flutter_notification_center
|
||||
A Flutter package for creating notification center displaying a list of notifications.
|
||||
|
||||
A new Flutter project.
|
||||
## Features
|
||||
|
||||
## Getting Started
|
||||
- Notification center: A page containing a list of notifications.
|
||||
- Notification bell: A clickable bell icon that can be placed anywere showing the amound of unread notifications. Clicking the bell takes the user to the notification center.
|
||||
- Pinned notifications: A pinned notification can't be dismissed by the user from the notification center.
|
||||
- Dismissable notifications: A dismissable notification can be dismissed by the user from the notification center.
|
||||
- Notification detail page: Clicking on a notification takes the user to a notification detail page.
|
||||
- Notification types: Notification types that can be created are: instant, scheduled, recurring.
|
||||
|
||||
This project is a starting point for a Flutter application.
|
||||
## Setup
|
||||
|
||||
A few resources to get you started if this is your first Flutter project:
|
||||
To use this package, add `flutter_notification_center` as a dependency in your pubspec.yaml file.
|
||||
|
||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
||||
- For custom notification styling provide the optional notificationWidgetBuilder with your own implementation.
|
||||
|
||||
For help getting started with Flutter development, view the
|
||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
||||
The `NotificationConfig` has its own parameters, as specified below:
|
||||
| Parameter | Explanation |
|
||||
|-----------|-------------|
|
||||
| service | The notification service that will be used |
|
||||
| seperateNotificationsWithDivider | If true notifications will be seperated with dividers within the notification center |
|
||||
| translations | The translations that will be used |
|
||||
| notificationWidgetBuilder | The widget that defines the styles and logic for every notification |
|
||||
|
||||
The `notificationWidgetBuilder` expects the following parameters, as specified below:
|
||||
| Parameter | Explanation |
|
||||
|-----------|-------------|
|
||||
| notification | The notification that is being defined |
|
||||
| style | The styling that will be used for the notification |
|
||||
| notificationService | The notification service that will be used |
|
||||
| notificationTranslations | The translations that will be used for the notification|
|
||||
| context | The provided context |
|
||||
|
||||
## Usage
|
||||
Create instant notification:
|
||||
- Make a call to pushNotification() and provide a NotificationModel with the required attributes.
|
||||
|
||||
Create scheduled notification:
|
||||
- Make a call to createScheduledNotification() and provide a NotificationModel with the required attributes + scheduledFor.
|
||||
|
||||
Create recurring notification:
|
||||
- Make a call to createRecurringNotification() and provide a NotificationModel with the required attributes and the following additional attributes:
|
||||
- scheduledFor
|
||||
- recurring = true
|
||||
- occuringInterval with the pre defined interval (daily, weekly, monthly)
|
||||
|
||||
To create a pinned notification, set isPinned = true when creating the notification.
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
See [Example Code](example/lib/main.dart) for more info.
|
||||
|
||||
## Issues
|
||||
|
||||
Please file any issues, bugs or feature request as an issue on our [GitHub](https://github.com/Iconica-Development/flutter_notification_center/pulls) page. Commercial support is available if you need help with integration with your app or services. You can contact us at [support@iconica.nl](mailto:support@iconica.nl).
|
||||
|
||||
## Want to contribute
|
||||
|
||||
If you would like to contribute to the plugin (e.g. by improving the documentation, solving a bug or adding a cool new feature), please carefully review our [contribution guide](./CONTRIBUTING.md) and send us your [pull request](https://github.com/Iconica-Development/flutter_notification_center/pulls).
|
||||
|
||||
## Author
|
||||
|
||||
This `flutter_notification_center` for Flutter is developed by [Iconica](https://iconica.nl). You can contact us at <support@iconica.nl>
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
# flutter_notification_center
|
||||
|
||||
A new Flutter project.
|
||||
|
||||
## Getting Started
|
||||
|
||||
This project is a starting point for a Flutter application.
|
||||
|
||||
A few resources to get you started if this is your first Flutter project:
|
||||
|
||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
||||
|
||||
For help getting started with Flutter development, view the
|
||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
|
@ -1,16 +0,0 @@
|
|||
# example
|
||||
|
||||
A new Flutter project.
|
||||
|
||||
## Getting Started
|
||||
|
||||
This project is a starting point for a Flutter application.
|
||||
|
||||
A few resources to get you started if this is your first Flutter project:
|
||||
|
||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
||||
|
||||
For help getting started with Flutter development, view the
|
||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
|
@ -92,7 +92,7 @@ class CustomNotificationWidget extends StatelessWidget {
|
|||
height: 12.0,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: style.isReadDotColor ?? Colors.red,
|
||||
color: style.isReadDotColor,
|
||||
),
|
||||
)
|
||||
: null,
|
|
@ -1,11 +1,10 @@
|
|||
import 'package:example/customer_notification.dart';
|
||||
import 'package:example/custom_notification.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:flutter_notification_center_firebase/flutter_notification_center_firebase.dart';
|
||||
import 'package:intl/date_symbol_data_local.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:flutter_notification_center/flutter_notification_center.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
|
|
@ -12,9 +12,9 @@ class NotificationConfig {
|
|||
/// translations for notification messages.
|
||||
const NotificationConfig({
|
||||
required this.service,
|
||||
required this.seperateNotificationsWithDivider,
|
||||
this.seperateNotificationsWithDivider = true,
|
||||
this.translations = const NotificationTranslations(),
|
||||
required this.notificationWidgetBuilder,
|
||||
this.notificationWidgetBuilder,
|
||||
});
|
||||
|
||||
/// The notification service to use for delivering notifications.
|
||||
|
@ -27,6 +27,6 @@ class NotificationConfig {
|
|||
final NotificationTranslations translations;
|
||||
|
||||
/// Widget for building each notification item.
|
||||
final Widget Function(NotificationModel, BuildContext)
|
||||
final Widget Function(NotificationModel, BuildContext)?
|
||||
notificationWidgetBuilder;
|
||||
}
|
||||
|
|
|
@ -82,10 +82,117 @@ class NotificationCenterState extends State<NotificationCenter> {
|
|||
}
|
||||
var notification = snapshot.data![index ~/ 2];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||
child: widget.config
|
||||
.notificationWidgetBuilder(notification, context),
|
||||
);
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||
child: widget.config.notificationWidgetBuilder != null
|
||||
? widget.config.notificationWidgetBuilder!(
|
||||
notification, context)
|
||||
: notification.isPinned
|
||||
//Pinned notification
|
||||
? GestureDetector(
|
||||
onTap: () async =>
|
||||
_navigateToNotificationDetail(
|
||||
context,
|
||||
notification,
|
||||
widget.config.service,
|
||||
widget.config.translations,
|
||||
const NotificationStyle()),
|
||||
child: ListTile(
|
||||
leading: Icon(
|
||||
notification.icon,
|
||||
color: Colors.grey,
|
||||
),
|
||||
title: Row(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
notification.title,
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.push_pin),
|
||||
color: Colors.grey,
|
||||
onPressed: () async =>
|
||||
_navigateToNotificationDetail(
|
||||
context,
|
||||
notification,
|
||||
widget.config.service,
|
||||
widget.config.translations,
|
||||
const NotificationStyle()),
|
||||
padding:
|
||||
const EdgeInsets.only(left: 60.0),
|
||||
),
|
||||
),
|
||||
)
|
||||
//Dismissable notification
|
||||
: Dismissible(
|
||||
key: Key(notification.id),
|
||||
onDismissed: (direction) async {
|
||||
await dismissNotification(
|
||||
widget.config.service,
|
||||
notification,
|
||||
context);
|
||||
},
|
||||
background: Container(
|
||||
color: Colors.red,
|
||||
alignment: Alignment.centerRight,
|
||||
child: const Icon(
|
||||
Icons.delete,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: () async =>
|
||||
_navigateToNotificationDetail(
|
||||
context,
|
||||
notification,
|
||||
widget.config.service,
|
||||
widget.config.translations,
|
||||
const NotificationStyle()),
|
||||
child: ListTile(
|
||||
leading: Icon(
|
||||
notification.icon,
|
||||
color: Colors.grey,
|
||||
),
|
||||
title: Row(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
notification.title,
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
trailing: !notification.isRead
|
||||
? Container(
|
||||
margin: const EdgeInsets.only(
|
||||
right: 8.0),
|
||||
width: 12.0,
|
||||
height: 12.0,
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.red,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -93,3 +200,47 @@ class NotificationCenterState extends State<NotificationCenter> {
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _navigateToNotificationDetail(
|
||||
BuildContext context,
|
||||
NotificationModel notification,
|
||||
NotificationService notificationService,
|
||||
NotificationTranslations notificationTranslations,
|
||||
NotificationStyle style,
|
||||
) async {
|
||||
await markNotificationAsRead(notificationService, notification);
|
||||
if (context.mounted) {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => NotificationDetailPage(
|
||||
translations: notificationTranslations,
|
||||
notification: notification,
|
||||
notificationStyle: style,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> dismissNotification(
|
||||
NotificationService notificationService,
|
||||
NotificationModel notification,
|
||||
BuildContext context,
|
||||
) async {
|
||||
await notificationService.dismissActiveNotification(notification);
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text("Notification dismissed"),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> markNotificationAsRead(
|
||||
NotificationService notificationService,
|
||||
NotificationModel notification,
|
||||
) async {
|
||||
await notificationService.markNotificationAsRead(notification);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ abstract class NotificationService with ChangeNotifier {
|
|||
Future createRecurringNotification(NotificationModel notification);
|
||||
|
||||
/// Deletes a scheduled notification.
|
||||
Future deleteScheduledNotification(NotificationModel notification);
|
||||
Future deletePlannedNotification(NotificationModel notification);
|
||||
|
||||
/// Dismisses an active notification.
|
||||
Future dismissActiveNotification(NotificationModel notification);
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
# example
|
||||
|
||||
A new Flutter project.
|
||||
|
||||
## Getting Started
|
||||
|
||||
This project is a starting point for a Flutter application.
|
||||
|
||||
A few resources to get you started if this is your first Flutter project:
|
||||
|
||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
||||
|
||||
For help getting started with Flutter development, view the
|
||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
|
@ -113,7 +113,7 @@ class FirebaseNotificationService
|
|||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteScheduledNotification(
|
||||
Future<void> deletePlannedNotification(
|
||||
NotificationModel notificationModel) async {
|
||||
try {
|
||||
DocumentReference documentReference = FirebaseFirestore.instance
|
||||
|
@ -192,7 +192,7 @@ class FirebaseNotificationService
|
|||
if (notification.scheduledFor!.isBefore(currentTime) ||
|
||||
notification.scheduledFor!.isAtSameMomentAs(currentTime)) {
|
||||
await pushNotification(notification);
|
||||
await deleteScheduledNotification(notification);
|
||||
await deletePlannedNotification(notification);
|
||||
|
||||
//Plan new recurring notification instance
|
||||
if (notification.recurring) {
|
||||
|
|
Loading…
Reference in a new issue