From ab2b8463f60128cd899b01eb6b08435cae788e33 Mon Sep 17 00:00:00 2001 From: ronniedroid Date: Thu, 25 Apr 2024 12:26:49 +0300 Subject: [PATCH] added manual sorting to the alarms tab --- .../fossify/clock/adapters/AlarmsAdapter.kt | 53 +++++++++++++++++-- .../clock/dialogs/ChangeAlarmSortDialog.kt | 3 ++ .../fossify/clock/extensions/MutableList.kt | 7 +++ .../fossify/clock/fragments/AlarmFragment.kt | 21 ++++++++ .../org/fossify/clock/helpers/Config.kt | 4 ++ .../org/fossify/clock/helpers/Constants.kt | 1 + .../res/layout/dialog_change_alarm_sort.xml | 8 +++ app/src/main/res/layout/item_alarm.xml | 19 +++++-- app/src/main/res/values/dimens.xml | 1 + app/src/main/res/values/strings.xml | 1 + 10 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 app/src/main/kotlin/org/fossify/clock/extensions/MutableList.kt diff --git a/app/src/main/kotlin/org/fossify/clock/adapters/AlarmsAdapter.kt b/app/src/main/kotlin/org/fossify/clock/adapters/AlarmsAdapter.kt index 49d85ae7..7fcf1737 100644 --- a/app/src/main/kotlin/org/fossify/clock/adapters/AlarmsAdapter.kt +++ b/app/src/main/kotlin/org/fossify/clock/adapters/AlarmsAdapter.kt @@ -1,8 +1,13 @@ package org.fossify.clock.adapters +import android.annotation.SuppressLint +import android.util.Log import android.view.Menu +import android.view.MotionEvent import android.view.View import android.view.ViewGroup +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.RecyclerView import org.fossify.clock.R import org.fossify.clock.activities.SimpleActivity import org.fossify.clock.databinding.ItemAlarmBinding @@ -14,17 +19,32 @@ import org.fossify.clock.interfaces.ToggleAlarmInterface import org.fossify.clock.models.Alarm import org.fossify.commons.adapters.MyRecyclerViewAdapter import org.fossify.commons.dialogs.ConfirmationDialog +import org.fossify.commons.extensions.applyColorFilter import org.fossify.commons.extensions.beVisibleIf import org.fossify.commons.extensions.toast +import org.fossify.commons.helpers.SORT_BY_CUSTOM +import org.fossify.commons.interfaces.ItemMoveCallback +import org.fossify.commons.interfaces.ItemTouchHelperContract +import org.fossify.commons.interfaces.StartReorderDragListener import org.fossify.commons.views.MyRecyclerView class AlarmsAdapter( activity: SimpleActivity, var alarms: ArrayList, val toggleAlarmInterface: ToggleAlarmInterface, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit, -) : MyRecyclerViewAdapter(activity, recyclerView, itemClick) { +) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), ItemTouchHelperContract { + private var startReorderDragListener: StartReorderDragListener init { setupDragListener(true) + + val touchHelper = ItemTouchHelper(ItemMoveCallback(this)) + touchHelper.attachToRecyclerView(recyclerView) + + startReorderDragListener = object : StartReorderDragListener { + override fun requestDrag(viewHolder: RecyclerView.ViewHolder) { + touchHelper.startDrag(viewHolder) + } + } } override fun getActionMenuId() = R.menu.cab_alarms @@ -53,14 +73,18 @@ class AlarmsAdapter( override fun onActionModeDestroyed() {} + override fun onRowClear(myViewHolder: ViewHolder?) {} + + override fun onRowSelected(myViewHolder: ViewHolder?) {} + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { return createViewHolder(ItemAlarmBinding.inflate(layoutInflater, parent, false).root) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val alarm = alarms[position] - holder.bindView(alarm, true, true) { itemView, layoutPosition -> - setupView(itemView, alarm) + holder.bindView(alarm, true, true) { itemView, _ -> + setupView(itemView, alarm, holder) } bindViewHolder(holder) } @@ -87,10 +111,19 @@ class AlarmsAdapter( private fun getSelectedItems() = alarms.filter { selectedKeys.contains(it.id) } as ArrayList - private fun setupView(view: View, alarm: Alarm) { + @SuppressLint("ClickableViewAccessibility") + private fun setupView(view: View, alarm: Alarm, holder: ViewHolder) { val isSelected = selectedKeys.contains(alarm.id) ItemAlarmBinding.bind(view).apply { alarmHolder.isSelected = isSelected + alarmDragHandle.beVisibleIf(activity.config.alarmSort == SORT_BY_CUSTOM) + alarmDragHandle.applyColorFilter(textColor) + alarmDragHandle.setOnTouchListener { _, event -> + if (event.action == MotionEvent.ACTION_DOWN) { + startReorderDragListener.requestDrag(holder) + } + false + } alarmTime.text = activity.getFormattedTime(alarm.timeInMinutes * 60, false, true) alarmTime.setTextColor(textColor) @@ -137,4 +170,16 @@ class AlarmsAdapter( } } } + + override fun onRowMoved(fromPosition: Int, toPosition: Int) { + alarms.swap(fromPosition, toPosition) + notifyItemMoved(fromPosition, toPosition) + saveAlarmsCustomOrder(alarms) + } + + private fun saveAlarmsCustomOrder(alarms: ArrayList) { + val alarmsCustomSortingIds = alarms.map { it.id } + + activity.config.alarmsCustomSorting = alarmsCustomSortingIds.joinToString { it.toString() } + } } diff --git a/app/src/main/kotlin/org/fossify/clock/dialogs/ChangeAlarmSortDialog.kt b/app/src/main/kotlin/org/fossify/clock/dialogs/ChangeAlarmSortDialog.kt index 073d00e3..efd25852 100644 --- a/app/src/main/kotlin/org/fossify/clock/dialogs/ChangeAlarmSortDialog.kt +++ b/app/src/main/kotlin/org/fossify/clock/dialogs/ChangeAlarmSortDialog.kt @@ -9,12 +9,14 @@ import org.fossify.clock.helpers.SORT_BY_DATE_AND_TIME import org.fossify.commons.activities.BaseSimpleActivity import org.fossify.commons.extensions.getAlertDialogBuilder import org.fossify.commons.extensions.setupDialogStuff +import org.fossify.commons.helpers.SORT_BY_CUSTOM class ChangeAlarmSortDialog(val activity: BaseSimpleActivity, val callback: () -> Unit) { private val binding = DialogChangeAlarmSortBinding.inflate(activity.layoutInflater).apply { val activeRadioButton = when (activity.config.alarmSort) { SORT_BY_ALARM_TIME -> sortingDialogRadioAlarmTime SORT_BY_DATE_AND_TIME -> sortingDialogRadioDayAndTime + SORT_BY_CUSTOM -> sortingDialogRadioCustom else -> sortingDialogRadioCreationOrder } activeRadioButton.isChecked = true @@ -33,6 +35,7 @@ class ChangeAlarmSortDialog(val activity: BaseSimpleActivity, val callback: () - val sort = when (binding.sortingDialogRadioSorting.checkedRadioButtonId) { R.id.sorting_dialog_radio_alarm_time -> SORT_BY_ALARM_TIME R.id.sorting_dialog_radio_day_and_time -> SORT_BY_DATE_AND_TIME + R.id.sorting_dialog_radio_custom -> SORT_BY_CUSTOM else -> SORT_BY_CREATION_ORDER } diff --git a/app/src/main/kotlin/org/fossify/clock/extensions/MutableList.kt b/app/src/main/kotlin/org/fossify/clock/extensions/MutableList.kt new file mode 100644 index 00000000..9ca4e24f --- /dev/null +++ b/app/src/main/kotlin/org/fossify/clock/extensions/MutableList.kt @@ -0,0 +1,7 @@ +package org.fossify.clock.extensions + +fun MutableList.swap(index1: Int, index2: Int) { + this[index1] = this[index2].also { + this[index2] = this[index1] + } +} diff --git a/app/src/main/kotlin/org/fossify/clock/fragments/AlarmFragment.kt b/app/src/main/kotlin/org/fossify/clock/fragments/AlarmFragment.kt index de83517e..6c58af47 100644 --- a/app/src/main/kotlin/org/fossify/clock/fragments/AlarmFragment.kt +++ b/app/src/main/kotlin/org/fossify/clock/fragments/AlarmFragment.kt @@ -1,6 +1,7 @@ package org.fossify.clock.fragments import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -20,6 +21,7 @@ import org.fossify.commons.extensions.getProperBackgroundColor import org.fossify.commons.extensions.getProperTextColor import org.fossify.commons.extensions.toast import org.fossify.commons.extensions.updateTextColors +import org.fossify.commons.helpers.SORT_BY_CUSTOM import org.fossify.commons.helpers.SORT_BY_DATE_CREATED import org.fossify.commons.helpers.ensureBackgroundThread import org.fossify.commons.models.AlarmSound @@ -84,6 +86,25 @@ class AlarmFragment : Fragment(), ToggleAlarmInterface { }.thenBy { it.timeInMinutes }) + + SORT_BY_CUSTOM -> { + val customAlarmsSortOrderString = activity?.config?.alarmsCustomSorting + if (customAlarmsSortOrderString == "") { + alarms.sortBy { it.id } + } else { + val customAlarmsSortOrder: List = customAlarmsSortOrderString?.split(", ")?.map { it.toInt() }!! + val alarmsIdValueMap = alarms.associateBy { it.id } + + val sortedAlarms: ArrayList = ArrayList() + customAlarmsSortOrder.map { id -> + if (alarmsIdValueMap[id] != null) { + sortedAlarms.add(alarmsIdValueMap[id] as Alarm) + } + } + + alarms = (sortedAlarms + alarms.filter { it !in sortedAlarms }) as ArrayList + } + } } context?.getEnabledAlarms { enabledAlarms -> if (enabledAlarms.isNullOrEmpty()) { diff --git a/app/src/main/kotlin/org/fossify/clock/helpers/Config.kt b/app/src/main/kotlin/org/fossify/clock/helpers/Config.kt index 722abf5f..dfc21c2a 100644 --- a/app/src/main/kotlin/org/fossify/clock/helpers/Config.kt +++ b/app/src/main/kotlin/org/fossify/clock/helpers/Config.kt @@ -57,6 +57,10 @@ class Config(context: Context) : BaseConfig(context) { get() = prefs.getInt(ALARMS_SORT_BY, SORT_BY_CREATION_ORDER) set(alarmSort) = prefs.edit().putInt(ALARMS_SORT_BY, alarmSort).apply() + var alarmsCustomSorting: String + get() = prefs.getString(ALARMS_CUSTOM_SORTING, "")!! + set(alarmsCustomSorting) = prefs.edit().putString(ALARMS_CUSTOM_SORTING, alarmsCustomSorting).apply() + var timerSort: Int get() = prefs.getInt(TIMERS_SORT_BY, SORT_BY_CREATION_ORDER) set(timerSort) = prefs.edit().putInt(TIMERS_SORT_BY, timerSort).apply() diff --git a/app/src/main/kotlin/org/fossify/clock/helpers/Constants.kt b/app/src/main/kotlin/org/fossify/clock/helpers/Constants.kt index 7b19bcc5..8264da30 100644 --- a/app/src/main/kotlin/org/fossify/clock/helpers/Constants.kt +++ b/app/src/main/kotlin/org/fossify/clock/helpers/Constants.kt @@ -24,6 +24,7 @@ const val ALARM_LAST_CONFIG = "alarm_last_config" const val TIMER_LAST_CONFIG = "timer_last_config" const val INCREASE_VOLUME_GRADUALLY = "increase_volume_gradually" const val ALARMS_SORT_BY = "alarms_sort_by" +const val ALARMS_CUSTOM_SORTING = "alarms_custom_sorting" const val TIMERS_SORT_BY = "timers_sort_by" const val STOPWATCH_LAPS_SORT_BY = "stopwatch_laps_sort_by" const val WAS_INITIAL_WIDGET_SET_UP = "was_initial_widget_set_up" diff --git a/app/src/main/res/layout/dialog_change_alarm_sort.xml b/app/src/main/res/layout/dialog_change_alarm_sort.xml index 41d9db1d..f4cce66d 100644 --- a/app/src/main/res/layout/dialog_change_alarm_sort.xml +++ b/app/src/main/res/layout/dialog_change_alarm_sort.xml @@ -37,5 +37,13 @@ android:paddingBottom="@dimen/medium_margin" android:text="@string/sort_by_day_and_alarm_time" /> + + diff --git a/app/src/main/res/layout/item_alarm.xml b/app/src/main/res/layout/item_alarm.xml index 9edabf0e..c1fb26ec 100644 --- a/app/src/main/res/layout/item_alarm.xml +++ b/app/src/main/res/layout/item_alarm.xml @@ -12,6 +12,19 @@ android:paddingHorizontal="@dimen/activity_margin" android:paddingVertical="@dimen/medium_margin"> + + @@ -35,7 +48,7 @@ android:paddingHorizontal="@dimen/tiny_margin" android:textSize="@dimen/bigger_text_size" app:layout_constraintEnd_toStartOf="@id/alarm_switch" - app:layout_constraintStart_toStartOf="parent" + app:layout_constraintStart_toEndOf="@id/alarm_drag_handle" app:layout_constraintTop_toBottomOf="@id/alarm_time" tools:text="Mon, Tue, Wed, Thu, Fri" /> @@ -49,7 +62,7 @@ android:paddingHorizontal="@dimen/tiny_margin" android:textSize="@dimen/bigger_text_size" app:layout_constraintEnd_toStartOf="@id/alarm_switch" - app:layout_constraintStart_toStartOf="parent" + app:layout_constraintStart_toEndOf="@id/alarm_drag_handle" app:layout_constraintTop_toBottomOf="@id/alarm_days" tools:text="Good morning!" /> diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index a6255c42..d700694b 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -11,6 +11,7 @@ 50dp 56dp 24dp + 40dp 70sp 60sp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index aac66a3e..21cc9d9d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -33,6 +33,7 @@ Add timer Upcoming alarm Early alarm dismissal + Reorder items by dragging Timers are running