From 26e0d9c1100ac0e1e767c4b9417de261c75a8669 Mon Sep 17 00:00:00 2001 From: Adrasteon Dev Date: Thu, 26 Oct 2023 19:54:37 +0200 Subject: [PATCH 1/4] Add an option to receive persistent notifications --- CHANGELOG.md | 3 +- CONTRIBUTORS.md | 1 + lib/lang/en.dart | 1 + lib/lang/fr.dart | 1 + .../widgets/switch_notifications.dart | 78 +++++++++++++++++-- lib/utils/notification_service.dart | 9 +++ 6 files changed, 85 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf53470..64d7f8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ -## v1.5.3 - 09/2023 +## v1.5.3 - 10/2023 +- Added option to receive persistent notifications - Added option to change calendar days color for colorblind users - Added option to disable date filter in experimental file picker - Added reverse filter order button in experimental file picker diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index ce72cf3..15377bc 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -7,6 +7,7 @@ - Bagas Wastu (@bagaswastu) - Harry Schiller (@waitingwittykitty) - David Coker (@daoxve) +- Adrasteon (@AdrasteonDev) ## Testing & Feedback - Augusto Vesco diff --git a/lib/lang/en.dart b/lib/lang/en.dart index be58f69..87566cc 100644 --- a/lib/lang/en.dart +++ b/lib/lang/en.dart @@ -62,6 +62,7 @@ const Map en = { 'notifications': 'Notifications', 'enableNotifications': 'Enable Notifications', 'scheduleTime': 'Schedule Time', + 'usePersistentNotifications': 'Persistent notifications', 'test': 'Test', 'notificationTitle': 'Heyy!', 'notificationBody': 'Do not forget to record 1 second of your day 👀', diff --git a/lib/lang/fr.dart b/lib/lang/fr.dart index 19cac5e..0bb895a 100644 --- a/lib/lang/fr.dart +++ b/lib/lang/fr.dart @@ -62,6 +62,7 @@ const Map fr = { 'notifications': 'Notifications', 'enableNotifications': 'Activer les notifications', 'scheduleTime': 'Horaire', + 'usePersistentNotifications': 'Notifications persistantes', 'test': 'Test', 'notificationTitle': 'Hé !', 'notificationBody': "N'oubliez pas d'enregistrer une seconde de votre journée. 👀", diff --git a/lib/pages/home/notification/widgets/switch_notifications.dart b/lib/pages/home/notification/widgets/switch_notifications.dart index a40dcc6..bfa0d62 100644 --- a/lib/pages/home/notification/widgets/switch_notifications.dart +++ b/lib/pages/home/notification/widgets/switch_notifications.dart @@ -24,13 +24,20 @@ class _SwitchNotificationsComponentState final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); final int notificationId = 1; - late bool isSwitchToggled; + late bool isNotificationSwitchToggled; TimeOfDay scheduledTimeOfDay = const TimeOfDay(hour: 20, minute: 00); + late bool isPersistentSwitchToggled; @override void initState() { super.initState(); - isSwitchToggled = NotificationService().isNotificationActivated(); + isNotificationSwitchToggled = NotificationService().isNotificationActivated(); + isPersistentSwitchToggled = NotificationService().isPersistentNotificationActivated(); + + if(isPersistentSwitchToggled) + platformNotificationDetails = platformPersistentNotificationDetails; + else + platformNotificationDetails = platformNonPersistentNotificationDetails; // Sets the default values for scheduled time getScheduledTime(); @@ -58,11 +65,21 @@ class _SwitchNotificationsComponentState super.dispose(); } - final platformNotificationDetails = const NotificationDetails( + late NotificationDetails platformNotificationDetails; + final NotificationDetails platformNonPersistentNotificationDetails = const NotificationDetails( + android: AndroidNotificationDetails( + 'channel id', + 'channel name', + channelDescription: 'channel description', + ongoing: false + ), + ); + final NotificationDetails platformPersistentNotificationDetails = const NotificationDetails( android: AndroidNotificationDetails( 'channel id', 'channel name', channelDescription: 'channel description', + ongoing: true ), ); @@ -139,7 +156,7 @@ class _SwitchNotificationsComponentState ), ), Switch( - value: isSwitchToggled, + value: isNotificationSwitchToggled, onChanged: (value) async { if (value) { Utils.logInfo( @@ -163,7 +180,7 @@ class _SwitchNotificationsComponentState /// Update switch value setState(() { - isSwitchToggled = !isSwitchToggled; + isNotificationSwitchToggled = !isNotificationSwitchToggled; }); }, activeTrackColor: AppColors.mainColor.withOpacity(0.4), @@ -227,12 +244,12 @@ class _SwitchNotificationsComponentState if (newTimeOfDay == null) return; // Enable notification if it's disabled - if (!isSwitchToggled) { + if (!isNotificationSwitchToggled) { print('here'); await Utils.requestPermission(Permission.notification); NotificationService().switchNotification(); setState(() { - isSwitchToggled = true; + isNotificationSwitchToggled = true; }); } @@ -268,6 +285,53 @@ class _SwitchNotificationsComponentState ), ), const Divider(), + Container( + padding: const EdgeInsets.symmetric(horizontal: 15.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'usePersistentNotifications'.tr, + style: TextStyle( + fontSize: MediaQuery.of(context).size.width * 0.045, + ), + ), + Switch( + value: isPersistentSwitchToggled, + onChanged: (value) async { + if (value) { + Utils.logInfo( + '[NOTIFICATIONS] - Persistent notifications were enabled', + ); + platformNotificationDetails = platformPersistentNotificationDetails; + } else { + Utils.logInfo( + '[NOTIFICATIONS] - Persistent notifications were disabled', + ); + platformNotificationDetails = platformNonPersistentNotificationDetails; + } + + /// Schedule notification if switch in ON + if(isNotificationSwitchToggled){ + flutterLocalNotificationsPlugin.cancelAll(); + await scheduleNotification(); + } + + /// Save notification on SharedPrefs + NotificationService().switchPersistentNotification(); + + /// Update switch value + setState(() { + isPersistentSwitchToggled = !isPersistentSwitchToggled; + }); + }, + activeTrackColor: AppColors.mainColor.withOpacity(0.4), + activeColor: AppColors.mainColor, + ), + ], + ), + ), + const Divider(), ], ); } diff --git a/lib/utils/notification_service.dart b/lib/utils/notification_service.dart index c026382..9e4eff0 100644 --- a/lib/utils/notification_service.dart +++ b/lib/utils/notification_service.dart @@ -2,14 +2,23 @@ import 'shared_preferences_util.dart'; class NotificationService { final _key = 'activatedNotification'; + final _persistentKey = 'activatedNotification'; // Notification is deactivated by default bool isNotificationActivated() => SharedPrefsUtil.getBool(_key) ?? false; + bool isPersistentNotificationActivated() => SharedPrefsUtil.getBool(_persistentKey) ?? false; Future _saveNotification(bool isActivated) => SharedPrefsUtil.putBool(_key, isActivated); + Future _savePersistentNotification(bool isActivated) => + SharedPrefsUtil.putBool(_persistentKey, isActivated); + void switchNotification() { _saveNotification(!isNotificationActivated()); } + + void switchPersistentNotification() { + _savePersistentNotification(!isPersistentNotificationActivated()); + } } From bde7b61bc061333facbf947c8b83a290f1f5fc09 Mon Sep 17 00:00:00 2001 From: Adrasteon Dev Date: Mon, 30 Oct 2023 16:55:23 +0100 Subject: [PATCH 2/4] Add notification methods to NotificationService --- .../widgets/switch_notifications.dart | 170 +++-------------- lib/utils/notification_service.dart | 177 ++++++++++++++++-- 2 files changed, 193 insertions(+), 154 deletions(-) diff --git a/lib/pages/home/notification/widgets/switch_notifications.dart b/lib/pages/home/notification/widgets/switch_notifications.dart index bfa0d62..82d7cae 100644 --- a/lib/pages/home/notification/widgets/switch_notifications.dart +++ b/lib/pages/home/notification/widgets/switch_notifications.dart @@ -1,17 +1,10 @@ import 'package:flutter/material.dart'; -import 'package:flutter_local_notifications/flutter_local_notifications.dart'; -import 'package:fluttertoast/fluttertoast.dart'; import 'package:get/get.dart'; -import 'package:permission_handler/permission_handler.dart'; -import 'package:timezone/data/latest.dart' as tz; -import 'package:timezone/timezone.dart' as tz; import '../../../../routes/app_pages.dart'; import '../../../../utils/constants.dart'; import '../../../../utils/notification_service.dart'; -import '../../../../utils/shared_preferences_util.dart'; import '../../../../utils/theme.dart'; -import '../../../../utils/utils.dart'; class SwitchNotificationsComponent extends StatefulWidget { @override @@ -21,43 +14,19 @@ class SwitchNotificationsComponent extends StatefulWidget { class _SwitchNotificationsComponentState extends State { - final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); - - final int notificationId = 1; late bool isNotificationSwitchToggled; TimeOfDay scheduledTimeOfDay = const TimeOfDay(hour: 20, minute: 00); late bool isPersistentSwitchToggled; + NotificationService notificationService = NotificationService(); @override void initState() { super.initState(); - isNotificationSwitchToggled = NotificationService().isNotificationActivated(); - isPersistentSwitchToggled = NotificationService().isPersistentNotificationActivated(); - - if(isPersistentSwitchToggled) - platformNotificationDetails = platformPersistentNotificationDetails; - else - platformNotificationDetails = platformNonPersistentNotificationDetails; + isNotificationSwitchToggled = notificationService.isNotificationActivated(); + isPersistentSwitchToggled = notificationService.isPersistentNotificationActivated(); // Sets the default values for scheduled time - getScheduledTime(); - - /// Initializing notification settings - tz.initializeTimeZones(); - - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('@mipmap/ic_launcher'); - - const DarwinInitializationSettings iosInitializationSettings = - DarwinInitializationSettings(); - - const InitializationSettings initializationSettings = - InitializationSettings( - android: androidInitializationSettings, - iOS: iosInitializationSettings, - ); - - flutterLocalNotificationsPlugin.initialize(initializationSettings); + scheduledTimeOfDay = notificationService.getScheduledTime(); } @override @@ -65,79 +34,6 @@ class _SwitchNotificationsComponentState super.dispose(); } - late NotificationDetails platformNotificationDetails; - final NotificationDetails platformNonPersistentNotificationDetails = const NotificationDetails( - android: AndroidNotificationDetails( - 'channel id', - 'channel name', - channelDescription: 'channel description', - ongoing: false - ), - ); - final NotificationDetails platformPersistentNotificationDetails = const NotificationDetails( - android: AndroidNotificationDetails( - 'channel id', - 'channel name', - channelDescription: 'channel description', - ongoing: true - ), - ); - - // Checks for the scheduled time and sets it to a value in shared prefs - void getScheduledTime() { - final int hour = SharedPrefsUtil.getInt('scheduledTimeHour') ?? 20; - final int minute = SharedPrefsUtil.getInt('scheduledTimeMinute') ?? 00; - scheduledTimeOfDay = TimeOfDay(hour: hour, minute: minute); - } - - Future scheduleNotification() async { - final now = DateTime.now(); - - // sets the scheduled time in DateTime format - final String setTime = DateTime( - now.year, - now.month, - now.day, - scheduledTimeOfDay.hour, - scheduledTimeOfDay.minute, - ).toString(); - - Utils.logInfo('[NOTIFICATIONS] - Scheduled with setTime=$setTime'); - - /// Schedule notification - await flutterLocalNotificationsPlugin.zonedSchedule( - notificationId, - 'notificationTitle'.tr, - 'notificationBody'.tr, - tz.TZDateTime.parse(tz.local, setTime), - platformNotificationDetails, - uiLocalNotificationDateInterpretation: - UILocalNotificationDateInterpretation.absoluteTime, - androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle, - // Allow notification to be shown daily - matchDateTimeComponents: DateTimeComponents.time, - ); - } - - Future showTestNotification() async { - await flutterLocalNotificationsPlugin.show( - notificationId, - 'test'.tr, - 'test'.tr, - platformNotificationDetails, - ); - - // Feedback to the user that the notification was called - await Fluttertoast.showToast( - msg: 'done'.tr, - toastLength: Toast.LENGTH_SHORT, - gravity: ToastGravity.CENTER, - backgroundColor: AppColors.dark, - textColor: Colors.white, - fontSize: 16.0, - ); - } - @override Widget build(BuildContext context) { return Column( @@ -159,25 +55,14 @@ class _SwitchNotificationsComponentState value: isNotificationSwitchToggled, onChanged: (value) async { if (value) { - Utils.logInfo( - '[NOTIFICATIONS] - Notifications were enabled', - ); - - /// Schedule notification if switch in ON - await Utils.requestPermission(Permission.notification); - await scheduleNotification(); + await notificationService.turnOnNotifications(); + await notificationService.scheduleNotification( + scheduledTimeOfDay.hour, + scheduledTimeOfDay.minute); } else { - Utils.logInfo( - '[NOTIFICATIONS] - Notifications were disabled', - ); - - /// Cancel notification if switch is OFF - flutterLocalNotificationsPlugin.cancelAll(); + await notificationService.turnOffNotifications(); } - /// Save notification on SharedPrefs - NotificationService().switchNotification(); - /// Update switch value setState(() { isNotificationSwitchToggled = !isNotificationSwitchToggled; @@ -245,22 +130,22 @@ class _SwitchNotificationsComponentState // Enable notification if it's disabled if (!isNotificationSwitchToggled) { - print('here'); - await Utils.requestPermission(Permission.notification); - NotificationService().switchNotification(); + await notificationService.turnOnNotifications(); setState(() { isNotificationSwitchToggled = true; }); } - SharedPrefsUtil.putInt('scheduledTimeHour', newTimeOfDay.hour); - SharedPrefsUtil.putInt('scheduledTimeMinute', newTimeOfDay.minute); + notificationService.setScheduledTime(newTimeOfDay.hour, + newTimeOfDay.minute); setState(() { scheduledTimeOfDay = newTimeOfDay; }); - await scheduleNotification(); + await notificationService.scheduleNotification( + scheduledTimeOfDay.hour, + scheduledTimeOfDay.minute); }, child: Container( padding: @@ -300,25 +185,24 @@ class _SwitchNotificationsComponentState value: isPersistentSwitchToggled, onChanged: (value) async { if (value) { - Utils.logInfo( - '[NOTIFICATIONS] - Persistent notifications were enabled', - ); - platformNotificationDetails = platformPersistentNotificationDetails; + notificationService.activatePersistentNotifications(); } else { - Utils.logInfo( - '[NOTIFICATIONS] - Persistent notifications were disabled', - ); - platformNotificationDetails = platformNonPersistentNotificationDetails; + notificationService.unactivatePersistentNotifications(); } /// Schedule notification if switch in ON - if(isNotificationSwitchToggled){ - flutterLocalNotificationsPlugin.cancelAll(); - await scheduleNotification(); + if(isNotificationSwitchToggled && !isNotificationSwitchToggled){ + await notificationService.turnOnNotifications(); + setState(() { + isNotificationSwitchToggled = true; + }); } - /// Save notification on SharedPrefs - NotificationService().switchPersistentNotification(); + if(isNotificationSwitchToggled){ + await notificationService.scheduleNotification( + scheduledTimeOfDay.hour, + scheduledTimeOfDay.minute); + } /// Update switch value setState(() { diff --git a/lib/utils/notification_service.dart b/lib/utils/notification_service.dart index 9e4eff0..83d2000 100644 --- a/lib/utils/notification_service.dart +++ b/lib/utils/notification_service.dart @@ -1,24 +1,179 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:get/get.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:timezone/data/latest.dart' as tz; +import 'package:timezone/timezone.dart' as tz; + +import 'constants.dart'; import 'shared_preferences_util.dart'; +import 'utils.dart'; class NotificationService { - final _key = 'activatedNotification'; - final _persistentKey = 'activatedNotification'; + final _notificationKey = 'activatedNotification'; + final _persistentKey = 'persistentNotification'; + final _hourKey = 'scheduledTimeHour'; + final _minuteKey = 'scheduledTimeMinute'; + final int _notificationId = 1; + final _flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); + + late NotificationDetails _platformNotificationDetails; + final NotificationDetails _platformNonPersistentNotificationDetails = const NotificationDetails( + android: AndroidNotificationDetails( + 'channel id', + 'channel name', + channelDescription: 'channel description', + ongoing: false + ), + ); + final NotificationDetails _platformPersistentNotificationDetails = const NotificationDetails( + android: AndroidNotificationDetails( + 'channel id', + 'channel name', + channelDescription: 'channel description', + ongoing: true + ), + ); + + NotificationService(){ + if(isPersistentNotificationActivated()) + _platformNotificationDetails = _platformPersistentNotificationDetails; + else + _platformNotificationDetails = _platformNonPersistentNotificationDetails; + + /// Initializing notification settings + tz.initializeTimeZones(); + + const AndroidInitializationSettings androidInitializationSettings = + AndroidInitializationSettings('@mipmap/ic_launcher'); + + const DarwinInitializationSettings iosInitializationSettings = + DarwinInitializationSettings(); + + const InitializationSettings initializationSettings = + InitializationSettings( + android: androidInitializationSettings, + iOS: iosInitializationSettings, + ); + + _flutterLocalNotificationsPlugin.initialize(initializationSettings); + } // Notification is deactivated by default - bool isNotificationActivated() => SharedPrefsUtil.getBool(_key) ?? false; + bool isNotificationActivated() => SharedPrefsUtil.getBool(_notificationKey) ?? false; bool isPersistentNotificationActivated() => SharedPrefsUtil.getBool(_persistentKey) ?? false; - Future _saveNotification(bool isActivated) => - SharedPrefsUtil.putBool(_key, isActivated); + // Checks for the scheduled time and sets it to a value in shared prefs + TimeOfDay getScheduledTime() { + final int hour = SharedPrefsUtil.getInt(_hourKey) ?? 20; + final int minute = SharedPrefsUtil.getInt(_minuteKey) ?? 00; + return TimeOfDay(hour: hour, minute: minute); + } + + void _switchNotification() { + SharedPrefsUtil.putBool(_notificationKey, !isNotificationActivated()); + } + + void _switchPersistentNotification() { + SharedPrefsUtil.putBool(_persistentKey, !isPersistentNotificationActivated()); + } + + void setScheduledTime(int hour, int minute) { + SharedPrefsUtil.putInt(_hourKey, hour); + SharedPrefsUtil.putInt(_minuteKey, minute); + } + + Future turnOnNotifications() async { + Utils.logInfo( + '[NOTIFICATIONS] - Notifications were enabled', + ); - Future _savePersistentNotification(bool isActivated) => - SharedPrefsUtil.putBool(_persistentKey, isActivated); + /// Schedule notification if switch in ON + await Utils.requestPermission(Permission.notification); - void switchNotification() { - _saveNotification(!isNotificationActivated()); + /// Save notification on SharedPrefs + _switchNotification(); } - void switchPersistentNotification() { - _savePersistentNotification(!isPersistentNotificationActivated()); + Future turnOffNotifications() async { + Utils.logInfo( + '[NOTIFICATIONS] - Notifications were disabled', + ); + + /// Cancel notification if switch is OFF + _flutterLocalNotificationsPlugin.cancelAll(); + + /// Save notification on SharedPrefs + _switchNotification(); + } + + Future activatePersistentNotifications() async { + Utils.logInfo( + '[NOTIFICATIONS] - Persistent notifications were enabled', + ); + _platformNotificationDetails = _platformPersistentNotificationDetails; + + /// Save notification on SharedPrefs + _switchPersistentNotification(); + } + + Future unactivatePersistentNotifications() async { + Utils.logInfo( + '[NOTIFICATIONS] - Persistent notifications were disabled', + ); + _platformNotificationDetails = _platformNonPersistentNotificationDetails; + + /// Save notification on SharedPrefs + _switchPersistentNotification(); + } + + Future scheduleNotification(int hour, int minute) async { + _flutterLocalNotificationsPlugin.cancelAll(); + final now = DateTime.now(); + + // sets the scheduled time in DateTime format + final String setTime = DateTime( + now.year, + now.month, + now.day, + hour, + minute, + ).toString(); + + Utils.logInfo('[NOTIFICATIONS] - Scheduled with setTime=$setTime'); + + /// Schedule notification + await _flutterLocalNotificationsPlugin.zonedSchedule( + _notificationId, + 'notificationTitle'.tr, + 'notificationBody'.tr, + tz.TZDateTime.parse(tz.local, setTime), + _platformNotificationDetails, + uiLocalNotificationDateInterpretation: + UILocalNotificationDateInterpretation.absoluteTime, + androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle, + // Allow notification to be shown daily + matchDateTimeComponents: DateTimeComponents.time, + ); + } + + Future showTestNotification() async { + await _flutterLocalNotificationsPlugin.show( + _notificationId, + 'test'.tr, + 'test'.tr, + _platformNotificationDetails, + ); + + // Feedback to the user that the notification was called + await Fluttertoast.showToast( + msg: 'done'.tr, + toastLength: Toast.LENGTH_SHORT, + gravity: ToastGravity.CENTER, + backgroundColor: AppColors.dark, + textColor: Colors.white, + fontSize: 16.0, + ); } } From 74cd1e745656de42966eeb2e646facf61a8807d3 Mon Sep 17 00:00:00 2001 From: Adrasteon Dev Date: Tue, 31 Oct 2023 11:50:56 +0100 Subject: [PATCH 3/4] Reschedule notification when the daily entry status change --- lib/bindings/initial_binding.dart | 5 +++++ lib/controllers/daily_entry_controller.dart | 5 +++++ .../widgets/switch_notifications.dart | 18 ++++++++++----- lib/utils/notification_service.dart | 22 ++++++++++++------- 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/lib/bindings/initial_binding.dart b/lib/bindings/initial_binding.dart index 54dff5c..7e25d98 100644 --- a/lib/bindings/initial_binding.dart +++ b/lib/bindings/initial_binding.dart @@ -1,10 +1,15 @@ import 'package:get/get.dart'; import '../controllers/lang_controller.dart'; +import '../utils/notification_service.dart'; class InitialBinding extends Bindings { @override void dependencies() { Get.put(LanguageController()); + Get.put( + NotificationService(), + permanent: true, + ); } } diff --git a/lib/controllers/daily_entry_controller.dart b/lib/controllers/daily_entry_controller.dart index 152aa77..9835967 100644 --- a/lib/controllers/daily_entry_controller.dart +++ b/lib/controllers/daily_entry_controller.dart @@ -1,6 +1,7 @@ import 'package:get/get.dart'; import '../utils/date_format_utils.dart'; +import '../utils/notification_service.dart'; import '../utils/shared_preferences_util.dart'; class DailyEntryController extends GetxController { @@ -11,11 +12,15 @@ class DailyEntryController extends GetxController { } final dailyEntry = SharedPrefsUtil.getBool('dailyEntry')?.obs ?? false.obs; + final NotificationService notificationService = Get.find(); void updateDaily({bool value = true}) { SharedPrefsUtil.putBool('dailyEntry', value); dailyEntry.value = value; dailyEntry.refresh(); + + // Remove the existing notification and schedule it again + notificationService.rescheduleNotification(DateTime.now()); } void _checkTodayEntry() { diff --git a/lib/pages/home/notification/widgets/switch_notifications.dart b/lib/pages/home/notification/widgets/switch_notifications.dart index 82d7cae..7e1adf1 100644 --- a/lib/pages/home/notification/widgets/switch_notifications.dart +++ b/lib/pages/home/notification/widgets/switch_notifications.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import '../../../../controllers/daily_entry_controller.dart'; import '../../../../routes/app_pages.dart'; import '../../../../utils/constants.dart'; import '../../../../utils/notification_service.dart'; @@ -17,7 +18,7 @@ class _SwitchNotificationsComponentState late bool isNotificationSwitchToggled; TimeOfDay scheduledTimeOfDay = const TimeOfDay(hour: 20, minute: 00); late bool isPersistentSwitchToggled; - NotificationService notificationService = NotificationService(); + final NotificationService notificationService = Get.find(); @override void initState() { @@ -56,9 +57,12 @@ class _SwitchNotificationsComponentState onChanged: (value) async { if (value) { await notificationService.turnOnNotifications(); + await notificationService.scheduleNotification( scheduledTimeOfDay.hour, - scheduledTimeOfDay.minute); + scheduledTimeOfDay.minute, + DateTime.now() + ); } else { await notificationService.turnOffNotifications(); } @@ -145,7 +149,9 @@ class _SwitchNotificationsComponentState await notificationService.scheduleNotification( scheduledTimeOfDay.hour, - scheduledTimeOfDay.minute); + scheduledTimeOfDay.minute, + DateTime.now() + ); }, child: Container( padding: @@ -187,7 +193,7 @@ class _SwitchNotificationsComponentState if (value) { notificationService.activatePersistentNotifications(); } else { - notificationService.unactivatePersistentNotifications(); + notificationService.deactivatePersistentNotifications(); } /// Schedule notification if switch in ON @@ -201,7 +207,9 @@ class _SwitchNotificationsComponentState if(isNotificationSwitchToggled){ await notificationService.scheduleNotification( scheduledTimeOfDay.hour, - scheduledTimeOfDay.minute); + scheduledTimeOfDay.minute, + DateTime.now() + ); } /// Update switch value diff --git a/lib/utils/notification_service.dart b/lib/utils/notification_service.dart index 83d2000..0c502fa 100644 --- a/lib/utils/notification_service.dart +++ b/lib/utils/notification_service.dart @@ -24,7 +24,8 @@ class NotificationService { 'channel id', 'channel name', channelDescription: 'channel description', - ongoing: false + ongoing: false, + autoCancel: true ), ); final NotificationDetails _platformPersistentNotificationDetails = const NotificationDetails( @@ -32,7 +33,8 @@ class NotificationService { 'channel id', 'channel name', channelDescription: 'channel description', - ongoing: true + ongoing: true, + autoCancel: false ), ); @@ -118,7 +120,7 @@ class NotificationService { _switchPersistentNotification(); } - Future unactivatePersistentNotifications() async { + Future deactivatePersistentNotifications() async { Utils.logInfo( '[NOTIFICATIONS] - Persistent notifications were disabled', ); @@ -128,15 +130,14 @@ class NotificationService { _switchPersistentNotification(); } - Future scheduleNotification(int hour, int minute) async { + Future scheduleNotification(int hour, int minute, DateTime day) async { _flutterLocalNotificationsPlugin.cancelAll(); - final now = DateTime.now(); // sets the scheduled time in DateTime format final String setTime = DateTime( - now.year, - now.month, - now.day, + day.year, + day.month, + day.day, hour, minute, ).toString(); @@ -158,6 +159,11 @@ class NotificationService { ); } + Future rescheduleNotification(DateTime day) async { + final TimeOfDay timeOfDay = getScheduledTime(); + await scheduleNotification(timeOfDay.hour, timeOfDay.minute, day); + } + Future showTestNotification() async { await _flutterLocalNotificationsPlugin.show( _notificationId, From b1916366bdcb2596c57e8b38f37f964102bf67dc Mon Sep 17 00:00:00 2001 From: Adrasteon Dev Date: Sun, 19 Nov 2023 19:36:28 +0100 Subject: [PATCH 4/4] Reschedule notification when the user open the app if there is a daily entry --- lib/controllers/daily_entry_controller.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/controllers/daily_entry_controller.dart b/lib/controllers/daily_entry_controller.dart index 9835967..21e50f6 100644 --- a/lib/controllers/daily_entry_controller.dart +++ b/lib/controllers/daily_entry_controller.dart @@ -33,5 +33,9 @@ class DailyEntryController extends GetxController { dailyEntry.value = false; dailyEntry.refresh(); } + + // Remove the existing notification and schedule it again if there is a daily entry + if(dailyEntry.value) + notificationService.rescheduleNotification(DateTime.now()); } }