diff --git a/android/app/build.gradle b/android/app/build.gradle index 1ba30fd..3ad429a 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -46,7 +46,7 @@ android { applicationId "haus.nightmare.tbdoctor" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. - minSdkVersion flutter.minSdkVersion + minSdkVersion 21 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/lib/main.dart b/lib/main.dart index b380dc7..30d3cd0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,14 +7,38 @@ import 'package:intl/intl.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:http/http.dart' as http; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:awesome_notifications/awesome_notifications.dart'; +import 'package:scheduled_timer/scheduled_timer.dart'; void main() { + AwesomeNotifications().initialize( + // set the icon to null if you want to use the default app icon + null, + [ + NotificationChannel( + channelGroupKey: 'reminder_channel_group', + channelKey: 'reminder_channel', + channelName: 'Check-In Reminder notifications', + channelDescription: 'Notification channel for Check-In Reminders', + defaultColor: Colors.cyan.shade900, + ledColor: Colors.white) + ], + // Channel groups are only visual and are not required + channelGroups: [ + NotificationChannelGroup( + channelGroupkey: 'reminder_channel_group', + channelGroupName: 'Reminder group') + ], + debug: true + ); runApp(const TBDoctor()); } class TBDoctor extends StatelessWidget { const TBDoctor({Key? key}) : super(key: key); + get id => null; + // This widget is the root of your application. @override Widget build(BuildContext context) { @@ -115,6 +139,7 @@ class _TBDoctorHomePageState extends State { // Required for program late SharedPreferences _prefs; + late ScheduledTimer checkinReminder; void _setCalcs() async { if (_inOfficeHoursToDate == 0.0 && _tbdHoursToDate == 0.0 || @@ -313,6 +338,24 @@ class _TBDoctorHomePageState extends State { ], ); } + void _showReminderNotification() { + DateTime now = DateTime.now(); + if (now.weekday == DateTime.saturday || now.weekday == DateTime.sunday) { + return; + } + AwesomeNotifications().createNotification( + content: NotificationContent( + id: 10, + channelKey: 'reminder_channel', + title: 'Check-In Reminder', + body: 'Are you remote, in office, or out today?'), + actionButtons: [ + NotificationActionButton(key: 'remote', label: 'Remote'), + NotificationActionButton(key: 'office', label: 'In Office'), + NotificationActionButton(key: 'no', label: 'Not Today'), + ], + ); + } @override void initState() { @@ -324,6 +367,57 @@ class _TBDoctorHomePageState extends State { _setCalcs(); _populateSelf(); }); + DateTime now = DateTime.now(); + checkinReminder = ScheduledTimer( + id: "checkinReminder", + onExecute: _showReminderNotification, + defaultScheduledTime: DateTime(now.year, now.month, now.day + 1, 7, 0), + onMissedSchedule: _showReminderNotification, + ); + + AwesomeNotifications().actionStream.listen((receivedNotification) { + DateTime now = DateTime.now(); + double hours = 7.5; + if (now.weekday == DateTime.saturday || now.weekday == DateTime.sunday) { + debugPrint("Detected weekend, no work allowed"); + return; + } + if (now.isAfter(DateTime(now.year, 06, 23)) || now.isBefore(DateTime(now.year, 09, 14))) { + debugPrint("Detected summer hours"); + hours = 8; + if (now.weekday == DateTime.friday) { + debugPrint("Detected summer hours, half day friday"); + hours = 4.5; + } + } + SharedPreferences.getInstance().then((SharedPreferences p) { + _prefs = p; + switch(receivedNotification.buttonKeyPressed) { + case "remote": + debugPrint("Modifying TBD since user responded 'remote'"); + _tbdHoursToDate += hours; + _prefs.setDouble("_tbdHoursToDate", _tbdHoursToDate); + break; + case "office": + debugPrint("Modifying in-office since user responded 'office'"); + _inOfficeHoursToDate += hours; + _prefs.setDouble("_tbdHoursToDate", _tbdHoursToDate); + break; + default: + debugPrint("Didn't care."); + break; + } + // Schedule the next one? + DateTime now = DateTime.now(); + checkinReminder = ScheduledTimer( + id: "checkinReminder", + onExecute: _showReminderNotification, + defaultScheduledTime: DateTime(now.year, now.month, now.day + 1, 7, 0), + onMissedSchedule: _showReminderNotification, + ); + _setCalcs(); + }); + }); super.initState(); } diff --git a/pubspec.lock b/pubspec.lock index c60e135..f5d0cdb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -22,6 +22,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.8.2" + awesome_notifications: + dependency: "direct main" + description: + name: awesome_notifications + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.21" boolean_selector: dependency: transitive description: @@ -240,6 +247,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.2.4" + scheduled_timer: + dependency: "direct main" + description: + name: scheduled_timer + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" shared_preferences: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index dc53a84..90ce38a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -36,6 +36,8 @@ dependencies: # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 shared_preferences: ^2.0.15 + awesome_notifications: any + scheduled_timer: ^2.0.1 dev_dependencies: flutter_test: