Merge pull request #25 from Iconica-Development/bugfix/notification_center

fix: styling and service
This commit is contained in:
mike doornenbal 2024-07-18 13:12:33 +02:00 committed by GitHub
commit 2acb617512
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 39 additions and 134 deletions

View file

@ -6,14 +6,12 @@ import 'package:flutter_notification_center_firebase/flutter_notification_center
class CustomNotificationWidget extends StatelessWidget { class CustomNotificationWidget extends StatelessWidget {
final NotificationModel notification; final NotificationModel notification;
final NotificationStyle style;
final FirebaseNotificationService notificationService; final FirebaseNotificationService notificationService;
final NotificationTranslations notificationTranslations; final NotificationTranslations notificationTranslations;
final BuildContext context; final BuildContext context;
const CustomNotificationWidget({ const CustomNotificationWidget({
required this.notification, required this.notification,
required this.style,
required this.notificationTranslations, required this.notificationTranslations,
required this.notificationService, required this.notificationService,
required this.context, required this.context,
@ -56,26 +54,18 @@ class CustomNotificationWidget extends StatelessWidget {
onTap: () async => onTap: () async =>
_navigateToNotificationDetail(context, notification), _navigateToNotificationDetail(context, notification),
child: ListTile( child: ListTile(
leading: style.showNotificationIcon != null
? Icon(
notification.icon,
color: style.leadingIconColor,
)
: null,
title: Row( title: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
notification.title, notification.title,
style: style.titleTextStyle,
), ),
), ),
], ],
), ),
trailing: IconButton( trailing: IconButton(
icon: const Icon(Icons.push_pin), icon: const Icon(Icons.push_pin),
color: style.pinnedIconColor,
onPressed: () async => onPressed: () async =>
_navigateToNotificationDetail(context, notification), _navigateToNotificationDetail(context, notification),
padding: const EdgeInsets.only(left: 60.0), padding: const EdgeInsets.only(left: 60.0),
@ -147,9 +137,8 @@ class CustomNotificationWidget extends StatelessWidget {
margin: const EdgeInsets.only(right: 8.0), margin: const EdgeInsets.only(right: 8.0),
width: 12.0, width: 12.0,
height: 12.0, height: 12.0,
decoration: BoxDecoration( decoration: const BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: style.isReadDotColor,
), ),
) )
: null, : null,
@ -170,7 +159,6 @@ class CustomNotificationWidget extends StatelessWidget {
builder: (context) => NotificationDetailPage( builder: (context) => NotificationDetailPage(
translations: notificationTranslations, translations: notificationTranslations,
notification: notification, notification: notification,
notificationStyle: style,
), ),
), ),
); );

View file

@ -63,21 +63,6 @@ class _NotificationCenterDemoState extends State<NotificationCenterDemo> {
notificationWidgetBuilder: (notification, context) => notificationWidgetBuilder: (notification, context) =>
CustomNotificationWidget( CustomNotificationWidget(
notification: notification, notification: notification,
style: const NotificationStyle(
appTitleTextStyle: TextStyle(
color: Colors.black,
fontSize: 20,
),
titleTextStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400,
fontSize: 16,
),
leadingIconColor: Colors.grey,
pinnedIconColor: Colors.grey,
isReadDotColor: Colors.red,
showNotificationIcon: true,
),
notificationService: service, notificationService: service,
notificationTranslations: const NotificationTranslations.empty(), notificationTranslations: const NotificationTranslations.empty(),
context: context, context: context,

View file

@ -18,13 +18,13 @@ dependencies:
git: git:
url: https://github.com/Iconica-Development/flutter_notification_center url: https://github.com/Iconica-Development/flutter_notification_center
path: packages/flutter_notification_center path: packages/flutter_notification_center
ref: 2.0.0 ref: 3.0.0
flutter_notification_center_firebase: flutter_notification_center_firebase:
git: git:
url: https://github.com/Iconica-Development/flutter_notification_center url: https://github.com/Iconica-Development/flutter_notification_center
path: packages/flutter_notification_center_firebase path: packages/flutter_notification_center_firebase
ref: 2.0.0 ref: 3.0.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View file

@ -6,7 +6,6 @@ export "package:flutter_animated_widgets/flutter_animated_widgets.dart";
export "src/models/notification.dart"; export "src/models/notification.dart";
export "src/models/notification_config.dart"; export "src/models/notification_config.dart";
export "src/models/notification_theme.dart";
export "src/models/notification_translation.dart"; export "src/models/notification_translation.dart";
export "src/notification_bell.dart"; export "src/notification_bell.dart";
export "src/notification_bell_story.dart"; export "src/notification_bell_story.dart";

View file

@ -17,6 +17,8 @@ class NotificationConfig {
this.showAsSnackBar = true, this.showAsSnackBar = true,
this.enableNotificationPopups = true, this.enableNotificationPopups = true,
this.bellStyle = const AnimatedNotificationBellStyle(), this.bellStyle = const AnimatedNotificationBellStyle(),
this.pinnedIconColor = Colors.black,
this.emptyNotificationsBuilder,
}); });
/// The notification service to use for delivering notifications. /// The notification service to use for delivering notifications.
@ -38,4 +40,10 @@ class NotificationConfig {
/// The style of the notification bell. /// The style of the notification bell.
final AnimatedNotificationBellStyle bellStyle; final AnimatedNotificationBellStyle bellStyle;
/// The color of the trailing icon (if any) in the notification.
final Color? pinnedIconColor;
/// A builder function to display when there are no notifications.
final Widget Function()? emptyNotificationsBuilder;
} }

View file

@ -1,71 +0,0 @@
import "package:flutter/material.dart";
/// Defines the appearance customization for notifications.
class NotificationStyle {
/// Creates a new [NotificationStyle] instance.
///
/// Each parameter is optional and allows customizing various aspects
/// of the notification appearance.
const NotificationStyle({
this.titleTextStyle,
this.subtitleTextStyle,
this.backgroundColor,
this.leadingIconColor,
this.pinnedIconColor,
this.contentPadding,
this.titleTextAlign,
this.subtitleTextAlign,
this.dense,
this.tileDecoration,
this.emptyNotificationsBuilder,
this.appTitleTextStyle,
this.dividerColor,
this.isReadDotColor,
this.showNotificationIcon,
});
/// The text style for the title of the notification.
final TextStyle? titleTextStyle;
/// The text style for the subtitle of the notification.
final TextStyle? subtitleTextStyle;
/// The background color of the notification.
final Color? backgroundColor;
/// The color of the leading icon (if any) in the notification.
final Color? leadingIconColor;
/// The color of the trailing icon (if any) in the notification.
final Color? pinnedIconColor;
/// The padding around the content of the notification.
final EdgeInsets? contentPadding;
/// The alignment of the title text within the notification.
final TextAlign? titleTextAlign;
/// The alignment of the subtitle text within the notification.
final TextAlign? subtitleTextAlign;
/// Whether the notification should be dense or not.
final bool? dense;
/// The decoration to apply to the tile of the notification.
final BoxDecoration? tileDecoration;
/// A builder function to display when there are no notifications.
final Widget Function()? emptyNotificationsBuilder;
/// The text style for the application title.
final TextStyle? appTitleTextStyle;
/// The color of the divider.
final Color? dividerColor;
/// The color of the dot that shows that anotification has not been read.
final Color? isReadDotColor;
/// Whether to show the notification icon.
final bool? showNotificationIcon;
}

View file

@ -14,7 +14,7 @@ class NotificationTranslations {
}); });
const NotificationTranslations.empty({ const NotificationTranslations.empty({
this.appBarTitle = "Notifications", this.appBarTitle = "notifications",
this.noNotifications = "No unread notifications available.", this.noNotifications = "No unread notifications available.",
this.notificationDismissed = "Notification dismissed.", this.notificationDismissed = "Notification dismissed.",
this.notificationPinned = "Notification pinned.", this.notificationPinned = "Notification pinned.",

View file

@ -46,6 +46,7 @@ class _NotificationBellState extends State<NotificationBell> {
@override @override
Widget build(BuildContext context) => IconButton( Widget build(BuildContext context) => IconButton(
padding: EdgeInsets.zero,
onPressed: widget.onTap, onPressed: widget.onTap,
icon: AnimatedNotificationBell( icon: AnimatedNotificationBell(
duration: const Duration(seconds: 1), duration: const Duration(seconds: 1),

View file

@ -48,12 +48,11 @@ class NotificationCenterState extends State<NotificationCenter> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
var theme = Theme.of(context); var theme = Theme.of(context);
return Scaffold( return Scaffold(
backgroundColor: theme.colorScheme.surface,
appBar: AppBar( appBar: AppBar(
backgroundColor: theme.appBarTheme.backgroundColor, backgroundColor: theme.appBarTheme.backgroundColor,
title: Text( title: Text(
widget.config.translations.appBarTitle, widget.config.translations.appBarTitle,
style: theme.appBarTheme.titleTextStyle, style: theme.textTheme.headlineLarge,
), ),
centerTitle: true, centerTitle: true,
iconTheme: theme.appBarTheme.iconTheme ?? iconTheme: theme.appBarTheme.iconTheme ??
@ -76,8 +75,12 @@ class NotificationCenterState extends State<NotificationCenter> {
debugPrint("Error: ${snapshot.error}"); debugPrint("Error: ${snapshot.error}");
return Center(child: Text(widget.config.translations.errorMessage)); return Center(child: Text(widget.config.translations.errorMessage));
} else if (snapshot.data == null || snapshot.data!.isEmpty) { } else if (snapshot.data == null || snapshot.data!.isEmpty) {
return Center( return widget.config.emptyNotificationsBuilder?.call() ??
child: Text(widget.config.translations.noNotifications), Center(
child: Text(
widget.config.translations.noNotifications,
style: theme.textTheme.bodyMedium,
),
); );
} else { } else {
return ListView.builder( return ListView.builder(
@ -95,7 +98,6 @@ class NotificationCenterState extends State<NotificationCenter> {
notification, notification,
widget.config.service, widget.config.service,
widget.config.translations, widget.config.translations,
const NotificationStyle(),
), ),
child: Dismissible( child: Dismissible(
key: Key("${notification.id}_pinned"), key: Key("${notification.id}_pinned"),
@ -154,6 +156,7 @@ class NotificationCenterState extends State<NotificationCenter> {
child: _notificationItem( child: _notificationItem(
context, context,
notification, notification,
widget.config,
), ),
), ),
) )
@ -163,7 +166,6 @@ class NotificationCenterState extends State<NotificationCenter> {
notification, notification,
widget.config.service, widget.config.service,
widget.config.translations, widget.config.translations,
const NotificationStyle(),
), ),
child: Dismissible( child: Dismissible(
key: Key(notification.id), key: Key(notification.id),
@ -225,6 +227,7 @@ class NotificationCenterState extends State<NotificationCenter> {
child: _notificationItem( child: _notificationItem(
context, context,
notification, notification,
widget.config,
), ),
), ),
); );
@ -240,6 +243,7 @@ class NotificationCenterState extends State<NotificationCenter> {
Widget _notificationItem( Widget _notificationItem(
BuildContext context, BuildContext context,
NotificationModel notification, NotificationModel notification,
NotificationConfig config,
) { ) {
var theme = Theme.of(context); var theme = Theme.of(context);
var dateTimePushed = var dateTimePushed =
@ -267,7 +271,7 @@ Widget _notificationItem(
const Icon( const Icon(
Icons.circle_rounded, Icons.circle_rounded,
color: Colors.black, color: Colors.black,
size: 10, size: 8,
), ),
const SizedBox( const SizedBox(
width: 8, width: 8,
@ -283,7 +287,7 @@ Widget _notificationItem(
notification.isRead notification.isRead
? Icons.push_pin_outlined ? Icons.push_pin_outlined
: Icons.push_pin, : Icons.push_pin,
color: Colors.black, color: config.pinnedIconColor,
size: 30, size: 30,
), ),
), ),
@ -293,15 +297,15 @@ Widget _notificationItem(
], ],
Text( Text(
notification.title, notification.title,
style: notification.isRead style: notification.isRead && !notification.isPinned
? theme.textTheme.bodyMedium ? theme.textTheme.bodyMedium
: theme.textTheme.bodyLarge, : theme.textTheme.titleMedium,
), ),
], ],
), ),
Text( Text(
dateTimePushed, dateTimePushed,
style: theme.textTheme.bodyMedium, style: theme.textTheme.labelSmall,
), ),
], ],
), ),
@ -315,7 +319,6 @@ Future<void> _navigateToNotificationDetail(
NotificationModel notification, NotificationModel notification,
NotificationService notificationService, NotificationService notificationService,
NotificationTranslations notificationTranslations, NotificationTranslations notificationTranslations,
NotificationStyle style,
) async { ) async {
if (context.mounted) { if (context.mounted) {
await Navigator.push( await Navigator.push(
@ -324,7 +327,6 @@ Future<void> _navigateToNotificationDetail(
builder: (context) => NotificationDetailPage( builder: (context) => NotificationDetailPage(
translations: notificationTranslations, translations: notificationTranslations,
notification: notification, notification: notification,
notificationStyle: style,
), ),
), ),
); );

View file

@ -11,15 +11,11 @@ class NotificationDetailPage extends StatelessWidget {
/// The [notification] parameter specifies the notification /// The [notification] parameter specifies the notification
/// to display details for. /// to display details for.
const NotificationDetailPage({ const NotificationDetailPage({
required this.notificationStyle,
required this.notification, required this.notification,
required this.translations, required this.translations,
super.key, super.key,
}); });
/// The notification style.
final NotificationStyle notificationStyle;
/// The notification to display details for. /// The notification to display details for.
final NotificationModel notification; final NotificationModel notification;
@ -30,12 +26,11 @@ class NotificationDetailPage extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
var theme = Theme.of(context); var theme = Theme.of(context);
return Scaffold( return Scaffold(
backgroundColor: theme.colorScheme.surface,
appBar: AppBar( appBar: AppBar(
backgroundColor: theme.appBarTheme.backgroundColor, backgroundColor: theme.appBarTheme.backgroundColor,
title: Text( title: Text(
translations.appBarTitle, translations.appBarTitle,
style: theme.appBarTheme.titleTextStyle, style: theme.textTheme.headlineLarge,
), ),
iconTheme: theme.appBarTheme.iconTheme ?? iconTheme: theme.appBarTheme.iconTheme ??
const IconThemeData(color: Colors.white), const IconThemeData(color: Colors.white),
@ -57,12 +52,12 @@ class NotificationDetailPage extends StatelessWidget {
children: [ children: [
Text( Text(
notification.title, notification.title,
style: notificationStyle.titleTextStyle ?? const TextStyle(), style: theme.textTheme.titleMedium,
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
Text( Text(
notification.body, notification.body,
style: notificationStyle.subtitleTextStyle ?? const TextStyle(), style: theme.textTheme.bodyMedium,
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
Text( Text(
@ -70,10 +65,7 @@ class NotificationDetailPage extends StatelessWidget {
' ${DateFormat('yyyy-MM-dd HH:mm').format( ' ${DateFormat('yyyy-MM-dd HH:mm').format(
notification.dateTimePushed ?? DateTime.now(), notification.dateTimePushed ?? DateTime.now(),
)}', )}',
style: const TextStyle( style: theme.textTheme.labelSmall,
fontSize: 12,
color: Colors.grey,
),
), ),
], ],
), ),

View file

@ -1,7 +1,7 @@
name: flutter_notification_center name: flutter_notification_center
description: "A Flutter package for displaying notifications in a notification center." description: "A Flutter package for displaying notifications in a notification center."
publish_to: "none" publish_to: "none"
version: 2.0.0 version: 3.0.0
environment: environment:
sdk: ">=3.3.2 <4.0.0" sdk: ">=3.3.2 <4.0.0"
@ -14,7 +14,7 @@ dependencies:
flutter_animated_widgets: flutter_animated_widgets:
git: git:
url: https://github.com/Iconica-Development/flutter_animated_widgets url: https://github.com/Iconica-Development/flutter_animated_widgets
ref: 0.3.0 ref: 0.3.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View file

@ -238,7 +238,7 @@ class FirebaseNotificationService
.doc(notificationModel.id); .doc(notificationModel.id);
await documentReference.delete(); await documentReference.delete();
listOfActiveNotifications listOfActiveNotifications
.removeAt(listOfActiveNotifications.indexOf(notificationModel)); .removeWhere((element) => element.id == notificationModel.id);
notifyListeners(); notifyListeners();
} on Exception catch (e) { } on Exception catch (e) {
debugPrint("Error deleting document: $e"); debugPrint("Error deleting document: $e");
@ -403,6 +403,7 @@ class FirebaseNotificationService
.collection(activeNotificationsCollection) .collection(activeNotificationsCollection)
.doc(userId) .doc(userId)
.collection(activeNotificationsCollection) .collection(activeNotificationsCollection)
.where("isRead", isEqualTo: false)
.snapshots() .snapshots()
.map((e) => e.docs.length); .map((e) => e.docs.length);
yield* amount; yield* amount;

View file

@ -1,7 +1,7 @@
name: flutter_notification_center_firebase name: flutter_notification_center_firebase
description: "A new Flutter project." description: "A new Flutter project."
publish_to: "none" publish_to: "none"
version: 2.0.0 version: 3.0.0
environment: environment:
sdk: ">=2.18.0 <3.0.0" sdk: ">=2.18.0 <3.0.0"
@ -21,7 +21,7 @@ dependencies:
flutter_notification_center: flutter_notification_center:
git: git:
url: https://github.com/Iconica-Development/flutter_notification_center url: https://github.com/Iconica-Development/flutter_notification_center
ref: 2.0.0 ref: 3.0.0
path: packages/flutter_notification_center path: packages/flutter_notification_center
dev_dependencies: dev_dependencies: