diff --git a/app/src/main/java/com/todoroo/astrid/dao/TaskDao.kt b/app/src/main/java/com/todoroo/astrid/dao/TaskDao.kt index 0a9a62f4a..678ba8f14 100644 --- a/app/src/main/java/com/todoroo/astrid/dao/TaskDao.kt +++ b/app/src/main/java/com/todoroo/astrid/dao/TaskDao.kt @@ -5,7 +5,6 @@ */ package com.todoroo.astrid.dao -import com.todoroo.andlib.utility.DateUtilities import com.todoroo.astrid.api.Filter import com.todoroo.astrid.data.Task import org.tasks.data.SubtaskInfo @@ -26,8 +25,6 @@ class TaskDao @Inject constructor( suspend fun activeTimers(): Int = taskDao.activeTimers() - suspend fun activeNotifications(): List = taskDao.activeNotifications() - suspend fun fetch(remoteId: String): Task? = taskDao.fetch(remoteId) suspend fun getRecurringTasks(remoteIds: List): List = diff --git a/app/src/main/java/com/todoroo/astrid/reminders/ReminderService.kt b/app/src/main/java/com/todoroo/astrid/reminders/ReminderService.kt index 8c481e697..d8c27f131 100644 --- a/app/src/main/java/com/todoroo/astrid/reminders/ReminderService.kt +++ b/app/src/main/java/com/todoroo/astrid/reminders/ReminderService.kt @@ -30,26 +30,18 @@ class ReminderService internal constructor( taskDao: TaskDao ) : this(preferences, notificationQueue, Random(), taskDao) - suspend fun scheduleAllAlarms(taskIds: List) { - taskDao - .fetch(taskIds) - .map { getReminderEntry(it) } - .let { jobs.add(it) } - } + suspend fun scheduleAlarm(id: Long) = scheduleAllAlarms(listOf(id)) - suspend fun scheduleAllAlarms() { - taskDao - .getTasksWithReminders() - .map { getReminderEntry(it) } - .let { jobs.add(it) } - } + suspend fun scheduleAllAlarms(taskIds: List) = scheduleAlarms(taskDao.fetch(taskIds)) - fun scheduleAlarm(task: Task?) { - val reminder = getReminderEntry(task) - if (reminder != null) { - jobs.add(reminder) - } - } + suspend fun scheduleAllAlarms() = scheduleAlarms(taskDao.getTasksWithReminders()) + + fun scheduleAlarm(task: Task) = scheduleAlarms(listOf(task)) + + private fun scheduleAlarms(tasks: List) = + tasks + .mapNotNull { getReminderEntry(it) } + .let { jobs.add(it) } fun cancelReminder(taskId: Long) { jobs.cancelReminder(taskId) diff --git a/app/src/main/java/org/tasks/Notifier.kt b/app/src/main/java/org/tasks/Notifier.kt index 1b2a891f4..41c40b7e8 100644 --- a/app/src/main/java/org/tasks/Notifier.kt +++ b/app/src/main/java/org/tasks/Notifier.kt @@ -18,7 +18,6 @@ import org.tasks.preferences.Preferences import org.tasks.themes.ColorProvider import org.tasks.time.DateTimeUtils import timber.log.Timber -import java.util.* import javax.inject.Inject import kotlin.math.min @@ -67,20 +66,22 @@ class Notifier @Inject constructor( } suspend fun triggerNotifications(entries: List) { - val notifications: MutableList = ArrayList() var ringFiveTimes = false var ringNonstop = false - for (entry in entries.takeLast(NotificationManager.MAX_NOTIFICATIONS)) { - val task = taskDao.fetch(entry.taskId) ?: continue - if (entry.type != ReminderService.TYPE_RANDOM) { - ringFiveTimes = ringFiveTimes or task.isNotifyModeFive - ringNonstop = ringNonstop or task.isNotifyModeNonstop - } - val notification = notificationManager.getTaskNotification(entry) - if (notification != null) { - notifications.add(entry) - } - } + val notifications = entries + .filter { + taskDao.fetch(it.taskId) + ?.let { task -> + if (it.type != ReminderService.TYPE_RANDOM) { + ringFiveTimes = ringFiveTimes or task.isNotifyModeFive + ringNonstop = ringNonstop or task.isNotifyModeNonstop + } + notificationManager.getTaskNotification(it) != null + } + ?: false + } + .takeLast(NotificationManager.MAX_NOTIFICATIONS) + if (notifications.isEmpty()) { return } diff --git a/app/src/main/java/org/tasks/data/TaskDao.kt b/app/src/main/java/org/tasks/data/TaskDao.kt index 3f8f98b66..3f4b85b72 100644 --- a/app/src/main/java/org/tasks/data/TaskDao.kt +++ b/app/src/main/java/org/tasks/data/TaskDao.kt @@ -147,6 +147,9 @@ SELECT EXISTS(SELECT 1 FROM tasks WHERE parent > 0 AND deleted = 0) AS hasSubtas @Query("UPDATE tasks SET parent = :parent WHERE _id IN (:children)") internal abstract suspend fun setParentInternal(parent: Long, children: List) + @Query("UPDATE tasks SET lastNotified = :timestamp WHERE _id = :id AND lastNotified != :timestamp") + abstract suspend fun setLastNotified(id: Long, timestamp: Long): Int + @Transaction open suspend fun fetchChildren(id: Long): List { return fetch(getChildren(id)) diff --git a/app/src/main/java/org/tasks/jobs/NotificationQueue.kt b/app/src/main/java/org/tasks/jobs/NotificationQueue.kt index d3e69cddc..ae92cc34b 100644 --- a/app/src/main/java/org/tasks/jobs/NotificationQueue.kt +++ b/app/src/main/java/org/tasks/jobs/NotificationQueue.kt @@ -18,9 +18,9 @@ class NotificationQueue @Inject constructor(private val preferences: Preferences fun add(entry: T) = add(listOf(entry)) @Synchronized - fun add(entries: Iterable) { + fun add(entries: Iterable) { val originalFirstTime = firstTime() - entries.filterNotNull().forEach { jobs.put(it.time, it) } + entries.forEach { jobs.put(it.time, it) } if (originalFirstTime != firstTime()) { scheduleNext(true) } diff --git a/app/src/main/java/org/tasks/notifications/NotificationManager.kt b/app/src/main/java/org/tasks/notifications/NotificationManager.kt index 32b798f4a..031fbc231 100644 --- a/app/src/main/java/org/tasks/notifications/NotificationManager.kt +++ b/app/src/main/java/org/tasks/notifications/NotificationManager.kt @@ -11,7 +11,6 @@ import com.todoroo.andlib.sql.QueryTemplate import com.todoroo.andlib.utility.AndroidUtilities import com.todoroo.andlib.utility.DateUtilities import com.todoroo.astrid.api.Filter -import com.todoroo.astrid.dao.TaskDao import com.todoroo.astrid.data.Task import com.todoroo.astrid.reminders.ReminderService import dagger.hilt.android.qualifiers.ApplicationContext @@ -19,6 +18,7 @@ import org.tasks.LocalBroadcastManager import org.tasks.R import org.tasks.Strings.isNullOrEmpty import org.tasks.data.LocationDao +import org.tasks.data.TaskDao import org.tasks.intents.TaskIntents import org.tasks.preferences.Preferences import org.tasks.receivers.CompleteTaskReceiver @@ -40,7 +40,8 @@ class NotificationManager @Inject constructor( private val notificationDao: NotificationDao, private val taskDao: TaskDao, private val locationDao: LocationDao, - private val localBroadcastManager: LocalBroadcastManager) { + private val localBroadcastManager: LocalBroadcastManager, + private val reminderService: ReminderService) { private val notificationManagerCompat = NotificationManagerCompat.from(context) private val colorProvider = ColorProvider(context, preferences) private val throttle = Throttle(NOTIFICATIONS_PER_SECOND) @@ -159,6 +160,10 @@ class NotificationManager @Inject constructor( .setGroupAlertBehavior( if (alert) NotificationCompat.GROUP_ALERT_CHILDREN else NotificationCompat.GROUP_ALERT_SUMMARY) notify(notification.taskId, builder, alert, nonstop, fiveTimes) + val reminderTime = DateTime(notification.timestamp).endOfMinute().millis + if (taskDao.setLastNotified(notification.taskId, reminderTime) == 1) { + reminderService.scheduleAlarm(notification.taskId) + } alert = false } } @@ -303,12 +308,6 @@ class NotificationManager @Inject constructor( val taskTitle = task.title val taskDescription = task.notes - // update last reminder time - val reminderTime = DateTime(`when`).endOfMinute().millis - if (reminderTime != task.reminderLast) { - task.reminderLast = reminderTime - taskDao.save(task) - } val builder = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_DEFAULT) .setCategory(NotificationCompat.CATEGORY_REMINDER) .setContentTitle(taskTitle)