mirror of
https://github.com/Iconica-Development/flutter_notification_center.git
synced 2025-05-18 16:43:44 +02:00
refactor: change to monorepo and add notificationWidgetBuilder
This commit is contained in:
parent
13e950fc43
commit
d48a42ccda
39 changed files with 618 additions and 873 deletions
|
@ -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'
|
|
@ -1,4 +0,0 @@
|
|||
mixin FirebaseCollectionNames {
|
||||
static const String active_notifications = 'active_notifications';
|
||||
static const String planned_notifications = 'planned_notifications';
|
||||
}
|
|
@ -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<NotificationModel> listOfActiveNotifications;
|
||||
// @override
|
||||
// List<NotificationModel> listOfPlannedNotifications;
|
||||
|
||||
// late Timer _timer;
|
||||
|
||||
// LocalNotificationService(
|
||||
// {this.listOfActiveNotifications = const [],
|
||||
// this.listOfPlannedNotifications = const []}) {
|
||||
// _startTimer();
|
||||
// }
|
||||
|
||||
// void _startTimer() {
|
||||
// _timer = Timer.periodic(const Duration(seconds: 5), (timer) {
|
||||
// debugPrint('Checking for scheduled notifications...');
|
||||
// checkForScheduledNotifications();
|
||||
// });
|
||||
// }
|
||||
|
||||
// void _cancelTimer() {
|
||||
// _timer.cancel();
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future pushNotification(NotificationModel notification) async {
|
||||
// notification.dateTimePushed = DateTime.now();
|
||||
// listOfActiveNotifications.add(notification);
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future<List<NotificationModel>> getActiveNotifications() async {
|
||||
// print('Getting all active notifications...');
|
||||
// return listOfActiveNotifications;
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future createScheduledNotification(NotificationModel notification) async {
|
||||
// listOfPlannedNotifications = [...listOfPlannedNotifications, notification];
|
||||
// print('Creating scheduled notification: $notification');
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future createRecurringNotification(NotificationModel notification) async {
|
||||
// // If recurring, update the scheduled date for the next occurrence
|
||||
// notification.title = notification.id.toString();
|
||||
// await pushNotification(notification);
|
||||
// if (notification.recurring) {
|
||||
// switch (notification.occuringInterval) {
|
||||
// case OcurringInterval.daily:
|
||||
// notification.scheduledFor =
|
||||
// notification.scheduledFor!.add(const Duration(days: 1));
|
||||
// break;
|
||||
// case OcurringInterval.weekly:
|
||||
// notification.scheduledFor =
|
||||
// notification.scheduledFor!.add(const Duration(days: 7));
|
||||
// break;
|
||||
// case OcurringInterval.monthly:
|
||||
// // Add logic for monthly recurrence, e.g., adding 1 month to the scheduled date
|
||||
// break;
|
||||
// case OcurringInterval.debug:
|
||||
// notification.scheduledFor =
|
||||
// notification.scheduledFor!.add(const Duration(seconds: 5));
|
||||
// break;
|
||||
// case null:
|
||||
// // TODO: Handle this case.
|
||||
// }
|
||||
|
||||
// // Create the next recurring notification
|
||||
// listOfPlannedNotifications = [
|
||||
// ...listOfPlannedNotifications,
|
||||
// notification
|
||||
// ];
|
||||
// print('Created recurring notification for: ${notification.scheduledFor}');
|
||||
// }
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future deleteScheduledNotification(NotificationModel notification) async {
|
||||
// listOfPlannedNotifications =
|
||||
// listOfPlannedNotifications.where((n) => n != notification).toList();
|
||||
// print('Notification deleted: $notification');
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future dismissActiveNotification(NotificationModel notification) async {
|
||||
// String id = notification.id;
|
||||
// listOfActiveNotifications.removeWhere((n) => n.id == id);
|
||||
// print('Notification with ID $id dismissed');
|
||||
// print('List of active notifications: $listOfActiveNotifications');
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future<void> checkForScheduledNotifications() async {
|
||||
// DateTime currentTime = DateTime.now();
|
||||
|
||||
// if (listOfPlannedNotifications.isEmpty) {
|
||||
// print('There are no scheduled notifications to be pushed');
|
||||
// return;
|
||||
// }
|
||||
|
||||
// for (NotificationModel notification
|
||||
// in listOfPlannedNotifications.toList()) {
|
||||
// // Check if scheduledFor is not null
|
||||
// if (notification.scheduledFor != null) {
|
||||
// // Check if the scheduled date and time is before or equal to the current date and time
|
||||
// if (notification.scheduledFor!.isBefore(currentTime) ||
|
||||
// notification.scheduledFor!.isAtSameMomentAs(currentTime)) {
|
||||
// // Push the notification if it's due
|
||||
// await pushNotification(notification);
|
||||
// print('Scheduled notification pushed: $notification');
|
||||
|
||||
// // If recurring, update the scheduled date for the next occurrence
|
||||
// if (notification.recurring) {
|
||||
// // Increment the ID for recurring notifications
|
||||
// notification.id += 1;
|
||||
// notification.title = notification.id.toString();
|
||||
// print('New RECURRING ID IS: ${notification.id}');
|
||||
|
||||
// // Create the next recurring notification
|
||||
// await createRecurringNotification(notification);
|
||||
// } else {
|
||||
// // Delete the notification if not recurring
|
||||
// print('Non-recurring notification removed: $notification');
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
|
@ -1,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"
|
|
@ -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";
|
|
@ -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<NotificationCenter> {
|
||||
late Future<List<NotificationModel>> _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<List<NotificationModel>>(
|
||||
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<void> _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<void> _addNewNotification() async {
|
||||
await widget.config.service.pushNotification(
|
||||
NotificationModel(
|
||||
id: UniqueKey().toString(),
|
||||
title: UniqueKey().toString(),
|
||||
icon: Icons.notifications_active,
|
||||
body: "This is a new notification",
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
43
packages/flutter_notification_center/.gitignore
vendored
Normal file
43
packages/flutter_notification_center/.gitignore
vendored
Normal file
|
@ -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
|
16
packages/flutter_notification_center/README.md
Normal file
16
packages/flutter_notification_center/README.md
Normal file
|
@ -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.
|
|
@ -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
|
|
@ -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<void> _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<void> dismissNotification(
|
||||
FirebaseNotificationService notificationService,
|
||||
NotificationModel notification,
|
||||
) async {
|
||||
await notificationService.dismissActiveNotification(notification);
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text("Notification dismissed"),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> markNotificationAsRead(
|
||||
FirebaseNotificationService notificationService,
|
||||
NotificationModel notification,
|
||||
) async {
|
||||
await notificationService.markNotificationAsRead(notification);
|
||||
}
|
||||
}
|
|
@ -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<void> _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<void> _signInUser() async {
|
|||
}
|
||||
|
||||
class NotificationCenterDemo extends StatefulWidget {
|
||||
const NotificationCenterDemo({Key? key}) : super(key: key);
|
||||
const NotificationCenterDemo({super.key});
|
||||
|
||||
@override
|
||||
State<NotificationCenterDemo> createState() => _NotificationCenterDemoState();
|
||||
|
@ -69,17 +69,29 @@ class _NotificationCenterDemoState extends State<NotificationCenterDemo> {
|
|||
Widget build(BuildContext context) {
|
||||
var config = NotificationConfig(
|
||||
service: Provider.of<FirebaseNotificationService>(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<FirebaseNotificationService>(context),
|
||||
notificationTranslations: const NotificationTranslations(),
|
||||
context: context,
|
||||
),
|
||||
seperateNotificationsWithDivider: true,
|
||||
);
|
||||
|
||||
return Scaffold(
|
49
packages/flutter_notification_center/example/pubspec.yaml
Normal file
49
packages/flutter_notification_center/example/pubspec.yaml
Normal file
|
@ -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
|
||||
|
|
@ -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";
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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.
|
||||
///
|
|
@ -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 {
|
|
@ -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<NotificationCenter> {
|
||||
late Future<List<NotificationModel>> _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<List<NotificationModel>>(
|
||||
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),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
|
@ -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(
|
|
@ -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 {
|
32
packages/flutter_notification_center/pubspec.yaml
Normal file
32
packages/flutter_notification_center/pubspec.yaml
Normal file
|
@ -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
|
12
packages/flutter_notification_center/test/widget_test.dart
Normal file
12
packages/flutter_notification_center/test/widget_test.dart
Normal file
|
@ -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);
|
||||
});
|
||||
}
|
52
packages/flutter_notification_center_firebase/.gitignore
vendored
Normal file
52
packages/flutter_notification_center_firebase/.gitignore
vendored
Normal file
|
@ -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
|
||||
|
16
packages/flutter_notification_center_firebase/README.md
Normal file
16
packages/flutter_notification_center_firebase/README.md
Normal file
|
@ -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.
|
|
@ -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
|
|
@ -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";
|
|
@ -0,0 +1,4 @@
|
|||
mixin FirebaseCollectionNames {
|
||||
static const String activeNotifications = 'active_notifications';
|
||||
static const String plannedNotifications = 'planned_notifications';
|
||||
}
|
|
@ -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;
|
|
@ -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<NotificationModel> listOfPlannedNotifications;
|
||||
|
||||
// ignore: unused_field
|
||||
late Timer _timer;
|
||||
|
||||
FirebaseNotificationService(
|
||||
|
@ -33,7 +33,7 @@ class FirebaseNotificationService
|
|||
Future<void> 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<String, dynamic> notificationMap = notification.toMap();
|
||||
await plannedNotifications.doc(notification.id).set(notificationMap);
|
||||
} catch (e) {
|
||||
|
@ -113,16 +113,16 @@ class FirebaseNotificationService
|
|||
}
|
||||
|
||||
@override
|
||||
Future deleteScheduledNotification(
|
||||
Future<void> 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<void> 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;
|
|
@ -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
|
Loading…
Reference in a new issue