Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
LucaCoduriV committed Sep 21, 2022
1 parent 9b3048e commit 6f4b600
Show file tree
Hide file tree
Showing 10 changed files with 206 additions and 107 deletions.
7 changes: 6 additions & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@ if (keystorePropertiesFile.exists()) {
}

android {
compileSdkVersion 31
compileSdkVersion 33

compileOptions {
// Flag to enable support for the new language APIs for Local notification
coreLibraryDesugaringEnabled true
// Sets Java compatibility to Java 8
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
Expand All @@ -54,6 +57,7 @@ android {
targetSdkVersion 31
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
multiDexEnabled true // Added for local notifications
}

signingConfigs {
Expand All @@ -78,4 +82,5 @@ flutter {

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' // Added for local notifications
}
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:4.2.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Expand Down
46 changes: 17 additions & 29 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:flutter/foundation.dart' as foundation;
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_dropdown_alert/dropdown_alert.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get_it/get_it.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:heig_front/services/api/iapi.dart';
Expand All @@ -26,6 +27,7 @@ import 'services/api/api.dart';
import 'services/auth/auth.dart';
import 'services/auth/iauth.dart';
import 'services/background_tasks/check_new_grades.dart';
import 'services/notification.dart';
import 'services/providers/bulletin_provider.dart';
import 'services/providers/drawer_provider.dart';
import 'services/providers/horaires_provider.dart';
Expand All @@ -37,6 +39,7 @@ import 'utils/navigation.dart' as navigation;
/// Prparation de la base de données local et des singletons.
Future<void> setup() async {
await initializeDateFormatting('fr_FR');
tz.initializeTimeZones();
await dotenv.load();
await Hive.initFlutter();
await IdGenerator.initialize();
Expand All @@ -63,35 +66,20 @@ Future<void> setup() async {
..registerSingleton<MenusProvider>(MenusProvider())
..registerSingleton<GlobalKey<RefreshIndicatorState>>(
GlobalKey<RefreshIndicatorState>());
GetIt.I.registerSingleton<NotificationController>(NotificationController());
await GetIt.I.get<NotificationController>().initialize();

final bool canNotify =
await GetIt.I.get<NotificationController>().canNotifiy();

if (!canNotify) {
await GetIt.I
.get<FlutterLocalNotificationsPlugin>()
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.requestPermission();
}

await AwesomeNotifications().initialize(
null,
[
NotificationChannel(
channelKey: 'todos_channel',
channelName: 'Todo',
channelDescription: 'Notification channel for todos',
importance: NotificationImportance.High,
defaultColor: Colors.red,
ledColor: Colors.white,
),
NotificationChannel(
channelKey: 'horaires_channel',
channelName: 'Horaire',
channelDescription: 'Notification channel for schedules',
importance: NotificationImportance.High,
defaultColor: Colors.red,
ledColor: Colors.white,
),
],
);
await AwesomeNotifications().isNotificationAllowed().then((isAllowed) {
if (!isAllowed) {
// Insert here your friendly dialog box before call the request method
// This is very important to not harm the user experience
AwesomeNotifications().requestPermissionToSendNotifications();
}
});
Workmanager().initialize(
callbackDispatcher, // The top level function, aka callbackDispatcher
isInDebugMode:
Expand Down
33 changes: 15 additions & 18 deletions lib/models/heure_de_cours.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:get_it/get_it.dart';
import 'package:heig_front/utils/id_generator.dart';
import 'package:heig_front/utils/notification.dart' show CanNotify;
import 'package:hive_flutter/adapters.dart';
import 'package:timezone/timezone.dart';

part 'heure_de_cours.g.dart';

Expand Down Expand Up @@ -36,23 +36,20 @@ class HeureDeCours with CanNotify {
"${debut.hour.toString().padLeft(2, '0')}:${debut.minute.toString().padLeft(2, '0')}";

final dateMinus20 = debut.subtract(const Duration(minutes: 20));
final zurich = getLocation('Europe/Zurich');
initCanNotifyMixin(
NotificationCalendar(
day: dateMinus20.day,
year: dateMinus20.year,
month: dateMinus20.month,
hour: dateMinus20.hour,
minute: dateMinus20.minute,
second: dateMinus20.second,
allowWhileIdle: true,
),
NotificationContent(
category: NotificationCategory.Reminder,
id: 0,
channelKey: 'horaires_channel',
title: 'Cours: $nom Classe: $salle',
body: dateSlug,
));
TZDateTime(
zurich,
dateMinus20.year,
dateMinus20.month,
dateMinus20.day,
dateMinus20.hour,
dateMinus20.minute,
dateMinus20.second,
),
'Cours: $nom Classe: $salle',
dateSlug,
);
}

factory HeureDeCours.fromJson(Map<String, dynamic> json) {
Expand All @@ -78,7 +75,7 @@ class HeureDeCours with CanNotify {
DateTime(
startYear, startMonth, startDay, startHour, startMinute, startSecond),
DateTime(endYear, endMonth, endDay, endHour, endMinute, endSecond),
'Professeur inconnu' ?? '',
'Professeur inconnu',
json['LOCATION'] ?? '',
json['UID'] ?? '',
json['RRULE'] ?? '',
Expand Down
44 changes: 17 additions & 27 deletions lib/services/background_tasks/check_new_grades.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import 'dart:io' show Platform;

import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:get_it/get_it.dart';
import 'package:heig_front/models/branche.dart';
import 'package:heig_front/models/bulletin.dart';
import 'package:heig_front/models/heure_de_cours.dart';
Expand All @@ -17,10 +18,13 @@ import 'package:workmanager/workmanager.dart';

import '../../utils/asymmetric_crypt.dart';
import '../../utils/id_generator.dart';
import '../notification.dart';

Future<void> setupBackgroundTask() async {
WidgetsFlutterBinding.ensureInitialized();

tz.initializeTimeZones();

final connectivityResult = await Connectivity().checkConnectivity();
if (connectivityResult == ConnectivityResult.none) {
return;
Expand All @@ -43,24 +47,15 @@ Future<void> setupBackgroundTask() async {
Hive.registerAdapter(UserAdapter());
}

await AwesomeNotifications().initialize(
null,
[
NotificationChannel(
channelKey: 'grade_channel',
channelName: 'Grade',
channelDescription: 'Notification channel for Grades',
defaultColor: Colors.red,
ledColor: Colors.white,
enableVibration: true,
),
],
);
await AwesomeNotifications().isNotificationAllowed().then((isAllowed) {
if (!isAllowed) {
return;
}
});
GetIt.I.registerSingleton<NotificationController>(NotificationController());
await GetIt.I.get<NotificationController>().initialize();

final bool canNotify =
await GetIt.I.get<NotificationController>().canNotifiy();

if (!canNotify) {
return;
}
}

void startBackgroundTask(Duration duration) {
Expand Down Expand Up @@ -135,14 +130,9 @@ Future<bool> backgroundMain() async {

try {
// Notify the user of the change.
AwesomeNotifications().createNotification(
content: NotificationContent(
id: 10000,
channelKey: 'grade_channel',
title: 'Nouvelle(s) note(s) disponibles !',
body: notificationBody.join(' \n- '),
),
);
await GetIt.I
.get<NotificationController>()
.notifyNewGrade(notificationBody);
} catch (e) {
debugPrint(e.toString());
return Future.value(false);
Expand Down
84 changes: 84 additions & 0 deletions lib/services/notification.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:timezone/timezone.dart';

class NotificationController {
final FlutterLocalNotificationsPlugin _instance;

NotificationController() : _instance = FlutterLocalNotificationsPlugin();

Future<void> initialize() async {
const InitializationSettings initializationSettings =
InitializationSettings(
android: AndroidInitializationSettings('app_icon'));
await _instance.initialize(initializationSettings);
}

Future<bool> canNotifiy() async {
return await _instance
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.areNotificationsEnabled() ??
true;
}

Future<bool> requestPermission() async {
return await _instance
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.requestPermission() ??
true;
}

Future<void> notifyNewGrade(List<String> notificationBody) async {
return _instance.show(
10000,
'Nouvelle(s) note(s) disponibles !',
notificationBody.join(' \n- '),
const NotificationDetails(
android: AndroidNotificationDetails(
'grade_channel',
'Grade',
channelDescription: 'Notification channel for Grades',
enableLights: true,
ledColor: Colors.white,
color: Colors.red,
importance: Importance.high,
)),
);
}

Future<void> cancelSchedule(int id) async {
return _instance.cancel(id);
}

Future<void> cancelAllSchedule() async {
return _instance.cancelAll();
}

Future<void> cancelAllScheduleFromChannel(String channelId) async {
final activeNotifs = await _instance.getActiveNotifications();
await Future.wait(activeNotifs
.where((notif) => notif.channelId == channelId)
.map((notif) => _instance.cancel(notif.id)));
}

Future<void> schedule(
int id,
String? title,
String? body,
TZDateTime scheduledDate,
NotificationDetails notificationDetails,
) async {
_instance.zonedSchedule(
id,
title,
body,
scheduledDate,
notificationDetails,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
androidAllowWhileIdle: true,
);
}
}
6 changes: 4 additions & 2 deletions lib/services/providers/horaires_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:flutter_dropdown_alert/model/data_alert.dart';
import 'package:get_it/get_it.dart';
import 'package:heig_front/services/api/iapi.dart';
import 'package:heig_front/services/auth/iauth.dart';
import 'package:heig_front/services/notification.dart';
import 'package:heig_front/utils/constants.dart';
import 'package:heig_front/utils/notification.dart';
import 'package:hive_flutter/hive_flutter.dart';
Expand Down Expand Up @@ -31,8 +32,9 @@ class HorairesProvider extends ChangeNotifier {
Horaires get horaires => _horaires;

Future<void> cancelNotifications() async {
//cancelMultipleNotifications(_horaires.horaires);
cancelMultipleNotificationsWithChannelKey('horaires_channel');
GetIt.I
.get<NotificationController>()
.cancelAllScheduleFromChannel('horaires_channel');
}

void registerNotifications() {
Expand Down
Loading

0 comments on commit 6f4b600

Please sign in to comment.