From 6af51d8fc8cd532eef564f4455d949fead0c1474 Mon Sep 17 00:00:00 2001 From: partisan Date: Sun, 18 May 2025 09:24:05 +0200 Subject: [PATCH] Added search for Contacts/Allowlist tab --- .../weforge/xyz/pulse/ContactAdapter.kt | 20 ++++++++++-- .../weforge/xyz/pulse/ContactsFragment.kt | 32 ++++++++++++++++++- .../main/res/drawable/search_background.xml | 5 +++ app/src/main/res/layout/fragment_contacts.xml | 16 +++++++++- app/src/main/res/values/colors.xml | 2 ++ app/src/main/res/values/strings.xml | 1 + app/src/main/res/values/themes.xml | 1 + 7 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 app/src/main/res/drawable/search_background.xml diff --git a/app/src/main/java/partisan/weforge/xyz/pulse/ContactAdapter.kt b/app/src/main/java/partisan/weforge/xyz/pulse/ContactAdapter.kt index bc69051..d581f05 100644 --- a/app/src/main/java/partisan/weforge/xyz/pulse/ContactAdapter.kt +++ b/app/src/main/java/partisan/weforge/xyz/pulse/ContactAdapter.kt @@ -8,9 +8,11 @@ import androidx.recyclerview.widget.RecyclerView class ContactAdapter( private val prefs: Preferences, - private val contacts: List + private val fullList: List ) : RecyclerView.Adapter() { + private var filteredList = fullList.toMutableList() + inner class ViewHolder(inflater: LayoutInflater, parent: ViewGroup) : RecyclerView.ViewHolder(inflater.inflate(R.layout.item_contact, parent, false)) { val contactName: TextView = itemView.findViewById(R.id.contactName) @@ -22,8 +24,9 @@ class ContactAdapter( } override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val contact = contacts[position] + val contact = filteredList[position] holder.contactName.text = contact.name + holder.contactAllowed.setOnCheckedChangeListener(null) holder.contactAllowed.isChecked = prefs.isContactWhitelisted(contact.phoneNumber) holder.contactAllowed.setOnCheckedChangeListener { _, isChecked -> @@ -31,5 +34,16 @@ class ContactAdapter( } } - override fun getItemCount(): Int = contacts.size + override fun getItemCount(): Int = filteredList.size + + fun filter(query: String) { + filteredList = if (query.isBlank()) { + fullList.toMutableList() + } else { + fullList.filter { + it.name.contains(query, ignoreCase = true) + }.toMutableList() + } + notifyDataSetChanged() + } } diff --git a/app/src/main/java/partisan/weforge/xyz/pulse/ContactsFragment.kt b/app/src/main/java/partisan/weforge/xyz/pulse/ContactsFragment.kt index 2244501..370281d 100644 --- a/app/src/main/java/partisan/weforge/xyz/pulse/ContactsFragment.kt +++ b/app/src/main/java/partisan/weforge/xyz/pulse/ContactsFragment.kt @@ -6,6 +6,7 @@ import android.provider.ContactsContract import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.graphics.Color import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import partisan.weforge.xyz.pulse.databinding.FragmentContactsBinding @@ -47,15 +48,44 @@ class ContactsFragment : Fragment() { (requireActivity() as? MainActivity)?.setupPopupToggle(false) } + private lateinit var adapter: ContactAdapter override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) prefs = Preferences(requireContext()) val contacts = getContacts() - val adapter = ContactAdapter(prefs, contacts) + adapter = ContactAdapter(prefs, contacts) + binding.contactRecycler.layoutManager = LinearLayoutManager(requireContext()) binding.contactRecycler.adapter = adapter + + binding.contactSearch.setOnQueryTextListener(object : androidx.appcompat.widget.SearchView.OnQueryTextListener { + override fun onQueryTextSubmit(query: String?): Boolean = false + override fun onQueryTextChange(newText: String?): Boolean { + adapter.filter(newText ?: "") + return true + } + }) + + val searchView = binding.contactSearch + + searchView.setIconifiedByDefault(false) + searchView.isIconified = false + searchView.isSubmitButtonEnabled = false + searchView.clearFocus() + + val editText = searchView.findViewById( + androidx.appcompat.R.id.search_src_text + ) + editText.isFocusable = true + editText.isFocusableInTouchMode = true + editText.setTextColor(Color.WHITE) + editText.setHintTextColor(Color.LTGRAY) + + val searchPlate = searchView.findViewById(androidx.appcompat.R.id.search_plate) + searchPlate.setBackgroundColor(Color.TRANSPARENT) + searchPlate.setPadding(0, 0, 0, 0) } private fun getContacts(): List { diff --git a/app/src/main/res/drawable/search_background.xml b/app/src/main/res/drawable/search_background.xml new file mode 100644 index 0000000..89c2de3 --- /dev/null +++ b/app/src/main/res/drawable/search_background.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/layout/fragment_contacts.xml b/app/src/main/res/layout/fragment_contacts.xml index 057c3ff..f154b17 100644 --- a/app/src/main/res/layout/fragment_contacts.xml +++ b/app/src/main/res/layout/fragment_contacts.xml @@ -6,11 +6,25 @@ android:layout_height="match_parent" android:padding="16dp"> + + #000000 @color/colorPrimary + + #2B3542 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e5e8e6c..3de9eec 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -16,6 +16,7 @@ WhatsApp The delay before a call will be redirected. Here you can enable or disable redirection to individual services and change their priority by dragging them. Redirection will be handled in order from top to bottom. + Filter contacts Popup position To start, grant the required permissions by tapping the Activate button. Activate diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 1c43235..07f34f0 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -12,5 +12,6 @@ @color/black @style/TextAppearance.Material3.BodyMedium ?attr/colorSurfaceContainerLowest + @color/colorSurfaceVariant \ No newline at end of file