refactor: make changes based on review comments

This commit is contained in:
Vick Top 2024-04-11 16:36:51 +02:00
parent 718395fb53
commit a29ecba146
10 changed files with 222 additions and 70 deletions

View file

@ -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>

View file

@ -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.

View file

@ -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.

View file

@ -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,

View file

@ -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';

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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.

View file

@ -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) {