From f5bdaf85fdc25dcf0290e7a1284fb9a493a6e0b6 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 8 Apr 2024 16:17:22 +0200 Subject: [PATCH] Improved contacts display, fixed issue with LDAP results --- .../org/linphone/contacts/ContactsManager.kt | 2 +- .../main/contacts/fragment/ContactFragment.kt | 2 +- .../contacts/fragment/ContactsListFragment.kt | 4 +- .../ContactsListMenuDialogFragment.kt | 2 + .../main/contacts/model/ContactAvatarModel.kt | 4 +- .../contacts/viewmodel/ContactViewModel.kt | 31 +++- .../viewmodel/ContactsListViewModel.kt | 4 + .../main/settings/viewmodel/LdapViewModel.kt | 2 + .../ui/main/viewmodel/SharedMainViewModel.kt | 2 + app/src/main/res/layout/contact_fragment.xml | 165 +++++++++--------- .../layout/contacts_list_long_press_menu.xml | 9 +- app/src/main/res/values-fr/strings.xml | 6 +- app/src/main/res/values/strings.xml | 8 +- 13 files changed, 141 insertions(+), 100 deletions(-) diff --git a/app/src/main/java/org/linphone/contacts/ContactsManager.kt b/app/src/main/java/org/linphone/contacts/ContactsManager.kt index 60a532450..610ef5d5d 100644 --- a/app/src/main/java/org/linphone/contacts/ContactsManager.kt +++ b/app/src/main/java/org/linphone/contacts/ContactsManager.kt @@ -274,7 +274,7 @@ class ContactsManager @UiThread constructor() { return found } } - Log.d("$TAG No friend matching ref key [$id] has been found") + Log.w("$TAG No friend matching ref key [$id] has been found") return null } diff --git a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactFragment.kt b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactFragment.kt index 3fa175150..84c8377f0 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactFragment.kt @@ -98,7 +98,7 @@ class ContactFragment : SlidingPaneChildFragment() { val refKey = args.contactRefKey Log.i("$TAG Looking up for contact with ref key [$refKey]") - viewModel.findContactByRefKey(refKey) + viewModel.findContact(sharedViewModel.displayedFriend, refKey) binding.setBackClickListener { goBack() diff --git a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsListFragment.kt b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsListFragment.kt index 4e5188f0b..1180909d0 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsListFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsListFragment.kt @@ -206,6 +206,7 @@ class ContactsListFragment : AbstractTopBarFragment() { it.consume { model -> val modalBottomSheet = ContactsListMenuDialogFragment( model.isFavourite.value == true, + model.isStored, { // onDismiss adapter.resetSelection() }, @@ -244,7 +245,8 @@ class ContactsListFragment : AbstractTopBarFragment() { adapter.contactClickedEvent.observe(viewLifecycleOwner) { it.consume { model -> - sharedViewModel.showContactEvent.value = Event(model.id ?: "") + sharedViewModel.displayedFriend = model.friend + sharedViewModel.showContactEvent.value = Event(model.id) } } } diff --git a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsListMenuDialogFragment.kt b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsListMenuDialogFragment.kt index 7994ec44f..15ab357c3 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsListMenuDialogFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsListMenuDialogFragment.kt @@ -34,6 +34,7 @@ import org.linphone.databinding.ContactsListLongPressMenuBinding @UiThread class ContactsListMenuDialogFragment( private val isFavourite: Boolean, + private val isStored: Boolean, private val onDismiss: (() -> Unit)? = null, private val onFavourite: (() -> Unit)? = null, private val onShare: (() -> Unit)? = null, @@ -68,6 +69,7 @@ class ContactsListMenuDialogFragment( ): View { val view = ContactsListLongPressMenuBinding.inflate(layoutInflater) view.isFavourite = isFavourite + view.isStored = isStored view.setFavoriteClickListener { onFavourite?.invoke() diff --git a/app/src/main/java/org/linphone/ui/main/contacts/model/ContactAvatarModel.kt b/app/src/main/java/org/linphone/ui/main/contacts/model/ContactAvatarModel.kt index 39f6c1ece..a142a10f3 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/model/ContactAvatarModel.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/model/ContactAvatarModel.kt @@ -40,10 +40,12 @@ class ContactAvatarModel @WorkerThread constructor(val friend: Friend, val addre private const val TAG = "[Contact Avatar Model]" } - val id = friend.refKey ?: friend.name + val id = friend.refKey ?: friend.name ?: "" val contactName = friend.name + val isStored = friend.inList() + val isFavourite = MutableLiveData() val lastPresenceInfo = MutableLiveData() diff --git a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactViewModel.kt b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactViewModel.kt index c5d8ec5d7..0d2c730e6 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactViewModel.kt @@ -84,6 +84,8 @@ class ContactViewModel @UiThread constructor() : ViewModel() { val contactFoundEvent = MutableLiveData>() + val isStored = MutableLiveData() + val chatDisabled = MutableLiveData() val videoCallDisabled = MutableLiveData() @@ -229,6 +231,7 @@ class ContactViewModel @UiThread constructor() : ViewModel() { private var refKey: String = "" init { + isStored.value = false expandNumbersAndAddresses.value = true trustedDevicesPercentage.value = 0 @@ -255,14 +258,33 @@ class ContactViewModel @UiThread constructor() : ViewModel() { } @UiThread - fun findContactByRefKey(refKey: String) { + fun findContact(displayedFriend: Friend?, refKey: String) { this.refKey = refKey coreContext.postOnCoreThread { - val friend = coreContext.contactsManager.findContactById(refKey) - if (friend != null) { + if (displayedFriend != null && ::friend.isInitialized && friend == displayedFriend) { + Log.i("$TAG Contact object already in memory, skipping") + + refreshContactInfo() + contactFoundEvent.postValue(Event(true)) + return@postOnCoreThread + } + + if (displayedFriend != null && (!::friend.isInitialized || friend != displayedFriend)) { + if (displayedFriend.refKey == refKey) { + friend = displayedFriend + Log.i("$TAG Friend object available in sharedViewModel, using it") + + refreshContactInfo() + contactFoundEvent.postValue(Event(true)) + return@postOnCoreThread + } + } + + val found = coreContext.contactsManager.findContactById(refKey) + if (found != null) { + friend = found Log.i("$TAG Found contact [${friend.name}] matching ref key [$refKey]") - this.friend = friend refreshContactInfo() contactFoundEvent.postValue(Event(true)) @@ -273,6 +295,7 @@ class ContactViewModel @UiThread constructor() : ViewModel() { @WorkerThread fun refreshContactInfo() { isFavourite.postValue(friend.starred) + isStored.postValue(friend.inList()) contact.value?.destroy() contact.postValue(ContactAvatarModel(friend)) diff --git a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactsListViewModel.kt b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactsListViewModel.kt index bb56380b7..b03dda4e7 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactsListViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactsListViewModel.kt @@ -237,6 +237,10 @@ class ContactsListViewModel @UiThread constructor() : AbstractTopBarViewModel() for (result in results) { val friend = result.friend + if (friend != null && result.sourceFlags == MagicSearch.Source.LdapServers.toInt()) { + // TODO FIXME: Fix issue in SDK, each LDAP friend should have a proper refKey + friend.refKey = friend.name + } val model = if (friend != null) { coreContext.contactsManager.getContactAvatarModelForFriend(friend) diff --git a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/LdapViewModel.kt b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/LdapViewModel.kt index 9c6f1eff0..668e83842 100644 --- a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/LdapViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/LdapViewModel.kt @@ -79,6 +79,8 @@ class LdapViewModel : ViewModel() { useTls.value = true minCharacters.value = "3" + requestTimeout.value = "5" + requestDelay.value = "2000" } @UiThread diff --git a/app/src/main/java/org/linphone/ui/main/viewmodel/SharedMainViewModel.kt b/app/src/main/java/org/linphone/ui/main/viewmodel/SharedMainViewModel.kt index 9be6c3cb6..0b77aee72 100644 --- a/app/src/main/java/org/linphone/ui/main/viewmodel/SharedMainViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/viewmodel/SharedMainViewModel.kt @@ -25,6 +25,7 @@ import androidx.annotation.UiThread import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import org.linphone.core.ChatRoom +import org.linphone.core.Friend import org.linphone.ui.main.chat.model.MessageModel import org.linphone.utils.Event @@ -75,6 +76,7 @@ class SharedMainViewModel @UiThread constructor() : ViewModel() { /* Contacts related */ + var displayedFriend: Friend? = null // Prevents the need to go look for the friend val showContactEvent: MutableLiveData> by lazy { MutableLiveData>() } diff --git a/app/src/main/res/layout/contact_fragment.xml b/app/src/main/res/layout/contact_fragment.xml index 8d1396e88..307539c49 100644 --- a/app/src/main/res/layout/contact_fragment.xml +++ b/app/src/main/res/layout/contact_fragment.xml @@ -64,6 +64,7 @@ android:padding="15dp" android:adjustViewBounds="true" android:src="@drawable/pencil_simple" + android:visibility="@{viewModel.isStored ? View.VISIBLE : View.GONE}" app:tint="?attr/color_main1_500" app:layout_constraintBottom_toBottomOf="@id/invisible_title" app:layout_constraintEnd_toEndOf="parent" @@ -475,99 +476,97 @@ android:layout_height="0dp" android:layout_marginTop="8dp" android:layout_marginStart="16dp" + android:layout_marginBottom="@dimen/screen_bottom_margin" android:layout_marginEnd="16dp" - android:src="@drawable/shape_squircle_white_background" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/actions" - app:layout_constraintBottom_toBottomOf="@id/action_delete" /> + app:layout_constraintBottom_toBottomOf="parent" /> - - - - - - - - - - - - - + android:paddingBottom="8dp" + android:paddingTop="8dp" + android:background="@drawable/shape_squircle_white_background" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toBottomOf="@id/actions" + app:layout_constraintBottom_toBottomOf="parent"> + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/contacts_list_long_press_menu.xml b/app/src/main/res/layout/contacts_list_long_press_menu.xml index abc029793..f79e52c4b 100644 --- a/app/src/main/res/layout/contacts_list_long_press_menu.xml +++ b/app/src/main/res/layout/contacts_list_long_press_menu.xml @@ -19,6 +19,9 @@ + Base de recherche (ne peut être vide) Filtre Nombre de résultats maximum - Durée maximum - Délai entre 2 requêtes (en secondes) - Nombre minimum de caractères pour lancer la requête (en millisecondes) + Durée maximum (en secondes) + Délai entre 2 requêtes (en millisecondes) + Nombre minimum de caractères pour lancer la requête Attributs de nom Attributs SIP Domaine SIP diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b0de6217d..a2d9dbb98 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -269,10 +269,10 @@ Use TLS Search Search base (can\'t be empty) - Filter - Max results - Timeout (in seconds) - Delay between two requests (in milliseconds) + Max results + Timeout (in seconds) + Delay between two queries (in milliseconds) + Min characters to start a query Name attributes SIP attributes SIP domain