From 7c8d11ca208179a214c6e90f591f34e00e0d9a27 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 3 Aug 2023 15:39:44 +0200 Subject: [PATCH] Using new lib to display avatars --- app/build.gradle | 2 + .../ui/contacts/model/ContactModel.kt | 6 +++ .../org/linphone/utils/DataBindingUtils.kt | 29 ++++++++-- .../java/org/linphone/utils/LinphoneUtils.kt | 54 +++++++++++++++++++ app/src/main/res/layout/contact_list_cell.xml | 27 ++++++++-- 5 files changed, 109 insertions(+), 9 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 333e1e737..26c2c7611 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -80,6 +80,8 @@ dependencies { implementation("io.coil-kt:coil-gif:$coil_version") implementation("io.coil-kt:coil-svg:$coil_version") implementation("io.coil-kt:coil-video:$coil_version") + // https://github.com/GetStream/avatarview-android/blob/main/LICENSE Apache v2.0 + implementation "io.getstream:avatarview-coil:1.0.7" implementation platform('com.google.firebase:firebase-bom:30.3.2') implementation 'com.google.firebase:firebase-messaging' diff --git a/app/src/main/java/org/linphone/ui/contacts/model/ContactModel.kt b/app/src/main/java/org/linphone/ui/contacts/model/ContactModel.kt index 91ff27acd..60e1e385f 100644 --- a/app/src/main/java/org/linphone/ui/contacts/model/ContactModel.kt +++ b/app/src/main/java/org/linphone/ui/contacts/model/ContactModel.kt @@ -26,10 +26,13 @@ import androidx.lifecycle.MutableLiveData import org.linphone.core.ConsolidatedPresence import org.linphone.core.Friend import org.linphone.core.FriendListenerStub +import org.linphone.utils.LinphoneUtils class ContactModel(val friend: Friend) { val id = friend.refKey + val initials = LinphoneUtils.getInitials(friend.name.orEmpty()) + val presenceStatus = MutableLiveData() val name = MutableLiveData() @@ -43,6 +46,7 @@ class ContactModel(val friend: Friend) { } init { + // Core thread name.postValue(friend.name) presenceStatus.postValue(friend.consolidatedPresence) @@ -52,10 +56,12 @@ class ContactModel(val friend: Friend) { } fun destroy() { + // Core thread friend.removeListener(friendListener) } private fun getAvatarUri(): Uri? { + // Core thread val refKey = friend.refKey if (refKey != null) { val lookupUri = ContentUris.withAppendedId( diff --git a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt index dd3bc6209..6fa2ac6b9 100644 --- a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt +++ b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt @@ -32,8 +32,12 @@ import androidx.core.view.doOnLayout import androidx.databinding.BindingAdapter import coil.load import coil.transform.CircleCropTransformation +import io.getstream.avatarview.AvatarView +import io.getstream.avatarview.coil.loadImage import org.linphone.R import org.linphone.contacts.ContactData +import org.linphone.core.ConsolidatedPresence +import org.linphone.core.tools.Log import org.linphone.ui.contacts.model.ContactModel /** @@ -105,13 +109,28 @@ fun loadContactPictureWithCoil2(imageView: ImageView, contact: ContactData?) { } @BindingAdapter("contactAvatar") -fun loadContactPictureWithCoil(imageView: ImageView, contact: ContactModel?) { +fun AvatarView.loadContactPicture(contact: ContactModel?) { if (contact == null) { - imageView.load(R.drawable.contact_avatar) + loadImage(R.drawable.contact_avatar) } else { - imageView.load(contact.avatar) { - transformations(CircleCropTransformation()) - error(R.drawable.contact_avatar) + indicatorColor = when (contact.presenceStatus.value) { + ConsolidatedPresence.Online -> R.color.green_online + else -> R.color.blue_outgoing_message } + indicatorEnabled = true + + val uri = contact.avatar + Log.i("[Data binding Utils] Loading URI [$uri]") + loadImage( + data = uri, + onStart = { + // Use initials as placeholder + avatarInitials = contact.initials + }, + onSuccess = { _, _ -> + // If loading is successful, remove initials otherwise image won't be visible + avatarInitials = "" + } + ) } } diff --git a/app/src/main/java/org/linphone/utils/LinphoneUtils.kt b/app/src/main/java/org/linphone/utils/LinphoneUtils.kt index 2bf88b787..80d1a2800 100644 --- a/app/src/main/java/org/linphone/utils/LinphoneUtils.kt +++ b/app/src/main/java/org/linphone/utils/LinphoneUtils.kt @@ -22,14 +22,68 @@ package org.linphone.utils import android.content.ContentUris import android.net.Uri import android.provider.ContactsContract +import androidx.emoji2.text.EmojiCompat import java.io.IOException +import java.util.Locale import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.core.Address import org.linphone.core.ChatRoom import org.linphone.core.Friend +import org.linphone.core.tools.Log class LinphoneUtils { companion object { + private val emojiCompat: EmojiCompat? + get() = initEmojiCompat() + + private fun initEmojiCompat(): EmojiCompat? { + return try { + EmojiCompat.get() + } catch (ise: IllegalStateException) { + Log.w( + "[App Utils] EmojiCompat.get() triggered IllegalStateException [$ise], trying manual init" + ) + EmojiCompat.init(coreContext.context) + } + } + + fun getInitials(displayName: String, limit: Int = 2): String { + if (displayName.isEmpty()) return "" + + val split = displayName.uppercase(Locale.getDefault()).split(" ") + var initials = "" + var characters = 0 + val emoji = emojiCompat + + for (i in split.indices) { + if (split[i].isNotEmpty()) { + try { + if (emoji?.loadState == EmojiCompat.LOAD_STATE_SUCCEEDED && emoji.hasEmojiGlyph( + split[i] + ) + ) { + val glyph = emoji.process(split[i]) + if (characters > 0) { // Limit initial to 1 emoji only + Log.d("[App Utils] We limit initials to one emoji only") + initials = "" + } + initials += glyph + break // Limit initial to 1 emoji only + } else { + initials += split[i][0] + } + } catch (ise: IllegalStateException) { + Log.e("[App Utils] Can't call hasEmojiGlyph: $ise") + initials += split[i][0] + } + + characters += 1 + if (characters >= limit) break + } + } + return initials + } + private fun getChatRoomId(localAddress: Address, remoteAddress: Address): String { val localSipUri = localAddress.clone() localSipUri.clean() diff --git a/app/src/main/res/layout/contact_list_cell.xml b/app/src/main/res/layout/contact_list_cell.xml index 15e029536..018c7c1c3 100644 --- a/app/src/main/res/layout/contact_list_cell.xml +++ b/app/src/main/res/layout/contact_list_cell.xml @@ -18,16 +18,26 @@ android:layout_marginBottom="5dp" android:background="@drawable/cell_background"> - @@ -42,6 +52,15 @@ app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent"/> + + \ No newline at end of file