You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tasks/app/src/main/java/org/tasks/filters/FilterCriteriaProvider.kt

233 lines
9.6 KiB
Kotlin

package org.tasks.filters
import android.content.Context
import com.todoroo.andlib.sql.Criterion.Companion.and
import com.todoroo.andlib.sql.Criterion.Companion.or
import com.todoroo.andlib.sql.Field.Companion.field
import com.todoroo.andlib.sql.Join.Companion.inner
import com.todoroo.andlib.sql.Query.Companion.select
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 dagger.hilt.android.qualifiers.ApplicationContext
import org.tasks.R
import org.tasks.data.*
import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible
import java.util.*
import javax.inject.Inject
class FilterCriteriaProvider @Inject constructor(
@param:ApplicationContext private val context: Context,
private val tagDataDao: TagDataDao,
private val googleTaskListDao: GoogleTaskListDao,
private val caldavDao: CaldavDao) {
private val r = context.resources
suspend fun getFilterCriteria(identifier: String): CustomFilterCriterion {
return when (identifier) {
IDENTIFIER_UNIVERSE -> startingUniverse
IDENTIFIER_TITLE -> taskTitleContainsFilter
IDENTIFIER_IMPORTANCE -> priorityFilter
IDENTIFIER_DUEDATE -> dueDateFilter
IDENTIFIER_GTASKS -> gtasksFilterCriteria()
IDENTIFIER_CALDAV -> caldavFilterCriteria()
IDENTIFIER_TAG_IS -> tagFilter()
IDENTIFIER_TAG_CONTAINS -> tagNameContainsFilter
else -> throw RuntimeException("Unknown identifier: $identifier")
}
}
val startingUniverse: CustomFilterCriterion
get() = MultipleSelectCriterion(
IDENTIFIER_UNIVERSE,
context.getString(R.string.BFE_Active),
null,
null,
null,
null,
null)
suspend fun all(): List<CustomFilterCriterion> {
val result: MutableList<CustomFilterCriterion> = ArrayList()
result.add(tagFilter())
result.add(tagNameContainsFilter)
result.add(dueDateFilter)
result.add(priorityFilter)
result.add(taskTitleContainsFilter)
if (googleTaskListDao.getAccounts().isNotEmpty()) {
result.add(gtasksFilterCriteria())
}
result.add(caldavFilterCriteria())
return result
}
// TODO: adding to hash set because duplicate tag name bug hasn't been fixed yet
private suspend fun tagFilter(): CustomFilterCriterion {
// TODO: adding to hash set because duplicate tag name bug hasn't been fixed yet
val tagNames = tagDataDao
.tagDataOrderedByName()
.map(TagData::name)
.distinct()
.toTypedArray()
val values: MutableMap<String, Any> = HashMap()
values[Tag.KEY] = "?"
return MultipleSelectCriterion(
IDENTIFIER_TAG_IS,
context.getString(R.string.CFC_tag_text),
select(Tag.TASK)
.from(Tag.TABLE)
.join(inner(Task.TABLE, Tag.TASK.eq(Task.ID)))
.where(and(activeAndVisible(), Tag.NAME.eq("?")))
.toString(),
values,
tagNames,
tagNames,
context.getString(R.string.CFC_tag_name))
}
val tagNameContainsFilter: CustomFilterCriterion
get() = TextInputCriterion(
IDENTIFIER_TAG_CONTAINS,
context.getString(R.string.CFC_tag_contains_text),
select(Tag.TASK)
.from(Tag.TABLE)
.join(inner(Task.TABLE, Tag.TASK.eq(Task.ID)))
.where(and(activeAndVisible(), Tag.NAME.like("%?%")))
.toString(),
context.getString(R.string.CFC_tag_contains_name),
"",
context.getString(R.string.CFC_tag_contains_name))
val dueDateFilter: CustomFilterCriterion
get() {
val entryValues = arrayOf(
"0",
PermaSql.VALUE_EOD_YESTERDAY,
PermaSql.VALUE_EOD,
PermaSql.VALUE_EOD_TOMORROW,
PermaSql.VALUE_EOD_DAY_AFTER,
PermaSql.VALUE_EOD_NEXT_WEEK,
PermaSql.VALUE_EOD_NEXT_MONTH)
val values: MutableMap<String?, Any> = HashMap()
values[Task.DUE_DATE.name] = "?"
return MultipleSelectCriterion(
IDENTIFIER_DUEDATE,
r.getString(R.string.CFC_dueBefore_text),
select(Task.ID)
.from(Task.TABLE)
.where(
and(
activeAndVisible(),
or(field("?").eq(0), Task.DUE_DATE.gt(0)),
Task.DUE_DATE.lte("?")))
.toString(),
values,
r.getStringArray(R.array.CFC_dueBefore_entries),
entryValues,
r.getString(R.string.CFC_dueBefore_name))
}
val priorityFilter: CustomFilterCriterion
get() {
val entryValues = arrayOf(
Task.Priority.HIGH.toString(),
Task.Priority.MEDIUM.toString(),
Task.Priority.LOW.toString(),
Task.Priority.NONE.toString())
val entries = arrayOf("!!!", "!!", "!", "o")
val values: MutableMap<String?, Any> = HashMap()
values[Task.IMPORTANCE.name] = "?"
return MultipleSelectCriterion(
IDENTIFIER_IMPORTANCE,
r.getString(R.string.CFC_importance_text),
select(Task.ID)
.from(Task.TABLE)
.where(and(activeAndVisible(), Task.IMPORTANCE.lte("?")))
.toString(),
values,
entries,
entryValues,
r.getString(R.string.CFC_importance_name))
}
private val taskTitleContainsFilter: CustomFilterCriterion
get() = TextInputCriterion(
IDENTIFIER_TITLE,
r.getString(R.string.CFC_title_contains_text),
select(Task.ID)
.from(Task.TABLE)
.where(and(activeAndVisible(), Task.TITLE.like("%?%")))
.toString(),
r.getString(R.string.CFC_title_contains_name),
"",
r.getString(R.string.CFC_title_contains_name))
private suspend fun gtasksFilterCriteria(): CustomFilterCriterion {
val lists = googleTaskListDao.getAllLists()
val listNames = arrayOfNulls<String>(lists.size)
val listIds = arrayOfNulls<String>(lists.size)
for (i in lists.indices) {
listNames[i] = lists[i].title
listIds[i] = lists[i].remoteId
}
val values: MutableMap<String, Any> = HashMap()
values[GoogleTask.KEY] = "?"
return MultipleSelectCriterion(
IDENTIFIER_GTASKS,
context.getString(R.string.CFC_gtasks_list_text),
select(GoogleTask.TASK)
.from(GoogleTask.TABLE)
.join(inner(Task.TABLE, GoogleTask.TASK.eq(Task.ID)))
.where(
and(
activeAndVisible(),
GoogleTask.DELETED.eq(0),
GoogleTask.LIST.eq("?")))
.toString(),
values,
listNames,
listIds,
context.getString(R.string.CFC_gtasks_list_name))
}
private suspend fun caldavFilterCriteria(): CustomFilterCriterion {
val calendars = caldavDao.getCalendars()
val names = arrayOfNulls<String>(calendars.size)
val ids = arrayOfNulls<String>(calendars.size)
for (i in calendars.indices) {
names[i] = calendars[i].name
ids[i] = calendars[i].uuid
}
val values: MutableMap<String, Any> = HashMap()
values[CaldavTask.KEY] = "?"
return MultipleSelectCriterion(
IDENTIFIER_CALDAV,
context.getString(R.string.CFC_gtasks_list_text),
select(CaldavTask.TASK)
.from(CaldavTask.TABLE)
.join(inner(Task.TABLE, CaldavTask.TASK.eq(Task.ID)))
.where(
and(
activeAndVisible(),
CaldavTask.DELETED.eq(0),
CaldavTask.CALENDAR.eq("?")))
.toString(),
values,
names,
ids,
context.getString(R.string.CFC_list_name))
}
companion object {
private const val IDENTIFIER_UNIVERSE = "active"
private const val IDENTIFIER_TITLE = "title"
private const val IDENTIFIER_IMPORTANCE = "importance"
private const val IDENTIFIER_DUEDATE = "dueDate"
private const val IDENTIFIER_GTASKS = "gtaskslist"
private const val IDENTIFIER_CALDAV = "caldavlist"
private const val IDENTIFIER_TAG_IS = "tag_is"
private const val IDENTIFIER_TAG_CONTAINS = "tag_contains"
}
}