Fixed contacts not updated in conversation if found after view was layed out

This commit is contained in:
Sylvain Berfini 2023-04-24 12:05:40 +02:00
parent e725eb4e7b
commit 0733ced356
5 changed files with 53 additions and 14 deletions

View file

@ -260,11 +260,26 @@ class ChatMessagesListAdapter(
fun bind(eventLog: EventLogData) { fun bind(eventLog: EventLogData) {
with(binding) { with(binding) {
if (eventLog.eventLog.type == EventLog.Type.ConferenceChatMessage) { if (eventLog.eventLog.type == EventLog.Type.ConferenceChatMessage) {
val chatMessageViewModel = eventLog.data as ChatMessageData val chatMessageData = eventLog.data as ChatMessageData
chatMessageViewModel.setContentClickListener(contentClickedListener) chatMessageData.setContentClickListener(contentClickedListener)
val chatMessage = chatMessageViewModel.chatMessage val chatMessage = chatMessageData.chatMessage
data = chatMessageViewModel data = chatMessageData
chatMessageData.contactNewlyFoundEvent.observe(viewLifecycleOwner) {
it.consume {
// Post to prevent IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling
binding.root.post {
try {
notifyItemChanged(bindingAdapterPosition)
} catch (e: Exception) {
Log.e(
"[Chat Messages Adapter] Can't notify item [$bindingAdapterPosition] has changed: $e"
)
}
}
}
}
lifecycleOwner = viewLifecycleOwner lifecycleOwner = viewLifecycleOwner
@ -283,7 +298,7 @@ class ChatMessagesListAdapter(
} }
setReplyClickListener { setReplyClickListener {
val reply = chatMessageViewModel.replyData.value?.chatMessage val reply = chatMessageData.replyData.value?.chatMessage
if (reply != null) { if (reply != null) {
scrollToChatMessageEvent.value = Event(reply) scrollToChatMessageEvent.value = Event(reply)
} }
@ -323,7 +338,7 @@ class ChatMessagesListAdapter(
} }
} }
chatMessageViewModel.updateBubbleBackground(hasPrevious, hasNext) chatMessageData.updateBubbleBackground(hasPrevious, hasNext)
executePendingBindings() executePendingBindings()
@ -354,7 +369,7 @@ class ChatMessagesListAdapter(
totalSize -= itemSize totalSize -= itemSize
} }
if (chatMessage.isOutgoing || if (chatMessage.isOutgoing ||
chatMessageViewModel.contact.value != null || chatMessageData.contact.value != null ||
advancedContextMenuOptionsDisabled || advancedContextMenuOptionsDisabled ||
corePreferences.readOnlyNativeContacts corePreferences.readOnlyNativeContacts
) { ) {

View file

@ -24,12 +24,15 @@ import android.text.Spannable
import android.util.Patterns import android.util.Patterns
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import java.util.regex.Pattern import java.util.regex.Pattern
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R import org.linphone.R
import org.linphone.contact.ContactsUpdatedListenerStub
import org.linphone.contact.GenericContactData import org.linphone.contact.GenericContactData
import org.linphone.core.ChatMessage import org.linphone.core.ChatMessage
import org.linphone.core.ChatMessageListenerStub import org.linphone.core.ChatMessageListenerStub
import org.linphone.core.tools.Log import org.linphone.core.tools.Log
import org.linphone.utils.AppUtils import org.linphone.utils.AppUtils
import org.linphone.utils.Event
import org.linphone.utils.PatternClickableSpan import org.linphone.utils.PatternClickableSpan
import org.linphone.utils.TimestampUtils import org.linphone.utils.TimestampUtils
@ -64,6 +67,10 @@ class ChatMessageData(val chatMessage: ChatMessage) : GenericContactData(chatMes
val isOutgoing = chatMessage.isOutgoing val isOutgoing = chatMessage.isOutgoing
val contactNewlyFoundEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}
var hasPreviousMessage = false var hasPreviousMessage = false
var hasNextMessage = false var hasNextMessage = false
@ -80,6 +87,16 @@ class ChatMessageData(val chatMessage: ChatMessage) : GenericContactData(chatMes
} }
} }
private val contactsListener = object : ContactsUpdatedListenerStub() {
override fun onContactsUpdated() {
contactLookup()
if (contact.value != null) {
coreContext.contactsManager.removeListener(this)
contactNewlyFoundEvent.value = Event(true)
}
}
}
init { init {
chatMessage.addListener(listener) chatMessage.addListener(listener)
@ -101,6 +118,10 @@ class ChatMessageData(val chatMessage: ChatMessage) : GenericContactData(chatMes
updateChatMessageState(chatMessage.state) updateChatMessageState(chatMessage.state)
updateContentsList() updateContentsList()
if (contact.value == null) {
coreContext.contactsManager.addListener(contactsListener)
}
} }
override fun destroy() { override fun destroy() {

View file

@ -260,12 +260,13 @@ class ConferenceViewModel : ViewModel() {
if (state == Call.State.StreamsRunning && call.conference?.isIn == true) { if (state == Call.State.StreamsRunning && call.conference?.isIn == true) {
isConferenceLocallyPaused.value = false isConferenceLocallyPaused.value = false
conferenceParticipantDevices.value?.forEach { conferenceParticipantDevices.value?.forEach {
if (it.isMe) if (it.isMe) {
it.isInConference.value = true it.isInConference.value = true
} }
} }
} }
} }
}
init { init {
coreContext.core.addListener(listener) coreContext.core.addListener(listener)

View file

@ -61,7 +61,7 @@ open class GenericContactData(private val sipAddress: Address) : ContactDataInte
open fun destroy() { open fun destroy() {
} }
private fun contactLookup() { protected fun contactLookup() {
displayName.value = LinphoneUtils.getDisplayName(sipAddress) displayName.value = LinphoneUtils.getDisplayName(sipAddress)
val friend = coreContext.contactsManager.findContactByAddress(sipAddress) val friend = coreContext.contactsManager.findContactByAddress(sipAddress)
@ -88,7 +88,7 @@ abstract class GenericContactViewModel(private val sipAddress: Address) : Messag
contactLookup() contactLookup()
} }
private fun contactLookup() { protected fun contactLookup() {
displayName.value = LinphoneUtils.getDisplayName(sipAddress) displayName.value = LinphoneUtils.getDisplayName(sipAddress)
val friend = coreContext.contactsManager.findContactByAddress(sipAddress) val friend = coreContext.contactsManager.findContactByAddress(sipAddress)
if (friend != null) { if (friend != null) {

View file

@ -64,10 +64,11 @@ class NativeCallWrapper(var callId: String) : Connection() {
override fun onHold() { override fun onHold() {
Log.i("[Connection] Pausing telecom call with id: $callId") Log.i("[Connection] Pausing telecom call with id: $callId")
getCall()?.let { call -> getCall()?.let { call ->
if (call.conference != null) if (call.conference != null) {
call.conference?.leave() call.conference?.leave()
else } else {
call.pause() call.pause()
}
} ?: selfDestroy() } ?: selfDestroy()
setOnHold() setOnHold()
} }
@ -75,10 +76,11 @@ class NativeCallWrapper(var callId: String) : Connection() {
override fun onUnhold() { override fun onUnhold() {
Log.i("[Connection] Resuming telecom call with id: $callId") Log.i("[Connection] Resuming telecom call with id: $callId")
getCall()?.let { call -> getCall()?.let { call ->
if (call.conference != null) if (call.conference != null) {
call.conference?.enter() call.conference?.enter()
else } else {
call.resume() call.resume()
}
} ?: selfDestroy() } ?: selfDestroy()
setActive() setActive()
} }