diff --git a/example/.metadata b/example/.metadata deleted file mode 100644 index 94c106f..0000000 --- a/example/.metadata +++ /dev/null @@ -1,45 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: "68bfaea224880b488c617afe30ab12091ea8fa4e" - channel: "stable" - -project_type: app - -# Tracks metadata for the flutter migrate command -migration: - platforms: - - platform: root - create_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e - base_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e - - platform: android - create_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e - base_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e - - platform: ios - create_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e - base_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e - - platform: linux - create_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e - base_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e - - platform: macos - create_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e - base_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e - - platform: web - create_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e - base_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e - - platform: windows - create_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e - base_revision: 68bfaea224880b488c617afe30ab12091ea8fa4e - - # User provided section - - # List of Local paths (relative to this file) that should be - # ignored by the migrate tool. - # - # Files that are not part of the templates will be ignored by default. - unmanaged_files: - - 'lib/main.dart' - - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/example/lib/config/firebase_collections.dart b/example/lib/config/firebase_collections.dart deleted file mode 100644 index 93e4986..0000000 --- a/example/lib/config/firebase_collections.dart +++ /dev/null @@ -1,4 +0,0 @@ -mixin FirebaseCollectionNames { - static const String active_notifications = 'active_notifications'; - static const String planned_notifications = 'planned_notifications'; -} diff --git a/example/lib/services/local_notification_service.dart b/example/lib/services/local_notification_service.dart deleted file mode 100644 index c4f54a3..0000000 --- a/example/lib/services/local_notification_service.dart +++ /dev/null @@ -1,136 +0,0 @@ -// 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 { -// String 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/example/pubspec.lock b/example/pubspec.lock deleted file mode 100644 index 940a500..0000000 --- a/example/pubspec.lock +++ /dev/null @@ -1,410 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _flutterfire_internals: - dependency: transitive - description: - name: _flutterfire_internals - sha256: "79b6452b4066fcbdd74c2aac354e80c591a727e0364bedccecdb5a5321784fa2" - url: "https://pub.dev" - source: hosted - version: "1.3.28" - async: - dependency: transitive - description: - name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" - url: "https://pub.dev" - source: hosted - version: "2.11.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - characters: - dependency: transitive - description: - name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" - url: "https://pub.dev" - source: hosted - version: "1.3.0" - clock: - dependency: transitive - description: - name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" - source: hosted - version: "1.1.1" - cloud_firestore: - dependency: "direct main" - description: - name: cloud_firestore - sha256: "1368754eb153676e7f188aadcc01b3d280f1e2fbe125cceb7fd319670e9846ca" - url: "https://pub.dev" - source: hosted - version: "4.16.0" - cloud_firestore_platform_interface: - dependency: transitive - description: - name: cloud_firestore_platform_interface - sha256: "8f0f25ca02a850d909c06c098d49a09b616133ac2d2acb12129e14c5310b7ebe" - url: "https://pub.dev" - source: hosted - version: "6.1.12" - cloud_firestore_web: - dependency: transitive - description: - name: cloud_firestore_web - sha256: b6f05eb405517ddda1be982ed0c707d0977a45e2fcfa2086d1125ce0916ad823 - url: "https://pub.dev" - source: hosted - version: "3.11.0" - collection: - dependency: transitive - description: - name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a - url: "https://pub.dev" - source: hosted - version: "1.18.0" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d - url: "https://pub.dev" - source: hosted - version: "1.0.6" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - firebase_auth: - dependency: "direct main" - description: - name: firebase_auth - sha256: "4a958a32c8f0ed7573153edc3b09e0552fe0aba93be9028e8dbc5148d6f49f15" - url: "https://pub.dev" - source: hosted - version: "4.19.0" - firebase_auth_platform_interface: - dependency: transitive - description: - name: firebase_auth_platform_interface - sha256: "5b26659a47fcaf6fcb36658c57d56f99e31d8393b72337ccde726bd8292baa25" - url: "https://pub.dev" - source: hosted - version: "7.2.1" - firebase_auth_web: - dependency: transitive - description: - name: firebase_auth_web - sha256: a9c9faea77db8b7215f642d7a9a715347f1c46093f025813226596e3a25879b0 - url: "https://pub.dev" - source: hosted - version: "5.11.0" - firebase_core: - dependency: "direct main" - description: - name: firebase_core - sha256: "4b45655ec1b21a1783681f72f840a2e74d298046c2b7c286ab0e4f0efbf93d0a" - url: "https://pub.dev" - source: hosted - version: "2.28.0" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - sha256: c437ae5d17e6b5cc7981cf6fd458a5db4d12979905f9aafd1fea930428a9fe63 - url: "https://pub.dev" - source: hosted - version: "5.0.0" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - sha256: "28e30e00748497b9a70db2025942a42c5d752534eb678e9b9b98db056cf404ba" - url: "https://pub.dev" - source: hosted - version: "2.14.0" - firebase_storage: - dependency: "direct main" - description: - name: firebase_storage - sha256: d140fa336d29bc9e128448bb2f582407c6dc01c8d7d4b3160e1ab198e5f7f74c - url: "https://pub.dev" - source: hosted - version: "11.7.0" - firebase_storage_platform_interface: - dependency: transitive - description: - name: firebase_storage_platform_interface - sha256: b14e6a872da7303a45e081ff55160fd772eb15b7a00bdca12c740546fb67c18f - url: "https://pub.dev" - source: hosted - version: "5.1.15" - firebase_storage_web: - dependency: transitive - description: - name: firebase_storage_web - sha256: a1ad5da5983ac91c85ca7b5b4735b580cc7e1646aa502d7fa4dff7ab899e2159 - url: "https://pub.dev" - source: hosted - version: "3.9.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_animated_widgets: - dependency: transitive - description: - path: "." - ref: "0.0.1" - resolved-ref: "0eb6ea4c2e64b757b468e23ee2055e27e8302397" - url: "https://github.com/Iconica-Development/flutter_animated_widgets" - source: git - version: "0.0.1" - flutter_dotenv: - dependency: "direct main" - description: - name: flutter_dotenv - sha256: "9357883bdd153ab78cbf9ffa07656e336b8bbb2b5a3ca596b0b27e119f7c7d77" - url: "https://pub.dev" - source: hosted - version: "5.1.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 - url: "https://pub.dev" - source: hosted - version: "2.0.3" - flutter_notification_center: - dependency: "direct main" - description: - path: ".." - relative: true - source: path - version: "1.0.0+1" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - http: - dependency: transitive - description: - name: http - sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" - url: "https://pub.dev" - source: hosted - version: "0.13.6" - http_parser: - dependency: transitive - description: - name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" - url: "https://pub.dev" - source: hosted - version: "4.0.2" - intl: - dependency: "direct main" - description: - name: intl - sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" - url: "https://pub.dev" - source: hosted - version: "0.17.0" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" - url: "https://pub.dev" - source: hosted - version: "10.0.0" - leak_tracker_flutter_testing: - dependency: transitive - description: - name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 - url: "https://pub.dev" - source: hosted - version: "2.0.1" - leak_tracker_testing: - dependency: transitive - description: - name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 - url: "https://pub.dev" - source: hosted - version: "2.0.1" - lints: - dependency: transitive - description: - name: lints - sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - matcher: - dependency: transitive - description: - name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb - url: "https://pub.dev" - source: hosted - version: "0.12.16+1" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" - url: "https://pub.dev" - source: hosted - version: "0.8.0" - meta: - dependency: transitive - description: - name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 - url: "https://pub.dev" - source: hosted - version: "1.11.0" - nested: - dependency: transitive - description: - name: nested - sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" - url: "https://pub.dev" - source: hosted - version: "1.0.0" - path: - dependency: transitive - description: - name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" - url: "https://pub.dev" - source: hosted - version: "1.9.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - url: "https://pub.dev" - source: hosted - version: "2.1.8" - provider: - dependency: "direct main" - description: - name: provider - sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c - url: "https://pub.dev" - source: hosted - version: "6.1.2" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" - url: "https://pub.dev" - source: hosted - version: "1.10.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" - url: "https://pub.dev" - source: hosted - version: "1.11.1" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 - url: "https://pub.dev" - source: hosted - version: "2.1.2" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" - url: "https://pub.dev" - source: hosted - version: "0.6.1" - typed_data: - dependency: transitive - description: - name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c - url: "https://pub.dev" - source: hosted - version: "1.3.2" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - vm_service: - dependency: transitive - description: - name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 - url: "https://pub.dev" - source: hosted - version: "13.0.0" - web: - dependency: transitive - description: - name: web - sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" - url: "https://pub.dev" - source: hosted - version: "0.5.1" -sdks: - dart: ">=3.3.2 <4.0.0" - flutter: ">=3.3.0" diff --git a/lib/flutter_notification_center.dart b/lib/flutter_notification_center.dart deleted file mode 100644 index bc844f4..0000000 --- a/lib/flutter_notification_center.dart +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Iconica -// -// SPDX-License-Identifier: BSD-3-Clause - -export "package:flutter_notification_center/src/models/notification.dart"; -export "package:flutter_notification_center/src/models/notification_config.dart"; -export "package:flutter_notification_center/src/models/notification_theme.dart"; -export "package:flutter_notification_center/src/models/notification_translation.dart"; -export "package:flutter_notification_center/src/notification_bell.dart"; -export "package:flutter_notification_center/src/notification_bell_story.dart"; -export "package:flutter_notification_center/src/notification_center.dart"; -export "package:flutter_notification_center/src/services/notification_service.dart"; diff --git a/lib/src/notification_center.dart b/lib/src/notification_center.dart deleted file mode 100644 index b713e22..0000000 --- a/lib/src/notification_center.dart +++ /dev/null @@ -1,211 +0,0 @@ -import "package:flutter/material.dart"; -import "package:flutter_notification_center/flutter_notification_center.dart"; -import "package:flutter_notification_center/src/notification_detail.dart"; - -/// Widget for displaying the notification center. -class NotificationCenter extends StatefulWidget { - /// Constructs a new NotificationCenter instance. - /// - /// [config]: Configuration for the notification center. - const NotificationCenter({ - required this.config, - super.key, - }); - - /// Configuration for the notification center. - final NotificationConfig config; - - @override - NotificationCenterState createState() => NotificationCenterState(); -} - -/// State for the notification center. -class NotificationCenterState extends State { - late Future> _notificationsFuture; - - @override - void initState() { - super.initState(); - // ignore: discarded_futures - _notificationsFuture = widget.config.service.getActiveNotifications(); - widget.config.service.addListener(_listener); - } - - @override - void dispose() { - widget.config.service.removeListener(_listener); - super.dispose(); - } - - void _listener() { - setState(() {}); - } - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar( - title: Text( - widget.config.translations.appBarTitle, - style: widget.config.style.appTitleTextStyle, - ), - centerTitle: true, - leading: IconButton( - icon: const Icon(Icons.arrow_back), - onPressed: () { - Navigator.pop(context); - }, - ), - ), - 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 { - return ListView.builder( - itemCount: snapshot.data!.length * 2 - - 1, // Double the itemCount to include dividers - itemBuilder: (context, index) { - if (index.isOdd) { - // If index is odd, return a Divider with padding - return const Padding( - padding: EdgeInsets.symmetric(horizontal: 24.0), - child: Divider( - color: Colors.grey, // Customize as needed - thickness: 1.0, // Customize thickness as needed - ), - ); - } - var notification = snapshot.data![index ~/ 2]; - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 24.0), - child: notification.isPinned - ? GestureDetector( - onTap: () async => - _navigateToNotificationDetail(notification), - child: ListTile( - leading: Icon( - notification.icon, - color: widget.config.style.leadingIconColor, - ), - title: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Text( - notification.title, - style: widget.config.style.titleTextStyle, - ), - ), - ], - ), - trailing: IconButton( - icon: const Icon(Icons.push_pin), - color: widget.config.style.trailingIconColor, - onPressed: () async => - _navigateToNotificationDetail(notification), - ), - ), - ) - : Dismissible( - key: Key(notification.id), - onDismissed: (direction) async { - await widget.config.service - .dismissActiveNotification(notification); - // ignore: use_build_context_synchronously - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text("Notification dismissed"), - ), - ); - }, - background: Container( - color: Colors.red, - alignment: Alignment.centerRight, - child: const Icon( - Icons.delete, - color: Colors.white, - ), - ), - child: GestureDetector( - onTap: () async => - _navigateToNotificationDetail(notification), - child: ListTile( - leading: Icon( - Icons.notification_important, - color: widget.config.style.leadingIconColor, - ), - title: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Text( - notification.title, - style: - widget.config.style.titleTextStyle, - ), - ), - ], - ), - trailing: !notification.isRead - ? Container( - margin: - const EdgeInsets.only(left: 4.0), - width: 12.0, - height: 12.0, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: widget.config.style - .isReadDotColor ?? - Colors.red, - ), - ) - : null, - ), - ), - ), - ); - }, - ); - } - }, - ), - floatingActionButton: FloatingActionButton( - onPressed: _addNewNotification, - child: const Icon(Icons.add), - ), - ); - - Future _navigateToNotificationDetail( - NotificationModel notification, - ) async { - await widget.config.service.markNotificationAsRead(notification); - await Navigator.push( - // ignore: use_build_context_synchronously - context, - MaterialPageRoute( - builder: (context) => NotificationDetailPage( - config: widget.config, - notification: notification, - ), - ), - ); - } - - Future _addNewNotification() async { - await widget.config.service.pushNotification( - NotificationModel( - id: UniqueKey().toString(), - title: UniqueKey().toString(), - icon: Icons.notifications_active, - body: "This is a new notification", - ), - ); - } -} diff --git a/packages/flutter_notification_center/.gitignore b/packages/flutter_notification_center/.gitignore new file mode 100644 index 0000000..29a3a50 --- /dev/null +++ b/packages/flutter_notification_center/.gitignore @@ -0,0 +1,43 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/packages/flutter_notification_center/README.md b/packages/flutter_notification_center/README.md new file mode 100644 index 0000000..abfba57 --- /dev/null +++ b/packages/flutter_notification_center/README.md @@ -0,0 +1,16 @@ +# 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. diff --git a/example/analysis_options.yaml b/packages/flutter_notification_center/analysis_options.yaml similarity index 100% rename from example/analysis_options.yaml rename to packages/flutter_notification_center/analysis_options.yaml diff --git a/example/.gitignore b/packages/flutter_notification_center/example/.gitignore similarity index 100% rename from example/.gitignore rename to packages/flutter_notification_center/example/.gitignore diff --git a/example/README.md b/packages/flutter_notification_center/example/README.md similarity index 100% rename from example/README.md rename to packages/flutter_notification_center/example/README.md diff --git a/packages/flutter_notification_center/example/analysis_options.yaml b/packages/flutter_notification_center/example/analysis_options.yaml new file mode 100644 index 0000000..0d29021 --- /dev/null +++ b/packages/flutter_notification_center/example/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/packages/flutter_notification_center/example/lib/customer_notification.dart b/packages/flutter_notification_center/example/lib/customer_notification.dart new file mode 100644 index 0000000..0560baa --- /dev/null +++ b/packages/flutter_notification_center/example/lib/customer_notification.dart @@ -0,0 +1,143 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_notification_center/flutter_notification_center.dart'; +import 'package:flutter_notification_center_firebase/flutter_notification_center_firebase.dart'; + +class CustomNotificationWidget extends StatelessWidget { + final NotificationModel notification; + final NotificationStyle style; + final FirebaseNotificationService notificationService; + final NotificationTranslations notificationTranslations; + final BuildContext context; + + const CustomNotificationWidget({ + required this.notification, + required this.style, + required this.notificationTranslations, + required this.notificationService, + required this.context, + super.key, + }); + + @override + Widget build(BuildContext context) { + return notification.isPinned + //Pinned notification + ? GestureDetector( + onTap: () async => + _navigateToNotificationDetail(context, notification), + child: ListTile( + leading: style.showNotificationIcon != null + ? Icon( + notification.icon, + color: style.leadingIconColor, + ) + : null, + title: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Text( + notification.title, + style: style.titleTextStyle, + ), + ), + ], + ), + trailing: IconButton( + icon: const Icon(Icons.push_pin), + color: style.pinnedIconColor, + onPressed: () async => + _navigateToNotificationDetail(context, notification), + padding: const EdgeInsets.only(left: 60.0), + ), + ), + ) + //Dismissable notification + : Dismissible( + key: Key(notification.id), + onDismissed: (direction) async { + await dismissNotification(notificationService, notification); + }, + background: Container( + color: Colors.red, + alignment: Alignment.centerRight, + child: const Icon( + Icons.delete, + color: Colors.white, + ), + ), + child: GestureDetector( + onTap: () async => + _navigateToNotificationDetail(context, notification), + child: ListTile( + leading: Icon( + notification.icon, + color: style.leadingIconColor, + ), + title: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Text( + notification.title, + style: style.titleTextStyle, + ), + ), + ], + ), + trailing: !notification.isRead + ? Container( + margin: const EdgeInsets.only(right: 8.0), + width: 12.0, + height: 12.0, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: style.isReadDotColor ?? Colors.red, + ), + ) + : null, + ), + ), + ); + } + + Future _navigateToNotificationDetail( + BuildContext context, + NotificationModel notification, + ) async { + await markNotificationAsRead(notificationService, notification); + if (context.mounted) { + await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => NotificationDetailPage( + translations: notificationTranslations, + notification: notification, + notificationStyle: style, + ), + ), + ); + } + } + + Future dismissNotification( + FirebaseNotificationService notificationService, + NotificationModel notification, + ) async { + await notificationService.dismissActiveNotification(notification); + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text("Notification dismissed"), + ), + ); + } + } + + Future markNotificationAsRead( + FirebaseNotificationService notificationService, + NotificationModel notification, + ) async { + await notificationService.markNotificationAsRead(notification); + } +} diff --git a/example/lib/main.dart b/packages/flutter_notification_center/example/lib/main.dart similarity index 66% rename from example/lib/main.dart rename to packages/flutter_notification_center/example/lib/main.dart index b11d591..5af84ea 100644 --- a/example/lib/main.dart +++ b/packages/flutter_notification_center/example/lib/main.dart @@ -1,9 +1,9 @@ -import 'package:example/config/firebase_options.dart'; -import 'package:example/services/firebase_notification_service.dart'; +import 'package:example/customer_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'; @@ -47,7 +47,7 @@ Future _signInUser() async { User? user = auth.currentUser; if (user == null) { try { - UserCredential userCredential = await auth.signInWithEmailAndPassword( + await auth.signInWithEmailAndPassword( email: 'freek@iconica.nl', password: 'wachtwoord', ); @@ -58,7 +58,7 @@ Future _signInUser() async { } class NotificationCenterDemo extends StatefulWidget { - const NotificationCenterDemo({Key? key}) : super(key: key); + const NotificationCenterDemo({super.key}); @override State createState() => _NotificationCenterDemoState(); @@ -69,17 +69,29 @@ class _NotificationCenterDemoState extends State { Widget build(BuildContext context) { var config = NotificationConfig( service: Provider.of(context), - style: const NotificationStyle( - appTitleTextStyle: TextStyle( - color: Colors.black, - fontSize: 20, - ), - titleTextStyle: TextStyle( - color: Colors.black, - fontWeight: FontWeight.w400, - fontSize: 16, + notificationWidgetBuilder: (notification, context) => + CustomNotificationWidget( + 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: Provider.of(context), + notificationTranslations: const NotificationTranslations(), + context: context, ), + seperateNotificationsWithDivider: true, ); return Scaffold( diff --git a/packages/flutter_notification_center/example/pubspec.yaml b/packages/flutter_notification_center/example/pubspec.yaml new file mode 100644 index 0000000..de3c852 --- /dev/null +++ b/packages/flutter_notification_center/example/pubspec.yaml @@ -0,0 +1,49 @@ +name: example +description: "A new Flutter project." +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +version: 1.0.0 + +environment: + sdk: '>=3.3.2 <4.0.0' + +dependencies: + flutter: + sdk: flutter + intl: ^0.17.0 + + flutter_animated_widgets: + git: + url: https://github.com/Iconica-Development/flutter_animated_widgets + ref: 0.0.1 + cloud_firestore: ^4.16.1 + + flutter_dotenv: ^5.0.2 + firebase_auth: ^4.2.6 + firebase_core: ^2.5.0 + firebase_storage: ^11.0.14 + provider: ^6.1.2 + + flutter_notification_center: + path: ../ + flutter_notification_center_firebase: + path: ../../flutter_notification_center_firebase + + + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_iconica_analysis: + git: + url: https://github.com/Iconica-Development/flutter_iconica_analysis + ref: 7.0.0 + +# The following section is specific to Flutter packages. +flutter: + uses-material-design: true + assets: + - dotenv + diff --git a/packages/flutter_notification_center/lib/flutter_notification_center.dart b/packages/flutter_notification_center/lib/flutter_notification_center.dart new file mode 100644 index 0000000..fe636f9 --- /dev/null +++ b/packages/flutter_notification_center/lib/flutter_notification_center.dart @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2024 Iconica +// +// SPDX-License-Identifier: BSD-3-Clause + +export "src/models/notification.dart"; +export "src/models/notification_config.dart"; +export "src/models/notification_theme.dart"; +export "src/models/notification_translation.dart"; +export "src/notification_bell.dart"; +export "src/notification_detail.dart"; +export "src/notification_bell_story.dart"; +export "src/notification_center.dart"; +export "src/services/notification_service.dart"; diff --git a/lib/src/models/notification.dart b/packages/flutter_notification_center/lib/src/models/notification.dart similarity index 100% rename from lib/src/models/notification.dart rename to packages/flutter_notification_center/lib/src/models/notification.dart diff --git a/lib/src/models/notification_config.dart b/packages/flutter_notification_center/lib/src/models/notification_config.dart similarity index 63% rename from lib/src/models/notification_config.dart rename to packages/flutter_notification_center/lib/src/models/notification_config.dart index 1b95d48..b99d407 100644 --- a/lib/src/models/notification_config.dart +++ b/packages/flutter_notification_center/lib/src/models/notification_config.dart @@ -1,4 +1,6 @@ -import "package:flutter_notification_center/flutter_notification_center.dart"; +import 'package:flutter/material.dart'; + +import '../../flutter_notification_center.dart'; /// Configuration class for notifications. class NotificationConfig { @@ -10,16 +12,21 @@ class NotificationConfig { /// translations for notification messages. const NotificationConfig({ required this.service, - this.style = const NotificationStyle(), + required this.seperateNotificationsWithDivider, this.translations = const NotificationTranslations(), + required this.notificationWidgetBuilder, }); /// The notification service to use for delivering notifications. final NotificationService service; - /// The style of the notification. - final NotificationStyle style; + /// Whether to seperate notifications with a divider. + final bool seperateNotificationsWithDivider; /// Translations for notification messages. final NotificationTranslations translations; + + /// Widget for building each notification item. + final Widget Function(NotificationModel, BuildContext) + notificationWidgetBuilder; } diff --git a/lib/src/models/notification_theme.dart b/packages/flutter_notification_center/lib/src/models/notification_theme.dart similarity index 88% rename from lib/src/models/notification_theme.dart rename to packages/flutter_notification_center/lib/src/models/notification_theme.dart index a954952..d8c5aa0 100644 --- a/lib/src/models/notification_theme.dart +++ b/packages/flutter_notification_center/lib/src/models/notification_theme.dart @@ -11,7 +11,7 @@ class NotificationStyle { this.subtitleTextStyle, this.backgroundColor, this.leadingIconColor, - this.trailingIconColor, + this.pinnedIconColor, this.contentPadding, this.titleTextAlign, this.subtitleTextAlign, @@ -21,6 +21,7 @@ class NotificationStyle { this.appTitleTextStyle, this.dividerColor, this.isReadDotColor, + this.showNotificationIcon, }); /// The text style for the title of the notification. @@ -36,7 +37,7 @@ class NotificationStyle { final Color? leadingIconColor; /// The color of the trailing icon (if any) in the notification. - final Color? trailingIconColor; + final Color? pinnedIconColor; /// The padding around the content of the notification. final EdgeInsets? contentPadding; @@ -62,6 +63,9 @@ class NotificationStyle { /// The color of the divider. final Color? dividerColor; - /// The color of the dot indicating if the notification is read. + /// 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; } diff --git a/lib/src/models/notification_translation.dart b/packages/flutter_notification_center/lib/src/models/notification_translation.dart similarity index 100% rename from lib/src/models/notification_translation.dart rename to packages/flutter_notification_center/lib/src/models/notification_translation.dart diff --git a/lib/src/notification_bell.dart b/packages/flutter_notification_center/lib/src/notification_bell.dart similarity index 95% rename from lib/src/notification_bell.dart rename to packages/flutter_notification_center/lib/src/notification_bell.dart index b45c2ea..06e8d41 100644 --- a/lib/src/notification_bell.dart +++ b/packages/flutter_notification_center/lib/src/notification_bell.dart @@ -1,6 +1,6 @@ import "package:flutter/material.dart"; import "package:flutter_animated_widgets/flutter_animated_widgets.dart"; -import "package:flutter_notification_center/flutter_notification_center.dart"; +import "../flutter_notification_center.dart"; /// A bell icon widget that displays the number of active notifications. /// diff --git a/lib/src/notification_bell_story.dart b/packages/flutter_notification_center/lib/src/notification_bell_story.dart similarity index 90% rename from lib/src/notification_bell_story.dart rename to packages/flutter_notification_center/lib/src/notification_bell_story.dart index a279144..f2aeab7 100644 --- a/lib/src/notification_bell_story.dart +++ b/packages/flutter_notification_center/lib/src/notification_bell_story.dart @@ -1,5 +1,5 @@ import "package:flutter/material.dart"; -import "package:flutter_notification_center/flutter_notification_center.dart"; +import "../flutter_notification_center.dart"; /// A widget representing a notification bell. class NotificationBellWidgetStory extends StatelessWidget { diff --git a/packages/flutter_notification_center/lib/src/notification_center.dart b/packages/flutter_notification_center/lib/src/notification_center.dart new file mode 100644 index 0000000..cc5f4dc --- /dev/null +++ b/packages/flutter_notification_center/lib/src/notification_center.dart @@ -0,0 +1,95 @@ +import 'package:flutter/material.dart'; +import '../flutter_notification_center.dart'; + +/// Widget for displaying the notification center. +class NotificationCenter extends StatefulWidget { + /// Constructs a new NotificationCenter instance. + /// + /// [config]: Configuration for the notification center. + const NotificationCenter({ + required this.config, + super.key, + }); + + /// Configuration for the notification center. + final NotificationConfig config; + + @override + NotificationCenterState createState() => NotificationCenterState(); +} + +/// State for the notification center. +class NotificationCenterState extends State { + late Future> _notificationsFuture; + + @override + void initState() { + super.initState(); + // ignore: discarded_futures + _notificationsFuture = widget.config.service.getActiveNotifications(); + widget.config.service.addListener(_listener); + } + + @override + void dispose() { + widget.config.service.removeListener(_listener); + super.dispose(); + } + + void _listener() { + setState(() {}); + } + + @override + Widget build(BuildContext context) => Scaffold( + appBar: AppBar( + title: Text( + widget.config.translations.appBarTitle, + ), + centerTitle: true, + leading: IconButton( + icon: const Icon(Icons.arrow_back), + onPressed: () { + Navigator.pop(context); + }, + ), + ), + 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 { + return ListView.builder( + itemCount: snapshot.data!.length * 2 - 1, + itemBuilder: (context, index) { + if (index.isOdd) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 24.0), + child: widget.config.seperateNotificationsWithDivider + ? const Divider( + color: Colors.grey, + thickness: 1.0, + ) + : Container(), + ); + } + var notification = snapshot.data![index ~/ 2]; + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 12.0), + child: widget.config + .notificationWidgetBuilder(notification, context), + ); + }, + ); + } + }, + ), + ); +} diff --git a/lib/src/notification_detail.dart b/packages/flutter_notification_center/lib/src/notification_detail.dart similarity index 70% rename from lib/src/notification_detail.dart rename to packages/flutter_notification_center/lib/src/notification_detail.dart index 78dc671..d5ff647 100644 --- a/lib/src/notification_detail.dart +++ b/packages/flutter_notification_center/lib/src/notification_detail.dart @@ -1,33 +1,37 @@ import "package:flutter/material.dart"; -import "package:flutter_notification_center/flutter_notification_center.dart"; +import "../flutter_notification_center.dart"; import "package:intl/intl.dart"; /// A page displaying the details of a notification. class NotificationDetailPage extends StatelessWidget { /// Creates a new [NotificationDetailPage] instance. /// - /// The [config] parameter specifies the notification configuration. + /// The [notificationStyle] parameter specifies the notification style. /// /// The [notification] parameter specifies the notification /// to display details for. const NotificationDetailPage({ - required this.config, + required this.notificationStyle, required this.notification, + required this.translations, super.key, }); - /// The notification configuration. - final NotificationConfig config; + /// The notification style. + final NotificationStyle notificationStyle; /// The notification to display details for. final NotificationModel notification; + /// The translations for the notification detail page. + final NotificationTranslations translations; + @override Widget build(BuildContext context) => Scaffold( appBar: AppBar( title: Text( - config.translations.appBarTitle, - style: config.style.appTitleTextStyle, + translations.appBarTitle, + style: notificationStyle.appTitleTextStyle, ), centerTitle: true, ), @@ -39,12 +43,13 @@ class NotificationDetailPage extends StatelessWidget { children: [ Text( notification.title, - style: config.style.titleTextStyle ?? const TextStyle(), + style: notificationStyle.titleTextStyle ?? const TextStyle(), ), const SizedBox(height: 10), Text( notification.body, - style: config.style.subtitleTextStyle ?? const TextStyle(), + style: + notificationStyle.subtitleTextStyle ?? const TextStyle(), ), const SizedBox(height: 10), Text( diff --git a/lib/src/services/notification_service.dart b/packages/flutter_notification_center/lib/src/services/notification_service.dart similarity index 95% rename from lib/src/services/notification_service.dart rename to packages/flutter_notification_center/lib/src/services/notification_service.dart index 4464606..c3f5f12 100644 --- a/lib/src/services/notification_service.dart +++ b/packages/flutter_notification_center/lib/src/services/notification_service.dart @@ -1,7 +1,7 @@ import "dart:async"; import "package:flutter/material.dart"; -import "package:flutter_notification_center/src/models/notification.dart"; +import "../models/notification.dart"; /// An abstract class representing a service for managing notifications. abstract class NotificationService with ChangeNotifier { diff --git a/packages/flutter_notification_center/pubspec.yaml b/packages/flutter_notification_center/pubspec.yaml new file mode 100644 index 0000000..983031a --- /dev/null +++ b/packages/flutter_notification_center/pubspec.yaml @@ -0,0 +1,32 @@ +name: flutter_notification_center +description: "A new Flutter project." +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +version: 1.0.0 + +environment: + sdk: '>=3.3.2 <4.0.0' + +dependencies: + flutter: + sdk: flutter + intl: ^0.17.0 + + flutter_animated_widgets: + git: + url: https://github.com/Iconica-Development/flutter_animated_widgets + ref: 0.0.1 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_iconica_analysis: + git: + url: https://github.com/Iconica-Development/flutter_iconica_analysis + ref: 7.0.0 + +# The following section is specific to Flutter packages. +flutter: + uses-material-design: true diff --git a/packages/flutter_notification_center/test/widget_test.dart b/packages/flutter_notification_center/test/widget_test.dart new file mode 100644 index 0000000..0a17bd7 --- /dev/null +++ b/packages/flutter_notification_center/test/widget_test.dart @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: 2022 Iconica +// +// SPDX-License-Identifier: BSD-3-Clause +// SPDX-License-Identifier: GPL-3.0-or-later + +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test('test', () { + expect(true, true); + }); +} diff --git a/packages/flutter_notification_center_firebase/.gitignore b/packages/flutter_notification_center_firebase/.gitignore new file mode 100644 index 0000000..46d0fec --- /dev/null +++ b/packages/flutter_notification_center_firebase/.gitignore @@ -0,0 +1,52 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ +.dart_tools/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release + +# iOS related +/ios/ + +lib/config/ +pubspec.lock +dotenv + diff --git a/packages/flutter_notification_center_firebase/README.md b/packages/flutter_notification_center_firebase/README.md new file mode 100644 index 0000000..2b3fce4 --- /dev/null +++ b/packages/flutter_notification_center_firebase/README.md @@ -0,0 +1,16 @@ +# 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. diff --git a/packages/flutter_notification_center_firebase/analysis_options.yaml b/packages/flutter_notification_center_firebase/analysis_options.yaml new file mode 100644 index 0000000..0d29021 --- /dev/null +++ b/packages/flutter_notification_center_firebase/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/packages/flutter_notification_center_firebase/lib/flutter_notification_center_firebase.dart b/packages/flutter_notification_center_firebase/lib/flutter_notification_center_firebase.dart new file mode 100644 index 0000000..d5d82dd --- /dev/null +++ b/packages/flutter_notification_center_firebase/lib/flutter_notification_center_firebase.dart @@ -0,0 +1,9 @@ +// SPDX-FileCopyrightText: 2024 Iconica +// +// SPDX-License-Identifier: BSD-3-Clause + +export "src/services/firebase_notification_service.dart"; +export "src/config/firebase_collections.dart"; +export "src/config/environment.dart"; +export "src/config/firebase_options.dart"; +export "src/config/firebase.dart"; diff --git a/example/lib/config/environment.dart b/packages/flutter_notification_center_firebase/lib/src/config/environment.dart similarity index 100% rename from example/lib/config/environment.dart rename to packages/flutter_notification_center_firebase/lib/src/config/environment.dart diff --git a/example/lib/config/environment_config.dart b/packages/flutter_notification_center_firebase/lib/src/config/environment_config.dart similarity index 100% rename from example/lib/config/environment_config.dart rename to packages/flutter_notification_center_firebase/lib/src/config/environment_config.dart diff --git a/example/lib/config/firebase.dart b/packages/flutter_notification_center_firebase/lib/src/config/firebase.dart similarity index 100% rename from example/lib/config/firebase.dart rename to packages/flutter_notification_center_firebase/lib/src/config/firebase.dart diff --git a/packages/flutter_notification_center_firebase/lib/src/config/firebase_collections.dart b/packages/flutter_notification_center_firebase/lib/src/config/firebase_collections.dart new file mode 100644 index 0000000..e0ca12d --- /dev/null +++ b/packages/flutter_notification_center_firebase/lib/src/config/firebase_collections.dart @@ -0,0 +1,4 @@ +mixin FirebaseCollectionNames { + static const String activeNotifications = 'active_notifications'; + static const String plannedNotifications = 'planned_notifications'; +} diff --git a/example/lib/config/firebase_options.dart b/packages/flutter_notification_center_firebase/lib/src/config/firebase_options.dart similarity index 98% rename from example/lib/config/firebase_options.dart rename to packages/flutter_notification_center_firebase/lib/src/config/firebase_options.dart index 8205e6c..05be768 100644 --- a/example/lib/config/firebase_options.dart +++ b/packages/flutter_notification_center_firebase/lib/src/config/firebase_options.dart @@ -1,7 +1,7 @@ // File generated by FlutterFire CLI. // ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members -import 'package:example/config/environment_config.dart'; +import 'environment_config.dart'; import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; import 'package:flutter/foundation.dart' show TargetPlatform, defaultTargetPlatform, kIsWeb; diff --git a/example/lib/services/firebase_notification_service.dart b/packages/flutter_notification_center_firebase/lib/src/services/firebase_notification_service.dart similarity index 85% rename from example/lib/services/firebase_notification_service.dart rename to packages/flutter_notification_center_firebase/lib/src/services/firebase_notification_service.dart index 32b04c8..420e67c 100644 --- a/example/lib/services/firebase_notification_service.dart +++ b/packages/flutter_notification_center_firebase/lib/src/services/firebase_notification_service.dart @@ -2,9 +2,8 @@ import 'dart:async'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_notification_center/flutter_notification_center.dart'; import '../config/firebase_collections.dart'; -import 'package:flutter_notification_center/src/models/notification.dart'; -import 'package:flutter_notification_center/src/services/notification_service.dart'; class FirebaseNotificationService with ChangeNotifier @@ -14,6 +13,7 @@ class FirebaseNotificationService @override List listOfPlannedNotifications; + // ignore: unused_field late Timer _timer; FirebaseNotificationService( @@ -33,7 +33,7 @@ class FirebaseNotificationService Future pushNotification(NotificationModel notification) async { try { CollectionReference notifications = FirebaseFirestore.instance - .collection(FirebaseCollectionNames.active_notifications); + .collection(FirebaseCollectionNames.activeNotifications); DateTime currentDateTime = DateTime.now(); notification.dateTimePushed = currentDateTime; @@ -52,7 +52,7 @@ class FirebaseNotificationService try { CollectionReference activeNotificationsCollection = FirebaseFirestore .instance - .collection(FirebaseCollectionNames.active_notifications); + .collection(FirebaseCollectionNames.activeNotifications); QuerySnapshot querySnapshot = await activeNotificationsCollection.get(); @@ -104,7 +104,7 @@ class FirebaseNotificationService NotificationModel notification) async { try { CollectionReference plannedNotifications = FirebaseFirestore.instance - .collection(FirebaseCollectionNames.planned_notifications); + .collection(FirebaseCollectionNames.plannedNotifications); Map notificationMap = notification.toMap(); await plannedNotifications.doc(notification.id).set(notificationMap); } catch (e) { @@ -113,16 +113,16 @@ class FirebaseNotificationService } @override - Future deleteScheduledNotification( + Future deleteScheduledNotification( NotificationModel notificationModel) async { try { DocumentReference documentReference = FirebaseFirestore.instance - .collection(FirebaseCollectionNames.planned_notifications) + .collection(FirebaseCollectionNames.plannedNotifications) .doc(notificationModel.id); await documentReference.delete(); QuerySnapshot querySnapshot = await FirebaseFirestore.instance - .collection(FirebaseCollectionNames.planned_notifications) + .collection(FirebaseCollectionNames.plannedNotifications) .get(); if (querySnapshot.docs.isEmpty) { @@ -137,10 +137,11 @@ class FirebaseNotificationService } @override - Future dismissActiveNotification(NotificationModel notificationModel) async { + Future dismissActiveNotification( + NotificationModel notificationModel) async { try { DocumentReference documentReference = FirebaseFirestore.instance - .collection(FirebaseCollectionNames.active_notifications) + .collection(FirebaseCollectionNames.activeNotifications) .doc(notificationModel.id); await documentReference.delete(); listOfActiveNotifications @@ -156,7 +157,7 @@ class FirebaseNotificationService NotificationModel notificationModel) async { try { DocumentReference documentReference = FirebaseFirestore.instance - .collection(FirebaseCollectionNames.active_notifications) + .collection(FirebaseCollectionNames.activeNotifications) .doc(notificationModel.id); await documentReference.update({'isRead': true}); notificationModel.isRead = true; @@ -172,7 +173,7 @@ class FirebaseNotificationService try { CollectionReference plannedNotificationsCollection = FirebaseFirestore .instance - .collection(FirebaseCollectionNames.planned_notifications); + .collection(FirebaseCollectionNames.plannedNotifications); QuerySnapshot querySnapshot = await plannedNotificationsCollection.get(); @@ -207,13 +208,6 @@ class FirebaseNotificationService } } } - - plannedNotifications.forEach((notification) async { - if (notification.scheduledFor!.isBefore(currentTime) || - notification.scheduledFor!.isAtSameMomentAs(currentTime)) { - await deleteScheduledNotification(notification); - } - }); } catch (e) { debugPrint('Error getting planned notifications: $e'); return; diff --git a/example/pubspec.yaml b/packages/flutter_notification_center_firebase/pubspec.yaml similarity index 86% rename from example/pubspec.yaml rename to packages/flutter_notification_center_firebase/pubspec.yaml index e9fda19..570d640 100644 --- a/example/pubspec.yaml +++ b/packages/flutter_notification_center_firebase/pubspec.yaml @@ -1,4 +1,4 @@ -name: example +name: flutter_notification_center_firebase description: "A new Flutter project." publish_to: "none" @@ -21,10 +21,11 @@ dependencies: firebase_storage: ^11.0.14 cupertino_icons: ^1.0.2 - flutter_notification_center: - path: ../ provider: ^6.1.2 + flutter_notification_center: + path: ../flutter_notification_center + dev_dependencies: flutter_test: sdk: flutter diff --git a/example/test/widget_test.dart b/packages/flutter_notification_center_firebase/test/widget_test.dart similarity index 100% rename from example/test/widget_test.dart rename to packages/flutter_notification_center_firebase/test/widget_test.dart