Using IO dispatcher to create generated avatar

This commit is contained in:
Sylvain Berfini 2022-06-09 15:24:43 +02:00
parent 5fac97b55d
commit e6c842cd35
7 changed files with 97 additions and 53 deletions

View file

@ -27,6 +27,8 @@ import android.view.animation.LinearInterpolator
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.CoroutineScope
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
@ -53,6 +55,7 @@ class ChatRoomViewModel(val chatRoom: ChatRoom) : ViewModel(), ContactDataInterf
override val securityLevel: MutableLiveData<ChatRoomSecurityLevel> = MutableLiveData<ChatRoomSecurityLevel>()
override val showGroupChatAvatar: Boolean = chatRoom.hasCapability(ChatRoomCapabilities.Conference.toInt()) &&
!chatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())
override val coroutineScope: CoroutineScope = viewModelScope
val subject = MutableLiveData<String>()

View file

@ -25,8 +25,10 @@ import android.media.ExifInterface
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import java.io.ByteArrayOutputStream
import java.io.IOException
import kotlinx.coroutines.CoroutineScope
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.activities.main.contact.data.NumberOrAddressEditorData
@ -50,6 +52,7 @@ class ContactEditorViewModel(val c: Friend?) : ViewModel(), ContactDataInterface
override val contact: MutableLiveData<Friend> = MutableLiveData<Friend>()
override val displayName: MutableLiveData<String> = MutableLiveData<String>()
override val securityLevel: MutableLiveData<ChatRoomSecurityLevel> = MutableLiveData<ChatRoomSecurityLevel>()
override val coroutineScope: CoroutineScope = viewModelScope
val firstName = MutableLiveData<String>()

View file

@ -24,6 +24,8 @@ import android.provider.ContactsContract
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.CoroutineScope
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
@ -52,6 +54,7 @@ class ContactViewModel(friend: Friend, async: Boolean = false) : MessageNotifier
override val contact: MutableLiveData<Friend> = MutableLiveData<Friend>()
override val displayName: MutableLiveData<String> = MutableLiveData<String>()
override val securityLevel: MutableLiveData<ChatRoomSecurityLevel> = MutableLiveData<ChatRoomSecurityLevel>()
override val coroutineScope: CoroutineScope = viewModelScope
var fullName = ""

View file

@ -20,6 +20,8 @@
package org.linphone.contact
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.CoroutineScope
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.activities.main.viewmodels.MessageNotifierViewModel
import org.linphone.core.Address
@ -36,12 +38,15 @@ interface ContactDataInterface {
val showGroupChatAvatar: Boolean
get() = false
val coroutineScope: CoroutineScope
}
open class GenericContactData(private val sipAddress: Address) : ContactDataInterface {
final override val contact: MutableLiveData<Friend> = MutableLiveData<Friend>()
final override val displayName: MutableLiveData<String> = MutableLiveData<String>()
final override val securityLevel: MutableLiveData<ChatRoomSecurityLevel> = MutableLiveData<ChatRoomSecurityLevel>()
final override val coroutineScope: CoroutineScope = coreContext.coroutineScope
init {
securityLevel.value = ChatRoomSecurityLevel.ClearText
@ -63,6 +68,7 @@ abstract class GenericContactViewModel(private val sipAddress: Address) : Messag
final override val contact: MutableLiveData<Friend> = MutableLiveData<Friend>()
final override val displayName: MutableLiveData<String> = MutableLiveData<String>()
final override val securityLevel: MutableLiveData<ChatRoomSecurityLevel> = MutableLiveData<ChatRoomSecurityLevel>()
final override val coroutineScope: CoroutineScope = viewModelScope
init {
securityLevel.value = ChatRoomSecurityLevel.ClearText

View file

@ -20,6 +20,7 @@
package org.linphone.contact
import androidx.lifecycle.MutableLiveData
import kotlinx.coroutines.CoroutineScope
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.core.*
import org.linphone.utils.LinphoneUtils
@ -28,6 +29,7 @@ class ContactSelectionData(private val searchResult: SearchResult) : ContactData
override val contact: MutableLiveData<Friend> = MutableLiveData<Friend>()
override val displayName: MutableLiveData<String> = MutableLiveData<String>()
override val securityLevel: MutableLiveData<ChatRoomSecurityLevel> = MutableLiveData<ChatRoomSecurityLevel>()
override val coroutineScope: CoroutineScope = coreContext.coroutineScope
val isDisabled: MutableLiveData<Boolean> by lazy {
MutableLiveData<Boolean>()

View file

@ -118,8 +118,9 @@ class CoreContext(
MutableLiveData<Event<String>>()
}
val coroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
private val loggingService = Factory.instance().loggingService
private val coroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
private var overlayX = 0f
private var overlayY = 0f

View file

@ -42,7 +42,9 @@ import coil.request.CachePolicy
import coil.request.videoFrameMillis
import coil.transform.CircleCropTransformation
import com.google.android.material.switchmaterial.SwitchMaterial
import kotlinx.coroutines.*
import org.linphone.BR
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
import org.linphone.activities.GenericActivity
@ -320,7 +322,7 @@ fun loadImageWithCoil(imageView: ImageView, path: String?) {
}
}
private fun loadContactPictureWithCoil(
private suspend fun loadContactPictureWithCoil(
imageView: ImageView,
contact: ContactDataInterface?,
useThumbnail: Boolean,
@ -329,76 +331,100 @@ private fun loadContactPictureWithCoil(
color: Int = 0,
textColor: Int = 0
) {
if (contact != null) {
val context = imageView.context
val displayName = contact.contact.value?.name ?: contact.displayName.value.orEmpty()
val source = contact.contact.value?.getPictureUri(useThumbnail)
imageView.load(source) {
transformations(CircleCropTransformation())
error(
if (contact.showGroupChatAvatar) {
val bg = AppCompatResources.getDrawable(context, R.drawable.generated_avatar_bg)
imageView.background = bg
AppCompatResources.getDrawable(context, R.drawable.icon_multiple_contacts_avatar)
} else if (displayName.isEmpty() || AppUtils.getInitials(displayName) == "+") {
val bg = AppCompatResources.getDrawable(context, R.drawable.generated_avatar_bg)
imageView.background = bg
AppCompatResources.getDrawable(context, R.drawable.icon_single_contact_avatar)
} else {
val builder = ContactAvatarGenerator(context)
builder.setLabel(displayName)
if (size > 0) {
builder.setAvatarSize(AppUtils.getDimension(size).toInt())
}
if (textSize > 0) {
builder.setTextSize(AppUtils.getDimension(textSize))
}
if (color > 0) {
builder.setBackgroundColorAttribute(color)
}
if (textColor > 0) {
builder.setTextColorResource(textColor)
}
builder.build()
coroutineScope {
withContext(Dispatchers.IO) {
if (contact != null) {
val context = imageView.context
val displayName = contact.contact.value?.name ?: contact.displayName.value.orEmpty()
val source = contact.contact.value?.getPictureUri(useThumbnail)
imageView.load(source) {
transformations(CircleCropTransformation())
error(
if (contact.showGroupChatAvatar) {
val bg = AppCompatResources.getDrawable(context, R.drawable.generated_avatar_bg)
imageView.background = bg
AppCompatResources.getDrawable(context, R.drawable.icon_multiple_contacts_avatar)
} else if (displayName.isEmpty() || AppUtils.getInitials(displayName) == "+") {
val bg = AppCompatResources.getDrawable(context, R.drawable.generated_avatar_bg)
imageView.background = bg
AppCompatResources.getDrawable(context, R.drawable.icon_single_contact_avatar)
} else {
val builder = ContactAvatarGenerator(context)
builder.setLabel(displayName)
if (size > 0) {
builder.setAvatarSize(AppUtils.getDimension(size).toInt())
}
if (textSize > 0) {
builder.setTextSize(AppUtils.getDimension(textSize))
}
if (color > 0) {
builder.setBackgroundColorAttribute(color)
}
if (textColor > 0) {
builder.setTextColorResource(textColor)
}
builder.build()
}
)
}
)
} else {
val bg = AppCompatResources.getDrawable(imageView.context, R.drawable.generated_avatar_bg)
imageView.background = bg
imageView.load(R.drawable.icon_single_contact_avatar)
}
}
} else {
val bg = AppCompatResources.getDrawable(imageView.context, R.drawable.generated_avatar_bg)
imageView.background = bg
imageView.load(R.drawable.icon_single_contact_avatar)
}
}
@BindingAdapter("coilContact")
fun loadContactPictureWithCoil(imageView: ImageView, contact: ContactDataInterface?) {
loadContactPictureWithCoil(imageView, contact, true)
val coroutineScope = contact?.coroutineScope ?: coreContext.coroutineScope
coroutineScope.launch {
withContext(Dispatchers.Main) {
loadContactPictureWithCoil(imageView, contact, true)
}
}
}
@BindingAdapter("coilContactBig")
fun loadBigContactPictureWithCoil(imageView: ImageView, contact: ContactDataInterface?) {
loadContactPictureWithCoil(
imageView, contact, false,
R.dimen.contact_avatar_big_size, R.dimen.contact_avatar_text_big_size
)
val coroutineScope = contact?.coroutineScope ?: coreContext.coroutineScope
coroutineScope.launch {
withContext(Dispatchers.Main) {
loadContactPictureWithCoil(
imageView, contact, false,
R.dimen.contact_avatar_big_size, R.dimen.contact_avatar_text_big_size
)
}
}
}
@BindingAdapter("coilVoipContactAlt")
fun loadVoipContactPictureWithCoilAlt(imageView: ImageView, contact: ContactDataInterface?) {
loadContactPictureWithCoil(
imageView, contact, false,
R.dimen.voip_contact_avatar_max_size, R.dimen.voip_contact_avatar_text_size,
R.attr.voipParticipantBackgroundColor, R.color.white_color
)
val coroutineScope = contact?.coroutineScope ?: coreContext.coroutineScope
coroutineScope.launch {
withContext(Dispatchers.Main) {
loadContactPictureWithCoil(
imageView, contact, false,
R.dimen.voip_contact_avatar_max_size, R.dimen.voip_contact_avatar_text_size,
R.attr.voipParticipantBackgroundColor, R.color.white_color
)
}
}
}
@BindingAdapter("coilVoipContact")
fun loadVoipContactPictureWithCoil(imageView: ImageView, contact: ContactDataInterface?) {
loadContactPictureWithCoil(
imageView, contact, false,
R.dimen.voip_contact_avatar_max_size, R.dimen.voip_contact_avatar_text_size,
R.attr.voipBackgroundColor, R.color.white_color
)
val coroutineScope = contact?.coroutineScope ?: coreContext.coroutineScope
coroutineScope.launch {
withContext(Dispatchers.Main) {
loadContactPictureWithCoil(
imageView, contact, false,
R.dimen.voip_contact_avatar_max_size, R.dimen.voip_contact_avatar_text_size,
R.attr.voipBackgroundColor, R.color.white_color
)
}
}
}
@BindingAdapter("coilGoneIfError")