Use read-only information from FriendList if any to hide edit/delete/mark as favortie buttons in contact details & contacts list long press menu

This commit is contained in:
Sylvain Berfini 2025-06-30 13:40:50 +02:00
parent ff425089c7
commit aa0255bcfd
8 changed files with 43 additions and 24 deletions

View file

@ -243,6 +243,7 @@ class ContactsListFragment : AbstractMainFragment() {
val modalBottomSheet = ContactsListMenuDialogFragment( val modalBottomSheet = ContactsListMenuDialogFragment(
model.isFavourite.value == true, model.isFavourite.value == true,
model.isStored, model.isStored,
isReadOnly = model.isReadOnly,
{ // onDismiss { // onDismiss
adapter.resetSelection() adapter.resetSelection()
}, },

View file

@ -35,6 +35,7 @@ import org.linphone.databinding.ContactsListLongPressMenuBinding
class ContactsListMenuDialogFragment( class ContactsListMenuDialogFragment(
private val isFavourite: Boolean, private val isFavourite: Boolean,
private val isStored: Boolean, private val isStored: Boolean,
private val isReadOnly: Boolean,
private val onDismiss: (() -> Unit)? = null, private val onDismiss: (() -> Unit)? = null,
private val onFavourite: (() -> Unit)? = null, private val onFavourite: (() -> Unit)? = null,
private val onShare: (() -> Unit)? = null, private val onShare: (() -> Unit)? = null,
@ -70,6 +71,7 @@ class ContactsListMenuDialogFragment(
val view = ContactsListLongPressMenuBinding.inflate(layoutInflater) val view = ContactsListLongPressMenuBinding.inflate(layoutInflater)
view.isFavourite = isFavourite view.isFavourite = isFavourite
view.isStored = isStored view.isStored = isStored
view.isReadOnly = isReadOnly
view.setFavoriteClickListener { view.setFavoriteClickListener {
onFavourite?.invoke() onFavourite?.invoke()

View file

@ -51,6 +51,8 @@ class ContactAvatarModel
val isStored = friend.inList() val isStored = friend.inList()
val isReadOnly = friend.isReadOnly
val isFavourite = MutableLiveData<Boolean>() val isFavourite = MutableLiveData<Boolean>()
val lastPresenceInfo = MutableLiveData<String>() val lastPresenceInfo = MutableLiveData<String>()

View file

@ -152,14 +152,14 @@ class ContactNewOrEditViewModel
} }
val name = if (fn.isNotEmpty() && ln.isNotEmpty()) { val name = if (fn.isNotEmpty() && ln.isNotEmpty()) {
"$fn $ln" "$fn $ln"
} else if (fn.isNotEmpty()) {
fn
} else if (ln.isNotEmpty()) {
ln
} else if (organization.isNotEmpty()) {
organization
} else { } else {
"<Unknown>" fn.ifEmpty {
ln.ifEmpty {
organization.ifEmpty {
"<Unknown>"
}
}
}
} }
friend.edit() friend.edit()

View file

@ -91,6 +91,8 @@ class ContactViewModel
val isStored = MutableLiveData<Boolean>() val isStored = MutableLiveData<Boolean>()
val isReadOnly = MutableLiveData<Boolean>()
val chatDisabled = MutableLiveData<Boolean>() val chatDisabled = MutableLiveData<Boolean>()
val videoCallDisabled = MutableLiveData<Boolean>() val videoCallDisabled = MutableLiveData<Boolean>()
@ -237,6 +239,7 @@ class ContactViewModel
init { init {
isStored.value = false isStored.value = false
isReadOnly.value = false
expandNumbersAndAddresses.value = true expandNumbersAndAddresses.value = true
trustedDevicesPercentage.value = 0 trustedDevicesPercentage.value = 0
@ -312,6 +315,7 @@ class ContactViewModel
// Do not show edit contact button for contacts not stored in a FriendList or // Do not show edit contact button for contacts not stored in a FriendList or
// if they are in a temporary one (for example if they are from a remote directory such as LDAP or CardDAV) // if they are in a temporary one (for example if they are from a remote directory such as LDAP or CardDAV)
isStored.postValue(!coreContext.contactsManager.isContactTemporary(friend)) isStored.postValue(!coreContext.contactsManager.isContactTemporary(friend))
isReadOnly.postValue(friend.isReadOnly)
contact.value?.destroy() contact.value?.destroy()
contact.postValue(ContactAvatarModel(friend)) contact.postValue(ContactAvatarModel(friend))

View file

@ -83,6 +83,19 @@ class CardDavViewModel
syncInProgress.postValue(false) syncInProgress.postValue(false)
showGreenToast(R.string.settings_contacts_carddav_sync_successful_toast, R.drawable.check) showGreenToast(R.string.settings_contacts_carddav_sync_successful_toast, R.drawable.check)
val name = displayName.value.orEmpty().trim()
if (storeNewContactsInIt.value == true) {
val previous = corePreferences.friendListInWhichStoreNewlyCreatedFriends
if (friendList.isReadOnly) {
Log.w("$TAG User asked to add newly created contacts in this friend list but it is read only, keep currently default friend list [$previous]")
} else {
Log.i(
"$TAG Updating default friend list to store newly created contacts from [$previous] to [$name]"
)
corePreferences.friendListInWhichStoreNewlyCreatedFriends = name
}
}
Log.i("$TAG Notifying contacts manager that contacts have changed") Log.i("$TAG Notifying contacts manager that contacts have changed")
coreContext.contactsManager.notifyContactsListChanged() coreContext.contactsManager.notifyContactsListChanged()
@ -231,13 +244,7 @@ class CardDavViewModel
) )
} }
if (storeNewContactsInIt.value == true) { if (storeNewContactsInIt.value == false && corePreferences.friendListInWhichStoreNewlyCreatedFriends == name) {
val previous = corePreferences.friendListInWhichStoreNewlyCreatedFriends
Log.i(
"$TAG Updating default friend list to store newly created contacts from [$previous] to [$name]"
)
corePreferences.friendListInWhichStoreNewlyCreatedFriends = name
} else if (storeNewContactsInIt.value == false) {
Log.i( Log.i(
"$TAG No longer using friend list [$name] as default friend list, switching back to [$LINPHONE_ADDRESS_BOOK_FRIEND_LIST]" "$TAG No longer using friend list [$name] as default friend list, switching back to [$LINPHONE_ADDRESS_BOOK_FRIEND_LIST]"
) )

View file

@ -64,7 +64,7 @@
android:layout_height="0dp" android:layout_height="0dp"
android:src="@drawable/pencil_simple" android:src="@drawable/pencil_simple"
android:contentDescription="@string/content_description_contact_edit" android:contentDescription="@string/content_description_contact_edit"
android:visibility="@{viewModel.isStored ? View.VISIBLE : View.GONE}" android:visibility="@{viewModel.isStored &amp;&amp; !viewModel.isReadOnly ? View.VISIBLE : View.GONE}"
app:tint="?attr/color_main2_500" app:tint="?attr/color_main2_500"
app:layout_constraintBottom_toBottomOf="@id/invisible_title" app:layout_constraintBottom_toBottomOf="@id/invisible_title"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
@ -510,7 +510,7 @@
android:text="@string/contact_details_edit" android:text="@string/contact_details_edit"
android:drawableStart="@drawable/pencil_simple" android:drawableStart="@drawable/pencil_simple"
android:background="@drawable/action_background_top" android:background="@drawable/action_background_top"
android:visibility="@{viewModel.isStored ? View.VISIBLE : View.GONE}" android:visibility="@{viewModel.isStored &amp;&amp; !viewModel.isReadOnly ? View.VISIBLE : View.GONE}"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/actions"/> app:layout_constraintTop_toBottomOf="@id/actions"/>
@ -524,7 +524,7 @@
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:background="@drawable/action_background_middle" android:background="@drawable/action_background_middle"
android:visibility="@{viewModel.isStored ? View.VISIBLE : View.GONE}" android:visibility="@{viewModel.isStored &amp;&amp; !viewModel.isReadOnly ? View.VISIBLE : View.GONE}"
android:text="@{viewModel.isFavourite ? @string/contact_details_remove_from_favourites : @string/contact_details_add_to_favourites, default=@string/contact_details_add_to_favourites}" android:text="@{viewModel.isFavourite ? @string/contact_details_remove_from_favourites : @string/contact_details_add_to_favourites, default=@string/contact_details_add_to_favourites}"
android:drawableStart="@{viewModel.isFavourite ? @drawable/heart_fill : @drawable/heart, default=@drawable/heart_fill}" android:drawableStart="@{viewModel.isFavourite ? @drawable/heart_fill : @drawable/heart, default=@drawable/heart_fill}"
android:drawableTint="@{viewModel.isFavourite ? @color/danger_500 : @color/main2_500, default=@color/main2_500}" android:drawableTint="@{viewModel.isFavourite ? @color/danger_500 : @color/main2_500, default=@color/main2_500}"
@ -540,7 +540,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:background="@{viewModel.isStored ? @drawable/action_background_middle : @drawable/action_background_full, default=@drawable/action_background_middle}" android:background="@{viewModel.isStored &amp;&amp; !viewModel.isReadOnly ? @drawable/action_background_middle : @drawable/action_background_full, default=@drawable/action_background_middle}"
android:text="@string/contact_details_share" android:text="@string/contact_details_share"
android:drawableStart="@drawable/share_network" android:drawableStart="@drawable/share_network"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@ -558,7 +558,7 @@
android:background="@drawable/action_background_bottom" android:background="@drawable/action_background_bottom"
android:text="@string/contact_details_delete" android:text="@string/contact_details_delete"
android:drawableStart="@drawable/trash_simple" android:drawableStart="@drawable/trash_simple"
android:visibility="@{viewModel.isStored ? View.VISIBLE : View.GONE}" android:visibility="@{viewModel.isStored &amp;&amp; !viewModel.isReadOnly ? View.VISIBLE : View.GONE}"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/action_share"/> app:layout_constraintTop_toBottomOf="@id/action_share"/>
@ -569,7 +569,7 @@
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:background="?attr/color_separator" android:background="?attr/color_separator"
android:visibility="@{viewModel.isStored ? View.VISIBLE : View.GONE}" android:visibility="@{viewModel.isStored &amp;&amp; !viewModel.isReadOnly ? View.VISIBLE : View.GONE}"
app:layout_constraintEnd_toEndOf="@id/action_edit" app:layout_constraintEnd_toEndOf="@id/action_edit"
app:layout_constraintStart_toStartOf="@id/action_edit" app:layout_constraintStart_toStartOf="@id/action_edit"
app:layout_constraintTop_toBottomOf="@+id/action_edit"/> app:layout_constraintTop_toBottomOf="@+id/action_edit"/>
@ -580,7 +580,7 @@
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:background="?attr/color_separator" android:background="?attr/color_separator"
android:visibility="@{viewModel.isStored ? View.VISIBLE : View.GONE}" android:visibility="@{viewModel.isStored &amp;&amp; !viewModel.isReadOnly ? View.VISIBLE : View.GONE}"
app:layout_constraintEnd_toEndOf="@id/action_favorite" app:layout_constraintEnd_toEndOf="@id/action_favorite"
app:layout_constraintStart_toStartOf="@id/action_favorite" app:layout_constraintStart_toStartOf="@id/action_favorite"
app:layout_constraintTop_toBottomOf="@+id/action_favorite"/> app:layout_constraintTop_toBottomOf="@+id/action_favorite"/>
@ -591,7 +591,7 @@
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:background="?attr/color_separator" android:background="?attr/color_separator"
android:visibility="@{viewModel.isStored ? View.VISIBLE : View.GONE}" android:visibility="@{viewModel.isStored &amp;&amp; !viewModel.isReadOnly ? View.VISIBLE : View.GONE}"
app:layout_constraintEnd_toEndOf="@id/action_share" app:layout_constraintEnd_toEndOf="@id/action_share"
app:layout_constraintStart_toStartOf="@id/action_share" app:layout_constraintStart_toStartOf="@id/action_share"
app:layout_constraintTop_toBottomOf="@+id/action_share"/> app:layout_constraintTop_toBottomOf="@+id/action_share"/>

View file

@ -22,6 +22,9 @@
<variable <variable
name="isStored" name="isStored"
type="Boolean" /> type="Boolean" />
<variable
name="isReadOnly"
type="Boolean" />
</data> </data>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
@ -37,7 +40,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="1dp" android:layout_marginBottom="1dp"
android:background="@drawable/menu_item_background" android:background="@drawable/menu_item_background"
android:visibility="@{isStored ? View.VISIBLE : View.GONE}" android:visibility="@{isStored &amp;&amp; !isReadOnly ? View.VISIBLE : View.GONE}"
android:text="@{isFavourite ? @string/contact_details_remove_from_favourites : @string/contact_details_add_to_favourites, default=@string/contact_details_add_to_favourites}" android:text="@{isFavourite ? @string/contact_details_remove_from_favourites : @string/contact_details_add_to_favourites, default=@string/contact_details_add_to_favourites}"
android:drawableStart="@{isFavourite ? @drawable/heart_fill : @drawable/heart, default=@drawable/heart_fill}" android:drawableStart="@{isFavourite ? @drawable/heart_fill : @drawable/heart, default=@drawable/heart_fill}"
android:drawableTint="@{isFavourite ? @color/danger_500 : @color/main2_500, default=@color/main2_500}" android:drawableTint="@{isFavourite ? @color/danger_500 : @color/main2_500, default=@color/main2_500}"
@ -66,7 +69,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/contact_details_delete" android:text="@string/contact_details_delete"
android:visibility="@{isStored ? View.VISIBLE : View.GONE}" android:visibility="@{isStored &amp;&amp; !isReadOnly ? View.VISIBLE : View.GONE}"
android:background="@drawable/menu_item_background" android:background="@drawable/menu_item_background"
android:layout_marginBottom="1dp" android:layout_marginBottom="1dp"
android:drawableStart="@drawable/trash_simple" android:drawableStart="@drawable/trash_simple"