Add option to disable completed at bottom

pull/1760/head
Alex Baker 2 years ago
parent 95b34d2a21
commit 90ca4beb63

@ -20,7 +20,7 @@ internal object TaskListQueryNonRecursive {
private val TAGS =
field("group_concat(distinct(${TaskListFragment.TAGS_METADATA_JOIN}.tag_uid))")
.`as`("tags")
private const val ORDER_BY = "ORDER BY parentComplete ASC, tasks.completed DESC"
private const val COMPLETION_SORT = "parentComplete ASC, tasks.completed DESC, "
private val FIELDS =
TaskListQuery.FIELDS.plus(listOf(
TAGS,
@ -32,13 +32,20 @@ internal object TaskListQueryNonRecursive {
val sortMode = preferences.sortMode
val sortGroup = field(SortHelper.getSortGroup(sortMode) ?: "NULL").`as`("sortGroup")
val query = SortHelper.adjustQueryForFlagsAndSort(preferences, joinedQuery, sortMode)
val completionSort = if (preferences.completedTasksAtBottom) {
COMPLETION_SORT
} else {
""
}
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,")
query.replace("ORDER BY", "GROUP BY ${Task.ID} ORDER BY $completionSort")
preferences.completedTasksAtBottom ->
"$query GROUP BY ${Task.ID} ORDER BY $completionSort"
else ->
"$query GROUP BY ${Task.ID} $ORDER_BY"
"$query GROUP BY ${Task.ID}"
}
return mutableListOf(
Query.select(*FIELDS.plus(sortGroup))

@ -98,12 +98,22 @@ internal object TaskListQueryRecursive {
}
val reverseSort = preferences.isReverseSort && sortMode != SortHelper.SORT_GTASKS && sortMode != SortHelper.SORT_CALDAV
val sortSelect = SortHelper.orderSelectForSortTypeRecursive(sortMode)
val parentCompleted = if (preferences.completedTasksAtBottom) {
"tasks.completed > 0"
} else {
"0"
}
val completionSort = if (preferences.completedTasksAtBottom) {
"tasks.completed"
} else {
"0"
}
val withClause ="""
CREATE TEMPORARY TABLE `recursive_tasks` AS
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
SELECT tasks._id, $parentCompleted as parent_complete, 0 as subtask_complete, $completionSort 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.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
UNION ALL SELECT tasks._id, recursive_tasks.parent_complete, $parentCompleted as subtask_complete, $completionSort 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 parent_complete ASC, sort_indent DESC, subtask_complete ASC, completion_sort DESC, ${SortHelper.orderForSortTypeRecursive(sortMode, reverseSort)}
) SELECT * FROM recursive_tasks

@ -359,6 +359,9 @@ class Preferences @JvmOverloads constructor(
get() = getBoolean(R.string.p_always_display_full_date, false)
set(value) { setBoolean(R.string.p_always_display_full_date, value)}
override val completedTasksAtBottom: Boolean
get() = getBoolean(R.string.p_completed_tasks_at_bottom, true)
private fun setPublicPref(key: String, value: Int) {
val edit = publicPrefs.edit()
edit?.putInt(key, value)?.apply()

@ -15,5 +15,7 @@ interface QueryPreferences {
var alwaysDisplayFullDate: Boolean
val completedTasksAtBottom: Boolean
fun usePagedQueries(): Boolean
}

@ -85,7 +85,13 @@ class DragAndDropRecyclerAdapter(
override fun getItem(position: Int) = items.getItem(position)
override fun transform(list: List<TaskContainer>): SectionedDataSource =
SectionedDataSource(list, disableHeaders, preferences.sortMode, adapter.getCollapsed())
SectionedDataSource(
list,
disableHeaders,
preferences.sortMode,
adapter.getCollapsed(),
preferences.completedTasksAtBottom,
)
override fun diff(last: SectionedDataSource, next: SectionedDataSource) =
DiffUtil.calculateDiff(DiffCallback(last, next, adapter), next.size < LONG_LIST_SIZE)

@ -8,10 +8,11 @@ import org.tasks.data.TaskContainer
import org.tasks.time.DateTimeUtils.startOfDay
class SectionedDataSource constructor(
tasks: List<TaskContainer>,
disableHeaders: Boolean,
val sortMode: Int,
private val collapsed: Set<Long>
tasks: List<TaskContainer>,
disableHeaders: Boolean,
val sortMode: Int,
private val collapsed: Set<Long>,
private val completedAtBottom: Boolean,
) {
private val tasks = tasks.toMutableList()
@ -61,7 +62,7 @@ class SectionedDataSource constructor(
for (i in tasks.indices) {
val task = tasks[i]
val sortGroup = task.sortGroup
val header = if (task.parentComplete) {
val header = if (completedAtBottom && task.parentComplete) {
HEADER_COMPLETED
} else if (sortGroup == null) {
continue
@ -83,7 +84,7 @@ class SectionedDataSource constructor(
val previousTask = tasks[i - 1]
val previous = previousTask.sortGroup
when {
task.parentComplete -> {
completedAtBottom && task.parentComplete -> {
if (!previousTask.parentComplete) {
sections.add(AdapterSection(i, header, 0, isCollapsed))
}

@ -73,7 +73,13 @@ internal class ScrollableViewsFactory(
private var isRtl = false
private var collapsed = mutableSetOf(HEADER_COMPLETED)
private var sortMode = -1
private var tasks = SectionedDataSource(emptyList(), false, 0, collapsed)
private var tasks = SectionedDataSource(
emptyList(),
disableHeaders = false,
sortMode = 0,
collapsed,
preferences.completedTasksAtBottom,
)
private val widgetPreferences = WidgetPreferences(context, preferences, widgetId)
private var isDark = checkIfDark
private var showFullDate = false
@ -95,7 +101,8 @@ internal class ScrollableViewsFactory(
taskDao.fetchTasks { getQuery(filter, it) },
disableGroups,
sortMode,
collapsed
collapsed,
widgetPreferences.completedTasksAtBottom,
)
if (collapsed.retainAll(tasks.getSectionValues())) {
widgetPreferences.setCollapsed(collapsed)

@ -284,6 +284,11 @@ public class WidgetPreferences implements QueryPreferences {
@Override
public boolean getAlwaysDisplayFullDate() { return preferences.getAlwaysDisplayFullDate(); }
@Override
public boolean getCompletedTasksAtBottom() {
return preferences.getCompletedTasksAtBottom();
}
@Override
public boolean usePagedQueries() {
return preferences.usePagedQueries();

@ -447,4 +447,5 @@
<string name="p_markdown">markdown</string>
<string name="p_app_bar_position">app_bar_position</string>
<string name="p_app_bar_collapse">app_bar_collapse</string>
<string name="p_completed_tasks_at_bottom">completed_tasks_at_bottom</string>
</resources>

@ -713,4 +713,5 @@ File %1$s contained %2$s.\n\n
<string name="bottom">Bottom</string>
<string name="completed">Completed</string>
<string name="snackbar_task_completed">Task completed</string>
<string name="completed_tasks_at_bottom">Move completed tasks to bottom</string>
</resources>

@ -106,6 +106,11 @@
android:summary="@string/linkify_description"
android:title="@string/linkify" />
<SwitchPreferenceCompat
android:defaultValue="true"
android:key="@string/p_completed_tasks_at_bottom"
android:title="@string/completed_tasks_at_bottom" />
<SwitchPreferenceCompat
android:defaultValue="false"
app:allowDividerAbove="true"

Loading…
Cancel
Save