Added search for Contacts/Allowlist tab
This commit is contained in:
parent
6d9024a580
commit
6af51d8fc8
7 changed files with 72 additions and 5 deletions
|
@ -8,9 +8,11 @@ import androidx.recyclerview.widget.RecyclerView
|
||||||
|
|
||||||
class ContactAdapter(
|
class ContactAdapter(
|
||||||
private val prefs: Preferences,
|
private val prefs: Preferences,
|
||||||
private val contacts: List<ContactEntry>
|
private val fullList: List<ContactEntry>
|
||||||
) : RecyclerView.Adapter<ContactAdapter.ViewHolder>() {
|
) : RecyclerView.Adapter<ContactAdapter.ViewHolder>() {
|
||||||
|
|
||||||
|
private var filteredList = fullList.toMutableList()
|
||||||
|
|
||||||
inner class ViewHolder(inflater: LayoutInflater, parent: ViewGroup) :
|
inner class ViewHolder(inflater: LayoutInflater, parent: ViewGroup) :
|
||||||
RecyclerView.ViewHolder(inflater.inflate(R.layout.item_contact, parent, false)) {
|
RecyclerView.ViewHolder(inflater.inflate(R.layout.item_contact, parent, false)) {
|
||||||
val contactName: TextView = itemView.findViewById(R.id.contactName)
|
val contactName: TextView = itemView.findViewById(R.id.contactName)
|
||||||
|
@ -22,8 +24,9 @@ class ContactAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val contact = contacts[position]
|
val contact = filteredList[position]
|
||||||
holder.contactName.text = contact.name
|
holder.contactName.text = contact.name
|
||||||
|
holder.contactAllowed.setOnCheckedChangeListener(null)
|
||||||
holder.contactAllowed.isChecked = prefs.isContactWhitelisted(contact.phoneNumber)
|
holder.contactAllowed.isChecked = prefs.isContactWhitelisted(contact.phoneNumber)
|
||||||
|
|
||||||
holder.contactAllowed.setOnCheckedChangeListener { _, isChecked ->
|
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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.provider.ContactsContract
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.graphics.Color
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import partisan.weforge.xyz.pulse.databinding.FragmentContactsBinding
|
import partisan.weforge.xyz.pulse.databinding.FragmentContactsBinding
|
||||||
|
@ -47,15 +48,44 @@ class ContactsFragment : Fragment() {
|
||||||
(requireActivity() as? MainActivity)?.setupPopupToggle(false)
|
(requireActivity() as? MainActivity)?.setupPopupToggle(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private lateinit var adapter: ContactAdapter
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
prefs = Preferences(requireContext())
|
prefs = Preferences(requireContext())
|
||||||
|
|
||||||
val contacts = getContacts()
|
val contacts = getContacts()
|
||||||
val adapter = ContactAdapter(prefs, contacts)
|
adapter = ContactAdapter(prefs, contacts)
|
||||||
|
|
||||||
binding.contactRecycler.layoutManager = LinearLayoutManager(requireContext())
|
binding.contactRecycler.layoutManager = LinearLayoutManager(requireContext())
|
||||||
binding.contactRecycler.adapter = adapter
|
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.widget.SearchView.SearchAutoComplete>(
|
||||||
|
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<View>(androidx.appcompat.R.id.search_plate)
|
||||||
|
searchPlate.setBackgroundColor(Color.TRANSPARENT)
|
||||||
|
searchPlate.setPadding(0, 0, 0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getContacts(): List<ContactEntry> {
|
private fun getContacts(): List<ContactEntry> {
|
||||||
|
|
5
app/src/main/res/drawable/search_background.xml
Normal file
5
app/src/main/res/drawable/search_background.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="?attr/colorSurfaceVariant" />
|
||||||
|
<corners android:radius="50dp" />
|
||||||
|
</shape>
|
|
@ -6,11 +6,25 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:padding="16dp">
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.SearchView
|
||||||
|
android:id="@+id/contactSearch"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:background="@drawable/search_background"
|
||||||
|
android:iconifiedByDefault="false"
|
||||||
|
android:queryHint="@string/contact_search"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginHorizontal="4dp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/contactRecycler"
|
android:id="@+id/contactRecycler"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toBottomOf="@id/contactSearch"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
|
|
@ -14,4 +14,6 @@
|
||||||
<color name="colorOnSecondary">#000000</color>
|
<color name="colorOnSecondary">#000000</color>
|
||||||
|
|
||||||
<color name="launcher_background">@color/colorPrimary</color>
|
<color name="launcher_background">@color/colorPrimary</color>
|
||||||
|
|
||||||
|
<color name="colorSurfaceVariant">#2B3542</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
<string name="destination_whatsapp">WhatsApp</string>
|
<string name="destination_whatsapp">WhatsApp</string>
|
||||||
<string name="redirection_delay_description">The delay before a call will be redirected.</string>
|
<string name="redirection_delay_description">The delay before a call will be redirected.</string>
|
||||||
<string name="services_desc">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.</string>
|
<string name="services_desc">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.</string>
|
||||||
|
<string name="contact_search">Filter contacts</string>
|
||||||
<string name="popup_position">Popup position</string>
|
<string name="popup_position">Popup position</string>
|
||||||
<string name="activate_description">To start, grant the required permissions by tapping the Activate button.</string>
|
<string name="activate_description">To start, grant the required permissions by tapping the Activate button.</string>
|
||||||
<string name="activate">Activate</string>
|
<string name="activate">Activate</string>
|
||||||
|
|
|
@ -12,5 +12,6 @@
|
||||||
<item name="colorOnSurface">@color/black</item>
|
<item name="colorOnSurface">@color/black</item>
|
||||||
<item name="textAppearanceBodyMedium">@style/TextAppearance.Material3.BodyMedium</item>
|
<item name="textAppearanceBodyMedium">@style/TextAppearance.Material3.BodyMedium</item>
|
||||||
<item name="colorSurfaceContainerLowest">?attr/colorSurfaceContainerLowest</item>
|
<item name="colorSurfaceContainerLowest">?attr/colorSurfaceContainerLowest</item>
|
||||||
|
<item name="colorSurfaceVariant">@color/colorSurfaceVariant</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
Loading…
Add table
Add a link
Reference in a new issue