From 48e73b4bb3d31cc977ff9036418e81389e67bc89 Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Fri, 26 May 2023 00:24:00 -0500 Subject: [PATCH] Sort options for completed tasks --- .../todoroo/astrid/activity/MainActivity.kt | 11 +- .../com/todoroo/astrid/core/SortHelper.java | 2 + .../tasks/data/TaskListQueryNonRecursive.kt | 3 +- .../org/tasks/data/TaskListQueryRecursive.kt | 14 +- .../org/tasks/dialogs/SortSettingsActivity.kt | 316 +++++++++++------- .../tasks/dialogs/SortSettingsViewModel.kt | 35 ++ .../java/org/tasks/preferences/Preferences.kt | 14 +- .../org/tasks/preferences/QueryPreferences.kt | 8 +- .../org/tasks/widget/WidgetPreferences.java | 24 +- app/src/main/res/values-ar/strings.xml | 1 - app/src/main/res/values-bg-rBG/strings.xml | 1 - app/src/main/res/values-cs/strings.xml | 1 - app/src/main/res/values-da/strings.xml | 1 - app/src/main/res/values-de/strings.xml | 1 - app/src/main/res/values-es/strings.xml | 1 - app/src/main/res/values-eu/strings.xml | 1 - app/src/main/res/values-fi/strings.xml | 1 - app/src/main/res/values-fr/strings.xml | 1 - app/src/main/res/values-gl/strings.xml | 1 - app/src/main/res/values-hr/strings.xml | 1 - app/src/main/res/values-hu/strings.xml | 1 - app/src/main/res/values-id/strings.xml | 1 - app/src/main/res/values-it/strings.xml | 1 - app/src/main/res/values-ja/strings.xml | 1 - app/src/main/res/values-ko/strings.xml | 1 - app/src/main/res/values-lt/strings.xml | 1 - app/src/main/res/values-nb/strings.xml | 1 - app/src/main/res/values-nl/strings.xml | 1 - app/src/main/res/values-pl/strings.xml | 1 - app/src/main/res/values-pt-rBR/strings.xml | 1 - app/src/main/res/values-pt/strings.xml | 1 - app/src/main/res/values-ro/strings.xml | 1 - app/src/main/res/values-ru/strings.xml | 1 - app/src/main/res/values-si/strings.xml | 1 - app/src/main/res/values-sv/strings.xml | 1 - app/src/main/res/values-tr/strings.xml | 1 - app/src/main/res/values-uk/strings.xml | 1 - app/src/main/res/values-vi/strings.xml | 1 - app/src/main/res/values-zh-rCN/strings.xml | 1 - app/src/main/res/values/keys.xml | 3 +- app/src/main/res/values/strings.xml | 2 +- .../main/res/xml/preferences_task_list.xml | 12 - 42 files changed, 292 insertions(+), 182 deletions(-) diff --git a/app/src/main/java/com/todoroo/astrid/activity/MainActivity.kt b/app/src/main/java/com/todoroo/astrid/activity/MainActivity.kt index 0e737a017..806f09558 100644 --- a/app/src/main/java/com/todoroo/astrid/activity/MainActivity.kt +++ b/app/src/main/java/com/todoroo/astrid/activity/MainActivity.kt @@ -132,7 +132,10 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl } TaskListFragment.REQUEST_SORT -> if (resultCode == RESULT_OK) { - sortChanged(data?.getBooleanExtra(SortSettingsActivity.EXTRA_FORCE_RELOAD, false) ?: false) + sortChanged( + reload = data?.getBooleanExtra(SortSettingsActivity.EXTRA_FORCE_RELOAD, false) ?: false, + groupChange = data?.getBooleanExtra(SortSettingsActivity.EXTRA_CHANGED_GROUP, false) ?: false, + ) } else -> super.onActivityResult(requestCode, resultCode, data) @@ -449,8 +452,10 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl } } - private fun sortChanged(reload: Boolean) { - taskListFragment?.clearCollapsed() + private fun sortChanged(reload: Boolean, groupChange: Boolean) { + if (groupChange) { + taskListFragment?.clearCollapsed() + } localBroadcastManager.broadcastRefresh() if (reload) { openTaskListFragment(filter, true) diff --git a/app/src/main/java/com/todoroo/astrid/core/SortHelper.java b/app/src/main/java/com/todoroo/astrid/core/SortHelper.java index bf4ba074f..469be7e50 100644 --- a/app/src/main/java/com/todoroo/astrid/core/SortHelper.java +++ b/app/src/main/java/com/todoroo/astrid/core/SortHelper.java @@ -41,6 +41,7 @@ public class SortHelper { public static final int SORT_CALDAV = 7; public static final int SORT_START = 8; public static final int SORT_LIST = 9; + public static final int SORT_COMPLETED = 10; public static final long APPLE_EPOCH = 978307200000L; // 1/1/2001 GMT @SuppressLint("DefaultLocale") @@ -192,6 +193,7 @@ public class SortHelper { case SORT_GTASKS -> "tasks.`order`"; case SORT_CALDAV -> CALDAV_ORDER_COLUMN; case SORT_LIST -> "CASE WHEN cdl_order = -1 THEN cdl_name ELSE cdl_order END"; + case SORT_COMPLETED -> "tasks.completed"; default -> "(CASE WHEN (tasks.dueDate=0) " + // if no due date "THEN (strftime('%s','now')*1000)*2 " diff --git a/app/src/main/java/org/tasks/data/TaskListQueryNonRecursive.kt b/app/src/main/java/org/tasks/data/TaskListQueryNonRecursive.kt index 7122e0b8f..f13d0b277 100644 --- a/app/src/main/java/org/tasks/data/TaskListQueryNonRecursive.kt +++ b/app/src/main/java/org/tasks/data/TaskListQueryNonRecursive.kt @@ -33,8 +33,7 @@ internal object TaskListQueryNonRecursive { val sortGroup = field(SortHelper.getSortGroup(groupMode) ?: "NULL").`as`("sortGroup") val query = SortHelper.adjustQueryForFlagsAndSort(preferences, joinedQuery, sortMode) val completeAtBottom = if (preferences.completedTasksAtBottom) "parentComplete ASC," else "" - val completionSort = - if (preferences.completedTasksAtBottom && preferences.sortCompletedByCompletionDate) { + val completionSort = if (preferences.completedTasksAtBottom) { "tasks.completed DESC," } else { "" diff --git a/app/src/main/java/org/tasks/data/TaskListQueryRecursive.kt b/app/src/main/java/org/tasks/data/TaskListQueryRecursive.kt index 71201999a..bb6e7f1f0 100644 --- a/app/src/main/java/org/tasks/data/TaskListQueryRecursive.kt +++ b/app/src/main/java/org/tasks/data/TaskListQueryRecursive.kt @@ -60,6 +60,7 @@ internal object TaskListQueryRecursive { manualSort && filter is CaldavFilter -> SortHelper.SORT_CALDAV else -> sortPreference } + val completedMode = preferences.completedMode val groupAscending = preferences.groupAscending && groupMode != SortHelper.GROUP_NONE val sortAscending = @@ -72,12 +73,11 @@ internal object TaskListQueryRecursive { primarySortSelect } val parentCompleted = if (preferences.completedTasksAtBottom) "tasks.completed > 0" else "0" - val completionSort = - if (preferences.completedTasksAtBottom && preferences.sortCompletedByCompletionDate) { - "tasks.completed" - } else { - "0" - } + val completionSort = if (preferences.completedTasksAtBottom) { + "(CASE WHEN tasks.completed > 0 THEN ${SortHelper.orderSelectForSortTypeRecursive(completedMode, false)} ELSE 0 END)" + } 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, primary_group, primary_sort, secondary_sort, sort_group) AS ( @@ -96,7 +96,7 @@ internal object TaskListQueryRecursive { $parentQuery 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, recursive_tasks.primary_group as primary_group, recursive_tasks.primary_sort as primary_sort, $secondarySortSelect as secondary_sort, recursive_tasks.sort_group FROM tasks $SUBTASK_QUERY - ORDER BY parent_complete ASC, sort_indent DESC, subtask_complete ASC, completion_sort DESC, ${SortHelper.orderForGroupTypeRecursive(groupMode, groupAscending)}, ${SortHelper.orderForSortTypeRecursive(sortMode, sortAscending)} + ORDER BY parent_complete ASC, sort_indent DESC, subtask_complete ASC, completion_sort ${if (preferences.completedAscending) "ASC" else "DESC"}, ${SortHelper.orderForGroupTypeRecursive(groupMode, groupAscending)}, ${SortHelper.orderForSortTypeRecursive(sortMode, sortAscending)} ) SELECT * FROM recursive_tasks WHERE indent = (SELECT MAX(indent) FROM recursive_tasks as r WHERE r.task = recursive_tasks.task) """.trimIndent() diff --git a/app/src/main/java/org/tasks/dialogs/SortSettingsActivity.kt b/app/src/main/java/org/tasks/dialogs/SortSettingsActivity.kt index ea60af959..e9f81e6bb 100644 --- a/app/src/main/java/org/tasks/dialogs/SortSettingsActivity.kt +++ b/app/src/main/java/org/tasks/dialogs/SortSettingsActivity.kt @@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width @@ -27,8 +28,10 @@ import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.ArrowDownward import androidx.compose.material.icons.outlined.ArrowUpward +import androidx.compose.material3.Divider import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.Switch import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -79,12 +82,16 @@ class SortSettingsActivity : ComponentActivity() { val scope = rememberCoroutineScope() var showGroupPicker by remember { mutableStateOf(false) } var showSortPicker by remember { mutableStateOf(false) } + var showCompletedPicker by remember { mutableStateOf(false) } ModalBottomSheet( onDismissRequest = { val forceReload = viewModel.forceReload + val changedGroup = viewModel.changedGroup setResult( RESULT_OK, - Intent().putExtra(EXTRA_FORCE_RELOAD, forceReload) + Intent() + .putExtra(EXTRA_FORCE_RELOAD, forceReload) + .putExtra(EXTRA_CHANGED_GROUP, changedGroup) ) finish() overridePendingTransition(0, 0) @@ -97,14 +104,20 @@ class SortSettingsActivity : ComponentActivity() { BottomSheetContent( groupMode = state.groupMode, sortMode = state.sortMode, + completedMode = state.completedMode, sortAscending = state.sortAscending, groupAscending = state.groupAscending, + completedAscending = state.completedAscending, manualSort = state.manualSort && manualEnabled, astridSort = state.astridSort && astridEnabled, + completedAtBottom = state.completedAtBottom, setSortAscending = { viewModel.setSortAscending(it) }, setGroupAscending = { viewModel.setGroupAscending(it) }, + setCompletedAscending = { viewModel.setCompletedAscending(it) }, + setCompletedAtBottom = { viewModel.setCompletedAtBottom(it) }, clickGroupMode = { showGroupPicker = true }, clickSortMode = { showSortPicker = true }, + clickCompletedMode = { showCompletedPicker = true }, ) } ) @@ -123,8 +136,9 @@ class SortSettingsActivity : ComponentActivity() { scrimColor = Color.Transparent, shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp), content = { - GroupSheetContent( + SortPicker( selected = state.groupMode, + options = groupOptions, onSelected = { viewModel.setGroupMode(it) closePicker() @@ -175,6 +189,35 @@ class SortSettingsActivity : ComponentActivity() { sheetState.show() } } + if (showCompletedPicker) { + val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) + val closePicker: () -> Unit = { + scope.launch { + sheetState.hide() + showCompletedPicker = false + } + } + ModalBottomSheet( + onDismissRequest = closePicker, + sheetState = sheetState, + containerColor = MaterialTheme.colors.surface, + scrimColor = Color.Transparent, + shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp), + content = { + SortPicker( + selected = state.completedMode, + options = completedOptions, + onSelected = { + viewModel.setCompletedMode(it) + closePicker() + } + ) + } + ) + LaunchedEffect(Unit) { + sheetState.show() + } + } LaunchedEffect(Unit) { mainSheetState.show() } @@ -195,6 +238,7 @@ class SortSettingsActivity : ComponentActivity() { const val EXTRA_ASTRID_ORDER = "extra_astrid_order" const val EXTRA_WIDGET_ID = "extra_widget_id" const val EXTRA_FORCE_RELOAD = "extra_force_reload" + const val EXTRA_CHANGED_GROUP = "extra_changed_group" const val WIDGET_NONE = -1 fun getIntent( @@ -234,83 +278,56 @@ fun SortSheetContent( setAstridSort(true) } } - SortOption( - resId = R.string.SSD_sort_auto, - selected = !manualSortSelected && selected == SortHelper.SORT_AUTO, - onClick = { onSelected(SortHelper.SORT_AUTO) } - ) - SortOption( - resId = R.string.SSD_sort_start, - selected = !manualSortSelected && selected == SortHelper.SORT_START, - onClick = { onSelected(SortHelper.SORT_START) } - ) - SortOption( - resId = R.string.SSD_sort_due, - selected = !manualSortSelected && selected == SortHelper.SORT_DUE, - onClick = { onSelected(SortHelper.SORT_DUE) } - ) - SortOption( - resId = R.string.SSD_sort_importance, - selected = !manualSortSelected && selected == SortHelper.SORT_IMPORTANCE, - onClick = { onSelected(SortHelper.SORT_IMPORTANCE) } - ) - SortOption( - resId = R.string.SSD_sort_alpha, - selected = !manualSortSelected && selected == SortHelper.SORT_ALPHA, - onClick = { onSelected(SortHelper.SORT_ALPHA) } - ) - SortOption( - resId = R.string.SSD_sort_modified, - selected = !manualSortSelected && selected == SortHelper.SORT_MODIFIED, - onClick = { onSelected(SortHelper.SORT_MODIFIED) } - ) - SortOption( - resId = R.string.sort_created, - selected = !manualSortSelected && selected == SortHelper.SORT_CREATED, - onClick = { onSelected(SortHelper.SORT_CREATED) } + SortPicker( + selected = if (manualSortSelected) -1 else selected, + options = sortOptions, + onSelected = { onSelected(it) }, ) } +val sortOptions = linkedMapOf( + R.string.SSD_sort_auto to SortHelper.SORT_AUTO, + R.string.SSD_sort_start to SortHelper.SORT_START, + R.string.SSD_sort_due to SortHelper.SORT_DUE, + R.string.SSD_sort_importance to SortHelper.SORT_IMPORTANCE, + R.string.SSD_sort_alpha to SortHelper.SORT_ALPHA, + R.string.SSD_sort_modified to SortHelper.SORT_MODIFIED, + R.string.sort_created to SortHelper.SORT_CREATED, +) + +val groupOptions = linkedMapOf( + R.string.none to SortHelper.GROUP_NONE, + R.string.SSD_sort_due to SortHelper.SORT_DUE, + R.string.SSD_sort_start to SortHelper.SORT_START, + R.string.SSD_sort_importance to SortHelper.SORT_IMPORTANCE, + R.string.SSD_sort_modified to SortHelper.SORT_MODIFIED, + R.string.sort_created to SortHelper.SORT_CREATED, + R.string.sort_list to SortHelper.SORT_LIST, +) + +private val completedOptions = linkedMapOf( + R.string.sort_completed to SortHelper.SORT_COMPLETED, + R.string.SSD_sort_start to SortHelper.SORT_START, + R.string.SSD_sort_due to SortHelper.SORT_DUE, + R.string.SSD_sort_importance to SortHelper.SORT_IMPORTANCE, + R.string.SSD_sort_alpha to SortHelper.SORT_ALPHA, + R.string.SSD_sort_modified to SortHelper.SORT_MODIFIED, + R.string.sort_created to SortHelper.SORT_CREATED, +) + @Composable -fun GroupSheetContent( +fun SortPicker( selected: Int, + options: Map, onSelected: (Int) -> Unit, ) { - SortOption( - resId = R.string.none, - selected = selected == SortHelper.GROUP_NONE, - onClick = { onSelected(SortHelper.GROUP_NONE) } - ) - SortOption( - resId = R.string.SSD_sort_due, - selected = selected == SortHelper.SORT_DUE, - onClick = { onSelected(SortHelper.SORT_DUE) } - ) - SortOption( - resId = R.string.SSD_sort_start, - selected = selected == SortHelper.SORT_START, - onClick = { onSelected(SortHelper.SORT_START) } - ) - SortOption( - resId = R.string.SSD_sort_importance, - selected = selected == SortHelper.SORT_IMPORTANCE, - onClick = { onSelected(SortHelper.SORT_IMPORTANCE) } - ) - SortOption( - resId = R.string.SSD_sort_modified, - selected = selected == SortHelper.SORT_MODIFIED, - onClick = { onSelected(SortHelper.SORT_MODIFIED) } - ) - SortOption( - resId = R.string.sort_created, - selected = selected == SortHelper.SORT_CREATED, - onClick = { onSelected(SortHelper.SORT_CREATED) } - ) - SortOption( - resId = R.string.sort_list, - selected = selected == SortHelper.SORT_LIST, - onClick = { onSelected(SortHelper.SORT_LIST) } - ) + options.forEach { (resId, sortMode) -> + SortOption( + resId = resId, + selected = selected == sortMode, + onClick = { onSelected(sortMode) }, + ) + } } @Composable @@ -336,14 +353,20 @@ fun SortOption( fun BottomSheetContent( groupMode: Int, sortMode: Int, + completedMode: Int, sortAscending: Boolean, groupAscending: Boolean, + completedAscending: Boolean, manualSort: Boolean, astridSort: Boolean, + completedAtBottom: Boolean, setSortAscending: (Boolean) -> Unit, setGroupAscending: (Boolean) -> Unit, + setCompletedAscending: (Boolean) -> Unit, + setCompletedAtBottom: (Boolean) -> Unit, clickGroupMode: () -> Unit, clickSortMode: () -> Unit, + clickCompletedMode: () -> Unit, ) { Row( modifier = Modifier.padding(16.dp), @@ -369,24 +392,9 @@ fun BottomSheetContent( SortHelper.SORT_IMPORTANCE -> !groupAscending else -> groupAscending } - Chip( - onClick = { setGroupAscending(!groupAscending) }, - shape = RoundedCornerShape(4.dp), - border = ChipDefaults.outlinedBorder, - colors = ChipDefaults.outlinedChipColors(), - leadingIcon = { - Icon( - imageVector = if (displayAscending) Icons.Outlined.ArrowUpward else Icons.Outlined.ArrowDownward, - modifier = Modifier.size(16.dp), - contentDescription = null, - ) - }, - content = { - Text( - text = stringResource(id = if (displayAscending) R.string.sort_ascending else R.string.sort_descending), - style = MaterialTheme.typography.body1, - ) - }, + OrderingChip( + ascending = displayAscending, + onClick = { setGroupAscending(!groupAscending) } ) } } @@ -421,29 +429,94 @@ fun BottomSheetContent( SortHelper.SORT_IMPORTANCE -> !sortAscending else -> sortAscending } - Chip( - onClick = { setSortAscending(!sortAscending) }, - shape = RoundedCornerShape(4.dp), - border = ChipDefaults.outlinedBorder, - colors = ChipDefaults.outlinedChipColors(), - leadingIcon = { - Icon( - imageVector = if (displayAscending) Icons.Outlined.ArrowUpward else Icons.Outlined.ArrowDownward, - modifier = Modifier.size(16.dp), - contentDescription = null, + OrderingChip( + ascending = displayAscending, + onClick = { setSortAscending(!sortAscending) } + ) + } + } + if (!astridSort) { + Divider( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 8.dp) + .height(1.dp) + ) + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.padding(horizontal = 16.dp) + ) { + Text( + text = stringResource(R.string.completed_tasks_at_bottom), + style = MaterialTheme.typography.body1, + modifier = Modifier.weight(1f), + ) + Switch( + checked = completedAtBottom, + onCheckedChange = { setCompletedAtBottom(it) } + ) + } + if (completedAtBottom) { + Row( + modifier = Modifier.padding(16.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Column( + modifier = Modifier + .weight(1f) + .clickable { clickCompletedMode() } + ) { + Text( + text = stringResource(id = R.string.completed), + style = MaterialTheme.typography.h6, ) - }, - content = { Text( - text = stringResource(id = if (displayAscending) R.string.sort_ascending else R.string.sort_descending), + text = stringResource(id = completedMode.modeString), style = MaterialTheme.typography.body1, ) - }, - ) + } + Spacer(modifier = Modifier.width(16.dp)) + val displayAscending = when (completedMode) { + SortHelper.SORT_IMPORTANCE -> !completedAscending + else -> completedAscending + } + OrderingChip( + ascending = displayAscending, + onClick = { setCompletedAscending(!completedAscending) } + ) + } } } } +@OptIn(ExperimentalMaterialApi::class) +@Composable +fun OrderingChip( + ascending: Boolean, + onClick: () -> Unit, +) { + Chip( + onClick = onClick, + shape = RoundedCornerShape(4.dp), + border = ChipDefaults.outlinedBorder, + colors = ChipDefaults.outlinedChipColors(), + leadingIcon = { + Icon( + imageVector = if (ascending) Icons.Outlined.ArrowUpward else Icons.Outlined.ArrowDownward, + modifier = Modifier.size(16.dp), + contentDescription = null, + ) + }, + content = { + Text( + text = stringResource(id = if (ascending) R.string.sort_ascending else R.string.sort_descending), + style = MaterialTheme.typography.body1, + ) + }, + ) + +} + private val Int.modeString: Int get() = when (this) { SortHelper.GROUP_NONE -> R.string.none @@ -454,6 +527,7 @@ private val Int.modeString: Int SortHelper.SORT_CREATED -> R.string.sort_created SortHelper.SORT_START -> R.string.SSD_sort_start SortHelper.SORT_LIST -> R.string.sort_list + SortHelper.SORT_COMPLETED -> R.string.sort_completed else -> R.string.SSD_sort_auto } @@ -462,17 +536,25 @@ private val Int.modeString: Int @Composable fun PreviewSortBottomSheet() { MdcTheme { - BottomSheetContent( - groupMode = SortHelper.GROUP_NONE, - sortMode = SortHelper.SORT_AUTO, - sortAscending = false, - groupAscending = false, - manualSort = false, - astridSort = false, - clickGroupMode = {}, - clickSortMode = {}, - setSortAscending = {}, - setGroupAscending = {}, - ) + Column { + BottomSheetContent( + groupMode = SortHelper.GROUP_NONE, + sortMode = SortHelper.SORT_AUTO, + completedMode = SortHelper.SORT_ALPHA, + sortAscending = false, + groupAscending = false, + completedAscending = false, + manualSort = false, + astridSort = false, + completedAtBottom = true, + clickGroupMode = {}, + clickSortMode = {}, + clickCompletedMode = {}, + setCompletedAtBottom = {}, + setSortAscending = {}, + setGroupAscending = {}, + setCompletedAscending = {}, + ) + } } } diff --git a/app/src/main/java/org/tasks/dialogs/SortSettingsViewModel.kt b/app/src/main/java/org/tasks/dialogs/SortSettingsViewModel.kt index e90c72ebb..ddb244f4a 100644 --- a/app/src/main/java/org/tasks/dialogs/SortSettingsViewModel.kt +++ b/app/src/main/java/org/tasks/dialogs/SortSettingsViewModel.kt @@ -25,8 +25,11 @@ class SortSettingsViewModel @Inject constructor( val astridSort: Boolean, val groupMode: Int, val groupAscending: Boolean, + val completedAtBottom: Boolean, val sortMode: Int, val sortAscending: Boolean, + val completedMode: Int, + val completedAscending: Boolean, ) private val widgetId = savedStateHandle[SortSettingsActivity.EXTRA_WIDGET_ID] ?: WIDGET_NONE private val preferences = @@ -40,6 +43,9 @@ class SortSettingsViewModel @Inject constructor( astridSort = preferences.isAstridSort, groupMode = preferences.groupMode, groupAscending = preferences.groupAscending, + completedMode = preferences.completedMode, + completedAscending = preferences.completedAscending, + completedAtBottom = preferences.completedTasksAtBottom, sortMode = preferences.sortMode, sortAscending = preferences.sortAscending, ) @@ -56,6 +62,16 @@ class SortSettingsViewModel @Inject constructor( _viewState.update { it.copy(groupAscending = ascending) } } + fun setCompletedAscending(ascending: Boolean) { + preferences.completedAscending = ascending + _viewState.update { it.copy(completedAscending = ascending) } + } + + fun setCompletedAtBottom(completedAtBottom: Boolean) { + preferences.completedTasksAtBottom = completedAtBottom + _viewState.update { it.copy(completedAtBottom = completedAtBottom) } + } + fun setGroupMode(groupMode: Int) { if (groupMode != SortHelper.GROUP_NONE) { preferences.isManualSort = false @@ -78,6 +94,22 @@ class SortSettingsViewModel @Inject constructor( } } + fun setCompletedMode(completedMode: Int) { + preferences.completedMode = completedMode + val ascending = when (completedMode) { + SortHelper.SORT_MODIFIED, + SortHelper.SORT_CREATED -> false + else -> true + } + preferences.completedAscending = ascending + _viewState.update { + it.copy( + completedMode = completedMode, + completedAscending = ascending, + ) + } + } + fun setSortMode(sortMode: Int) { preferences.isManualSort = false preferences.isAstridSort = false @@ -127,4 +159,7 @@ class SortSettingsViewModel @Inject constructor( val forceReload: Boolean get() = initialState.manualSort != _viewState.value.manualSort || initialState.astridSort != _viewState.value.astridSort + + val changedGroup: Boolean + get() = initialState.groupMode != _viewState.value.groupMode } diff --git a/app/src/main/java/org/tasks/preferences/Preferences.kt b/app/src/main/java/org/tasks/preferences/Preferences.kt index bf9eaabd8..ff1de16bf 100644 --- a/app/src/main/java/org/tasks/preferences/Preferences.kt +++ b/app/src/main/java/org/tasks/preferences/Preferences.kt @@ -357,6 +357,10 @@ class Preferences @JvmOverloads constructor( get() = getInt(R.string.p_group_mode, SortHelper.GROUP_NONE) set(value) { setInt(R.string.p_group_mode, value) } + override var completedMode: Int + get() = getInt(R.string.p_completed_mode, SortHelper.SORT_COMPLETED) + set(value) { setInt(R.string.p_completed_mode, value) } + override var showHidden: Boolean get() = getBoolean(R.string.p_show_hidden_tasks, true) set(value) { setBoolean(R.string.p_show_hidden_tasks, value) } @@ -369,11 +373,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 + override var completedTasksAtBottom: Boolean get() = getBoolean(R.string.p_completed_tasks_at_bottom, true) - - override val sortCompletedByCompletionDate: Boolean - get() = getBoolean(R.string.p_completed_tasks_sort, true) + set(value) { setBoolean(R.string.p_completed_tasks_at_bottom, value) } val backupDirectory: Uri? get() = getDirectory(R.string.p_backup_dir, "backups") @@ -504,6 +506,10 @@ class Preferences @JvmOverloads constructor( get() = getBoolean(R.string.p_group_ascending, false) set(value) { setBoolean(R.string.p_group_ascending, value) } + override var completedAscending: Boolean + get() = getBoolean(R.string.p_completed_ascending, false) + set(value) { setBoolean(R.string.p_completed_ascending, value) } + val defaultPriority: Int get() = getIntegerFromString(R.string.p_default_importance_key, Task.Priority.LOW) diff --git a/app/src/main/java/org/tasks/preferences/QueryPreferences.kt b/app/src/main/java/org/tasks/preferences/QueryPreferences.kt index 659a6d3d2..0507f0e8e 100644 --- a/app/src/main/java/org/tasks/preferences/QueryPreferences.kt +++ b/app/src/main/java/org/tasks/preferences/QueryPreferences.kt @@ -5,6 +5,8 @@ interface QueryPreferences { var groupMode: Int + var completedMode: Int + var isManualSort: Boolean var isAstridSort: Boolean @@ -13,13 +15,13 @@ interface QueryPreferences { var groupAscending: Boolean + var completedAscending: Boolean + val showHidden: Boolean val showCompleted: Boolean var alwaysDisplayFullDate: Boolean - val completedTasksAtBottom: Boolean - - val sortCompletedByCompletionDate: Boolean + var completedTasksAtBottom: Boolean } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/widget/WidgetPreferences.java b/app/src/main/java/org/tasks/widget/WidgetPreferences.java index 93250d3fa..d4a735fcd 100644 --- a/app/src/main/java/org/tasks/widget/WidgetPreferences.java +++ b/app/src/main/java/org/tasks/widget/WidgetPreferences.java @@ -296,8 +296,8 @@ public class WidgetPreferences implements QueryPreferences { } @Override - public boolean getSortCompletedByCompletionDate() { - return preferences.getSortCompletedByCompletionDate(); + public void setCompletedTasksAtBottom(boolean value) { + preferences.setBoolean(R.string.p_completed_tasks_at_bottom, value); } @Override @@ -334,4 +334,24 @@ public class WidgetPreferences implements QueryPreferences { public void setAlwaysDisplayFullDate(boolean noWeekday) { preferences.setAlwaysDisplayFullDate(noWeekday); } + + @Override + public int getCompletedMode() { + return preferences.getCompletedMode(); + } + + @Override + public void setCompletedMode(int mode) { + preferences.setCompletedMode(mode); + } + + @Override + public boolean getCompletedAscending() { + return preferences.getCompletedAscending(); + } + + @Override + public void setCompletedAscending(boolean ascending) { + preferences.setCompletedAscending(ascending); + } } diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index be56c8d1e..34776d148 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -761,7 +761,6 @@ موقع شريط التطبيق %s بعد البدئ %s حتى موعد الإنتهاء - فرز حسب تاريخ الإكتمال انقل المهام المكتملة إلى الأسفل %d مهمة اكتملت %s قبل البدئ diff --git a/app/src/main/res/values-bg-rBG/strings.xml b/app/src/main/res/values-bg-rBG/strings.xml index b393d2126..bd88af191 100644 --- a/app/src/main/res/values-bg-rBG/strings.xml +++ b/app/src/main/res/values-bg-rBG/strings.xml @@ -684,7 +684,6 @@ Синхронизиранр на няколко профила Задачата е завършена Споделяне на списък - Сортиране по дата на завършване Свиване на лентата на приложението Не е намерен подходящо спонсорство в GitHub Приставки за Tasker, Automate и Locale diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 0a107c462..c380d4b08 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -730,7 +730,6 @@ Horní Splněný Přesunout splněné úkoly naspod - Seřadit podle data splnění %d úkolů splněno Typ serveru Odloženo diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 2f9370b8e..04d6a7265 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -688,7 +688,6 @@ Tilfældigt hver %s Opgave udført - Sorter efter færdiggørelsesdato Time Timer diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 5aab2e516..1a3328a64 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -687,7 +687,6 @@ Abgeschlossen Aufgabe abgeschlossen Erledigte Aufgaben nach unten verschieben - Nach Fertigstellungsdatum sortieren %d Aufgaben erledigt %s vor dem Start %s nach dem Start diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index cb60d9728..c10fa83b3 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -706,7 +706,6 @@ Mover las tareas completadas a la parte inferior %d tareas completadas %s después de la fecha límite - Ordenar por fecha de finalización %s antes de empezar %s tras el inicio %s antes de la fecha límite diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index 849e360b2..ccba78e9e 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -685,7 +685,6 @@ Amaituta Amaitutako zereginak Betetako atazak behealdera mugitu - Ordenatu amaiera-dataren arabera %d atazak osatuta %s hasi aurretik %s hasi ondoren diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index c86d67ed3..37a4353bb 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -703,7 +703,6 @@ Näytä ilmoitukset tehtäville ilman eräpäivää Synkronoi henkilökohtaisen Microsoft-tilin kanssa Siirrä valmiit tehtävät alimmaiseksi - Järjestä valmistumispäivän mukaan Tuntematon Muu Palvelimen tyyppi diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 10d67b2ba..afd924ff5 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -700,7 +700,6 @@ Tâche terminée Déplacer les tâches terminées vers le bas %d tâches terminées - Trier par date d\'achèvement %s avant le début %s après le début %s avant échéance diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 7241e3b7b..032b6d32b 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -405,7 +405,6 @@ Descoñecido Outro Máis opcións - Escoller por data de fin %d tarefas finalizadas Tipo de servidor Posposta diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 2bf08a141..7e0dd2227 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -704,7 +704,6 @@ Sklopi programske trake Zadatak obavljen Premjesti obavljene zadatke na kraj - Razvrtaj prema datumu obavljanja %d zadaci obavljeni %s prije početka %s nakon početka diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 782db9363..d56b3383c 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -685,7 +685,6 @@ Alul Feladat elvégezve Az elvégzett feladatok kerüljenek alulra - Rendezés elvégzés dátuma alapján %d feladat elvégezve %s kezdés előtt %s kezdés után diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml index f7f43afff..790dd8e14 100644 --- a/app/src/main/res/values-id/strings.xml +++ b/app/src/main/res/values-id/strings.xml @@ -691,7 +691,6 @@ Tugas selesai Notifikasi kustom Kamu dapat mengubah bagian ini dengan mengurutkan atau menghapus kolom - Urutkan berdasarkan tanggal selesai Detik sebelum mulai Detik setelah mulai \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index f3b85acdc..e6909dd6f 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -704,7 +704,6 @@ In basso Attività completata Sposta le attività completate in basso - Ordina per data di completamento %d attività completate %s dopo la scadenza %s prima di iniziare diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index cb975c594..58ee2a013 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -667,7 +667,6 @@ Tasks.org と同期し、他のユーザーと共同作業が可能 デスクトップアクセス あなたの支援が継続的な開発を支えます - 完了日順で並び替え 完了したタスク: %d 着手 %s 前 着手 %s 後 diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index ee2d15569..f9e14db20 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -705,7 +705,6 @@ 필드 순서 변경 또는 삭제 %s 완료 - 완료일순 정렬 닫기 정보가 너무 많은가요\? 앱 바메뉴 위치 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index f01d9cf78..7f09dbd2e 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -741,7 +741,6 @@ Užmigdyta iki %s Groti užbaigimo garsą Sukūrimo data - Rūšiuoti pagal užbaigimo datą Sinchronizuoti su asmenine Microsoft paskyra Užbaigimas %s Perkelti užbaigtas užduotis į apačią diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index 686723dd6..6398fc58d 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -702,7 +702,6 @@ Opprettelsesdato Synkroniser med din personlige Microsoft-konto Fullføring %s - Sorter etter fullførelsesdato %d gjøremål fullført Logg inn Har påminnelse diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 3190cf6b3..999b42d4e 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -688,7 +688,6 @@ Taak voltooid Plaats voltooide taken onderaan %d taken voltooid - Sorteren op datum voltooien %s voor vervallen %s na vervallen %s voor begin diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 5ef8e288c..388bb31fa 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -732,7 +732,6 @@ Góra Własne powiadomienie Zadanie zakończone - Posortuj po dacie zakończenia %d zadań zakończonych %s przed startem %s po rozpoczęciu diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 9d60e443a..043944efb 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -705,7 +705,6 @@ Notificação personalizada Tarefa completa %d tarefas concluídas - Classificar por data de conclusão %s antes de começar %s após o início %s antes do vencimento diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 2a1797998..0e6fd3465 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -688,7 +688,6 @@ Tarefa terminada Mover as tarefas terminadas para o fundo %d tarefas terminadas - Ordenar por data de finalização %s antes de começar %s após o início %s antes do término diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 346ecea78..3dc002684 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -703,7 +703,6 @@ Sarcină îndeplinită Mutați sarcinile finalizate în partea de jos %d sarcini finalizate - Sortează după data de finalizare %s înainte de start %s după pornire %s după scadență diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 94edc06fb..fec14f037 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -737,7 +737,6 @@ %s до %s после %s после начала - Сортировать по дате завершения Отложенные Неизвестный Другой diff --git a/app/src/main/res/values-si/strings.xml b/app/src/main/res/values-si/strings.xml index 27960841b..2b1d0a8a8 100644 --- a/app/src/main/res/values-si/strings.xml +++ b/app/src/main/res/values-si/strings.xml @@ -705,7 +705,6 @@ මිනිත්තු සම්පුර්ණ කරන ලද කාර්යයන් පහළට ගෙන යන්න - සම්පූර්ණ කරන දිනය අනුව වර්ග කරන්න %s ආරම්භයට පෙර %s ආරම්භයෙන් පසුව diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index fa86da5af..d4f0eb4e2 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -704,7 +704,6 @@ Uppgiften slutförd Flytta slutförda uppgifter till botten %d uppgifter slutförda - Sortera efter färdigdatum Har påminnelse Okänd Övrig diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 9e9ce091e..ab1f80402 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -688,7 +688,6 @@ Görev tamamlandı Tamamlanan görevleri alta taşı %d görev tamamlandı - Tamamlanma tarihine göre sırala Anımsatıcılı Saat diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 85b44bb7a..57525fd6f 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -709,7 +709,6 @@ Перемістити виконані завдання вниз %s до початку %s після початку - Сортувати за датою завершення %d завдань виконано %s до %s після diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index de8826523..82263771d 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -672,7 +672,6 @@ Đã đặt báo lại cho đến %s Công việc đã hoàn tất Di chuyển công việc đã hoàn tất xuống dưới - Sắp xếp theo ngày hoàn thành %d công việc đã hoàn tất %s trước bắt đầu %s sau bắt đầu diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index c17da7b4f..85532fdf3 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -678,7 +678,6 @@ 将已完成任务移至底部 完成了 %d 个任务 开始后 %s - 按完成日期排序 开始前 %s 到期前 %s 到期后 %s diff --git a/app/src/main/res/values/keys.xml b/app/src/main/res/values/keys.xml index 47488f007..6e3d06106 100644 --- a/app/src/main/res/values/keys.xml +++ b/app/src/main/res/values/keys.xml @@ -273,11 +273,13 @@ show_completed_tasks sort_ascending group_ascending + completed_ascending manual_sort astrid_sort astrid_sort_enabled sort_mode group_mode + completed_mode @string/TEA_ctrl_hide_until_pref @@ -446,7 +448,6 @@ app_bar_position app_bar_collapse completed_tasks_at_bottom - completed_tasks_sort shown_beast_mode_hint last_sync_time diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 93447ef5f..9f6710274 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -43,6 +43,7 @@ File %1$s contained %2$s.\n\n By last modified By creation time By list + By completion time Matching \'%s\' Create new filter Task name @@ -713,7 +714,6 @@ File %1$s contained %2$s.\n\n Completed Task completed Move completed tasks to bottom - Sort by completion date %d tasks completed %s before start %s after start diff --git a/app/src/main/res/xml/preferences_task_list.xml b/app/src/main/res/xml/preferences_task_list.xml index 85ad4b4e8..137650d92 100644 --- a/app/src/main/res/xml/preferences_task_list.xml +++ b/app/src/main/res/xml/preferences_task_list.xml @@ -55,18 +55,6 @@ android:summary="@string/linkify_description" android:title="@string/linkify" /> - - - -