Add 'Has reminder' custom filter criteria

pull/1768/head
Alex Baker 2 years ago
parent 00bc23c0dd
commit 03ea39c682

@ -19,6 +19,12 @@ abstract class Criterion(val operator: Operator) {
} }
} }
fun exists(query: Query): Criterion {
return object : Criterion(Operator.exists) {
override fun populate() = "EXISTS ($query)"
}
}
operator fun <T> T.plus(tail: Array<out T>): List<T> { operator fun <T> T.plus(tail: Array<out T>): List<T> {
val list = ArrayList<T>(1 + tail.size) val list = ArrayList<T>(1 + tail.size)

@ -12,6 +12,7 @@ class Operator private constructor(private val operator: String) {
val not = Operator("NOT") val not = Operator("NOT")
val like = Operator("LIKE") val like = Operator("LIKE")
val `in` = Operator("IN") val `in` = Operator("IN")
val exists = Operator("EXISTS")
val gt = Operator(">") val gt = Operator(">")
val gte = Operator(">=") val gte = Operator(">=")
val lt = Operator("<") val lt = Operator("<")

@ -6,10 +6,11 @@ import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.Ignore import androidx.room.Ignore
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.todoroo.andlib.data.Table
import org.tasks.time.DateTimeUtils.printTimestamp import org.tasks.time.DateTimeUtils.printTimestamp
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@Entity(tableName = "alarms") @Entity(tableName = Alarm.TABLE_NAME)
class Alarm : Parcelable { class Alarm : Parcelable {
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "_id") @ColumnInfo(name = "_id")
@ -96,6 +97,9 @@ class Alarm : Parcelable {
} }
companion object { companion object {
const val TABLE_NAME = "alarms"
val TABLE = Table(TABLE_NAME)
val TASK = TABLE.column("task")
const val TYPE_DATE_TIME = 0 const val TYPE_DATE_TIME = 0
const val TYPE_REL_START = 1 const val TYPE_REL_START = 1
const val TYPE_REL_END = 2 const val TYPE_REL_END = 2

@ -2,19 +2,30 @@ package org.tasks.filters
import android.content.Context import android.content.Context
import com.todoroo.andlib.sql.Criterion.Companion.and import com.todoroo.andlib.sql.Criterion.Companion.and
import com.todoroo.andlib.sql.Criterion.Companion.exists
import com.todoroo.andlib.sql.Criterion.Companion.or import com.todoroo.andlib.sql.Criterion.Companion.or
import com.todoroo.andlib.sql.Field.Companion.field import com.todoroo.andlib.sql.Field.Companion.field
import com.todoroo.andlib.sql.Join.Companion.inner import com.todoroo.andlib.sql.Join.Companion.inner
import com.todoroo.andlib.sql.Join.Companion.left import com.todoroo.andlib.sql.Join.Companion.left
import com.todoroo.andlib.sql.Query.Companion.select import com.todoroo.andlib.sql.Query.Companion.select
import com.todoroo.andlib.sql.UnaryCriterion.Companion.isNotNull import com.todoroo.andlib.sql.UnaryCriterion.Companion.isNotNull
import com.todoroo.astrid.api.* import com.todoroo.astrid.api.BooleanCriterion
import com.todoroo.astrid.api.CustomFilterCriterion
import com.todoroo.astrid.api.MultipleSelectCriterion
import com.todoroo.astrid.api.PermaSql
import com.todoroo.astrid.api.TextInputCriterion
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import org.tasks.R import org.tasks.R
import org.tasks.data.* import org.tasks.data.Alarm
import org.tasks.data.CaldavDao
import org.tasks.data.CaldavTask
import org.tasks.data.GoogleTask
import org.tasks.data.GoogleTaskListDao
import org.tasks.data.Tag
import org.tasks.data.TagData
import org.tasks.data.TagDataDao
import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible
import java.util.*
import javax.inject.Inject import javax.inject.Inject
class FilterCriteriaProvider @Inject constructor( class FilterCriteriaProvider @Inject constructor(
@ -39,6 +50,7 @@ class FilterCriteriaProvider @Inject constructor(
IDENTIFIER_HIDDEN -> hiddenFilter IDENTIFIER_HIDDEN -> hiddenFilter
IDENTIFIER_PARENT -> parentFilter IDENTIFIER_PARENT -> parentFilter
IDENTIFIER_SUBTASK -> subtaskFilter IDENTIFIER_SUBTASK -> subtaskFilter
IDENTIFIER_REMINDERS -> reminderFilter
else -> throw RuntimeException("Unknown identifier: $identifier") else -> throw RuntimeException("Unknown identifier: $identifier")
} }
@ -70,6 +82,7 @@ class FilterCriteriaProvider @Inject constructor(
add(hiddenFilter) add(hiddenFilter)
add(parentFilter) add(parentFilter)
add(subtaskFilter) add(subtaskFilter)
add(reminderFilter)
} }
return result return result
} }
@ -157,6 +170,18 @@ class FilterCriteriaProvider @Inject constructor(
.toString() .toString()
) )
private val reminderFilter: CustomFilterCriterion
get() {
return BooleanCriterion(
IDENTIFIER_REMINDERS,
context.getString(R.string.custom_filter_has_reminders),
select(Task.ID)
.from(Task.TABLE)
.where(exists(select(ONE).from(Alarm.TABLE).where(Alarm.TASK.eq(Task.ID))))
.toString()
)
}
val tagNameContainsFilter: CustomFilterCriterion val tagNameContainsFilter: CustomFilterCriterion
get() = TextInputCriterion( get() = TextInputCriterion(
IDENTIFIER_TAG_CONTAINS, IDENTIFIER_TAG_CONTAINS,
@ -342,5 +367,8 @@ class FilterCriteriaProvider @Inject constructor(
private const val IDENTIFIER_HIDDEN = "hidden" private const val IDENTIFIER_HIDDEN = "hidden"
private const val IDENTIFIER_PARENT = "parent" private const val IDENTIFIER_PARENT = "parent"
private const val IDENTIFIER_SUBTASK = "subtask" private const val IDENTIFIER_SUBTASK = "subtask"
private const val IDENTIFIER_REMINDERS = "reminders"
private val ONE = field("1")
} }
} }

@ -636,6 +636,7 @@ File %1$s contained %2$s.\n\n
<string name="delete_comment">Delete this comment?</string> <string name="delete_comment">Delete this comment?</string>
<string name="custom_filter_has_subtask">Has subtasks</string> <string name="custom_filter_has_subtask">Has subtasks</string>
<string name="custom_filter_is_subtask">Is subtask</string> <string name="custom_filter_is_subtask">Is subtask</string>
<string name="custom_filter_has_reminders">Has reminders</string>
<string name="your_subscription_expired">Your subscription has expired. Subscribe now to resume service.</string> <string name="your_subscription_expired">Your subscription has expired. Subscribe now to resume service.</string>
<string name="insufficient_subscription">Insufficient subscription level. Please upgrade your subscription to resume service.</string> <string name="insufficient_subscription">Insufficient subscription level. Please upgrade your subscription to resume service.</string>
<string name="insufficient_sponsorship">No eligible GitHub sponsorship found</string> <string name="insufficient_sponsorship">No eligible GitHub sponsorship found</string>

Loading…
Cancel
Save