From 307ce40e19d74154facbd142a27594dc1817d39b Mon Sep 17 00:00:00 2001 From: Pavel Poley Date: Thu, 5 May 2022 12:03:45 +0300 Subject: [PATCH 1/9] allow reordering favorites by drag and drop --- .../contacts/pro/adapters/ContactsAdapter.kt | 57 +++++++++++++++++-- .../pro/fragments/MyViewPagerFragment.kt | 12 +++- 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt index e918627a..7423a08c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt @@ -10,11 +10,14 @@ import android.graphics.drawable.Icon import android.graphics.drawable.LayerDrawable import android.util.TypedValue import android.view.Menu +import android.view.MotionEvent import android.view.View import android.view.ViewGroup import android.widget.FrameLayout import android.widget.ImageView import android.widget.TextView +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.request.RequestOptions @@ -25,6 +28,9 @@ import com.simplemobiletools.commons.dialogs.ConfirmationDialog import com.simplemobiletools.commons.dialogs.RadioGroupDialog import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.* +import com.simplemobiletools.commons.interfaces.ItemMoveCallback +import com.simplemobiletools.commons.interfaces.ItemTouchHelperContract +import com.simplemobiletools.commons.interfaces.StartReorderDragListener import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.contacts.pro.R @@ -38,10 +44,16 @@ import com.simplemobiletools.contacts.pro.interfaces.RemoveFromGroupListener import com.simplemobiletools.contacts.pro.models.Contact class ContactsAdapter( - activity: SimpleActivity, var contactItems: ArrayList, private val refreshListener: RefreshContactsListener?, - private val location: Int, private val removeListener: RemoveFromGroupListener?, recyclerView: MyRecyclerView, - highlightText: String = "", itemClick: (Any) -> Unit -) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate { + activity: SimpleActivity, + var contactItems: ArrayList, + private val refreshListener: RefreshContactsListener?, + private val location: Int, + private val removeListener: RemoveFromGroupListener?, + recyclerView: MyRecyclerView, + highlightText: String = "", + private val enableDrag: Boolean = false, + itemClick: (Any) -> Unit +) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate, ItemTouchHelperContract { private val NEW_GROUP_ID = -1 private var config = activity.config @@ -54,8 +66,22 @@ class ContactsAdapter( private val itemLayout = if (showPhoneNumbers) R.layout.item_contact_with_number else R.layout.item_contact_without_number + private var touchHelper: ItemTouchHelper? = null + private var startReorderDragListener: StartReorderDragListener? = null + init { setupDragListener(true) + + if (enableDrag) { + 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 @@ -117,7 +143,7 @@ class ContactsAdapter( val contact = contactItems[position] val allowLongClick = location != LOCATION_INSERT_OR_EDIT holder.bindView(contact, true, allowLongClick) { itemView, layoutPosition -> - setupView(itemView, contact) + setupView(itemView, contact, holder) } bindViewHolder(holder) } @@ -335,7 +361,7 @@ class ContactsAdapter( } } - private fun setupView(view: View, contact: Contact) { + private fun setupView(view: View, contact: Contact, holder: ViewHolder) { view.apply { findViewById(R.id.item_contact_frame)?.isSelected = selectedKeys.contains(contact.id) val fullName = contact.getNameToDisplay() @@ -393,8 +419,27 @@ class ContactsAdapter( .into(findViewById(R.id.item_contact_image)) } } + + findViewById(R.id.item_contact_image).setOnTouchListener { v, event -> + if (event.action == MotionEvent.ACTION_DOWN) { + startReorderDragListener?.requestDrag(holder) + } + false + } } } override fun onChange(position: Int) = contactItems.getOrNull(position)?.getBubbleText() ?: "" + + override fun onRowClear(myViewHolder: ViewHolder?) { + + } + + override fun onRowMoved(fromPosition: Int, toPosition: Int) { + + } + + override fun onRowSelected(myViewHolder: ViewHolder?) { + + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt index ed425cdd..5c615772 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt @@ -30,7 +30,6 @@ import kotlinx.android.synthetic.main.fragment_layout.view.fragment_placeholder_ import kotlinx.android.synthetic.main.fragment_layout.view.fragment_wrapper import kotlinx.android.synthetic.main.fragment_letters_layout.view.* import java.util.* -import kotlin.collections.ArrayList abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) : CoordinatorLayout(context, attributeSet) { protected var activity: SimpleActivity? = null @@ -219,7 +218,16 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) else -> LOCATION_CONTACTS_TAB } - ContactsAdapter(activity as SimpleActivity, contacts, activity as RefreshContactsListener, location, null, fragment_list) { + val enableDragReorder = this is FavoritesFragment + ContactsAdapter( + activity = activity as SimpleActivity, + contactItems = contacts, + refreshListener = activity as RefreshContactsListener, + location = location, + removeListener = null, + recyclerView = fragment_list, + enableDrag = enableDragReorder + ) { (activity as RefreshContactsListener).contactClicked(it as Contact) }.apply { fragment_list.adapter = this From f807961768aa0fa56ad27b377c80bd8f8e193bd2 Mon Sep 17 00:00:00 2001 From: Pavel Poley Date: Thu, 5 May 2022 18:03:58 +0300 Subject: [PATCH 2/9] allow reordering favorites by drag and drop --- .../contacts/pro/adapters/ContactsAdapter.kt | 33 ++++++++++++++++--- .../pro/dialogs/ChangeSortingDialog.kt | 2 ++ .../pro/fragments/MyViewPagerFragment.kt | 18 +++++++++- .../contacts/pro/helpers/Config.kt | 4 +++ .../contacts/pro/helpers/Constants.kt | 1 + .../main/res/layout/dialog_change_sorting.xml | 8 +++++ 6 files changed, 60 insertions(+), 6 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt index 7423a08c..bdddaf79 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt @@ -8,6 +8,7 @@ import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import android.graphics.drawable.Icon import android.graphics.drawable.LayerDrawable +import android.util.Log import android.util.TypedValue import android.view.Menu import android.view.MotionEvent @@ -22,6 +23,7 @@ import com.bumptech.glide.Glide import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.signature.ObjectKey +import com.google.gson.Gson import com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter import com.simplemobiletools.commons.dialogs.ConfirmationDialog @@ -42,6 +44,7 @@ import com.simplemobiletools.contacts.pro.helpers.* import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener import com.simplemobiletools.contacts.pro.interfaces.RemoveFromGroupListener import com.simplemobiletools.contacts.pro.models.Contact +import java.util.* class ContactsAdapter( activity: SimpleActivity, @@ -420,6 +423,10 @@ class ContactsAdapter( } } + // TODO: + if (enableDrag) { + + } findViewById(R.id.item_contact_image).setOnTouchListener { v, event -> if (event.action == MotionEvent.ACTION_DOWN) { startReorderDragListener?.requestDrag(holder) @@ -431,15 +438,31 @@ class ContactsAdapter( override fun onChange(position: Int) = contactItems.getOrNull(position)?.getBubbleText() ?: "" - override fun onRowClear(myViewHolder: ViewHolder?) { - - } - override fun onRowMoved(fromPosition: Int, toPosition: Int) { - + activity.config.sorting = SORT_BY_CUSTOM // TODO: check if i can use this constant + if (fromPosition < toPosition) { + for (i in fromPosition until toPosition) { + Collections.swap(contactItems, i, i + 1) + } + } else { + for (i in fromPosition downTo toPosition + 1) { + Collections.swap(contactItems, i, i - 1) + } + } + notifyItemMoved(fromPosition, toPosition) } override fun onRowSelected(myViewHolder: ViewHolder?) { } + + override fun onRowClear(myViewHolder: ViewHolder?) { + for (contact in contactItems) { + Log.d("test", "onRowClear: ${contact.getNameToDisplay()} ${contact.id} ${contact.contactId}") + } + val orderIds = contactItems.map { it.id } + val orderGsonString = Gson().toJson(orderIds) + Log.d("test", "onRowClear: $orderGsonString") + activity.config.favoritesContactsOrder = orderGsonString + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt index 480ed683..50192c9a 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt @@ -33,6 +33,7 @@ class ChangeSortingDialog(val activity: BaseSimpleActivity, private val callback currSorting and SORT_BY_MIDDLE_NAME != 0 -> sortingRadio.sorting_dialog_radio_middle_name currSorting and SORT_BY_SURNAME != 0 -> sortingRadio.sorting_dialog_radio_surname currSorting and SORT_BY_FULL_NAME != 0 -> sortingRadio.sorting_dialog_radio_full_name + currSorting and SORT_BY_CUSTOM != 0 -> sortingRadio.sorting_dialog_radio_custom else -> sortingRadio.sorting_dialog_radio_date_created } sortBtn.isChecked = true @@ -55,6 +56,7 @@ class ChangeSortingDialog(val activity: BaseSimpleActivity, private val callback R.id.sorting_dialog_radio_middle_name -> SORT_BY_MIDDLE_NAME R.id.sorting_dialog_radio_surname -> SORT_BY_SURNAME R.id.sorting_dialog_radio_full_name -> SORT_BY_FULL_NAME + R.id.sorting_dialog_radio_custom -> SORT_BY_CUSTOM else -> SORT_BY_DATE_CREATED } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt index 5c615772..ea8690e7 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt @@ -124,7 +124,15 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) val filtered = when { this is GroupsFragment -> contacts - this is FavoritesFragment -> contacts.filter { it.starred == 1 } as ArrayList + this is FavoritesFragment -> { + val favorites = contacts.filter { it.starred == 1 } as ArrayList + + if (activity!!.config.sorting == SORT_BY_CUSTOM) { + sortByCustomOrder(favorites) + } else { + favorites + } + } else -> { val contactSources = activity!!.getVisibleContactSources() contacts.filter { contactSources.contains(it.source) } as ArrayList @@ -152,6 +160,14 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) } } + private fun sortByCustomOrder(starred: List): ArrayList { + val favoritesOrder = activity!!.config.favoritesContactsOrder + val orderList = Converters().jsonToStringList(favoritesOrder) + val map = orderList.withIndex().associate { it.value to it.index } + val sorted = starred.sortedBy { map[it.id.toString()] } + return ArrayList(sorted) + } + private fun setupContacts(contacts: ArrayList) { if (this is GroupsFragment) { setupGroupsAdapter(contacts) { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Config.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Config.kt index fe209b56..ef11b261 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Config.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Config.kt @@ -66,4 +66,8 @@ class Config(context: Context) : BaseConfig(context) { var mergeDuplicateContacts: Boolean get() = prefs.getBoolean(MERGE_DUPLICATE_CONTACTS, true) set(mergeDuplicateContacts) = prefs.edit().putBoolean(MERGE_DUPLICATE_CONTACTS, mergeDuplicateContacts).apply() + + var favoritesContactsOrder: String + get() = prefs.getString(FAVORITES_CONTACTS_ORDER, "")!! + set(order) = prefs.edit().putString(FAVORITES_CONTACTS_ORDER, order).apply() } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt index 8a347061..d345ad93 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt @@ -22,6 +22,7 @@ const val LAST_EXPORT_PATH = "last_export_path" const val WAS_LOCAL_ACCOUNT_INITIALIZED = "was_local_account_initialized" const val SHOW_PRIVATE_CONTACTS = "show_private_contacts" const val MERGE_DUPLICATE_CONTACTS = "merge_duplicate_contacts" +const val FAVORITES_CONTACTS_ORDER = "favorites_contacts_order" const val SMT_PRIVATE = "smt_private" // used at the contact source of local contacts hidden from other apps const val GROUP = "group" diff --git a/app/src/main/res/layout/dialog_change_sorting.xml b/app/src/main/res/layout/dialog_change_sorting.xml index 29946081..a60535f7 100644 --- a/app/src/main/res/layout/dialog_change_sorting.xml +++ b/app/src/main/res/layout/dialog_change_sorting.xml @@ -59,6 +59,14 @@ android:paddingBottom="@dimen/medium_margin" android:text="@string/date_created" /> + + From b8113575cb8b311d4efd1ce2a434833aba2df48b Mon Sep 17 00:00:00 2001 From: Pavel Poley Date: Fri, 6 May 2022 12:13:04 +0300 Subject: [PATCH 3/9] allow reordering favorites by drag and drop --- app/build.gradle | 2 +- .../contacts/pro/adapters/ContactsAdapter.kt | 31 ++++++++++--------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 8b4089a8..0abf9e7d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -63,7 +63,7 @@ android { } dependencies { - implementation 'com.github.SimpleMobileTools:Simple-Commons:b264da6cff' + implementation 'com.github.SimpleMobileTools:Simple-Commons:1dfdd8d34d' implementation 'com.googlecode.ez-vcard:ez-vcard:0.11.3' implementation 'com.github.tibbi:IndicatorFastScroll:4524cd0b61' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt index bdddaf79..fc2d4b0b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt @@ -8,7 +8,6 @@ import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import android.graphics.drawable.Icon import android.graphics.drawable.LayerDrawable -import android.util.Log import android.util.TypedValue import android.view.Menu import android.view.MotionEvent @@ -136,9 +135,13 @@ class ContactsAdapter( override fun getItemKeyPosition(key: Int) = contactItems.indexOfFirst { it.id == key } - override fun onActionModeCreated() {} + override fun onActionModeCreated() { + notifyDataSetChanged() + } - override fun onActionModeDestroyed() {} + override fun onActionModeDestroyed() { + notifyDataSetChanged() + } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(itemLayout, parent) @@ -423,15 +426,17 @@ class ContactsAdapter( } } - // TODO: if (enableDrag) { - - } - findViewById(R.id.item_contact_image).setOnTouchListener { v, event -> - if (event.action == MotionEvent.ACTION_DOWN) { - startReorderDragListener?.requestDrag(holder) + findViewById(R.id.drag_handle_icon).apply { + beVisibleIf(selectedKeys.isNotEmpty()) + applyColorFilter(textColor) + setOnTouchListener { v, event -> + if (event.action == MotionEvent.ACTION_DOWN) { + startReorderDragListener?.requestDrag(holder) + } + false + } } - false } } } @@ -439,7 +444,7 @@ class ContactsAdapter( override fun onChange(position: Int) = contactItems.getOrNull(position)?.getBubbleText() ?: "" override fun onRowMoved(fromPosition: Int, toPosition: Int) { - activity.config.sorting = SORT_BY_CUSTOM // TODO: check if i can use this constant + activity.config.sorting = SORT_BY_CUSTOM if (fromPosition < toPosition) { for (i in fromPosition until toPosition) { Collections.swap(contactItems, i, i + 1) @@ -457,12 +462,8 @@ class ContactsAdapter( } override fun onRowClear(myViewHolder: ViewHolder?) { - for (contact in contactItems) { - Log.d("test", "onRowClear: ${contact.getNameToDisplay()} ${contact.id} ${contact.contactId}") - } val orderIds = contactItems.map { it.id } val orderGsonString = Gson().toJson(orderIds) - Log.d("test", "onRowClear: $orderGsonString") activity.config.favoritesContactsOrder = orderGsonString } } From f5a760eb796f7d17ab748c771d906296c80dc785 Mon Sep 17 00:00:00 2001 From: Pavel Poley Date: Fri, 6 May 2022 15:45:41 +0300 Subject: [PATCH 4/9] allow reordering favorites by drag and drop --- app/build.gradle | 2 +- .../contacts/pro/adapters/ContactsAdapter.kt | 8 +++----- .../pro/fragments/MyViewPagerFragment.kt | 20 ++++++++++++++++++- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 0abf9e7d..a62a215e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -63,7 +63,7 @@ android { } dependencies { - implementation 'com.github.SimpleMobileTools:Simple-Commons:1dfdd8d34d' + implementation 'com.github.SimpleMobileTools:Simple-Commons:34fdfce71c' implementation 'com.googlecode.ez-vcard:ez-vcard:0.11.3' implementation 'com.github.tibbi:IndicatorFastScroll:4524cd0b61' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt index fc2d4b0b..36d3b6a6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt @@ -22,7 +22,6 @@ import com.bumptech.glide.Glide import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.signature.ObjectKey -import com.google.gson.Gson import com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter import com.simplemobiletools.commons.dialogs.ConfirmationDialog @@ -55,7 +54,7 @@ class ContactsAdapter( highlightText: String = "", private val enableDrag: Boolean = false, itemClick: (Any) -> Unit -) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate, ItemTouchHelperContract { + ) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate, ItemTouchHelperContract { private val NEW_GROUP_ID = -1 private var config = activity.config @@ -70,6 +69,7 @@ class ContactsAdapter( private var touchHelper: ItemTouchHelper? = null private var startReorderDragListener: StartReorderDragListener? = null + var onDragEndListener: (() -> Unit)? = null init { setupDragListener(true) @@ -462,8 +462,6 @@ class ContactsAdapter( } override fun onRowClear(myViewHolder: ViewHolder?) { - val orderIds = contactItems.map { it.id } - val orderGsonString = Gson().toJson(orderIds) - activity.config.favoritesContactsOrder = orderGsonString + onDragEndListener?.invoke() } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt index ea8690e7..a5027756 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt @@ -5,6 +5,7 @@ import android.content.Intent import android.util.AttributeSet import android.view.ViewGroup import androidx.coordinatorlayout.widget.CoordinatorLayout +import com.google.gson.Gson import com.reddit.indicatorfastscroll.FastScrollItemIndicator import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter import com.simplemobiletools.commons.extensions.* @@ -242,11 +243,20 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) location = location, removeListener = null, recyclerView = fragment_list, - enableDrag = enableDragReorder + enableDrag = enableDragReorder, ) { (activity as RefreshContactsListener).contactClicked(it as Contact) }.apply { fragment_list.adapter = this + if (enableDragReorder) { + onDragEndListener = { + val adapter = fragment_list?.adapter + if (adapter is ContactsAdapter) { + saveCustomOrderToPrefs(adapter.contactItems) + } + refreshContacts(contacts) + } + } } if (context.areSystemAnimationsEnabled) { @@ -262,6 +272,14 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) } } + private fun saveCustomOrderToPrefs(items: ArrayList) { + activity?.apply { + val orderIds = items.map { it.id } + val orderGsonString = Gson().toJson(orderIds) + config.favoritesContactsOrder = orderGsonString + } + } + fun showContactThumbnailsChanged(showThumbnails: Boolean) { if (this is GroupsFragment) { (fragment_list.adapter as? GroupsAdapter)?.apply { From 716c527e0face636dc541859c47fcb1c52584039 Mon Sep 17 00:00:00 2001 From: Pavel Poley Date: Fri, 6 May 2022 15:57:20 +0300 Subject: [PATCH 5/9] allow reordering favorites by drag and drop --- .../contacts/pro/dialogs/ChangeSortingDialog.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt index 50192c9a..c6b0035a 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt @@ -2,6 +2,7 @@ package com.simplemobiletools.contacts.pro.dialogs import androidx.appcompat.app.AlertDialog import com.simplemobiletools.commons.activities.BaseSimpleActivity +import com.simplemobiletools.commons.extensions.beGoneIf import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.contacts.pro.R @@ -28,6 +29,12 @@ class ChangeSortingDialog(val activity: BaseSimpleActivity, private val callback private fun setupSortRadio() { val sortingRadio = view.sorting_dialog_radio_sorting + + sortingRadio.setOnCheckedChangeListener { group, checkedId -> + val isCustomSorting = checkedId == sortingRadio.sorting_dialog_radio_custom.id + view.sorting_dialog_radio_order.beGoneIf(isCustomSorting) + } + val sortBtn = when { currSorting and SORT_BY_FIRST_NAME != 0 -> sortingRadio.sorting_dialog_radio_first_name currSorting and SORT_BY_MIDDLE_NAME != 0 -> sortingRadio.sorting_dialog_radio_middle_name @@ -60,7 +67,7 @@ class ChangeSortingDialog(val activity: BaseSimpleActivity, private val callback else -> SORT_BY_DATE_CREATED } - if (view.sorting_dialog_radio_order.checkedRadioButtonId == R.id.sorting_dialog_radio_descending) { + if (sorting != SORT_BY_CUSTOM && view.sorting_dialog_radio_order.checkedRadioButtonId == R.id.sorting_dialog_radio_descending) { sorting = sorting or SORT_DESCENDING } From 145d781ecb73edc8544c6e1ca8ea5a53f4705b24 Mon Sep 17 00:00:00 2001 From: Pavel Poley Date: Fri, 6 May 2022 16:51:43 +0300 Subject: [PATCH 6/9] allow reordering favorites by drag and drop --- .../contacts/pro/adapters/ContactsAdapter.kt | 14 ++++++++++---- .../contacts/pro/fragments/MyViewPagerFragment.kt | 11 +++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt index 36d3b6a6..656d6eb0 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt @@ -54,7 +54,7 @@ class ContactsAdapter( highlightText: String = "", private val enableDrag: Boolean = false, itemClick: (Any) -> Unit - ) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate, ItemTouchHelperContract { +) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate, ItemTouchHelperContract { private val NEW_GROUP_ID = -1 private var config = activity.config @@ -426,17 +426,23 @@ class ContactsAdapter( } } - if (enableDrag) { - findViewById(R.id.drag_handle_icon).apply { + val dragIcon = findViewById(R.id.drag_handle_icon) + if (enableDrag && textToHighlight.isEmpty()) { + dragIcon.apply { beVisibleIf(selectedKeys.isNotEmpty()) applyColorFilter(textColor) - setOnTouchListener { v, event -> + setOnTouchListener { _, event -> if (event.action == MotionEvent.ACTION_DOWN) { startReorderDragListener?.requestDrag(holder) } false } } + } else { + dragIcon.apply { + beGone() + setOnTouchListener(null) + } } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt index a5027756..5bcc0aa6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt @@ -163,9 +163,15 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) private fun sortByCustomOrder(starred: List): ArrayList { val favoritesOrder = activity!!.config.favoritesContactsOrder + + if (favoritesOrder.isEmpty()) { + return ArrayList(starred) + } + val orderList = Converters().jsonToStringList(favoritesOrder) val map = orderList.withIndex().associate { it.value to it.index } val sorted = starred.sortedBy { map[it.id.toString()] } + return ArrayList(sorted) } @@ -252,9 +258,10 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) onDragEndListener = { val adapter = fragment_list?.adapter if (adapter is ContactsAdapter) { - saveCustomOrderToPrefs(adapter.contactItems) + val items = adapter.contactItems + saveCustomOrderToPrefs(items) + setupLetterFastscroller(items) } - refreshContacts(contacts) } } } From 5b75c5f26bee3c203378a063cb9ed3b276c7a5b3 Mon Sep 17 00:00:00 2001 From: Pavel Poley Date: Fri, 6 May 2022 22:19:17 +0300 Subject: [PATCH 7/9] allow reordering favorites by drag and drop --- .../contacts/pro/activities/MainActivity.kt | 8 +++-- .../contacts/pro/adapters/ContactsAdapter.kt | 4 ++- .../pro/dialogs/ChangeSortingDialog.kt | 30 +++++++++++++++++-- .../pro/fragments/MyViewPagerFragment.kt | 2 +- .../contacts/pro/helpers/Config.kt | 4 +++ .../contacts/pro/helpers/Constants.kt | 1 + 6 files changed, 41 insertions(+), 8 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/MainActivity.kt index 8ad84e5c..be34c253 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/activities/MainActivity.kt @@ -35,6 +35,7 @@ import com.simplemobiletools.contacts.pro.dialogs.ImportContactsDialog import com.simplemobiletools.contacts.pro.extensions.config import com.simplemobiletools.contacts.pro.extensions.getTempFile import com.simplemobiletools.contacts.pro.extensions.handleGenericContactClick +import com.simplemobiletools.contacts.pro.fragments.FavoritesFragment import com.simplemobiletools.contacts.pro.fragments.MyViewPagerFragment import com.simplemobiletools.contacts.pro.helpers.ALL_TABS_MASK import com.simplemobiletools.contacts.pro.helpers.ContactsHelper @@ -185,8 +186,9 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { - R.id.sort -> showSortingDialog() + R.id.sort -> showSortingDialog(showCustomSorting = getCurrentFragment() is FavoritesFragment) R.id.filter -> showFilterDialog() R.id.dialpad -> launchDialpad() R.id.import_contacts -> tryImportContacts() @@ -410,8 +412,8 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { } } - private fun showSortingDialog() { - ChangeSortingDialog(this) { + private fun showSortingDialog(showCustomSorting: Boolean) { + ChangeSortingDialog(this, showCustomSorting) { refreshContacts(TAB_CONTACTS or TAB_FAVORITES) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt index 656d6eb0..f148e47a 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt @@ -450,7 +450,8 @@ class ContactsAdapter( override fun onChange(position: Int) = contactItems.getOrNull(position)?.getBubbleText() ?: "" override fun onRowMoved(fromPosition: Int, toPosition: Int) { - activity.config.sorting = SORT_BY_CUSTOM + activity.config.isCustomOrderSelected = true + if (fromPosition < toPosition) { for (i in fromPosition until toPosition) { Collections.swap(contactItems, i, i + 1) @@ -460,6 +461,7 @@ class ContactsAdapter( Collections.swap(contactItems, i, i - 1) } } + notifyItemMoved(fromPosition, toPosition) } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt index c6b0035a..e4cbde6c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt @@ -9,7 +9,7 @@ import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.extensions.config import kotlinx.android.synthetic.main.dialog_change_sorting.view.* -class ChangeSortingDialog(val activity: BaseSimpleActivity, private val callback: () -> Unit) { +class ChangeSortingDialog(val activity: BaseSimpleActivity, private val showCustomSorting: Boolean = false, private val callback: () -> Unit) { private var currSorting = 0 private var config = activity.config private var view = activity.layoutInflater.inflate(R.layout.dialog_change_sorting, null) @@ -22,7 +22,16 @@ class ChangeSortingDialog(val activity: BaseSimpleActivity, private val callback activity.setupDialogStuff(view, this, R.string.sort_by) } - currSorting = config.sorting + currSorting = if (showCustomSorting) { + if (config.isCustomOrderSelected) { + SORT_BY_CUSTOM + } else { + config.sorting + } + } else { + config.sorting + } + setupSortRadio() setupOrderRadio() } @@ -44,6 +53,11 @@ class ChangeSortingDialog(val activity: BaseSimpleActivity, private val callback else -> sortingRadio.sorting_dialog_radio_date_created } sortBtn.isChecked = true + + if (showCustomSorting) { + sortingRadio.sorting_dialog_radio_custom.isChecked = config.isCustomOrderSelected + } + view.sorting_dialog_radio_custom.beGoneIf(!showCustomSorting) } private fun setupOrderRadio() { @@ -71,7 +85,17 @@ class ChangeSortingDialog(val activity: BaseSimpleActivity, private val callback sorting = sorting or SORT_DESCENDING } - config.sorting = sorting + if (showCustomSorting) { + if (sorting == SORT_BY_CUSTOM) { + config.isCustomOrderSelected = true + } else { + config.isCustomOrderSelected = false + config.sorting = sorting + } + } else { + config.sorting = sorting + } + callback() } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt index 5bcc0aa6..12703321 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/fragments/MyViewPagerFragment.kt @@ -128,7 +128,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) this is FavoritesFragment -> { val favorites = contacts.filter { it.starred == 1 } as ArrayList - if (activity!!.config.sorting == SORT_BY_CUSTOM) { + if (activity!!.config.isCustomOrderSelected) { sortByCustomOrder(favorites) } else { favorites diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Config.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Config.kt index ef11b261..4c584f9c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Config.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Config.kt @@ -70,4 +70,8 @@ class Config(context: Context) : BaseConfig(context) { var favoritesContactsOrder: String get() = prefs.getString(FAVORITES_CONTACTS_ORDER, "")!! set(order) = prefs.edit().putString(FAVORITES_CONTACTS_ORDER, order).apply() + + var isCustomOrderSelected: Boolean + get() = prefs.getBoolean(FAVORITES_CUSTOM_ORDER_SELECTED, false) + set(selected) = prefs.edit().putBoolean(FAVORITES_CUSTOM_ORDER_SELECTED, selected).apply() } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt index d345ad93..ef821611 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/helpers/Constants.kt @@ -23,6 +23,7 @@ const val WAS_LOCAL_ACCOUNT_INITIALIZED = "was_local_account_initialized" const val SHOW_PRIVATE_CONTACTS = "show_private_contacts" const val MERGE_DUPLICATE_CONTACTS = "merge_duplicate_contacts" const val FAVORITES_CONTACTS_ORDER = "favorites_contacts_order" +const val FAVORITES_CUSTOM_ORDER_SELECTED = "favorites_custom_order_selected" const val SMT_PRIVATE = "smt_private" // used at the contact source of local contacts hidden from other apps const val GROUP = "group" From 9dc953def9ec355f477bc10c70096a39078dd6e6 Mon Sep 17 00:00:00 2001 From: Pavel Poley Date: Wed, 11 May 2022 12:04:26 +0300 Subject: [PATCH 8/9] format code --- .../contacts/pro/adapters/ContactsAdapter.kt | 4 +--- .../contacts/pro/dialogs/ChangeSortingDialog.kt | 8 ++------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt index f148e47a..e86e59f6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/ContactsAdapter.kt @@ -465,9 +465,7 @@ class ContactsAdapter( notifyItemMoved(fromPosition, toPosition) } - override fun onRowSelected(myViewHolder: ViewHolder?) { - - } + override fun onRowSelected(myViewHolder: ViewHolder?) { } override fun onRowClear(myViewHolder: ViewHolder?) { onDragEndListener?.invoke() diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt index e4cbde6c..8f39b07c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt @@ -22,12 +22,8 @@ class ChangeSortingDialog(val activity: BaseSimpleActivity, private val showCust activity.setupDialogStuff(view, this, R.string.sort_by) } - currSorting = if (showCustomSorting) { - if (config.isCustomOrderSelected) { - SORT_BY_CUSTOM - } else { - config.sorting - } + currSorting = if (showCustomSorting && config.isCustomOrderSelected) { + SORT_BY_CUSTOM } else { config.sorting } From 97662dcb756a1c64ddd6d2fb2bded98b83575e3b Mon Sep 17 00:00:00 2001 From: Pavel Poley Date: Wed, 11 May 2022 12:14:20 +0300 Subject: [PATCH 9/9] remove divider when custom sorting is selected --- .../contacts/pro/dialogs/ChangeSortingDialog.kt | 1 + app/src/main/res/layout/dialog_change_sorting.xml | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt index 8f39b07c..9240dc4a 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ChangeSortingDialog.kt @@ -38,6 +38,7 @@ class ChangeSortingDialog(val activity: BaseSimpleActivity, private val showCust sortingRadio.setOnCheckedChangeListener { group, checkedId -> val isCustomSorting = checkedId == sortingRadio.sorting_dialog_radio_custom.id view.sorting_dialog_radio_order.beGoneIf(isCustomSorting) + view.divider.beGoneIf(isCustomSorting) } val sortBtn = when { diff --git a/app/src/main/res/layout/dialog_change_sorting.xml b/app/src/main/res/layout/dialog_change_sorting.xml index a60535f7..2a073839 100644 --- a/app/src/main/res/layout/dialog_change_sorting.xml +++ b/app/src/main/res/layout/dialog_change_sorting.xml @@ -69,7 +69,9 @@ - +