Using new lib to display avatars

This commit is contained in:
Sylvain Berfini 2023-08-03 15:39:44 +02:00
parent 1d9684e11e
commit 7c8d11ca20
5 changed files with 109 additions and 9 deletions

View file

@ -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'

View file

@ -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<ConsolidatedPresence>()
val name = MutableLiveData<String>()
@ -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(

View file

@ -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 = ""
}
)
}
}

View file

@ -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()

View file

@ -18,16 +18,26 @@
android:layout_marginBottom="5dp"
android:background="@drawable/cell_background">
<ImageView
<io.getstream.avatarview.AvatarView
android:id="@+id/avatar"
android:layout_width="wrap_content"
android:layout_width="36dp"
android:layout_height="36dp"
android:src="@{@drawable/contact_avatar}"
contactAvatar="@{model}"
android:layout_marginStart="10dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:adjustViewBounds="true"
contactAvatar="@{model}"
app:avatarViewPlaceholder="@drawable/contact_avatar"
app:avatarViewInitialsBackgroundColor="@color/blue_outgoing_message"
app:avatarViewInitialsTextColor="@color/gray_9"
app:avatarViewInitialsTextSize="16sp"
app:avatarViewInitialsTextStyle="bold"
app:avatarViewShape="circle"
app:avatarViewIndicatorEnabled="true"
app:avatarViewIndicatorBorderColor="@color/white"
app:avatarViewIndicatorSizeCriteria="6"
app:avatarViewIndicatorBorderSizeCriteria="8"
app:avatarViewIndicatorPosition="bottomRight"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@ -42,6 +52,15 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_marginEnd="10dp"
android:background="@color/blue_outgoing_message"
app:layout_constraintStart_toStartOf="@id/name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>