mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-29 09:39:20 +00:00
Updated adapters (no longer need viewlifecycleowner) & improved avatar loader
This commit is contained in:
parent
01dab1613d
commit
26b3fe67a3
18 changed files with 171 additions and 148 deletions
|
|
@ -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<CallModel, RecyclerView.ViewHolder>(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!!)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<ChatMessageBottomSheetParticip
|
|||
parent,
|
||||
false
|
||||
)
|
||||
binding.lifecycleOwner = parent.findViewTreeLifecycleOwner()
|
||||
return ViewHolder(binding)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ package org.linphone.ui.main.chat.adapter
|
|||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
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
|
||||
|
|
@ -57,8 +57,6 @@ class ConversationEventAdapter : ListAdapter<EventLogModel, RecyclerView.ViewHol
|
|||
MutableLiveData<Event<ChatMessageModel>>()
|
||||
}
|
||||
|
||||
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<EventLogModel, RecyclerView.ViewHol
|
|||
)
|
||||
val viewHolder = IncomingBubbleViewHolder(binding)
|
||||
binding.apply {
|
||||
lifecycleOwner = parent.findViewTreeLifecycleOwner()
|
||||
|
||||
setOnLongClickListener {
|
||||
chatMessageLongPressEvent.value = Event(model!!)
|
||||
true
|
||||
|
|
@ -100,7 +100,6 @@ class ConversationEventAdapter : ListAdapter<EventLogModel, RecyclerView.ViewHol
|
|||
setScrollToRepliedMessageClickListener {
|
||||
scrollToRepliedMessageEvent.value = Event(model!!)
|
||||
}
|
||||
lifecycleOwner = viewLifecycleOwner
|
||||
}
|
||||
return viewHolder
|
||||
}
|
||||
|
|
@ -114,6 +113,8 @@ class ConversationEventAdapter : ListAdapter<EventLogModel, RecyclerView.ViewHol
|
|||
)
|
||||
val viewHolder = OutgoingBubbleViewHolder(binding)
|
||||
binding.apply {
|
||||
lifecycleOwner = parent.findViewTreeLifecycleOwner()
|
||||
|
||||
setOnLongClickListener {
|
||||
chatMessageLongPressEvent.value = Event(model!!)
|
||||
true
|
||||
|
|
@ -128,7 +129,6 @@ class ConversationEventAdapter : ListAdapter<EventLogModel, RecyclerView.ViewHol
|
|||
setScrollToRepliedMessageClickListener {
|
||||
scrollToRepliedMessageEvent.value = Event(model!!)
|
||||
}
|
||||
lifecycleOwner = viewLifecycleOwner
|
||||
}
|
||||
return viewHolder
|
||||
}
|
||||
|
|
@ -140,7 +140,7 @@ class ConversationEventAdapter : ListAdapter<EventLogModel, RecyclerView.ViewHol
|
|||
parent,
|
||||
false
|
||||
)
|
||||
binding.lifecycleOwner = viewLifecycleOwner
|
||||
binding.lifecycleOwner = parent.findViewTreeLifecycleOwner()
|
||||
return EventViewHolder(binding)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ConversationParticipantsAdapter : ListAdapter<ParticipantModel, RecyclerVi
|
|||
parent,
|
||||
false
|
||||
)
|
||||
binding.lifecycleOwner = parent.findViewTreeLifecycleOwner()
|
||||
return ViewHolder(binding)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -14,9 +14,9 @@ import org.linphone.databinding.ChatListCellBinding
|
|||
import org.linphone.ui.main.chat.model.ConversationModel
|
||||
import org.linphone.utils.Event
|
||||
|
||||
class ConversationsListAdapter(
|
||||
private val viewLifecycleOwner: LifecycleOwner
|
||||
) : ListAdapter<ConversationModel, RecyclerView.ViewHolder>(ChatRoomDiffCallback()) {
|
||||
class ConversationsListAdapter : ListAdapter<ConversationModel, RecyclerView.ViewHolder>(
|
||||
ChatRoomDiffCallback()
|
||||
) {
|
||||
var selectedAdapterPosition = -1
|
||||
|
||||
val conversationClickedEvent: MutableLiveData<Event<ConversationModel>> by lazy {
|
||||
|
|
@ -36,7 +36,7 @@ class ConversationsListAdapter(
|
|||
)
|
||||
val viewHolder = ViewHolder(binding)
|
||||
binding.apply {
|
||||
lifecycleOwner = viewLifecycleOwner
|
||||
lifecycleOwner = parent.findViewTreeLifecycleOwner()
|
||||
|
||||
setOnClickListener {
|
||||
conversationClickedEvent.value = Event(model!!)
|
||||
|
|
|
|||
|
|
@ -203,7 +203,6 @@ class ConversationFragment : GenericFragment() {
|
|||
viewModel.showBackButton.value = slideable
|
||||
}
|
||||
|
||||
adapter.viewLifecycleOwner = viewLifecycleOwner
|
||||
binding.eventsList.setHasFixedSize(true)
|
||||
binding.eventsList.layoutManager = LinearLayoutManager(requireContext())
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<ContactAvatarModel, RecyclerView.ViewHolder>(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!!)
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<CallLogHistoryModel, RecyclerView.
|
|||
parent,
|
||||
false
|
||||
)
|
||||
// binding.lifecycleOwner = viewLifecycleOwner
|
||||
binding.lifecycleOwner = parent.findViewTreeLifecycleOwner()
|
||||
return ViewHolder(binding)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -73,6 +74,7 @@ class ContactsAndSuggestionsListAdapter :
|
|||
parent,
|
||||
false
|
||||
)
|
||||
binding.lifecycleOwner = parent.findViewTreeLifecycleOwner()
|
||||
ContactViewHolder(binding)
|
||||
}
|
||||
else -> {
|
||||
|
|
@ -83,6 +85,8 @@ class ContactsAndSuggestionsListAdapter :
|
|||
false
|
||||
)
|
||||
binding.apply {
|
||||
lifecycleOwner = parent.findViewTreeLifecycleOwner()
|
||||
|
||||
setOnClickListener {
|
||||
contactClickedEvent.value = Event(model!!)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<CallLogModel, RecyclerView.ViewHolder>(Ca
|
|||
)
|
||||
val viewHolder = ViewHolder(binding)
|
||||
binding.apply {
|
||||
lifecycleOwner = parent.findViewTreeLifecycleOwner()
|
||||
|
||||
setOnClickListener {
|
||||
callLogClickedEvent.value = Event(model!!)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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!!)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue