Sort completed tasks at bottom

pull/1736/head
Alex Baker 2 years ago
parent eda9cd0c97
commit ef62a946c6

@ -8,6 +8,7 @@ import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.PermaSql
import com.todoroo.astrid.core.SortHelper
import com.todoroo.astrid.data.Task
import org.tasks.filters.RecentlyModifiedFilter
import org.tasks.preferences.QueryPreferences
internal object TaskListQueryNonRecursive {
@ -19,17 +20,22 @@ internal object TaskListQueryNonRecursive {
private val TAGS =
field("group_concat(distinct(${TaskListFragment.TAGS_METADATA_JOIN}.tag_uid))")
.`as`("tags")
private val FIELDS = TaskListQuery.FIELDS.plus(TAGS).toTypedArray()
private val IS_COMPLETE = field("tasks.completed > 0").`as`("is_complete")
private const val ORDER_BY = "ORDER BY is_complete ASC, tasks.completed DESC"
private val FIELDS = TaskListQuery.FIELDS.plus(TAGS).plus(IS_COMPLETE).toTypedArray()
fun getNonRecursiveQuery(filter: Filter, preferences: QueryPreferences): MutableList<String> {
val joinedQuery = JOINS + filter.getSqlQuery()
val sortMode = preferences.sortMode
val sortGroup = field(SortHelper.getSortGroup(sortMode) ?: "NULL").`as`("sortGroup")
val query = SortHelper.adjustQueryForFlagsAndSort(preferences, joinedQuery, sortMode)
val groupedQuery = if (query.contains("ORDER BY")) {
query.replace("ORDER BY", "GROUP BY ${Task.ID} ORDER BY")
} else {
"$query GROUP BY ${Task.ID}"
val groupedQuery = when {
filter is RecentlyModifiedFilter ->
query.replace("ORDER BY", "GROUP BY ${Task.ID} ORDER BY")
query.contains("ORDER BY") ->
query.replace("ORDER BY", "GROUP BY ${Task.ID} $ORDER_BY,")
else ->
"$query GROUP BY ${Task.ID} $ORDER_BY"
}
return mutableListOf(
Query.select(*FIELDS.plus(sortGroup))

@ -98,12 +98,12 @@ internal object TaskListQueryRecursive {
val sortSelect = SortHelper.orderSelectForSortTypeRecursive(sortMode)
val withClause ="""
CREATE TEMPORARY TABLE `recursive_tasks` AS
WITH RECURSIVE recursive_tasks (task, parent, collapsed, hidden, indent, title, sortField, primary_sort, secondary_sort, sort_group) AS (
SELECT tasks._id, 0 as parent, tasks.collapsed as collapsed, 0 as hidden, 0 AS sort_indent, UPPER(tasks.title) AS sort_title, $sortSelect, $sortField as primary_sort, NULL as secondarySort, ${SortHelper.getSortGroup(sortMode)} FROM tasks
WITH RECURSIVE recursive_tasks (task, parent_complete, subtask_complete, completion_sort, parent, collapsed, hidden, indent, title, sortField, primary_sort, secondary_sort, sort_group) AS (
SELECT tasks._id, tasks.completed > 0 as parent_complete, 0 as subtask_complete, tasks.completed as completion_sort, 0 as parent, tasks.collapsed as collapsed, 0 as hidden, 0 AS sort_indent, UPPER(tasks.title) AS sort_title, $sortSelect, $sortField as primary_sort, NULL as secondarySort, ${SortHelper.getSortGroup(sortMode)} FROM tasks
$parentQuery
UNION ALL SELECT tasks._id, recursive_tasks.task as parent, tasks.collapsed as collapsed, CASE WHEN recursive_tasks.collapsed > 0 OR recursive_tasks.hidden > 0 THEN 1 ELSE 0 END as hidden, recursive_tasks.indent+1 AS sort_indent, UPPER(tasks.title) AS sort_title, $sortSelect, recursive_tasks.primary_sort as primary_sort, $sortField as secondary_sort, recursive_tasks.sort_group FROM tasks
UNION ALL SELECT tasks._id, recursive_tasks.parent_complete, tasks.completed > 0, tasks.completed as completion_sort, recursive_tasks.task as parent, tasks.collapsed as collapsed, CASE WHEN recursive_tasks.collapsed > 0 OR recursive_tasks.hidden > 0 THEN 1 ELSE 0 END as hidden, recursive_tasks.indent+1 AS sort_indent, UPPER(tasks.title) AS sort_title, $sortSelect, recursive_tasks.primary_sort as primary_sort, $sortField as secondary_sort, recursive_tasks.sort_group FROM tasks
$subtaskQuery
ORDER BY sort_indent DESC, ${SortHelper.orderForSortTypeRecursive(sortMode, reverseSort)}
ORDER BY parent_complete ASC, sort_indent DESC, subtask_complete ASC, completion_sort DESC, ${SortHelper.orderForSortTypeRecursive(sortMode, reverseSort)}
) SELECT * FROM recursive_tasks
""".trimIndent()

@ -7,6 +7,8 @@ import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.core.SortHelper.*
import org.tasks.R
import org.tasks.date.DateTimeUtils.toDateTime
import org.tasks.tasklist.SectionedDataSource.Companion.HEADER_COMPLETED
import org.tasks.tasklist.SectionedDataSource.Companion.HEADER_OVERDUE
import java.time.format.FormatStyle
import java.util.*
@ -34,8 +36,9 @@ data class AdapterSection(
compact: Boolean = false
): String =
when {
value == HEADER_COMPLETED -> context.getString(R.string.completed)
sortMode == SORT_IMPORTANCE -> context.getString(priorityToString())
value == -1L -> context.getString(R.string.filter_overdue)
value == HEADER_OVERDUE -> context.getString(R.string.filter_overdue)
value == 0L -> context.getString(when (sortMode) {
SORT_DUE -> R.string.no_due_date
SORT_START -> R.string.no_start_date

@ -62,12 +62,14 @@ class SectionedDataSource constructor(
for (i in tasks.indices) {
val task = tasks[i]
val sortGroup = task.sortGroup ?: continue
val header = if (sortMode == SortHelper.SORT_IMPORTANCE || sortGroup == 0L) {
val header = if (task.isCompleted && !task.hasParent()) {
HEADER_COMPLETED
} else if (sortMode == SortHelper.SORT_IMPORTANCE || sortGroup == 0L) {
sortGroup
} else if (sortMode == SortHelper.SORT_DUE) {
when {
sortGroup == 0L -> 0
sortGroup < startOfToday -> -1
sortGroup < startOfToday -> HEADER_OVERDUE
else -> sortGroup.startOfDay()
}
} else {
@ -77,14 +79,21 @@ class SectionedDataSource constructor(
if (i == 0) {
sections.add(AdapterSection(i, header, 0, isCollapsed))
} else {
val previous = tasks[i - 1].sortGroup
when (sortMode) {
SortHelper.SORT_IMPORTANCE -> if (header != previous) {
sections.add(AdapterSection(i, header, 0, isCollapsed))
val previousTask = tasks[i - 1]
val previous = previousTask.sortGroup
when {
task.isCompleted && !task.hasParent() -> {
if (!previousTask.isCompleted) {
sections.add(AdapterSection(i, header, 0, isCollapsed))
}
}
SortHelper.SORT_DUE -> {
sortMode == SortHelper.SORT_IMPORTANCE ->
if (header != previous) {
sections.add(AdapterSection(i, header, 0, isCollapsed))
}
sortMode == SortHelper.SORT_DUE -> {
val previousOverdue = previous < startOfToday
val currentOverdue = header == -1L
val currentOverdue = header == HEADER_OVERDUE
if (previous > 0 &&
((currentOverdue != previousOverdue) ||
(!currentOverdue && header != previous.startOfDay()))
@ -143,4 +152,9 @@ class SectionedDataSource constructor(
sections.forEach { _, header -> values.add(header.value) }
return values
}
companion object {
const val HEADER_OVERDUE = -1L
const val HEADER_COMPLETED = -2L
}
}

@ -710,4 +710,5 @@ File %1$s contained %2$s.\n\n
<string name="app_bar_position">App bar position</string>
<string name="top">Top</string>
<string name="bottom">Bottom</string>
<string name="completed">Completed</string>
</resources>

Loading…
Cancel
Save