Skip to content

Commit

Permalink
Merge branch 'rc-1.7.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
jenspfahl committed Aug 8, 2024
2 parents a85475d + 9bb5e01 commit 5ce3f9d
Show file tree
Hide file tree
Showing 18 changed files with 860 additions and 674 deletions.
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 33
compileSdkVersion 34

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
Expand All @@ -35,7 +35,7 @@ android {
defaultConfig {
applicationId "de.jepfa.personaltasklogger"
minSdkVersion 26
targetSdkVersion 33
targetSdkVersion 34
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
Expand Down
13 changes: 13 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,22 @@
<meta-data
android:name="flutterEmbedding"
android:value="2" />

<receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
<receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
</intent-filter>
</receiver>
<receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ActionBroadcastReceiver" />
</application>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />

<queries>
<intent>
Expand Down
6 changes: 3 additions & 3 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
buildscript {
ext.kotlin_version = '1.8.22'
ext.kotlin_version = '2.0.10'
repositories {
google()
jcenter()
}

dependencies {
classpath 'com.android.tools.build:gradle:7.1.2'
classpath 'com.android.tools.build:gradle:7.1.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

allprojects {
repositories {
google()
jcenter()
mavenCentral()
}
}

Expand Down
27 changes: 19 additions & 8 deletions lib/db/database.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 16 additions & 16 deletions lib/model/Schedule.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:jiffy/jiffy.dart';
import 'package:personaltasklogger/util/dates.dart';
import 'package:personaltasklogger/util/extensions.dart';

import '../util/units.dart';
import 'package:personaltasklogger/util/units.dart';
import 'When.dart';

enum RepetitionStep {DAILY, EVERY_OTHER_DAY, WEEKLY, EVERY_OTHER_WEEK, MONTHLY, EVERY_OTHER_MONTH, QUARTERLY, HALF_YEARLY, YEARLY, CUSTOM}
Expand Down Expand Up @@ -55,7 +55,7 @@ class CustomRepetition {
CustomRepetition(this.repetitionValue, this.repetitionUnit);

DateTime getNextRepetitionFrom(DateTime from) {
var jiffy = Jiffy(from);
var jiffy = Jiffy.parseFromDateTime(from);
switch(repetitionUnit) {
case RepetitionUnit.MINUTES: return jiffy.add(minutes: repetitionValue).dateTime;
case RepetitionUnit.HOURS: return jiffy.add(hours: repetitionValue).dateTime;
Expand All @@ -67,7 +67,7 @@ class CustomRepetition {
}

DateTime getPreviousRepetitionFrom(DateTime from) {
var jiffy = Jiffy(from);
var jiffy = Jiffy.parseFromDateTime(from);
switch(repetitionUnit) {
case RepetitionUnit.MINUTES: return jiffy.subtract(minutes: repetitionValue).dateTime;
case RepetitionUnit.HOURS: return jiffy.subtract(hours: repetitionValue).dateTime;
Expand Down Expand Up @@ -196,11 +196,11 @@ class Schedule {
case RepetitionStep.EVERY_OTHER_DAY: return from.add(Duration(days: 2));
case RepetitionStep.WEEKLY: return from.add(Duration(days: 7));
case RepetitionStep.EVERY_OTHER_WEEK: return from.add(Duration(days: 14));
case RepetitionStep.MONTHLY: return Jiffy(from).add(months: 1).dateTime;
case RepetitionStep.EVERY_OTHER_MONTH: return Jiffy(from).add(months: 2).dateTime;
case RepetitionStep.QUARTERLY: return Jiffy(from).add(months: 3).dateTime;
case RepetitionStep.HALF_YEARLY: return Jiffy(from).add(months: 6).dateTime;
case RepetitionStep.YEARLY: return Jiffy(from).add(years: 1).dateTime;
case RepetitionStep.MONTHLY: return Jiffy.parseFromDateTime(from).add(months: 1).dateTime;
case RepetitionStep.EVERY_OTHER_MONTH: return Jiffy.parseFromDateTime(from).add(months: 2).dateTime;
case RepetitionStep.QUARTERLY: return Jiffy.parseFromDateTime(from).add(months: 3).dateTime;
case RepetitionStep.HALF_YEARLY: return Jiffy.parseFromDateTime(from).add(months: 6).dateTime;
case RepetitionStep.YEARLY: return Jiffy.parseFromDateTime(from).add(years: 1).dateTime;
case RepetitionStep.CUSTOM: throw new Exception("custom repetition step not allowed here");
}
}
Expand All @@ -211,11 +211,11 @@ class Schedule {
case RepetitionStep.EVERY_OTHER_DAY: return from.subtract(Duration(days: 2));
case RepetitionStep.WEEKLY: return from.subtract(Duration(days: 7));
case RepetitionStep.EVERY_OTHER_WEEK: return from.subtract(Duration(days: 14));
case RepetitionStep.MONTHLY: return Jiffy(from).subtract(months: 1).dateTime;
case RepetitionStep.EVERY_OTHER_MONTH: return Jiffy(from).subtract(months: 2).dateTime;
case RepetitionStep.QUARTERLY: return Jiffy(from).subtract(months: 3).dateTime;
case RepetitionStep.HALF_YEARLY: return Jiffy(from).subtract(months: 6).dateTime;
case RepetitionStep.YEARLY: return Jiffy(from).subtract(years: 1).dateTime;
case RepetitionStep.MONTHLY: return Jiffy.parseFromDateTime(from).subtract(months: 1).dateTime;
case RepetitionStep.EVERY_OTHER_MONTH: return Jiffy.parseFromDateTime(from).subtract(months: 2).dateTime;
case RepetitionStep.QUARTERLY: return Jiffy.parseFromDateTime(from).subtract(months: 3).dateTime;
case RepetitionStep.HALF_YEARLY: return Jiffy.parseFromDateTime(from).subtract(months: 6).dateTime;
case RepetitionStep.YEARLY: return Jiffy.parseFromDateTime(from).subtract(years: 1).dateTime;
case RepetitionStep.CUSTOM: throw new Exception("custom repetition step not allowed here");
}
}
Expand Down Expand Up @@ -277,7 +277,7 @@ class Schedule {
return "${translate('model.repetition_step.every')} $unit";
}

static Unit fromCustomRepetitionToUnit(CustomRepetition customRepetition, [Clause? clause]) {
static GeneralUnit fromCustomRepetitionToUnit(CustomRepetition customRepetition, [Clause? clause]) {
switch(customRepetition.repetitionUnit) {
case RepetitionUnit.MINUTES: return Minutes(customRepetition.repetitionValue, clause);
case RepetitionUnit.HOURS: return Hours(customRepetition.repetitionValue, clause);
Expand Down Expand Up @@ -314,7 +314,7 @@ class Schedule {
return dayOfMonth;
},
shiftBack: (repetitionValue, from) {
return Jiffy(from).subtract(months: repetitionValue).dateTime;
return Jiffy.parseFromDateTime(from).subtract(months: repetitionValue).dateTime;
},
) ?? nextRegularDueDate;
}
Expand All @@ -328,7 +328,7 @@ class Schedule {
return dayOfMonth.value;
},
shiftBack: (repetitionValue, from) {
return Jiffy(from).subtract(years: repetitionValue).dateTime;
return Jiffy.parseFromDateTime(from).subtract(years: repetitionValue).dateTime;
},
) ?? nextRegularDueDate;
}
Expand Down
62 changes: 46 additions & 16 deletions lib/service/LocalNotificationService.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_timezone/flutter_timezone.dart';
import 'package:flutter_translate/flutter_translate.dart';
import 'package:personaltasklogger/model/Schedule.dart';
import 'package:timezone/data/latest.dart' as tz;
Expand Down Expand Up @@ -118,6 +119,14 @@ class LocalNotificationService {
InitializationSettings(android: initializationSettingsAndroid);

tz.initializeTimeZones();
try {
final String currentTimeZone = await FlutterTimezone.getLocalTimezone();
debugPrint("currentTimeZone=$currentTimeZone");
tz.setLocalLocation(tz.getLocation(currentTimeZone));
} catch (e) {
// ignore instead of failing
print(e);
}

await _flutterLocalNotificationsPlugin.initialize(initializationSettings,
onDidReceiveNotificationResponse: (NotificationResponse response) async {
Expand Down Expand Up @@ -145,33 +154,45 @@ class LocalNotificationService {

Future<void> scheduleNotification(String receiverKey, int id, String title, message, Duration duration, String channelId,
[Color? color, List<AndroidNotificationAction>? actions, bool withTranslation = true, CustomRepetition? snoozePeriod]) async {
final when = tz.TZDateTime.now(tz.local).add(duration);

if (when.isBefore(DateTime.now())) {
debugPrint("Scheduled notification $id in the past, skip ($when)");
if (duration.isNegative || duration.inSeconds < 10) {
debugPrint(
"Scheduled notification $id in the past, skip");
return;
}

final now = DateTime.now().add(duration);

var zonedTime = tz.TZDateTime.local(now.year, now.month, now.day, now.hour, now.minute, now.second);
if (duration.inMinutes >= 1) {
// truncate to full minutes if duration greater than one minute
zonedTime = zonedTime.subtract(Duration(seconds: zonedTime.second));
}

final parameterMap = {
'receiverKey' : receiverKey,
'id' : id,
'title' : title,
'message' : message,
'channelId' : channelId,
'color' : color?.value,
'actions' : actions?.map((a) => a.id + "-" + a.showsUserInterface.toString() + "-" + a.title).toList(),
'snooze_period_value' : snoozePeriod?.repetitionValue,
'snooze_period_unit' : snoozePeriod?.repetitionUnit.index,
'receiverKey': receiverKey,
'id': id,
'title': title,
'message': message,
'channelId': channelId,
'color': color?.value,
'actions': actions?.map((a) =>
a.id + "-" + a.showsUserInterface.toString() + "-" + a.title).toList(),
'snooze_period_value': snoozePeriod?.repetitionValue,
'snooze_period_unit': snoozePeriod?.repetitionUnit.index,
};
final parametersAsJson = jsonEncode(parameterMap);

debugPrint("Schedule $id ($zonedTime), duration=${duration} tz=${tz.local}");


await _flutterLocalNotificationsPlugin.zonedSchedule(
id,
title,
message,
when.subtract(Duration(seconds: when.second)), // trunc seconds
zonedTime,
NotificationDetails(android: _createNotificationDetails(color, channelId, false, actions, withTranslation)),
androidAllowWhileIdle: true,
androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,
uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime,
payload: receiverKey + "-" + id.toString() + RESCHEDULE_JSON_START_MARKER + parametersAsJson);
}
Expand Down Expand Up @@ -200,12 +221,16 @@ class LocalNotificationService {
AndroidFlutterLocalNotificationsPlugin? nativePlugin = _flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation();
nativePlugin?.getActiveNotifications().then((activeNotifications) {
activeNotifications.forEach((element) {
_handleActiveNotification(element.id, element.channelId);
final id = element.id;
if (id != null) {
_handleActiveNotification(id, element.channelId);
}
});
handleActiveNotificationPostHandler(activeNotifications.map((e) => e.id).toList());
handleActiveNotificationPostHandler(activeNotifications.where((e) => e.id != null).map((e) => e.id!).toList());
});
}


void _handlePayload(bool isAppLaunch, String payload, String? actionId) {
debugPrint("_handlePayload=$payload $isAppLaunch");

Expand Down Expand Up @@ -247,5 +272,10 @@ class LocalNotificationService {
actions: actions,
);
}

void requestPermissions() {
AndroidFlutterLocalNotificationsPlugin? nativePlugin = _flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation();
nativePlugin?.requestExactAlarmsPermission();
}
}

2 changes: 1 addition & 1 deletion lib/service/PreferenceService.dart
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ class PreferenceService implements ITranslatePreferences {
KeyValueRepository.update(keyValue);
}
else {
KeyValueRepository.insert(KeyValue(null, key, value));
KeyValueRepository.insert(KeyValue(null, key, value.toString()));
}
});

Expand Down
2 changes: 2 additions & 0 deletions lib/ui/PersonalTaskLoggerApp.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class PersonalTaskLoggerApp extends StatelessWidget {
supportedLocales: localizationDelegate.supportedLocales,
locale: localizationDelegate.currentLocale,
darkTheme: ThemeData(
useMaterial3: false,
brightness: Brightness.dark,
primaryColor: PRIMARY_COLOR,
checkboxTheme: CheckboxThemeData(
Expand Down Expand Up @@ -60,6 +61,7 @@ class PersonalTaskLoggerApp extends StatelessWidget {

),
theme: ThemeData(
useMaterial3: false,
brightness: Brightness.light,
primaryColor: PRIMARY_COLOR,
primarySwatch: BUTTON_COLOR,
Expand Down
Loading

0 comments on commit 5ce3f9d

Please sign in to comment.