From 113cf6f1b84df1394cb4edbdf589bea2ae2a0f97 Mon Sep 17 00:00:00 2001 From: vulewuxe86 <55635116+vulewuxe86@users.noreply.github.com> Date: Sat, 16 Sep 2023 17:01:51 +0200 Subject: [PATCH] #2257 Change priority for selected items (#2452) --- .../astrid/activity/TaskListFragment.kt | 24 ++++-- .../org/tasks/compose/edit/PriorityRow.kt | 33 +++++--- .../java/org/tasks/dialogs/PriorityPicker.kt | 78 +++++++++++++++++++ .../tasks/dialogs/PriorityPickerViewModel.kt | 20 +++++ .../res/layout/dialog_priority_picker.xml | 13 ++++ app/src/main/res/menu/menu_multi_select.xml | 8 +- app/src/main/res/values-de/strings.xml | 4 +- app/src/main/res/values/strings.xml | 2 + 8 files changed, 163 insertions(+), 19 deletions(-) create mode 100644 app/src/main/java/org/tasks/dialogs/PriorityPicker.kt create mode 100644 app/src/main/java/org/tasks/dialogs/PriorityPickerViewModel.kt create mode 100644 app/src/main/res/layout/dialog_priority_picker.xml diff --git a/app/src/main/java/com/todoroo/astrid/activity/TaskListFragment.kt b/app/src/main/java/com/todoroo/astrid/activity/TaskListFragment.kt index 1b16a3892..33f474fde 100644 --- a/app/src/main/java/com/todoroo/astrid/activity/TaskListFragment.kt +++ b/app/src/main/java/com/todoroo/astrid/activity/TaskListFragment.kt @@ -100,6 +100,7 @@ import org.tasks.dialogs.DateTimePicker.Companion.newDateTimePicker import org.tasks.dialogs.DialogBuilder import org.tasks.dialogs.FilterPicker.Companion.newFilterPicker import org.tasks.dialogs.FilterPicker.Companion.setFilterPickerResultListener +import org.tasks.dialogs.PriorityPicker.Companion.newPriorityPicker import org.tasks.dialogs.SortSettingsActivity import org.tasks.extensions.Context.openUri import org.tasks.extensions.Context.toast @@ -750,6 +751,19 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL } true } + R.id.edit_priority -> { + lifecycleScope.launch { + taskDao + .fetch(selected) + .filterNot { it.readOnly } + .takeIf { it.isNotEmpty() } + ?.let { + newPriorityPicker(preferences.getBoolean(R.string.p_desaturate_colors, false), it) + .show(parentFragmentManager, FRAG_TAG_PRIORITY_PICKER) + } + } + true + } R.id.move_tasks -> { lifecycleScope.launch { val singleFilter = taskMover.getSingleFilter(selected) @@ -775,7 +789,7 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL true } R.id.menu_select_all -> { - lifecycleScope.launch { + lifecycleScope.launch { setSelected(taskDao.fetchTasks(preferences, filter) .map(TaskContainer::id)) } @@ -879,11 +893,10 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL makeSnackbar(R.string.delete_multiple_tasks_confirmation, result.size.toString())?.show() } - private fun setSelected(tasks: List) { - taskAdapter.setSelected(tasks) - updateModeTitle() - recyclerAdapter?.notifyDataSetChanged() + taskAdapter.setSelected(tasks) + updateModeTitle() + recyclerAdapter?.notifyDataSetChanged() } private fun copySelectedItems(tasks: List) = lifecycleScope.launch { @@ -1020,6 +1033,7 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL private const val EXTRA_FILTER = "extra_filter" private const val FRAG_TAG_REMOTE_LIST_PICKER = "frag_tag_remote_list_picker" private const val FRAG_TAG_DATE_TIME_PICKER = "frag_tag_date_time_picker" + private const val FRAG_TAG_PRIORITY_PICKER = "frag_tag_priority_picker" private const val REQUEST_LIST_SETTINGS = 10101 private const val REQUEST_TAG_TASKS = 10106 const val REQUEST_SORT = 10107 diff --git a/app/src/main/java/org/tasks/compose/edit/PriorityRow.kt b/app/src/main/java/org/tasks/compose/edit/PriorityRow.kt index ddba896bc..31368ad85 100644 --- a/app/src/main/java/org/tasks/compose/edit/PriorityRow.kt +++ b/app/src/main/java/org/tasks/compose/edit/PriorityRow.kt @@ -40,7 +40,7 @@ fun PriorityRow( TaskEditRow( iconRes = R.drawable.ic_outline_flag_24px, content = { - Priority( + PriorityLabeled( selected = priority, onClick = { onChangePriority(it) }, desaturate = desaturate, @@ -54,6 +54,24 @@ fun Priority( selected: Int, onClick: (Int) -> Unit = {}, desaturate: Boolean, +) { + Row(horizontalArrangement = Arrangement.SpaceBetween) { + for (i in Task.Priority.NONE downTo Task.Priority.HIGH) { + PriorityButton( + priority = i, + selected = selected, + onClick = onClick, + desaturate = desaturate, + ) + } + } +} + +@Composable +fun PriorityLabeled( + selected: Int, + onClick: (Int) -> Unit = {}, + desaturate: Boolean, ) { Row( modifier = Modifier @@ -70,16 +88,7 @@ fun Priority( modifier = Modifier.padding(end = 16.dp) ) Spacer(modifier = Modifier.weight(1f)) - Row(horizontalArrangement = Arrangement.SpaceBetween) { - for (i in Task.Priority.NONE downTo Task.Priority.HIGH) { - PriorityButton( - priority = i, - selected = selected, - onClick = onClick, - desaturate = desaturate, - ) - } - } + Priority(selected = selected, onClick = onClick, desaturate = desaturate) } } @@ -153,4 +162,4 @@ fun PriorityNarrowWidth() { desaturate = false, ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/tasks/dialogs/PriorityPicker.kt b/app/src/main/java/org/tasks/dialogs/PriorityPicker.kt new file mode 100644 index 000000000..32123dd56 --- /dev/null +++ b/app/src/main/java/org/tasks/dialogs/PriorityPicker.kt @@ -0,0 +1,78 @@ +package org.tasks.dialogs + +import android.app.Dialog +import android.os.Bundle +import androidx.appcompat.app.AlertDialog +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope +import com.todoroo.astrid.dao.TaskDao +import com.todoroo.astrid.data.Task +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.NonCancellable +import kotlinx.coroutines.launch +import org.tasks.compose.collectAsStateLifecycleAware +import org.tasks.compose.edit.Priority +import org.tasks.databinding.DialogDateTimePickerBinding +import org.tasks.databinding.DialogPriorityPickerBinding +import javax.inject.Inject + +@AndroidEntryPoint +class PriorityPicker : DialogFragment() { + + @Inject lateinit var taskDao: TaskDao + + private val taskIds: LongArray + get() = arguments?.getLongArray(EXTRA_TASKS) ?: longArrayOf() + + companion object { + const val EXTRA_TASKS = "extra_tasks" + const val EXTRA_DESATURATE = "extra_desaturatee" + + fun newPriorityPicker(desaturateColors: Boolean, tasks: List): PriorityPicker { + val bundle = Bundle() + bundle.putLongArray(EXTRA_TASKS, tasks.map { it.id }.toLongArray()) + bundle.putBoolean(EXTRA_DESATURATE, desaturateColors) + val fragment = PriorityPicker() + fragment.arguments = bundle + return fragment + } + } + + lateinit var binding: DialogDateTimePickerBinding + private val priorityPickerViewModel: PriorityPickerViewModel by viewModels() + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + return requireActivity().let { fragmentActivity -> + val inflater = fragmentActivity.layoutInflater + val binding = DialogPriorityPickerBinding.inflate(inflater, null, false) + binding.priorityRow.setContent { Priority(selected = priorityPickerViewModel.priority.collectAsStateLifecycleAware().value, + onClick = { priorityPickerViewModel.setPriority( it ) }, desaturate = savedInstanceState?.getBoolean( + EXTRA_DESATURATE) ?: false) } + val builder = AlertDialog.Builder(fragmentActivity) + .setTitle("Change priority") + .setView(binding.root) + + builder.setNegativeButton("Cancel") { _, _ -> + + } + builder.setPositiveButton("Ok") { _, _ -> + changePriority() + } + builder.create() + } + } + + private fun changePriority() { + lifecycleScope.launch(NonCancellable) { + taskDao + .fetch(taskIds.toList()) + .forEach { + it.priority = priorityPickerViewModel.priority.value + taskDao.save(it) + } + } + dismiss() + } + +} diff --git a/app/src/main/java/org/tasks/dialogs/PriorityPickerViewModel.kt b/app/src/main/java/org/tasks/dialogs/PriorityPickerViewModel.kt new file mode 100644 index 000000000..a6544b66f --- /dev/null +++ b/app/src/main/java/org/tasks/dialogs/PriorityPickerViewModel.kt @@ -0,0 +1,20 @@ +package org.tasks.dialogs + +import androidx.lifecycle.ViewModel +import com.todoroo.astrid.data.Task +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import javax.inject.Inject + +@HiltViewModel +class PriorityPickerViewModel @Inject constructor(): ViewModel() { + + private val _priority = MutableStateFlow(Task.Priority.NONE) + val priority = _priority.asStateFlow() + + fun setPriority(priority: Int) { + _priority.value = priority + } + +} diff --git a/app/src/main/res/layout/dialog_priority_picker.xml b/app/src/main/res/layout/dialog_priority_picker.xml new file mode 100644 index 000000000..d5bc782b1 --- /dev/null +++ b/app/src/main/res/layout/dialog_priority_picker.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/menu/menu_multi_select.xml b/app/src/main/res/menu/menu_multi_select.xml index 244982ad5..35519c013 100644 --- a/app/src/main/res/menu/menu_multi_select.xml +++ b/app/src/main/res/menu/menu_multi_select.xml @@ -8,6 +8,12 @@ android:title="@string/tags" app:showAsAction="always" /> + + - \ No newline at end of file + diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index dbbbf4809..ee12fe5ee 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -260,6 +260,8 @@ Wenn überfällig Wenn fällig Schlagwörter + Dringlichkeit + Dringlichkeit ändern Filter Für eine Stunde Vormittag @@ -738,4 +740,4 @@ Wiederholt sich Monatlich an Tag %1d Monatlich an dem %1$s %2$s - \ No newline at end of file + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b62c1ce30..c47fa26cf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -338,6 +338,8 @@ File %1$s contained %2$s.\n\n Geofence radius %s m Tags + Priorities + Change priority Filters For an hour Morning