Improved contacts list search field
This commit is contained in:
parent
7e81f775c3
commit
339e30a75e
10 changed files with 86 additions and 108 deletions
|
@ -23,7 +23,6 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.SearchView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
|
@ -122,6 +121,10 @@ class ChatRoomCreationFragment : Fragment() {
|
|||
}
|
||||
})
|
||||
|
||||
viewModel.filter.observe(viewLifecycleOwner, Observer {
|
||||
viewModel.applyFilter()
|
||||
})
|
||||
|
||||
adapter.selectedContact.observe(viewLifecycleOwner, Observer {
|
||||
it.consume { searchResult ->
|
||||
if (createGroup) {
|
||||
|
@ -145,17 +148,6 @@ class ChatRoomCreationFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
binding.searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
viewModel.filter(newText ?: "")
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.onErrorEvent.observe(viewLifecycleOwner, Observer {
|
||||
it.consume { messageResourceId ->
|
||||
(activity as MainActivity).showSnackBar(messageResourceId)
|
||||
|
|
|
@ -47,9 +47,10 @@ class ChatRoomCreationViewModel : ErrorReportingViewModel() {
|
|||
|
||||
val selectedAddresses = MutableLiveData<ArrayList<Address>>()
|
||||
|
||||
val limeAvailable: Boolean = LinphoneUtils.isLimeAvailable()
|
||||
val filter = MutableLiveData<String>()
|
||||
var previousFilter = ""
|
||||
|
||||
private var filter: String = ""
|
||||
val limeAvailable: Boolean = LinphoneUtils.isLimeAvailable()
|
||||
|
||||
private val contactsUpdatedListener = object : ContactsUpdatedListenerStub() {
|
||||
override fun onContactsUpdated() {
|
||||
|
@ -95,18 +96,19 @@ class ChatRoomCreationViewModel : ErrorReportingViewModel() {
|
|||
isEncrypted.value = encrypted
|
||||
}
|
||||
|
||||
fun filter(search: String) {
|
||||
if (filter.isNotEmpty() && filter.length > search.length) {
|
||||
fun applyFilter() {
|
||||
val filterValue = filter.value.orEmpty()
|
||||
if (previousFilter.isNotEmpty() && previousFilter.length > filterValue.length) {
|
||||
coreContext.contactsManager.magicSearch.resetSearchCache()
|
||||
}
|
||||
filter = search
|
||||
previousFilter = filterValue
|
||||
|
||||
updateContactsList()
|
||||
}
|
||||
|
||||
fun updateContactsList() {
|
||||
val domain = if (sipContactsSelected.value == true) coreContext.core.defaultProxyConfig?.domain ?: "" else ""
|
||||
val results = coreContext.contactsManager.magicSearch.getContactListFromFilter(filter, domain)
|
||||
val results = coreContext.contactsManager.magicSearch.getContactListFromFilter(filter.value.orEmpty(), domain)
|
||||
|
||||
val list = arrayListOf<SearchResult>()
|
||||
for (result in results) {
|
||||
|
|
|
@ -24,7 +24,6 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.SearchView
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
|
@ -104,6 +103,7 @@ class MasterContactsFragment : MasterFragment() {
|
|||
it.consume { contact ->
|
||||
Log.i("[Contacts] Selected item in list changed: $contact")
|
||||
sharedViewModel.selectedContact.value = contact
|
||||
listViewModel.filter.value = ""
|
||||
|
||||
if (editOnClick) {
|
||||
goToContactEditor()
|
||||
|
@ -130,23 +130,16 @@ class MasterContactsFragment : MasterFragment() {
|
|||
listViewModel.updateContactsList()
|
||||
})
|
||||
|
||||
listViewModel.filter.observe(viewLifecycleOwner, Observer {
|
||||
listViewModel.updateContactsList()
|
||||
})
|
||||
|
||||
binding.setNewContactClickListener {
|
||||
// Remove any previously selected contact
|
||||
sharedViewModel.selectedContact.value = null
|
||||
goToContactEditor()
|
||||
}
|
||||
|
||||
binding.searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
listViewModel.filter(newText ?: "")
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
||||
val id = arguments?.getString("id")
|
||||
if (id != null) {
|
||||
Log.i("[Contacts] Found contact id parameter in arguments: $id")
|
||||
|
|
|
@ -35,7 +35,7 @@ class ContactsListViewModel : ViewModel() {
|
|||
|
||||
val contactsList = MutableLiveData<ArrayList<Contact>>()
|
||||
|
||||
private var filter: String = ""
|
||||
val filter = MutableLiveData<String>()
|
||||
|
||||
private val contactsUpdatedListener = object : ContactsUpdatedListenerStub() {
|
||||
override fun onContactsUpdated() {
|
||||
|
@ -46,7 +46,6 @@ class ContactsListViewModel : ViewModel() {
|
|||
|
||||
init {
|
||||
sipContactsSelected.value = true
|
||||
filter = ""
|
||||
|
||||
coreContext.contactsManager.addListener(contactsUpdatedListener)
|
||||
}
|
||||
|
@ -61,10 +60,10 @@ class ContactsListViewModel : ViewModel() {
|
|||
var list = arrayListOf<Contact>()
|
||||
list.addAll(if (sipContactsSelected.value == true) coreContext.contactsManager.sipContacts else coreContext.contactsManager.contacts)
|
||||
|
||||
if (filter.isNotEmpty()) {
|
||||
val filter = filter.toLowerCase(Locale.getDefault())
|
||||
val filterValue = filter.value.orEmpty().toLowerCase(Locale.getDefault())
|
||||
if (filterValue.isNotEmpty()) {
|
||||
list = list.filter { contact ->
|
||||
contact.fullName?.toLowerCase(Locale.getDefault())?.contains(filter) ?: false
|
||||
contact.fullName?.toLowerCase(Locale.getDefault())?.contains(filterValue) ?: false
|
||||
} as ArrayList<Contact>
|
||||
}
|
||||
|
||||
|
@ -74,11 +73,6 @@ class ContactsListViewModel : ViewModel() {
|
|||
}
|
||||
}
|
||||
|
||||
fun filter(search: String) {
|
||||
filter = search
|
||||
updateContactsList()
|
||||
}
|
||||
|
||||
fun deleteContacts(list: ArrayList<Contact>) {
|
||||
val select = ContactsContract.Data.CONTACT_ID + " = ?"
|
||||
val ops = ArrayList<ContentProviderOperation>()
|
||||
|
|
|
@ -92,6 +92,7 @@ class DialerViewModel : ViewModel() {
|
|||
val addressToCall = enteredUri.value.orEmpty()
|
||||
if (addressToCall.isNotEmpty()) {
|
||||
coreContext.startCall(addressToCall)
|
||||
eraseAll()
|
||||
} else {
|
||||
setLastOutgoingCallAddress()
|
||||
}
|
||||
|
@ -101,6 +102,7 @@ class DialerViewModel : ViewModel() {
|
|||
val addressToCall = enteredUri.value.orEmpty()
|
||||
if (addressToCall.isNotEmpty()) {
|
||||
coreContext.transferCallTo(addressToCall)
|
||||
eraseAll()
|
||||
} else {
|
||||
setLastOutgoingCallAddress()
|
||||
}
|
||||
|
|
|
@ -440,3 +440,29 @@ fun setEditTextErrorListener(editText: EditText, attrChange: InverseBindingListe
|
|||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { }
|
||||
})
|
||||
}
|
||||
|
||||
@BindingAdapter("queryValue")
|
||||
fun setSearchViewQuery(view: SearchView, query: String?) {
|
||||
if (query != view.query) {
|
||||
view.setQuery(query, false)
|
||||
}
|
||||
}
|
||||
|
||||
@InverseBindingAdapter(attribute = "queryValue")
|
||||
fun getSearchViewQuery(view: SearchView): String? {
|
||||
return view.query?.toString()
|
||||
}
|
||||
|
||||
@BindingAdapter("queryValueAttrChanged")
|
||||
fun setSearchViewQueryListener(view: SearchView, attrChange: InverseBindingListener) {
|
||||
view.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
attrChange.onChange()
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -127,27 +127,19 @@
|
|||
android:layout_alignTop="@id/top_bar"
|
||||
tools:layout="@layout/list_edit_top_bar_fragment" />
|
||||
|
||||
<RelativeLayout
|
||||
<SearchView
|
||||
android:id="@+id/searchBar"
|
||||
queryValue="@={viewModel.filter}"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:focusableInTouchMode="true"
|
||||
android:layout_height="40dp"
|
||||
android:gravity="center"
|
||||
android:iconifiedByDefault="false"
|
||||
android:inputType="textPersonName"
|
||||
android:layout_below="@id/top_bar"
|
||||
android:layout_toRightOf="@id/tabs_fragment"
|
||||
android:layout_margin="10dp">
|
||||
|
||||
<SearchView
|
||||
android:id="@+id/searchView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:gravity="center"
|
||||
android:iconifiedByDefault="false"
|
||||
android:inputType="textPersonName"
|
||||
android:paddingRight="5dp"
|
||||
android:queryBackground="@color/transparent_color"
|
||||
android:queryHint="@string/contact_filter_hint"/>
|
||||
|
||||
</RelativeLayout>
|
||||
android:layout_margin="10dp"
|
||||
android:queryBackground="@color/transparent_color"
|
||||
android:queryHint="@string/contact_filter_hint"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/contactsList"
|
||||
|
|
|
@ -137,26 +137,18 @@
|
|||
android:layout_alignTop="@id/top_bar"
|
||||
tools:layout="@layout/list_edit_top_bar_fragment" />
|
||||
|
||||
<RelativeLayout
|
||||
<SearchView
|
||||
android:id="@+id/searchBar"
|
||||
queryValue="@={viewModel.filter}"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:focusableInTouchMode="true"
|
||||
android:layout_height="40dp"
|
||||
android:gravity="center"
|
||||
android:iconifiedByDefault="false"
|
||||
android:inputType="textPersonName"
|
||||
android:layout_below="@id/top_bar"
|
||||
android:layout_margin="10dp">
|
||||
|
||||
<SearchView
|
||||
android:id="@+id/searchView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:gravity="center"
|
||||
android:iconifiedByDefault="false"
|
||||
android:inputType="textPersonName"
|
||||
android:paddingRight="5dp"
|
||||
android:queryBackground="@color/transparent_color"
|
||||
android:queryHint="@string/contact_filter_hint"/>
|
||||
|
||||
</RelativeLayout>
|
||||
android:layout_margin="10dp"
|
||||
android:queryBackground="@color/transparent_color"
|
||||
android:queryHint="@string/contact_filter_hint"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/contactsList"
|
||||
|
|
|
@ -148,26 +148,19 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
<SearchView
|
||||
android:id="@+id/searchBar"
|
||||
queryValue="@={viewModel.filter}"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:focusableInTouchMode="true"
|
||||
android:layout_height="40dp"
|
||||
android:gravity="center"
|
||||
android:iconifiedByDefault="false"
|
||||
android:inputType="textPersonName"
|
||||
android:layout_below="@id/top_bar"
|
||||
android:layout_margin="10dp">
|
||||
|
||||
<SearchView
|
||||
android:id="@+id/searchView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:gravity="center"
|
||||
android:iconifiedByDefault="false"
|
||||
android:inputType="textPersonName"
|
||||
android:paddingRight="5dp"
|
||||
android:queryBackground="@color/transparent_color"
|
||||
android:queryHint="@string/contact_filter_hint"/>
|
||||
|
||||
</RelativeLayout>
|
||||
android:layout_margin="10dp"
|
||||
android:paddingRight="5dp"
|
||||
android:queryBackground="@color/transparent_color"
|
||||
android:queryHint="@string/contact_filter_hint"/>
|
||||
|
||||
<HorizontalScrollView
|
||||
android:visibility="@{viewModel.createGroupChat ? View.VISIBLE : View.GONE}"
|
||||
|
|
|
@ -126,26 +126,18 @@
|
|||
android:layout_alignTop="@id/top_bar"
|
||||
tools:layout="@layout/list_edit_top_bar_fragment" />
|
||||
|
||||
<RelativeLayout
|
||||
<SearchView
|
||||
android:id="@+id/searchBar"
|
||||
queryValue="@={viewModel.filter}"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:focusableInTouchMode="true"
|
||||
android:layout_height="40dp"
|
||||
android:layout_below="@id/top_bar"
|
||||
android:layout_margin="10dp">
|
||||
|
||||
<SearchView
|
||||
android:id="@+id/searchView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:gravity="center"
|
||||
android:iconifiedByDefault="false"
|
||||
android:inputType="textPersonName"
|
||||
android:paddingRight="5dp"
|
||||
android:queryBackground="@color/transparent_color"
|
||||
android:queryHint="@string/contact_filter_hint"/>
|
||||
|
||||
</RelativeLayout>
|
||||
android:layout_margin="10dp"
|
||||
android:gravity="center"
|
||||
android:iconifiedByDefault="false"
|
||||
android:inputType="textPersonName"
|
||||
android:queryBackground="@color/transparent_color"
|
||||
android:queryHint="@string/contact_filter_hint"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/contactsList"
|
||||
|
|
Loading…
Reference in a new issue