diff --git a/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatMessagesListAdapter.kt b/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatMessagesListAdapter.kt index b4fd5a72a..38a5de3f5 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatMessagesListAdapter.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatMessagesListAdapter.kt @@ -260,11 +260,26 @@ class ChatMessagesListAdapter( fun bind(eventLog: EventLogData) { with(binding) { if (eventLog.eventLog.type == EventLog.Type.ConferenceChatMessage) { - val chatMessageViewModel = eventLog.data as ChatMessageData - chatMessageViewModel.setContentClickListener(contentClickedListener) + val chatMessageData = eventLog.data as ChatMessageData + chatMessageData.setContentClickListener(contentClickedListener) - val chatMessage = chatMessageViewModel.chatMessage - data = chatMessageViewModel + val chatMessage = chatMessageData.chatMessage + 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 @@ -283,7 +298,7 @@ class ChatMessagesListAdapter( } setReplyClickListener { - val reply = chatMessageViewModel.replyData.value?.chatMessage + val reply = chatMessageData.replyData.value?.chatMessage if (reply != null) { scrollToChatMessageEvent.value = Event(reply) } @@ -323,7 +338,7 @@ class ChatMessagesListAdapter( } } - chatMessageViewModel.updateBubbleBackground(hasPrevious, hasNext) + chatMessageData.updateBubbleBackground(hasPrevious, hasNext) executePendingBindings() @@ -354,7 +369,7 @@ class ChatMessagesListAdapter( totalSize -= itemSize } if (chatMessage.isOutgoing || - chatMessageViewModel.contact.value != null || + chatMessageData.contact.value != null || advancedContextMenuOptionsDisabled || corePreferences.readOnlyNativeContacts ) { diff --git a/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageData.kt b/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageData.kt index dc8f84a90..a70fbfd11 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageData.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/data/ChatMessageData.kt @@ -24,12 +24,15 @@ import android.text.Spannable import android.util.Patterns import androidx.lifecycle.MutableLiveData import java.util.regex.Pattern +import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R +import org.linphone.contact.ContactsUpdatedListenerStub import org.linphone.contact.GenericContactData import org.linphone.core.ChatMessage import org.linphone.core.ChatMessageListenerStub import org.linphone.core.tools.Log import org.linphone.utils.AppUtils +import org.linphone.utils.Event import org.linphone.utils.PatternClickableSpan import org.linphone.utils.TimestampUtils @@ -64,6 +67,10 @@ class ChatMessageData(val chatMessage: ChatMessage) : GenericContactData(chatMes val isOutgoing = chatMessage.isOutgoing + val contactNewlyFoundEvent: MutableLiveData> by lazy { + MutableLiveData>() + } + var hasPreviousMessage = 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 { chatMessage.addListener(listener) @@ -101,6 +118,10 @@ class ChatMessageData(val chatMessage: ChatMessage) : GenericContactData(chatMes updateChatMessageState(chatMessage.state) updateContentsList() + + if (contact.value == null) { + coreContext.contactsManager.addListener(contactsListener) + } } override fun destroy() { diff --git a/app/src/main/java/org/linphone/activities/voip/viewmodels/ConferenceViewModel.kt b/app/src/main/java/org/linphone/activities/voip/viewmodels/ConferenceViewModel.kt index 5d022a125..d7685e7a9 100644 --- a/app/src/main/java/org/linphone/activities/voip/viewmodels/ConferenceViewModel.kt +++ b/app/src/main/java/org/linphone/activities/voip/viewmodels/ConferenceViewModel.kt @@ -260,8 +260,9 @@ class ConferenceViewModel : ViewModel() { if (state == Call.State.StreamsRunning && call.conference?.isIn == true) { isConferenceLocallyPaused.value = false conferenceParticipantDevices.value?.forEach { - if (it.isMe) + if (it.isMe) { it.isInConference.value = true + } } } } diff --git a/app/src/main/java/org/linphone/contact/ContactDataInterface.kt b/app/src/main/java/org/linphone/contact/ContactDataInterface.kt index 3d0fa893a..fe4e1ac1b 100644 --- a/app/src/main/java/org/linphone/contact/ContactDataInterface.kt +++ b/app/src/main/java/org/linphone/contact/ContactDataInterface.kt @@ -61,7 +61,7 @@ open class GenericContactData(private val sipAddress: Address) : ContactDataInte open fun destroy() { } - private fun contactLookup() { + protected fun contactLookup() { displayName.value = LinphoneUtils.getDisplayName(sipAddress) val friend = coreContext.contactsManager.findContactByAddress(sipAddress) @@ -88,7 +88,7 @@ abstract class GenericContactViewModel(private val sipAddress: Address) : Messag contactLookup() } - private fun contactLookup() { + protected fun contactLookup() { displayName.value = LinphoneUtils.getDisplayName(sipAddress) val friend = coreContext.contactsManager.findContactByAddress(sipAddress) if (friend != null) { diff --git a/app/src/main/java/org/linphone/telecom/NativeCallWrapper.kt b/app/src/main/java/org/linphone/telecom/NativeCallWrapper.kt index 1f74aa5dd..823490e32 100644 --- a/app/src/main/java/org/linphone/telecom/NativeCallWrapper.kt +++ b/app/src/main/java/org/linphone/telecom/NativeCallWrapper.kt @@ -64,10 +64,11 @@ class NativeCallWrapper(var callId: String) : Connection() { override fun onHold() { Log.i("[Connection] Pausing telecom call with id: $callId") getCall()?.let { call -> - if (call.conference != null) + if (call.conference != null) { call.conference?.leave() - else + } else { call.pause() + } } ?: selfDestroy() setOnHold() } @@ -75,10 +76,11 @@ class NativeCallWrapper(var callId: String) : Connection() { override fun onUnhold() { Log.i("[Connection] Resuming telecom call with id: $callId") getCall()?.let { call -> - if (call.conference != null) + if (call.conference != null) { call.conference?.enter() - else + } else { call.resume() + } } ?: selfDestroy() setActive() }