diff --git a/app/src/main/java/com/infomaniak/mail/data/models/Bimi.kt b/app/src/main/java/com/infomaniak/mail/data/models/Bimi.kt index 8b318e0571..314dd9c166 100644 --- a/app/src/main/java/com/infomaniak/mail/data/models/Bimi.kt +++ b/app/src/main/java/com/infomaniak/mail/data/models/Bimi.kt @@ -41,6 +41,8 @@ class Bimi() : EmbeddedRealmObject, Parcelable { this.isCertified = isCertified } + fun isDisplayable(): Boolean = isCertified && svgContentUrl?.isNotEmpty() == true + companion object : Parceler { override fun create(parcel: Parcel): Bimi = with(parcel) { diff --git a/app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListAdapter.kt b/app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListAdapter.kt index 10670ab811..d4f14d2cee 100644 --- a/app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListAdapter.kt +++ b/app/src/main/java/com/infomaniak/mail/ui/main/folder/ThreadListAdapter.kt @@ -49,7 +49,6 @@ import com.infomaniak.mail.R import com.infomaniak.mail.data.LocalSettings import com.infomaniak.mail.data.LocalSettings.SwipeAction import com.infomaniak.mail.data.LocalSettings.ThreadDensity -import com.infomaniak.mail.data.api.ApiRoutes import com.infomaniak.mail.data.models.Folder.FolderRole import com.infomaniak.mail.data.models.correspondent.Recipient import com.infomaniak.mail.data.models.thread.Thread @@ -402,11 +401,7 @@ class ThreadListAdapter @Inject constructor( private fun CardviewThreadItemBinding.displayAvatar(thread: Thread) { val (recipient, bimi) = thread.computeAvatarRecipient() - if (bimi?.isCertified == true) { - expeditorAvatar.loadBimiAvatar(ApiRoutes.bimi(bimi.svgContentUrl.toString()), recipient) - } else { - expeditorAvatar.loadAvatar(recipient) - } + expeditorAvatar.loadAvatar(recipient, bimi) } private fun CardviewThreadItemBinding.formatRecipientNames(recipients: List): String { diff --git a/app/src/main/java/com/infomaniak/mail/views/AvatarView.kt b/app/src/main/java/com/infomaniak/mail/views/AvatarView.kt index 814e5d12e4..4bb0ed12fc 100644 --- a/app/src/main/java/com/infomaniak/mail/views/AvatarView.kt +++ b/app/src/main/java/com/infomaniak/mail/views/AvatarView.kt @@ -58,17 +58,25 @@ class AvatarView @JvmOverloads constructor( private val binding by lazy { ViewAvatarBinding.inflate(LayoutInflater.from(context), this, true) } private var currentCorrespondent: Correspondent? = null - private var isBimiShown: Boolean = false + private var currentBimi: Bimi? = null private val mergedContactObserver = Observer { contacts -> - currentCorrespondent?.let { correspondent -> - if (!isBimiShown) loadAvatarUsingDictionary(correspondent, contacts) + val displayType = getAvatarDisplayType(currentCorrespondent, currentBimi) + + if (displayType == AvatarDisplayType.CUSTOM_AVATAR || displayType == AvatarDisplayType.INITIALS) { + loadAvatarUsingDictionary(currentCorrespondent!!, contacts) } } @Inject lateinit var avatarMergedContactData: AvatarMergedContactData + private val contactsFromViewModel: MergedContactDictionary + get() { + // Avoid lateinit property has not been initialized in preview + return if (isInEditMode) emptyMap() else avatarMergedContactData.mergedContactLiveData.value ?: emptyMap() + } + @Inject lateinit var svgImageLoader: ImageLoader @@ -129,15 +137,30 @@ class AvatarView @JvmOverloads constructor( ) } - fun loadAvatar(correspondent: Correspondent?) { - if (correspondent == null) { - loadUnknownUserAvatar() - } else { - // Avoid lateinit property has not been initialized in preview - val contactsFromViewModel = if (isInEditMode) emptyMap() else avatarMergedContactData.mergedContactLiveData.value - loadAvatarUsingDictionary(correspondent, contacts = contactsFromViewModel ?: emptyMap()) + fun loadAvatar(correspondent: Correspondent?, bimi: Bimi? = null) { + + fun loadSimpleCorrespondent(correspondent: Correspondent) { + loadAvatarUsingDictionary(correspondent, contacts = contactsFromViewModel) currentCorrespondent = correspondent } + + currentBimi = bimi + + when (getAvatarDisplayType(correspondent, bimi)) { + AvatarDisplayType.UNKNOWN_CORRESPONDENT -> loadUnknownUserAvatar() + AvatarDisplayType.CUSTOM_AVATAR -> loadSimpleCorrespondent(correspondent!!) + AvatarDisplayType.BIMI -> loadBimiAvatar(ApiRoutes.bimi(bimi!!.svgContentUrl!!), correspondent!!) + AvatarDisplayType.INITIALS -> loadSimpleCorrespondent(correspondent!!) + } + } + + private fun getAvatarDisplayType(correspondent: Correspondent?, bimi: Bimi?): AvatarDisplayType { + return when { + correspondent == null -> AvatarDisplayType.UNKNOWN_CORRESPONDENT + correspondent.hasMergedContactAvatar(contactsFromViewModel) -> AvatarDisplayType.CUSTOM_AVATAR + bimi?.isDisplayable() == true -> AvatarDisplayType.BIMI + else -> AvatarDisplayType.INITIALS + } } fun loadAvatar(mergedContact: MergedContact) { @@ -149,16 +172,15 @@ class AvatarView @JvmOverloads constructor( binding.avatarImage.load(R.drawable.ic_unknown_user_avatar) } - fun loadBimiAvatar(bimiUrl: String, correspondent: Correspondent?) = with(binding.avatarImage) { - contentDescription = correspondent?.email.orEmpty() - isBimiShown = bimiUrl.isNotEmpty() + private fun loadBimiAvatar(bimiUrl: String, correspondent: Correspondent) = with(binding.avatarImage) { + contentDescription = correspondent.email loadAvatar( backgroundColor = context.getBackgroundColorBasedOnId( - correspondent?.email.orEmpty().hashCode(), + correspondent.email.hashCode(), R.array.AvatarColors, ), avatarUrl = bimiUrl, - initials = correspondent?.initials.orEmpty(), + initials = correspondent.initials, imageLoader = svgImageLoader, initialsColor = context.getColor(R.color.onColorfulBackground), ) @@ -171,6 +193,10 @@ class AvatarView @JvmOverloads constructor( return recipientsForEmail?.getOrElse(correspondent.name) { recipientsForEmail.entries.elementAt(0).value } } + private fun Correspondent.hasMergedContactAvatar(contacts: MergedContactDictionary): Boolean { + return searchInMergedContact(correspondent = this, contacts)?.avatar != null + } + private fun loadAvatarUsingDictionary(correspondent: Correspondent, contacts: MergedContactDictionary) { val mergedContact = searchInMergedContact(correspondent, contacts) binding.avatarImage.baseLoadAvatar(correspondent = mergedContact ?: correspondent) @@ -192,12 +218,10 @@ class AvatarView @JvmOverloads constructor( } } - fun loadAvatar(correspondent: Correspondent?, bimi: Bimi?) { - val svgContentUrl = bimi?.svgContentUrl - if (bimi == null || !bimi.isCertified || svgContentUrl.isNullOrEmpty()) { - loadAvatar(correspondent) - } else { - loadBimiAvatar(ApiRoutes.bimi(svgContentUrl), correspondent) - } + enum class AvatarDisplayType { + UNKNOWN_CORRESPONDENT, + CUSTOM_AVATAR, + BIMI, + INITIALS, } }