diff --git a/app/src/main/java/org/linphone/ui/call/adapter/CallsListAdapter.kt b/app/src/main/java/org/linphone/ui/call/adapter/CallsListAdapter.kt index 8f8088ff4..40060638c 100644 --- a/app/src/main/java/org/linphone/ui/call/adapter/CallsListAdapter.kt +++ b/app/src/main/java/org/linphone/ui/call/adapter/CallsListAdapter.kt @@ -23,8 +23,8 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.annotation.UiThread import androidx.databinding.DataBindingUtil -import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView @@ -33,7 +33,7 @@ import org.linphone.databinding.CallListCellBinding import org.linphone.ui.call.model.CallModel import org.linphone.utils.Event -class CallsListAdapter(private val viewLifecycleOwner: LifecycleOwner) : +class CallsListAdapter : ListAdapter(CallDiffCallback()) { var selectedAdapterPosition = -1 @@ -54,7 +54,7 @@ class CallsListAdapter(private val viewLifecycleOwner: LifecycleOwner) : ) val viewHolder = ViewHolder(binding) binding.apply { - lifecycleOwner = viewLifecycleOwner + lifecycleOwner = parent.findViewTreeLifecycleOwner() setOnClickListener { callClickedEvent.value = Event(model!!) diff --git a/app/src/main/java/org/linphone/ui/call/adapter/ConferenceParticipantsListAdapter.kt b/app/src/main/java/org/linphone/ui/call/adapter/ConferenceParticipantsListAdapter.kt index 027590552..69b832887 100644 --- a/app/src/main/java/org/linphone/ui/call/adapter/ConferenceParticipantsListAdapter.kt +++ b/app/src/main/java/org/linphone/ui/call/adapter/ConferenceParticipantsListAdapter.kt @@ -23,6 +23,7 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.annotation.UiThread import androidx.databinding.DataBindingUtil +import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView @@ -40,6 +41,7 @@ class ConferenceParticipantsListAdapter : parent, false ) + binding.lifecycleOwner = parent.findViewTreeLifecycleOwner() return ViewHolder(binding) } diff --git a/app/src/main/java/org/linphone/ui/call/fragment/CallsListFragment.kt b/app/src/main/java/org/linphone/ui/call/fragment/CallsListFragment.kt index 42741d5b0..a8ff71da0 100644 --- a/app/src/main/java/org/linphone/ui/call/fragment/CallsListFragment.kt +++ b/app/src/main/java/org/linphone/ui/call/fragment/CallsListFragment.kt @@ -42,6 +42,12 @@ class CallsListFragment : GenericCallFragment() { private lateinit var adapter: CallsListAdapter + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + adapter = CallsListAdapter() + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -61,9 +67,7 @@ class CallsListFragment : GenericCallFragment() { binding.lifecycleOwner = viewLifecycleOwner binding.viewModel = viewModel - adapter = CallsListAdapter(viewLifecycleOwner) binding.callsList.setHasFixedSize(true) - binding.callsList.adapter = adapter binding.callsList.layoutManager = LinearLayoutManager(requireContext()) adapter.callLongClickedEvent.observe(viewLifecycleOwner) { @@ -89,6 +93,10 @@ class CallsListFragment : GenericCallFragment() { viewModel.calls.observe(viewLifecycleOwner) { Log.i("$TAG Calls list updated with [${it.size}] items") adapter.submitList(it) + + if (binding.callsList.adapter != adapter) { + binding.callsList.adapter = adapter + } } } } diff --git a/app/src/main/java/org/linphone/ui/main/chat/adapter/ChatMessageBottomSheetAdapter.kt b/app/src/main/java/org/linphone/ui/main/chat/adapter/ChatMessageBottomSheetAdapter.kt index 21b871390..dc864e57d 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/adapter/ChatMessageBottomSheetAdapter.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/adapter/ChatMessageBottomSheetAdapter.kt @@ -4,6 +4,7 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.annotation.UiThread import androidx.databinding.DataBindingUtil +import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView @@ -22,6 +23,7 @@ class ChatMessageBottomSheetAdapter : ListAdapter>() } - lateinit var viewLifecycleOwner: LifecycleOwner - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return when (viewType) { INCOMING_CHAT_MESSAGE -> createIncomingChatBubble(parent) @@ -86,6 +84,8 @@ class ConversationEventAdapter : ListAdapter(ChatRoomDiffCallback()) { +class ConversationsListAdapter : ListAdapter( + ChatRoomDiffCallback() +) { var selectedAdapterPosition = -1 val conversationClickedEvent: MutableLiveData> by lazy { @@ -36,7 +36,7 @@ class ConversationsListAdapter( ) val viewHolder = ViewHolder(binding) binding.apply { - lifecycleOwner = viewLifecycleOwner + lifecycleOwner = parent.findViewTreeLifecycleOwner() setOnClickListener { conversationClickedEvent.value = Event(model!!) diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationFragment.kt index 030fa9141..a6698929d 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationFragment.kt @@ -203,7 +203,6 @@ class ConversationFragment : GenericFragment() { viewModel.showBackButton.value = slideable } - adapter.viewLifecycleOwner = viewLifecycleOwner binding.eventsList.setHasFixedSize(true) binding.eventsList.layoutManager = LinearLayoutManager(requireContext()) diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationsListFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationsListFragment.kt index b2d0b72db..66039d7c7 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationsListFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationsListFragment.kt @@ -59,6 +59,12 @@ class ConversationsListFragment : AbstractTopBarFragment() { listViewModel.applyFilter() } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + adapter = ConversationsListAdapter() + } + override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? { if ( findNavController().currentDestination?.id == R.id.startConversationFragment || @@ -88,9 +94,7 @@ class ConversationsListFragment : AbstractTopBarFragment() { binding.lifecycleOwner = viewLifecycleOwner binding.viewModel = listViewModel - adapter = ConversationsListAdapter(viewLifecycleOwner) binding.conversationsList.setHasFixedSize(true) - binding.conversationsList.adapter = adapter binding.conversationsList.layoutManager = LinearLayoutManager(requireContext()) adapter.conversationLongClickedEvent.observe(viewLifecycleOwner) { @@ -151,6 +155,10 @@ class ConversationsListFragment : AbstractTopBarFragment() { adapter.submitList(it) Log.i("$TAG Conversations list ready with [${it.size}] items") + if (binding.conversationsList.adapter != adapter) { + binding.conversationsList.adapter = adapter + } + if (currentCount < it.size) { binding.conversationsList.scrollToPosition(0) } diff --git a/app/src/main/java/org/linphone/ui/main/contacts/adapter/ContactsListAdapter.kt b/app/src/main/java/org/linphone/ui/main/contacts/adapter/ContactsListAdapter.kt index cffa42e55..06d3ada00 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/adapter/ContactsListAdapter.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/adapter/ContactsListAdapter.kt @@ -4,8 +4,8 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.annotation.UiThread import androidx.databinding.DataBindingUtil -import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView @@ -17,7 +17,6 @@ import org.linphone.ui.main.contacts.model.ContactAvatarModel import org.linphone.utils.Event class ContactsListAdapter( - private val viewLifecycleOwner: LifecycleOwner, private val favourites: Boolean = false, private val disableLongClick: Boolean = false ) : ListAdapter(ContactDiffCallback()) { @@ -41,7 +40,7 @@ class ContactsListAdapter( ) val viewHolder = FavouriteViewHolder(binding) binding.apply { - lifecycleOwner = viewLifecycleOwner + lifecycleOwner = parent.findViewTreeLifecycleOwner() setOnClickListener { contactClickedEvent.value = Event(model!!) @@ -64,7 +63,7 @@ class ContactsListAdapter( ) val viewHolder = ViewHolder(binding) binding.apply { - lifecycleOwner = viewLifecycleOwner + lifecycleOwner = parent.findViewTreeLifecycleOwner() setOnClickListener { contactClickedEvent.value = Event(model!!) diff --git a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsListFragment.kt b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsListFragment.kt index 71c9c5363..4e1452c40 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsListFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsListFragment.kt @@ -67,6 +67,13 @@ class ContactsListFragment : AbstractTopBarFragment() { listViewModel.applyCurrentDefaultAccountFilter() } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + adapter = ContactsListAdapter() + favouritesAdapter = ContactsListAdapter(favourites = true) + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -85,21 +92,17 @@ class ContactsListFragment : AbstractTopBarFragment() { binding.lifecycleOwner = viewLifecycleOwner binding.viewModel = listViewModel - adapter = ContactsListAdapter(viewLifecycleOwner) binding.contactsList.setHasFixedSize(true) - binding.contactsList.adapter = adapter - configureAdapter(adapter) binding.contactsList.layoutManager = LinearLayoutManager(requireContext()) - favouritesAdapter = ContactsListAdapter(viewLifecycleOwner, favourites = true) binding.favouritesContactsList.setHasFixedSize(true) - binding.favouritesContactsList.adapter = favouritesAdapter - configureAdapter(favouritesAdapter) - val favouritesLayoutManager = LinearLayoutManager(requireContext()) favouritesLayoutManager.orientation = LinearLayoutManager.HORIZONTAL binding.favouritesContactsList.layoutManager = favouritesLayoutManager + configureAdapter(adapter) + configureAdapter(favouritesAdapter) + listViewModel.contactsList.observe( viewLifecycleOwner ) { @@ -107,6 +110,10 @@ class ContactsListFragment : AbstractTopBarFragment() { adapter.submitList(it) Log.i("$TAG Contacts list updated with [${it.size}] items") + if (binding.contactsList.adapter != adapter) { + binding.contactsList.adapter = adapter + } + if (currentCount < it.size) { Log.i("$TAG Contacts list updated with new items, scrolling to top") binding.contactsList.smoothScrollToPosition(0) @@ -122,6 +129,10 @@ class ContactsListFragment : AbstractTopBarFragment() { viewLifecycleOwner ) { favouritesAdapter.submitList(it) + + if (binding.favouritesContactsList.adapter != favouritesAdapter) { + binding.favouritesContactsList.adapter = favouritesAdapter + } Log.i("$TAG Favourites contacts list updated with [${it.size}] items") } diff --git a/app/src/main/java/org/linphone/ui/main/history/adapter/ContactHistoryListAdapter.kt b/app/src/main/java/org/linphone/ui/main/history/adapter/ContactHistoryListAdapter.kt index 25877c9b2..ecd9e9737 100644 --- a/app/src/main/java/org/linphone/ui/main/history/adapter/ContactHistoryListAdapter.kt +++ b/app/src/main/java/org/linphone/ui/main/history/adapter/ContactHistoryListAdapter.kt @@ -23,6 +23,7 @@ import android.view.LayoutInflater import android.view.ViewGroup import androidx.annotation.UiThread import androidx.databinding.DataBindingUtil +import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView @@ -40,7 +41,7 @@ class ContactHistoryListAdapter : ListAdapter { @@ -83,6 +85,8 @@ class ContactsAndSuggestionsListAdapter : false ) binding.apply { + lifecycleOwner = parent.findViewTreeLifecycleOwner() + setOnClickListener { contactClickedEvent.value = Event(model!!) } diff --git a/app/src/main/java/org/linphone/ui/main/history/adapter/HistoryListAdapter.kt b/app/src/main/java/org/linphone/ui/main/history/adapter/HistoryListAdapter.kt index 64b971d6b..003832814 100644 --- a/app/src/main/java/org/linphone/ui/main/history/adapter/HistoryListAdapter.kt +++ b/app/src/main/java/org/linphone/ui/main/history/adapter/HistoryListAdapter.kt @@ -5,6 +5,7 @@ import android.view.ViewGroup import androidx.annotation.UiThread import androidx.databinding.DataBindingUtil import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView @@ -37,6 +38,8 @@ class HistoryListAdapter : ListAdapter(Ca ) val viewHolder = ViewHolder(binding) binding.apply { + lifecycleOwner = parent.findViewTreeLifecycleOwner() + setOnClickListener { callLogClickedEvent.value = Event(model!!) } diff --git a/app/src/main/java/org/linphone/ui/main/history/model/CallLogModel.kt b/app/src/main/java/org/linphone/ui/main/history/model/CallLogModel.kt index 5adde47ce..2c3d60b59 100644 --- a/app/src/main/java/org/linphone/ui/main/history/model/CallLogModel.kt +++ b/app/src/main/java/org/linphone/ui/main/history/model/CallLogModel.kt @@ -52,7 +52,6 @@ class CallLogModel @WorkerThread constructor(private val callLog: CallLog) { dateTime.postValue("$date | $time") if (callLog.wasConference()) { - val conferenceInfo = coreContext.core.findConferenceInformationFromUri(address) if (conferenceInfo != null) { avatarModel = coreContext.contactsManager.getContactAvatarModelForConferenceInfo( diff --git a/app/src/main/java/org/linphone/ui/main/meetings/adapter/MeetingsListAdapter.kt b/app/src/main/java/org/linphone/ui/main/meetings/adapter/MeetingsListAdapter.kt index 0a3b05536..cc43691f0 100644 --- a/app/src/main/java/org/linphone/ui/main/meetings/adapter/MeetingsListAdapter.kt +++ b/app/src/main/java/org/linphone/ui/main/meetings/adapter/MeetingsListAdapter.kt @@ -7,6 +7,7 @@ import android.view.ViewGroup import androidx.annotation.UiThread import androidx.databinding.DataBindingUtil import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView @@ -53,6 +54,8 @@ class MeetingsListAdapter : false ) binding.apply { + lifecycleOwner = parent.findViewTreeLifecycleOwner() + setOnClickListener { meetingClickedEvent.value = Event(model!!) } diff --git a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt index 19f088d12..461dc5610 100644 --- a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt +++ b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt @@ -38,7 +38,6 @@ import androidx.annotation.UiThread import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.AppCompatEditText import androidx.appcompat.widget.AppCompatTextView -import androidx.core.content.res.ResourcesCompat import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.doOnLayout @@ -53,10 +52,8 @@ import coil.dispose import coil.load import coil.request.videoFrameMillis import coil.size.Dimension -import coil.transform.RoundedCornersTransformation import com.google.android.material.imageview.ShapeableImageView import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.linphone.BR @@ -246,13 +243,13 @@ private fun loadImageForChatBubble(imageView: ImageView, file: String?, grid: Bo } val width = if (grid) Dimension(dimen) else Dimension.Undefined val height = Dimension(dimen) - val radius = imageView.resources.getDimension( + /* val radius = imageView.resources.getDimension( R.dimen.chat_bubble_images_rounded_corner_radius - ) + ) */ if (FileUtils.isExtensionVideo(file)) { imageView.load(file) { videoFrameMillis(0) - transformations(RoundedCornersTransformation(radius)) + // transformations(RoundedCornersTransformation(radius)) size(width, height) listener( onError = { _, result -> @@ -295,52 +292,37 @@ fun ShapeableImageView.loadCircleFileWithCoil(file: String?) { @UiThread @BindingAdapter("coilAvatar") fun ShapeableImageView.loadAvatarWithCoil(model: AbstractAvatarModel?) { - val imageView = this - (context as AppCompatActivity).lifecycleScope.launch { - loadContactPictureWithCoil(imageView, model) - } + loadContactPictureWithCoil(this, model) } @UiThread @BindingAdapter("coilAvatarNoTrust") fun ShapeableImageView.loadAvatarWithCoilWithoutTrust(model: AbstractAvatarModel?) { - val imageView = this - (context as AppCompatActivity).lifecycleScope.launch { - loadContactPictureWithCoil(imageView, model, skipTrust = true) - } + loadContactPictureWithCoil(this, model, skipTrust = true) } @UiThread @BindingAdapter("coilBubbleAvatar") fun ShapeableImageView.loadBubbleAvatarWithCoil(model: AbstractAvatarModel?) { - val imageView = this - (context as AppCompatActivity).lifecycleScope.launch { - val size = R.dimen.avatar_bubble_size - val initialsSize = R.dimen.avatar_initials_bubble_text_size - loadContactPictureWithCoil(imageView, model, size = size, textSize = initialsSize) - } + val size = R.dimen.avatar_bubble_size + val initialsSize = R.dimen.avatar_initials_bubble_text_size + loadContactPictureWithCoil(this, model, size = size, textSize = initialsSize) } @UiThread @BindingAdapter("coilBigAvatar") fun ShapeableImageView.loadBigAvatarWithCoil(model: AbstractAvatarModel?) { - val imageView = this - (context as AppCompatActivity).lifecycleScope.launch { - val size = R.dimen.avatar_big_size - val initialsSize = R.dimen.avatar_initials_big_text_size - loadContactPictureWithCoil(imageView, model, size = size, textSize = initialsSize) - } + val size = R.dimen.avatar_big_size + val initialsSize = R.dimen.avatar_initials_big_text_size + loadContactPictureWithCoil(this, model, size = size, textSize = initialsSize) } @UiThread @BindingAdapter("coilCallAvatar") fun ShapeableImageView.loadCallAvatarWithCoil(model: AbstractAvatarModel?) { - val imageView = this - (context as AppCompatActivity).lifecycleScope.launch { - val size = R.dimen.avatar_in_call_size - val initialsSize = R.dimen.avatar_initials_call_text_size - loadContactPictureWithCoil(imageView, model, size = size, textSize = initialsSize) - } + val size = R.dimen.avatar_in_call_size + val initialsSize = R.dimen.avatar_initials_call_text_size + loadContactPictureWithCoil(this, model, size = size, textSize = initialsSize) } @UiThread @@ -356,109 +338,92 @@ fun ShapeableImageView.loadInitialsAvatarWithCoil(initials: String?) { } @SuppressLint("ResourceType") -private suspend fun loadContactPictureWithCoil( +private fun loadContactPictureWithCoil( imageView: ShapeableImageView, model: AbstractAvatarModel?, @DimenRes size: Int = 0, @DimenRes textSize: Int = 0, skipTrust: Boolean = false ) { - withContext(Dispatchers.IO) { - imageView.dispose() + imageView.dispose() - val context = imageView.context - if (model != null) { - if (model.forceConferenceIcon.value == true) { - imageView.load( - ResourcesCompat.getDrawable( - context.resources, - R.drawable.inset_users_three, - context.theme - ) - ) - return@withContext - } + val context = imageView.context + if (model != null) { + if (model.forceConferenceIcon.value == true) { + imageView.load(R.drawable.inset_users_three) + return + } - if (!skipTrust) { - if (model.showTrust.value == true) { - when (model.trust.value) { - ChatRoom.SecurityLevel.Safe -> { - imageView.setStrokeColorResource(R.color.blue_info_500) - imageView.setStrokeWidthResource(R.dimen.avatar_trust_border_width) - } - - ChatRoom.SecurityLevel.Unsafe -> { - imageView.setStrokeColorResource(R.color.red_danger_500) - imageView.setStrokeWidthResource(R.dimen.avatar_trust_border_width) - } - - else -> { - imageView.setStrokeColorResource(R.color.transparent_color) - imageView.setStrokeWidthResource(R.dimen.zero) - } + if (!skipTrust) { + if (model.showTrust.value == true) { + when (model.trust.value) { + ChatRoom.SecurityLevel.Safe -> { + imageView.setStrokeColorResource(R.color.blue_info_500) + imageView.setStrokeWidthResource(R.dimen.avatar_trust_border_width) } - } else { - imageView.setStrokeColorResource(R.color.transparent_color) - imageView.setStrokeWidthResource(R.dimen.zero) - } - } - val images = model.images.value.orEmpty() - val count = images.size - if (count == 1) { - val image = images.firstOrNull() + ChatRoom.SecurityLevel.Unsafe -> { + imageView.setStrokeColorResource(R.color.red_danger_500) + imageView.setStrokeWidthResource(R.dimen.avatar_trust_border_width) + } + + else -> { + imageView.setStrokeColorResource(R.color.transparent_color) + imageView.setStrokeWidthResource(R.dimen.zero) + } + } + } else { + imageView.setStrokeColorResource(R.color.transparent_color) + imageView.setStrokeWidthResource(R.dimen.zero) + } + } + + val images = model.images.value.orEmpty() + val count = images.size + if (count == 1) { + val image = images.firstOrNull() + if (image != null) { imageView.load(image) { - error( - coroutineScope { - withContext(Dispatchers.IO) { - val initials = model.initials.value.orEmpty() - if (initials.isEmpty() || initials == "+" || model.skipInitials.value == true) { - if (model.defaultToConferenceIcon.value == true) { - ResourcesCompat.getDrawable( - context.resources, - R.drawable.inset_users_three, - context.theme - ) - } else { - ResourcesCompat.getDrawable( - context.resources, - R.drawable.inset_user_circle, - context.theme - ) - } - } else { - val builder = AvatarGenerator(context) - builder.setInitials(model.initials.value.orEmpty()) - if (size > 0) { - builder.setAvatarSize(AppUtils.getDimension(size).toInt()) - } - if (textSize > 0) { - builder.setTextSize(AppUtils.getDimension(textSize)) - } - builder.build() - } - } + listener( + onError = { _, _ -> + imageView.load(getErrorImageLoader(context, model, size, textSize)) } ) } } else { - val w = if (size > 0) { - AppUtils.getDimension(size).toInt() - } else { - AppUtils.getDimension(R.dimen.avatar_list_cell_size).toInt() - } + imageView.load(getErrorImageLoader(context, model, size, textSize)) + } + } else { + val w = if (size > 0) { + AppUtils.getDimension(size).toInt() + } else { + AppUtils.getDimension(R.dimen.avatar_list_cell_size).toInt() + } + (context as AppCompatActivity).lifecycleScope.launch { val bitmap = ImageUtils.getBitmapFromMultipleAvatars(imageView.context, w, images) imageView.load(bitmap) } - } else { - imageView.load( - ResourcesCompat.getDrawable( - context.resources, - R.drawable.inset_user_circle, - context.theme - ) - ) } + } else { + imageView.load(R.drawable.smiley) + } +} + +private fun getErrorImageLoader( + context: Context, + model: AbstractAvatarModel, + size: Int, + textSize: Int +): Any { + val initials = model.initials.value.orEmpty() + return if (initials.isEmpty() || initials == "+" || model.skipInitials.value == true) { + if (model.defaultToConferenceIcon.value == true) { + R.drawable.inset_users_three + } else { + R.drawable.inset_user_circle + } + } else { + ImageUtils.getGeneratedAvatar(context, size, textSize, initials) } } diff --git a/app/src/main/java/org/linphone/utils/ImageUtils.kt b/app/src/main/java/org/linphone/utils/ImageUtils.kt index c486814f5..7a0c630b1 100644 --- a/app/src/main/java/org/linphone/utils/ImageUtils.kt +++ b/app/src/main/java/org/linphone/utils/ImageUtils.kt @@ -24,6 +24,7 @@ import android.graphics.Bitmap import android.graphics.Canvas import android.graphics.ImageDecoder import android.graphics.Rect +import android.graphics.drawable.BitmapDrawable import android.net.Uri import androidx.annotation.AnyThread import androidx.annotation.WorkerThread @@ -31,12 +32,28 @@ import androidx.core.graphics.drawable.toBitmap import coil.imageLoader import coil.request.ImageRequest import java.io.FileNotFoundException +import org.linphone.contacts.AvatarGenerator import org.linphone.core.tools.Log class ImageUtils { companion object { private const val TAG = "[Image Utils]" + @WorkerThread + fun getGeneratedAvatar(context: Context, size: Int = 0, textSize: Int = 0, initials: String): BitmapDrawable { + val builder = AvatarGenerator(context) + builder.setInitials(initials) + if (size > 0) { + builder.setAvatarSize( + AppUtils.getDimension(size).toInt() + ) + } + if (textSize > 0) { + builder.setTextSize(AppUtils.getDimension(textSize)) + } + return builder.build() + } + @WorkerThread fun getBitmap( context: Context,