Fixed ContactsSelectionViewModel used for chat room & conferences participant selection to use same MagicSearch APIs

This commit is contained in:
Sylvain Berfini 2022-03-11 15:42:23 +01:00
parent 2df68f8cf2
commit 71a2140dbd
5 changed files with 60 additions and 19 deletions

View file

@ -107,7 +107,7 @@ class ChatRoomCreationFragment : SecureFragment<ChatRoomCreationFragmentBinding>
viewModel.sipContactsSelected.observe( viewModel.sipContactsSelected.observe(
viewLifecycleOwner viewLifecycleOwner
) { ) {
viewModel.updateContactsList() viewModel.applyFilter()
} }
viewModel.selectedAddresses.observe( viewModel.selectedAddresses.observe(

View file

@ -74,7 +74,7 @@ class ConferenceSchedulingParticipantsListFragment : GenericFragment<ConferenceS
viewModel.sipContactsSelected.observe( viewModel.sipContactsSelected.observe(
viewLifecycleOwner viewLifecycleOwner
) { ) {
viewModel.updateContactsList() viewModel.applyFilter()
} }
viewModel.selectedAddresses.observe( viewModel.selectedAddresses.observe(

View file

@ -86,7 +86,7 @@ class ConferenceAddParticipantsFragment : GenericFragment<VoipConferenceParticip
viewModel.sipContactsSelected.observe( viewModel.sipContactsSelected.observe(
viewLifecycleOwner viewLifecycleOwner
) { ) {
viewModel.updateContactsList() viewModel.applyFilter()
} }
viewModel.selectedAddresses.observe( viewModel.selectedAddresses.observe(

View file

@ -20,11 +20,14 @@
package org.linphone.contact package org.linphone.contact
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.*
import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.activities.main.viewmodels.MessageNotifierViewModel import org.linphone.activities.main.viewmodels.MessageNotifierViewModel
import org.linphone.core.Address import org.linphone.core.*
import org.linphone.core.SearchResult
import org.linphone.core.tools.Log import org.linphone.core.tools.Log
import org.linphone.utils.Event
open class ContactsSelectionViewModel : MessageNotifierViewModel() { open class ContactsSelectionViewModel : MessageNotifierViewModel() {
val contactsList = MutableLiveData<ArrayList<SearchResult>>() val contactsList = MutableLiveData<ArrayList<SearchResult>>()
@ -34,12 +37,32 @@ open class ContactsSelectionViewModel : MessageNotifierViewModel() {
val selectedAddresses = MutableLiveData<ArrayList<Address>>() val selectedAddresses = MutableLiveData<ArrayList<Address>>()
val filter = MutableLiveData<String>() val filter = MutableLiveData<String>()
private var previousFilter = "" private var previousFilter = "NotSet"
val fetchInProgress = MutableLiveData<Boolean>()
private var searchResultsPending: Boolean = false
private var fastFetchJob: Job? = null
val moreResultsAvailableEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}
private val contactsUpdatedListener = object : ContactsUpdatedListenerStub() { private val contactsUpdatedListener = object : ContactsUpdatedListenerStub() {
override fun onContactsUpdated() { override fun onContactsUpdated() {
Log.i("[Contacts Selection] Contacts have changed") Log.i("[Contacts Selection] Contacts have changed")
updateContactsList() applyFilter()
}
}
private val magicSearchListener = object : MagicSearchListenerStub() {
override fun onSearchResultsReceived(magicSearch: MagicSearch) {
searchResultsPending = false
processMagicSearchResults(magicSearch.lastSearch)
fetchInProgress.value = false
}
override fun onLdapHaveMoreResults(magicSearch: MagicSearch, ldap: Ldap) {
moreResultsAvailableEvent.value = Event(true)
} }
} }
@ -49,9 +72,11 @@ open class ContactsSelectionViewModel : MessageNotifierViewModel() {
selectedAddresses.value = arrayListOf() selectedAddresses.value = arrayListOf()
coreContext.contactsManager.addListener(contactsUpdatedListener) coreContext.contactsManager.addListener(contactsUpdatedListener)
coreContext.contactsManager.magicSearch.addListener(magicSearchListener)
} }
override fun onCleared() { override fun onCleared() {
coreContext.contactsManager.magicSearch.removeListener(magicSearchListener)
coreContext.contactsManager.removeListener(contactsUpdatedListener) coreContext.contactsManager.removeListener(contactsUpdatedListener)
super.onCleared() super.onCleared()
@ -59,25 +84,32 @@ open class ContactsSelectionViewModel : MessageNotifierViewModel() {
fun applyFilter() { fun applyFilter() {
val filterValue = filter.value.orEmpty() val filterValue = filter.value.orEmpty()
if (previousFilter == filterValue) return
if (previousFilter.isNotEmpty() && previousFilter.length > filterValue.length) { if (previousFilter.isNotEmpty() && (
previousFilter.length > filterValue.length ||
(previousFilter.length == filterValue.length && previousFilter != filterValue)
)
) {
coreContext.contactsManager.magicSearch.resetSearchCache() coreContext.contactsManager.magicSearch.resetSearchCache()
} }
previousFilter = filterValue previousFilter = filterValue
updateContactsList()
}
fun updateContactsList() {
val domain = if (sipContactsSelected.value == true) coreContext.core.defaultAccount?.params?.domain ?: "" else "" val domain = if (sipContactsSelected.value == true) coreContext.core.defaultAccount?.params?.domain ?: "" else ""
val results = coreContext.contactsManager.magicSearch.getContactListFromFilter(filter.value.orEmpty(), domain) searchResultsPending = true
fastFetchJob?.cancel()
coreContext.contactsManager.magicSearch.getContactsAsync(filter.value.orEmpty(), domain, MagicSearchSource.All.toInt())
val list = arrayListOf<SearchResult>() val spinnerDelay = corePreferences.delayBeforeShowingContactsSearchSpinner.toLong()
for (result in results) { fastFetchJob = viewModelScope.launch {
list.add(result) withContext(Dispatchers.IO) {
delay(spinnerDelay)
withContext(Dispatchers.Main) {
if (searchResultsPending) {
fetchInProgress.value = true
}
}
}
} }
contactsList.value = list
} }
fun toggleSelectionForSearchResult(searchResult: SearchResult) { fun toggleSelectionForSearchResult(searchResult: SearchResult) {
@ -110,4 +142,13 @@ open class ContactsSelectionViewModel : MessageNotifierViewModel() {
selectedAddresses.value = list selectedAddresses.value = list
} }
private fun processMagicSearchResults(results: Array<SearchResult>) {
Log.i("[Contacts Selection] Processing ${results.size} results")
val list = arrayListOf<SearchResult>()
for (result in results) {
list.add(result)
}
contactsList.postValue(list)
}
} }

View file

@ -216,7 +216,7 @@
<include <include
layout="@layout/wait_layout" layout="@layout/wait_layout"
bind:visibility="@{viewModel.waitForChatRoomCreation}"/> bind:visibility="@{viewModel.waitForChatRoomCreation || viewModel.fetchInProgress}"/>
</RelativeLayout> </RelativeLayout>