diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt index 909c1f83d..bb500c2dd 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt @@ -83,7 +83,7 @@ class TaskAlarmManager( private fun setTimeForDailyReminder(remindersItem: RemindersItem?, task: Task): RemindersItem? { val newTime = task.getNextReminderOccurrence(remindersItem, context) - remindersItem?.time = newTime?.withZoneSameLocal(ZoneId.systemDefault())?.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) + remindersItem?.time = newTime?.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) return remindersItem } @@ -95,14 +95,13 @@ class TaskAlarmManager( * which is indicated by first nextDue being null (As the alarm is created before the API returns nextDue times) */ private fun setAlarmForRemindersItem(reminderItemTask: Task, remindersItem: RemindersItem?) { + if (remindersItem == null) return + val now = ZonedDateTime.now().withZoneSameLocal(ZoneId.systemDefault())?.toInstant() - val zonedTime = remindersItem?.getLocalZonedDateTimeInstant() - if (remindersItem == null || - (reminderItemTask.type == TaskType.DAILY && zonedTime?.isBefore(now) == true && reminderItemTask.nextDue?.firstOrNull() != null) || - (reminderItemTask.type == TaskType.TODO && zonedTime?.isBefore(now) == true || zonedTime == null) - ) { - return - } + val reminderZonedTime = remindersItem.getLocalZonedDateTimeInstant() + + if (reminderZonedTime == null || reminderZonedTime.isBefore(now)) return + val intent = Intent(context, TaskReceiver::class.java) intent.action = remindersItem.id @@ -129,7 +128,7 @@ class TaskAlarmManager( withImmutableFlag(PendingIntent.FLAG_CANCEL_CURRENT) ) - setAlarm(context, zonedTime.toEpochMilli(), sender) + setAlarm(context, reminderZonedTime.toEpochMilli(), sender) } private fun removeAlarmForRemindersItem(remindersItem: RemindersItem) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt index edbe560a0..ea2514e3c 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt @@ -344,38 +344,46 @@ open class Task : RealmObject, BaseMainObject, Parcelable, BaseTask { if (remindersItem == null) { return null } + val reminderTime = remindersItem.time?.parseToZonedDateTime() val zonedDateTimeNow = ZonedDateTime.now() - return if (nextDue?.firstOrNull() != null && (!isDisplayedActive || reminderTime?.isBefore(zonedDateTimeNow) == true) - ) { - val repeatingDays = repeat?.dayStrings(context) - val isScheduledForToday = repeatingDays?.find { day -> day == zonedDateTimeNow.dayOfWeekString() } - if (isScheduledForToday != null) { - val currentDateTime = LocalDateTime.now() - val updatedDateTime: LocalDateTime = LocalDateTime.of( - currentDateTime.year, - currentDateTime.month, - currentDateTime.dayOfMonth, - reminderTime?.hour ?: 0, - reminderTime?.minute ?: 0 - ) - updatedDateTime.atZone(ZoneId.systemDefault()) - } else { - val nextDate = LocalDateTime.ofInstant(nextDue?.firstOrNull()?.toInstant(), ZoneId.systemDefault()) - val updatedDateTime: LocalDateTime = LocalDateTime.of( - nextDate.year, - nextDate.month, - nextDate.dayOfMonth, - reminderTime?.hour ?: 0, - reminderTime?.minute ?: 0 - ) - updatedDateTime.atZone(ZoneId.systemDefault()) - } - } else { - return reminderTime + + // Check if the reminder is scheduled to repeat today + val repeatingDays = repeat?.dayStrings(context) + val isScheduledForToday = repeatingDays?.find { day -> day == zonedDateTimeNow.dayOfWeekString() } + // Check if reminder time already passed + val isReminderTimePassed = reminderTime?.isBefore(zonedDateTimeNow) == true + if (isScheduledForToday != null && !isReminderTimePassed) { + val currentDateTime = LocalDateTime.now() + val updatedDateTime: LocalDateTime = LocalDateTime.of( + currentDateTime.year, + currentDateTime.month, + currentDateTime.dayOfMonth, + reminderTime?.hour ?: 0, + reminderTime?.minute ?: 0 + ) + return updatedDateTime.atZone(ZoneId.systemDefault()) } + + + // If the reminder is not scheduled to repeat today, use the first upcoming nextDue date + val today = LocalDate.now() + // Filter out the dates that are in the past + val futureNextDues = nextDue?.filter { nextDueDate -> nextDueDate.toInstant().atZone(ZonedDateTime.now().zone).toLocalDate().isAfter(today) } + val earliestFutureDate = futureNextDues?.minByOrNull { it } + if (earliestFutureDate != null) { + return earliestFutureDate.toInstant() + .atZone(ZonedDateTime.now().zone) + .withHour(reminderTime?.hour ?: 0) + .withMinute(reminderTime?.minute ?: 0) + } + + + // If there are no upcoming nextDue dates, use the first upcoming reminder time + return reminderTime } + fun parseMarkdown() { parsedText = MarkdownParser.parseMarkdown(text) parsedNotes = MarkdownParser.parseMarkdown(notes)