From fc89db8a3c80e05f75c0e70e415e498291e04a1e Mon Sep 17 00:00:00 2001 From: Rodrigo Nunes Date: Fri, 27 Dec 2024 13:29:56 +0000 Subject: [PATCH 1/2] Added a new notification for classes --- .../notifications/class_notification.dart | 118 ++++++++++++++++++ packages/uni_app/pubspec.yaml | 1 + 2 files changed, 119 insertions(+) create mode 100644 packages/uni_app/lib/controller/background_workers/notifications/class_notification.dart diff --git a/packages/uni_app/lib/controller/background_workers/notifications/class_notification.dart b/packages/uni_app/lib/controller/background_workers/notifications/class_notification.dart new file mode 100644 index 000000000..b23c4ff36 --- /dev/null +++ b/packages/uni_app/lib/controller/background_workers/notifications/class_notification.dart @@ -0,0 +1,118 @@ +import "dart:async"; +import "package:flutter_local_notifications/flutter_local_notifications.dart"; +import "package:uni/controller/fetchers/schedule_fetcher/schedule_fetcher.dart"; +import "package:uni/controller/fetchers/schedule_fetcher/schedule_fetcher_new_api.dart"; +import "package:uni/controller/local_storage/database/app_lectures_database.dart"; +import "package:uni/model/entities/lecture.dart"; +import "package:uni/model/providers/state_provider_notifier.dart"; +import "package:uni/model/providers/state_providers.dart"; +import "package:uni/session/flows/base/session.dart"; + +final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); + + +void initializeNotifications() { + const androidInitialization = AndroidInitializationSettings("app_icon"); + const iOSInitialization = DarwinInitializationSettings(); + final initializationSettings = InitializationSettings( + android: androidInitialization, + iOS: iOSInitialization, + ); + + flutterLocalNotificationsPlugin.initialize(initializationSettings); + + tzData.initializeTimeZones(); +} + + +class LectureProvider extends StateProviderNotifier> { + LectureProvider() : super(cacheDuration: const Duration(hours: 6)); + + + @override + Future> loadFromStorage(StateProviders stateProviders) async { + final db = AppLecturesDatabase(); + return db.lectures(); + } + + @override + Future> loadFromRemote(StateProviders stateProviders) async { + return fetchUserLectures( + stateProviders.sessionProvider.state!, + ); + } + + Future> fetchUserLectures( + Session session, { + ScheduleFetcher? fetcher, + }) async { + final lectures = await getLecturesFromFetcherOrElse(fetcher, session); + + final db = AppLecturesDatabase(); + await db.saveIfPersistentSession(lectures); + + return lectures; + } + + Future> getLecturesFromFetcherOrElse( + ScheduleFetcher? fetcher, + Session session, + ) => + fetcher?.getLectures(session) ?? getLectures(session); + + Future> getLectures(Session session) { + return ScheduleFetcherNewApi().getLectures(session).catchError( + (e) => [], + ); + } +} + +void scheduleLectureNotifications(List lectures, FlutterLocalNotificationsPlugin localNotificationsPlugin) { + for (Lecture lecture in lectures) { + DateTime lectureStart = lecture.startTime; + DateTime notificationTime = lectureStart.subtract(Duration(minutes: 15)); + + if (notificationTime.isAfter(DateTime.now())) { + _scheduleNotification(notificationTime, lecture, localNotificationsPlugin); + } + } +} + + +Future _scheduleNotification(DateTime notificationTime, Lecture lecture, FlutterLocalNotificationsPlugin localNotificationsPlugin) async { + final location = tz.getLocation("Europe/Lisbon"); + final zonedNotificationTime = tz.TZDateTime.from(notificationTime, location); + + const androidDetails = AndroidNotificationDetails( + "lecture_notification_channel", + "Lecture Notifications", + importance: Importance.high, + priority: Priority.high, + showWhen: false + ); + const iOSDetails = DarwinNotificationDetails( + presentAlert: true, + presentBadge: true, + interruptionLevel: InterruptionLevel.active, + ); + + const notificationDetails = NotificationDetails( + android: androidDetails, + iOS: iOSDetails, + ); + + await localNotificationsPlugin.zonedSchedule( + 0, + "Upcoming Lecture: ${lecture.title}", + "Your lecture ${lecture.title} starts in 15 minutes!", + zonedNotificationTime, + notificationDetails, + androidAllowWhileIdle: true, + uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.wallClockTime, + ); +} + + +void onLecturesFetched(List lectures) { + scheduleLectureNotifications(lectures, flutterLocalNotificationsPlugin); +} diff --git a/packages/uni_app/pubspec.yaml b/packages/uni_app/pubspec.yaml index 844b53776..7b7be503b 100644 --- a/packages/uni_app/pubspec.yaml +++ b/packages/uni_app/pubspec.yaml @@ -71,6 +71,7 @@ dependencies: upgrader: ^10.3.0 url_launcher: ^6.2.2 workmanager: ^0.5.2 + timezone: ^0.7.0 dev_dependencies: build_runner: ^2.4.8 From 240b124c94f0939d1432eff3b3e5fc9dca6496cd Mon Sep 17 00:00:00 2001 From: Rodrigo Nunes Date: Fri, 27 Dec 2024 13:42:59 +0000 Subject: [PATCH 2/2] small code changes which where resulting in problems in relation to class Lecture --- .../notifications/class_notification.dart | 32 ++++++++++--------- packages/uni_app/pubspec.yaml | 2 +- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/packages/uni_app/lib/controller/background_workers/notifications/class_notification.dart b/packages/uni_app/lib/controller/background_workers/notifications/class_notification.dart index b23c4ff36..633712821 100644 --- a/packages/uni_app/lib/controller/background_workers/notifications/class_notification.dart +++ b/packages/uni_app/lib/controller/background_workers/notifications/class_notification.dart @@ -1,18 +1,20 @@ -import "dart:async"; -import "package:flutter_local_notifications/flutter_local_notifications.dart"; -import "package:uni/controller/fetchers/schedule_fetcher/schedule_fetcher.dart"; -import "package:uni/controller/fetchers/schedule_fetcher/schedule_fetcher_new_api.dart"; -import "package:uni/controller/local_storage/database/app_lectures_database.dart"; -import "package:uni/model/entities/lecture.dart"; -import "package:uni/model/providers/state_provider_notifier.dart"; -import "package:uni/model/providers/state_providers.dart"; -import "package:uni/session/flows/base/session.dart"; +import 'dart:async'; +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:uni/controller/fetchers/schedule_fetcher/schedule_fetcher.dart'; +import 'package:uni/controller/fetchers/schedule_fetcher/schedule_fetcher_new_api.dart'; +import 'package:uni/controller/local_storage/database/app_lectures_database.dart'; +import 'package:uni/model/entities/lecture.dart'; +import 'package:uni/model/providers/state_provider_notifier.dart'; +import 'package:uni/model/providers/state_providers.dart'; +import 'package:uni/session/flows/base/session.dart'; +import 'package:timezone/timezone.dart' as tz; +import 'package:timezone/data/latest.dart' as tzData; final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); void initializeNotifications() { - const androidInitialization = AndroidInitializationSettings("app_icon"); + const androidInitialization = AndroidInitializationSettings('app_icon'); const iOSInitialization = DarwinInitializationSettings(); final initializationSettings = InitializationSettings( android: androidInitialization, @@ -80,12 +82,12 @@ void scheduleLectureNotifications(List lectures, FlutterLocalNotificati Future _scheduleNotification(DateTime notificationTime, Lecture lecture, FlutterLocalNotificationsPlugin localNotificationsPlugin) async { - final location = tz.getLocation("Europe/Lisbon"); + final location = tz.getLocation('Europe/Lisbon'); final zonedNotificationTime = tz.TZDateTime.from(notificationTime, location); const androidDetails = AndroidNotificationDetails( - "lecture_notification_channel", - "Lecture Notifications", + 'lecture_notification_channel', + 'Lecture Notifications', importance: Importance.high, priority: Priority.high, showWhen: false @@ -103,8 +105,8 @@ Future _scheduleNotification(DateTime notificationTime, Lecture lecture, F await localNotificationsPlugin.zonedSchedule( 0, - "Upcoming Lecture: ${lecture.title}", - "Your lecture ${lecture.title} starts in 15 minutes!", + 'Upcoming Lecture: ${lecture.subject}', + 'Your lecture ${lecture.subject} starts in 15 minutes!', zonedNotificationTime, notificationDetails, androidAllowWhileIdle: true, diff --git a/packages/uni_app/pubspec.yaml b/packages/uni_app/pubspec.yaml index 7b7be503b..2db4b2cf7 100644 --- a/packages/uni_app/pubspec.yaml +++ b/packages/uni_app/pubspec.yaml @@ -71,7 +71,7 @@ dependencies: upgrader: ^10.3.0 url_launcher: ^6.2.2 workmanager: ^0.5.2 - timezone: ^0.7.0 + timezone: ^0.9.0 dev_dependencies: build_runner: ^2.4.8