Trying to optimize the ContactAvatarModel use

This commit is contained in:
Sylvain Berfini 2023-10-19 10:00:27 +02:00
parent be908cdf0e
commit 170e441744
19 changed files with 127 additions and 167 deletions

View file

@ -43,6 +43,7 @@ import org.linphone.core.FriendList
import org.linphone.core.FriendListListenerStub
import org.linphone.core.tools.Log
import org.linphone.ui.main.MainActivity
import org.linphone.ui.main.contacts.model.ContactAvatarModel
import org.linphone.ui.main.contacts.model.ContactNumberOrAddressClickListener
import org.linphone.ui.main.contacts.model.ContactNumberOrAddressModel
import org.linphone.ui.main.model.isInSecureMode
@ -61,12 +62,18 @@ class ContactsManager @UiThread constructor(context: Context) {
private val listeners = arrayListOf<ContactsListener>()
private val avatarsMap = hashMapOf<String, ContactAvatarModel>()
private val friendListListener: FriendListListenerStub = object : FriendListListenerStub() {
@WorkerThread
override fun onPresenceReceived(list: FriendList, friends: Array<Friend>) {
Log.i(
"$TAG Presence received for list [${list.displayName}] and [${friends.size}] friends"
)
avatarsMap.values.forEach(ContactAvatarModel::destroy)
avatarsMap.clear()
for (listener in listeners) {
listener.onContactsLoaded()
}
@ -127,6 +134,10 @@ class ContactsManager @UiThread constructor(context: Context) {
@UiThread
fun onNativeContactsLoaded() {
nativeContactsLoaded = true
avatarsMap.values.forEach(ContactAvatarModel::destroy)
avatarsMap.clear()
coreContext.postOnCoreThread {
notifyContactsListChanged()
}
@ -173,6 +184,34 @@ class ContactsManager @UiThread constructor(context: Context) {
return findContactByAddress(address)?.name ?: LinphoneUtils.getDisplayName(address)
}
@WorkerThread
fun getContactAvatarModelForAddress(address: Address?): ContactAvatarModel {
if (address == null) {
val fakeFriend = coreContext.core.createFriend()
return ContactAvatarModel(fakeFriend)
}
val clone = address.clone()
clone.clean()
val key = clone.asStringUriOnly()
val foundInMap = if (avatarsMap.keys.contains(key)) avatarsMap[key] else null
if (foundInMap != null) return foundInMap
val friend = coreContext.contactsManager.findContactByAddress(clone)
val avatar = if (friend != null) {
ContactAvatarModel(friend)
} else {
val fakeFriend = coreContext.core.createFriend()
fakeFriend.address = clone
ContactAvatarModel(fakeFriend)
}
avatarsMap[key] = avatar
return avatar
}
@WorkerThread
fun onCoreStarted(core: Core) {
core.addListener(coreListener)

View file

@ -57,9 +57,9 @@ class CallModel @WorkerThread constructor(val call: Call) {
call.addListener(callListener)
displayName.postValue(friend?.name ?: LinphoneUtils.getDisplayName(call.remoteAddress))
if (friend != null) {
contact.postValue(ContactAvatarModel(friend))
}
contact.postValue(
coreContext.contactsManager.getContactAvatarModelForAddress(call.remoteAddress)
)
state.postValue(LinphoneUtils.callStateToString(call.state))
isPaused.postValue(LinphoneUtils.isCallPaused(call.state))

View file

@ -396,6 +396,7 @@ class CurrentCallViewModel @UiThread constructor() : ViewModel() {
coreContext.postOnCoreThread { core ->
core.removeListener(coreListener)
contact.value?.destroy()
if (::currentCall.isInitialized) {
currentCall.removeListener(callListener)
@ -712,6 +713,8 @@ class CurrentCallViewModel @UiThread constructor() : ViewModel() {
@WorkerThread
private fun configureCall(call: Call) {
contact.value?.destroy()
currentCall = call
call.addListener(callListener)

View file

@ -28,6 +28,7 @@ import androidx.annotation.WorkerThread
import androidx.core.view.doOnPreDraw
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
import org.linphone.core.Address
import org.linphone.core.Friend
@ -35,7 +36,6 @@ import org.linphone.core.tools.Log
import org.linphone.databinding.StartChatFragmentBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.main.chat.viewmodel.StartConversationViewModel
import org.linphone.ui.main.contacts.model.ContactAvatarModel
import org.linphone.ui.main.fragment.GenericAddressPickerFragment
import org.linphone.ui.main.history.adapter.ContactsAndSuggestionsListAdapter
import org.linphone.ui.main.model.SelectedAddressModel
@ -132,7 +132,7 @@ class StartConversationFragment : GenericAddressPickerFragment() {
@WorkerThread
override fun onAddressSelected(address: Address, friend: Friend) {
if (viewModel.multipleSelectionMode.value == true) {
val avatarModel = ContactAvatarModel(friend)
val avatarModel = coreContext.contactsManager.getContactAvatarModelForAddress(address)
val model = SelectedAddressModel(address, avatarModel) {
viewModel.removeAddressModelFromSelection(it)
}

View file

@ -1,14 +1,18 @@
package org.linphone.ui.main.chat.model
import androidx.annotation.WorkerThread
import org.linphone.core.Friend
import org.linphone.LinphoneApplication
import org.linphone.core.ParticipantImdnState
import org.linphone.ui.main.contacts.model.ContactAvatarModel
import org.linphone.utils.TimestampUtils
class ChatMessageDeliveryModel @WorkerThread constructor(
friend: Friend,
imdnState: ParticipantImdnState
) : ContactAvatarModel(friend) {
) {
val address = imdnState.participant.address
val avatarModel = LinphoneApplication.coreContext.contactsManager.getContactAvatarModelForAddress(
address
)
val time = TimestampUtils.toString(imdnState.stateChangeTime)
}

View file

@ -28,7 +28,6 @@ import org.linphone.core.Address
import org.linphone.core.ChatMessage
import org.linphone.core.ChatMessageListenerStub
import org.linphone.core.ChatMessageReaction
import org.linphone.core.ParticipantImdnState
import org.linphone.core.tools.Log
import org.linphone.ui.main.contacts.model.ContactAvatarModel
import org.linphone.utils.Event
@ -133,30 +132,10 @@ class ChatMessageModel @WorkerThread constructor(
private fun computeDeliveryStatus() {
val list = arrayListOf<ChatMessageDeliveryModel>()
for (participant in chatMessage.getParticipantsByImdnState(ChatMessage.State.Displayed)) {
list.add(getDeliveryModelForAddress(participant))
}
/*for (participant in chatMessage.getParticipantsByImdnState(ChatMessage.State.Displayed)) {
list.add(ChatMessageDeliveryModel(participant))
}*/
deliveryModels.postValue(list)
}
@WorkerThread
private fun getDeliveryModelForAddress(participantImdnState: ParticipantImdnState): ChatMessageDeliveryModel {
val address = participantImdnState.participant.address
Log.i("$TAG Looking for participant model with address [${address.asStringUriOnly()}]")
val clone = address.clone()
clone.clean()
val friend = coreContext.contactsManager.findContactByAddress(clone)
val avatar = if (friend != null) {
ChatMessageDeliveryModel(friend, participantImdnState)
} else {
val fakeFriend = coreContext.core.createFriend()
fakeFriend.address = clone
ChatMessageDeliveryModel(fakeFriend, participantImdnState)
}
return avatar
}
}

View file

@ -149,16 +149,9 @@ class ConversationModel @WorkerThread constructor(private val chatRoom: ChatRoom
model.setPicturesFromFriends(friends)
avatarModel.postValue(model)
} else {
val friend = coreContext.contactsManager.findContactByAddress(address)
if (friend != null) {
val model = ContactAvatarModel(friend)
avatarModel.postValue(model)
} else {
val fakeFriend = coreContext.core.createFriend()
fakeFriend.address = address
val model = ContactAvatarModel(fakeFriend)
avatarModel.postValue(model)
}
avatarModel.postValue(
coreContext.contactsManager.getContactAvatarModelForAddress(address)
)
}
isMuted.postValue(chatRoom.muted)

View file

@ -22,19 +22,19 @@ package org.linphone.ui.main.chat.model
import android.view.View
import androidx.annotation.UiThread
import androidx.annotation.WorkerThread
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.core.Address
import org.linphone.core.Friend
import org.linphone.ui.main.contacts.model.ContactAvatarModel
class ParticipantModel @WorkerThread constructor(
friend: Friend,
val address: Address,
val isMyselfAdmin: Boolean,
val isParticipantAdmin: Boolean,
private val onMenuClicked: ((view: View, model: ParticipantModel) -> Unit)? = null
) : ContactAvatarModel(friend) {
) {
val sipUri = address.asStringUriOnly()
val avatarModel = coreContext.contactsManager.getContactAvatarModelForAddress(address)
@UiThread
fun openMenu(view: View) {
onMenuClicked?.invoke(view, this)

View file

@ -25,7 +25,6 @@ import androidx.annotation.WorkerThread
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.core.Address
import org.linphone.core.ChatRoom
import org.linphone.core.ChatRoomListenerStub
import org.linphone.core.EventLog
@ -74,8 +73,6 @@ class ConversationInfoViewModel @UiThread constructor() : ViewModel() {
private lateinit var chatRoom: ChatRoom
private val avatarsMap = hashMapOf<String, ParticipantModel>()
private val chatRoomListener = object : ChatRoomListenerStub() {
@WorkerThread
override fun onParticipantAdded(chatRoom: ChatRoom, eventLog: EventLog) {
@ -122,9 +119,6 @@ class ConversationInfoViewModel @UiThread constructor() : ViewModel() {
if (::chatRoom.isInitialized) {
chatRoom.removeListener(chatRoomListener)
}
avatarModel.value?.destroy()
avatarsMap.values.forEach(ParticipantModel::destroy)
}
}
@ -285,71 +279,43 @@ class ConversationInfoViewModel @UiThread constructor() : ViewModel() {
@WorkerThread
private fun computeParticipantsList() {
avatarModel.value?.destroy()
avatarsMap.values.forEach(ParticipantModel::destroy)
val groupChatRoom = isChatRoomAGroup()
val selfAdmin = chatRoom.me?.isAdmin == true
val friends = arrayListOf<Friend>()
val participantsList = arrayListOf<ParticipantModel>()
if (chatRoom.hasCapability(ChatRoom.Capabilities.Basic.toInt())) {
val model = getParticipantModelForAddress(chatRoom.peerAddress, false)
friends.add(model.friend)
val model = ParticipantModel(chatRoom.peerAddress, selfAdmin, false) { view, model ->
// openMenu
showParticipantAdminPopupMenuEvent.postValue(Event(Pair(view, model)))
}
friends.add(model.avatarModel.friend)
participantsList.add(model)
} else {
for (participant in chatRoom.participants) {
val model = getParticipantModelForAddress(
participant.address,
if (groupChatRoom) participant.isAdmin else false
)
friends.add(model.friend)
val isParticipantAdmin = if (groupChatRoom) participant.isAdmin else false
val model = ParticipantModel(participant.address, selfAdmin, isParticipantAdmin) { view, model ->
// openMenu
showParticipantAdminPopupMenuEvent.postValue(Event(Pair(view, model)))
}
friends.add(model.avatarModel.friend)
participantsList.add(model)
}
}
val avatar = if (groupChatRoom) {
val fakeFriend = coreContext.core.createFriend()
ContactAvatarModel(fakeFriend)
val model = ContactAvatarModel(fakeFriend)
model.setPicturesFromFriends(friends)
model
} else {
participantsList.first()
participantsList.first().avatarModel
}
avatar.setPicturesFromFriends(friends)
avatarModel.postValue(avatar)
participants.postValue(participantsList)
}
@WorkerThread
private fun getParticipantModelForAddress(address: Address, isAdmin: Boolean): ParticipantModel {
Log.i("$TAG Looking for participant model with address [${address?.asStringUriOnly()}]")
val selfAdmin = chatRoom.me?.isAdmin == true
val clone = address.clone()
clone.clean()
val key = clone.asStringUriOnly()
val foundInMap = if (avatarsMap.keys.contains(key)) avatarsMap[key] else null
if (foundInMap != null) return foundInMap
val friend = coreContext.contactsManager.findContactByAddress(clone)
val avatar = if (friend != null) {
ParticipantModel(friend, clone, selfAdmin, isAdmin) { view, model ->
// openMenu
showParticipantAdminPopupMenuEvent.postValue(Event(Pair(view, model)))
}
} else {
val fakeFriend = coreContext.core.createFriend()
fakeFriend.address = clone
ParticipantModel(fakeFriend, clone, selfAdmin, isAdmin) { view, model ->
// openMenu
showParticipantAdminPopupMenuEvent.postValue(Event(Pair(view, model)))
}
}
avatarsMap[key] = avatar
return avatar
}
@WorkerThread
private fun isChatRoomAGroup(): Boolean {
return if (::chatRoom.isInitialized) {

View file

@ -80,8 +80,6 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
private lateinit var chatRoom: ChatRoom
private val avatarsMap = hashMapOf<String, ContactAvatarModel>()
private val chatRoomListener = object : ChatRoomListenerStub() {
@WorkerThread
override fun onChatMessageSending(chatRoom: ChatRoom, eventLog: EventLog) {
@ -91,7 +89,9 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
val list = arrayListOf<EventLogModel>()
list.addAll(events.value.orEmpty())
val avatarModel = getAvatarModelForAddress(message?.localAddress)
val avatarModel = coreContext.contactsManager.getContactAvatarModelForAddress(
message?.localAddress
)
val lastEvent = events.value.orEmpty().lastOrNull()
val group = if (lastEvent != null) {
shouldWeGroupTwoEvents(eventLog, lastEvent.eventLog)
@ -144,6 +144,7 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
init {
searchBarVisible.value = false
isEmojiPickerOpen.value = false
}
override fun onCleared() {
@ -151,9 +152,7 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
coreContext.postOnCoreThread {
chatRoom.removeListener(chatRoomListener)
avatarModel.value?.destroy()
events.value.orEmpty().forEach(EventLogModel::destroy)
avatarsMap.values.forEach(ContactAvatarModel::destroy)
}
}
@ -300,11 +299,12 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
val avatar = if (group) {
val fakeFriend = coreContext.core.createFriend()
ContactAvatarModel(fakeFriend)
val model = ContactAvatarModel(fakeFriend)
model.setPicturesFromFriends(friends)
model
} else {
getAvatarModelForAddress(address)
coreContext.contactsManager.getContactAvatarModelForAddress(address)
}
avatar.setPicturesFromFriends(friends)
avatarModel.postValue(avatar)
computeEvents()
@ -329,7 +329,9 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
// Handle all events in group, then re-start a new group with current item
var index = 0
for (groupedEvent in groupedEventLogs) {
val avatar = getAvatarModelForAddress(groupedEvent.chatMessage?.fromAddress)
val avatar = coreContext.contactsManager.getContactAvatarModelForAddress(
groupedEvent.chatMessage?.fromAddress
)
val model = EventLogModel(
groupedEvent,
avatar,
@ -355,7 +357,9 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
if (event.type == EventLog.Type.ConferenceChatMessage) {
val message = event.chatMessage ?: continue
val fromAddress = message.fromAddress
val model = getAvatarModelForAddress(fromAddress)
val model = coreContext.contactsManager.getContactAvatarModelForAddress(
fromAddress
)
if (
!model.name.value.orEmpty().contains(filter, ignoreCase = true) &&
!fromAddress.asStringUriOnly().contains(filter, ignoreCase = true) &&
@ -407,40 +411,12 @@ class ConversationViewModel @UiThread constructor() : ViewModel() {
}
}
@WorkerThread
private fun getAvatarModelForAddress(address: Address?): ContactAvatarModel {
Log.i("$TAG Looking for avatar model with address [${address?.asStringUriOnly()}]")
if (address == null) {
val fakeFriend = coreContext.core.createFriend()
return ContactAvatarModel(fakeFriend)
}
val clone = address.clone()
clone.clean()
val key = clone.asStringUriOnly()
val foundInMap = if (avatarsMap.keys.contains(key)) avatarsMap[key] else null
if (foundInMap != null) return foundInMap
val friend = coreContext.contactsManager.findContactByAddress(clone)
val avatar = if (friend != null) {
ContactAvatarModel(friend)
} else {
val fakeFriend = coreContext.core.createFriend()
fakeFriend.address = clone
ContactAvatarModel(fakeFriend)
}
avatarsMap[key] = avatar
return avatar
}
@WorkerThread
private fun computeComposingLabel() {
var composingFriends = arrayListOf<String>()
val composingFriends = arrayListOf<String>()
var label = ""
for (address in chatRoom.composingAddresses) {
val avatar = getAvatarModelForAddress(address)
val avatar = coreContext.contactsManager.getContactAvatarModelForAddress(address)
val name = avatar.name.value ?: LinphoneUtils.getDisplayName(address)
composingFriends.add(name)
label += "$name, "

View file

@ -36,7 +36,6 @@ import org.linphone.core.MagicSearch
import org.linphone.core.MagicSearchListenerStub
import org.linphone.core.SearchResult
import org.linphone.core.tools.Log
import org.linphone.ui.main.contacts.model.ContactAvatarModel
import org.linphone.ui.main.history.model.ContactOrSuggestionModel
import org.linphone.ui.main.model.isInSecureMode
import org.linphone.ui.main.viewmodel.AddressSelectionViewModel
@ -356,7 +355,9 @@ class StartConversationViewModel @UiThread constructor() : AddressSelectionViewM
val friend = coreContext.contactsManager.findContactByAddress(address)
if (friend != null) {
val model = ContactOrSuggestionModel(address, friend)
val avatarModel = ContactAvatarModel(friend)
val avatarModel = coreContext.contactsManager.getContactAvatarModelForAddress(
address
)
model.avatarModel.postValue(avatarModel)
val currentLetter = friend.name?.get(0).toString()

View file

@ -36,7 +36,7 @@ import org.linphone.ui.main.model.isInSecureMode
import org.linphone.utils.AppUtils
import org.linphone.utils.TimestampUtils
open class ContactAvatarModel @WorkerThread constructor(val friend: Friend) : AbstractAvatarModel() {
class ContactAvatarModel @WorkerThread constructor(val friend: Friend) : AbstractAvatarModel() {
companion object {
private const val TAG = "[Contact Avatar Model]"
}
@ -66,7 +66,9 @@ open class ContactAvatarModel @WorkerThread constructor(val friend: Friend) : Ab
}
init {
friend.addListener(friendListener)
if (friend.addresses.isNotEmpty()) {
friend.addListener(friendListener)
}
initials.postValue(AppUtils.getInitials(friend.name.orEmpty()))
trust.postValue(SecurityLevel.Encrypted) // TODO FIXME: use API
@ -79,7 +81,9 @@ open class ContactAvatarModel @WorkerThread constructor(val friend: Friend) : Ab
@WorkerThread
fun destroy() {
friend.removeListener(friendListener)
if (friend.addresses.isNotEmpty()) {
friend.removeListener(friendListener)
}
}
@WorkerThread

View file

@ -160,6 +160,7 @@ class ContactViewModel @UiThread constructor() : ViewModel() {
coreContext.postOnCoreThread {
coreContext.contactsManager.removeListener(contactsListener)
contact.value?.destroy()
}
}
@ -183,6 +184,7 @@ class ContactViewModel @UiThread constructor() : ViewModel() {
fun refreshContactInfo() {
isFavourite.postValue(friend.starred)
contact.value?.destroy()
contact.postValue(ContactAvatarModel(friend))
val organization = friend.organization

View file

@ -107,6 +107,7 @@ class ContactsListViewModel @UiThread constructor() : AbstractTopBarViewModel()
coreContext.postOnCoreThread {
magicSearch.removeListener(magicSearchListener)
coreContext.contactsManager.removeListener(contactsListener)
contactsList.value.orEmpty().forEach(ContactAvatarModel::destroy)
}
super.onCleared()
}

View file

@ -43,15 +43,14 @@ class CallLogModel @WorkerThread constructor(private val callLog: CallLog) {
dateTime.postValue(displayedDate)
val friend = coreContext.contactsManager.findContactByAddress(address)
avatarModel = coreContext.contactsManager.getContactAvatarModelForAddress(address)
if (friend != null) {
friendRefKey = friend.refKey
avatarModel = ContactAvatarModel(friend)
friendExists = true
} else {
val fakeFriend = coreContext.core.createFriend()
fakeFriend.address = address
friendRefKey = null
avatarModel = ContactAvatarModel(fakeFriend)
friendExists = false
}

View file

@ -34,7 +34,6 @@ import org.linphone.core.MagicSearch
import org.linphone.core.MagicSearchListenerStub
import org.linphone.core.SearchResult
import org.linphone.core.tools.Log
import org.linphone.ui.main.contacts.model.ContactAvatarModel
import org.linphone.ui.main.history.model.ContactOrSuggestionModel
import org.linphone.ui.main.history.model.NumpadModel
import org.linphone.ui.main.model.isInSecureMode
@ -197,7 +196,9 @@ class StartCallViewModel @UiThread constructor() : ViewModel() {
val friend = coreContext.contactsManager.findContactByAddress(address)
if (friend != null) {
val model = ContactOrSuggestionModel(address, friend)
val avatarModel = ContactAvatarModel(friend)
val avatarModel = coreContext.contactsManager.getContactAvatarModelForAddress(
address
)
model.avatarModel.postValue(avatarModel)
val currentLetter = friend.name?.get(0).toString()

View file

@ -29,19 +29,11 @@ class ParticipantModel @WorkerThread constructor(address: Address, val isOrganiz
val avatarModel = MutableLiveData<ContactAvatarModel>()
init {
val friend = coreContext.contactsManager.findContactByAddress(address)
val avatar = if (friend != null) {
ContactAvatarModel(friend)
} else {
val fakeFriend = coreContext.core.createFriend()
fakeFriend.address = address
ContactAvatarModel(fakeFriend)
}
val avatar = coreContext.contactsManager.getContactAvatarModelForAddress(address)
avatarModel.postValue(avatar)
}
@WorkerThread
fun destroy() {
avatarModel.value?.destroy()
}
}

View file

@ -26,7 +26,7 @@
android:layout_height="@dimen/avatar_list_cell_size"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
coilAvatar="@{model}"
coilAvatar="@{model.avatarModel}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@ -38,8 +38,8 @@
android:layout_marginEnd="@dimen/avatar_presence_badge_end_margin"
android:background="@drawable/led_background"
android:padding="@dimen/avatar_presence_badge_padding"
app:presenceIcon="@{model.presenceStatus}"
android:visibility="@{model.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE}"
app:presenceIcon="@{model.avatarModel.presenceStatus}"
android:visibility="@{model.avatarModel.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE}"
app:layout_constraintEnd_toEndOf="@id/avatar"
app:layout_constraintBottom_toBottomOf="@id/avatar"/>
@ -47,8 +47,8 @@
android:id="@+id/trust_badge"
android:layout_width="@dimen/avatar_presence_badge_size"
android:layout_height="@dimen/avatar_presence_badge_size"
android:src="@{model.trust == SecurityLevel.Safe ? @drawable/trusted : @drawable/not_trusted, default=@drawable/trusted}"
android:visibility="@{model.trust == SecurityLevel.Safe || model.trust == SecurityLevel.Unsafe ? View.VISIBLE : View.GONE}"
android:src="@{model.avatarModel.trust == SecurityLevel.Safe ? @drawable/trusted : @drawable/not_trusted, default=@drawable/trusted}"
android:visibility="@{model.avatarModel.trust == SecurityLevel.Safe || model.avatarModel.trust == SecurityLevel.Unsafe ? View.VISIBLE : View.GONE}"
app:layout_constraintStart_toStartOf="@id/avatar"
app:layout_constraintBottom_toBottomOf="@id/avatar"/>
@ -57,7 +57,7 @@
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@{model.name, default=`John Doe`}"
android:text="@{model.avatarModel.name, default=`John Doe`}"
android:textSize="14sp"
android:layout_marginStart="10dp"
app:layout_constraintVertical_chainStyle="packed"

View file

@ -26,7 +26,7 @@
android:layout_height="@dimen/avatar_list_cell_size"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
coilAvatar="@{model}"
coilAvatar="@{model.avatarModel}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@ -38,8 +38,8 @@
android:layout_marginEnd="@dimen/avatar_presence_badge_end_margin"
android:background="@drawable/led_background"
android:padding="@dimen/avatar_presence_badge_padding"
app:presenceIcon="@{model.presenceStatus}"
android:visibility="@{model.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE}"
app:presenceIcon="@{model.avatarModel.presenceStatus}"
android:visibility="@{model.avatarModel.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE}"
app:layout_constraintEnd_toEndOf="@id/avatar"
app:layout_constraintBottom_toBottomOf="@id/avatar"/>
@ -47,8 +47,8 @@
android:id="@+id/trust_badge"
android:layout_width="@dimen/avatar_presence_badge_size"
android:layout_height="@dimen/avatar_presence_badge_size"
android:src="@{model.trust == SecurityLevel.Safe ? @drawable/trusted : @drawable/not_trusted, default=@drawable/trusted}"
android:visibility="@{model.trust == SecurityLevel.Safe || model.trust == SecurityLevel.Unsafe ? View.VISIBLE : View.GONE}"
android:src="@{model.avatarModel.trust == SecurityLevel.Safe ? @drawable/trusted : @drawable/not_trusted, default=@drawable/trusted}"
android:visibility="@{model.avatarModel.trust == SecurityLevel.Safe || model.avatarModel.trust == SecurityLevel.Unsafe ? View.VISIBLE : View.GONE}"
app:layout_constraintStart_toStartOf="@id/avatar"
app:layout_constraintBottom_toBottomOf="@id/avatar"/>
@ -57,7 +57,7 @@
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@{model.name, default=`John Doe`}"
android:text="@{model.avatarModel.name, default=`John Doe`}"
android:textSize="14sp"
android:layout_marginStart="10dp"
app:layout_constraintVertical_chainStyle="packed"