From e7f95adab9f77a1eefec2c13f9f8c4bc1ef0364f Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 29 May 2025 11:40:42 +0200 Subject: [PATCH] Only refresh conversation list cell when a message is deleted, prevents blinking --- .../ConversationEphemeralLifetimeFragment.kt | 2 +- .../ui/main/chat/fragment/ConversationFragment.kt | 11 +++++------ .../main/chat/fragment/ConversationInfoFragment.kt | 8 ++++---- .../chat/fragment/ConversationsListFragment.kt | 11 +++++++---- .../ui/main/chat/model/ConversationModel.kt | 14 ++++++++++++++ .../ui/main/viewmodel/SharedMainViewModel.kt | 14 +++++++------- 6 files changed, 38 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationEphemeralLifetimeFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationEphemeralLifetimeFragment.kt index 96332c9c5..b29ee0a23 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationEphemeralLifetimeFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationEphemeralLifetimeFragment.kt @@ -82,7 +82,7 @@ class ConversationEphemeralLifetimeFragment : SlidingPaneChildFragment() { } override fun onPause() { - sharedViewModel.newChatMessageEphemeralLifetimeToSet.value = Event( + sharedViewModel.newChatMessageEphemeralLifetimeToSetEvent.value = Event( viewModel.currentlySelectedValue.value ?: 0L ) super.onPause() 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 0e082fd0b..1fe062ec8 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 @@ -94,7 +94,6 @@ import org.linphone.utils.hideKeyboard import org.linphone.utils.setKeyboardInsetListener import org.linphone.utils.showKeyboard import androidx.core.net.toUri -import androidx.lifecycle.observe @UiThread open class ConversationFragment : SlidingPaneChildFragment() { @@ -819,7 +818,7 @@ open class ConversationFragment : SlidingPaneChildFragment() { val message = getString(R.string.conversation_message_deleted_toast) val icon = R.drawable.trash_simple (requireActivity() as GenericActivity).showGreenToast(message, icon) - sharedViewModel.forceRefreshConversations.value = Event(true) + sharedViewModel.updateConversationLastMessageEvent.value = Event(viewModel.conversationId) } } @@ -929,7 +928,7 @@ open class ConversationFragment : SlidingPaneChildFragment() { } } - sharedViewModel.forceRefreshConversationInfo.observe(viewLifecycleOwner) { + sharedViewModel.forceRefreshConversationInfoEvent.observe(viewLifecycleOwner) { it.consume { Log.i("$TAG Force refreshing conversation info") viewModel.refresh() @@ -943,7 +942,7 @@ open class ConversationFragment : SlidingPaneChildFragment() { } } - sharedViewModel.newChatMessageEphemeralLifetimeToSet.observe(viewLifecycleOwner) { + sharedViewModel.newChatMessageEphemeralLifetimeToSetEvent.observe(viewLifecycleOwner) { it.consume { ephemeralLifetime -> Log.i( "$TAG Setting [$ephemeralLifetime] as new ephemeral lifetime for messages" @@ -1190,14 +1189,14 @@ open class ConversationFragment : SlidingPaneChildFragment() { Log.i("$TAG Muting conversation") viewModel.mute() popupWindow.dismiss() - sharedViewModel.forceRefreshDisplayedConversation.value = Event(true) + sharedViewModel.forceRefreshDisplayedConversationEvent.value = Event(true) } popupView.setUnmuteClickListener { Log.i("$TAG Un-muting conversation") viewModel.unMute() popupWindow.dismiss() - sharedViewModel.forceRefreshDisplayedConversation.value = Event(true) + sharedViewModel.forceRefreshDisplayedConversationEvent.value = Event(true) } popupView.setConfigureEphemeralMessagesClickListener { diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationInfoFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationInfoFragment.kt index ba158ae8f..e804acabd 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationInfoFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationInfoFragment.kt @@ -136,7 +136,7 @@ class ConversationInfoFragment : SlidingPaneChildFragment() { viewModel.groupLeftEvent.observe(viewLifecycleOwner) { it.consume { Log.i("$TAG Group has been left, leaving conversation info...") - sharedViewModel.forceRefreshConversationInfo.value = Event(true) + sharedViewModel.forceRefreshConversationInfoEvent.value = Event(true) goBack() val message = getString(R.string.conversation_group_left_toast) (requireActivity() as GenericActivity).showGreenToast( @@ -149,7 +149,7 @@ class ConversationInfoFragment : SlidingPaneChildFragment() { viewModel.historyDeletedEvent.observe(viewLifecycleOwner) { it.consume { Log.i("$TAG History has been deleted, leaving conversation info...") - sharedViewModel.forceRefreshConversations.value = Event(true) + sharedViewModel.updateConversationLastMessageEvent.value = Event(viewModel.conversationId) sharedViewModel.forceRefreshConversationEvents.value = Event(true) goBack() val message = getString(R.string.conversation_info_history_deleted_toast) @@ -180,7 +180,7 @@ class ConversationInfoFragment : SlidingPaneChildFragment() { viewModel.infoChangedEvent.observe(viewLifecycleOwner) { it.consume { - sharedViewModel.forceRefreshConversationInfo.postValue(Event(true)) + sharedViewModel.forceRefreshConversationInfoEvent.postValue(Event(true)) } } @@ -197,7 +197,7 @@ class ConversationInfoFragment : SlidingPaneChildFragment() { } } - sharedViewModel.newChatMessageEphemeralLifetimeToSet.observe(viewLifecycleOwner) { + sharedViewModel.newChatMessageEphemeralLifetimeToSetEvent.observe(viewLifecycleOwner) { it.consume { ephemeralLifetime -> Log.i( "$TAG Setting [$ephemeralLifetime] as new ephemeral lifetime for messages" 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 862137b47..8bbd9548c 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 @@ -274,13 +274,16 @@ class ConversationsListFragment : AbstractMainFragment() { } } - sharedViewModel.forceRefreshConversations.observe(viewLifecycleOwner) { - it.consume { - listViewModel.filter() + sharedViewModel.updateConversationLastMessageEvent.observe(viewLifecycleOwner) { + it.consume { conversationId -> + val model = listViewModel.conversations.value.orEmpty().find { + it.id == conversationId + } + model?.updateLastMessageInfo() } } - sharedViewModel.forceRefreshDisplayedConversation.observe(viewLifecycleOwner) { + sharedViewModel.forceRefreshDisplayedConversationEvent.observe(viewLifecycleOwner) { it.consume { val displayChatRoom = sharedViewModel.displayedChatRoom if (displayChatRoom != null) { diff --git a/app/src/main/java/org/linphone/ui/main/chat/model/ConversationModel.kt b/app/src/main/java/org/linphone/ui/main/chat/model/ConversationModel.kt index 091799273..6392b6714 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/model/ConversationModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/model/ConversationModel.kt @@ -20,8 +20,10 @@ package org.linphone.ui.main.chat.model import android.text.Spannable +import android.text.SpannableStringBuilder import androidx.annotation.UiThread import androidx.annotation.WorkerThread +import androidx.core.text.toSpannable import androidx.lifecycle.MutableLiveData import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R @@ -272,6 +274,13 @@ class ConversationModel } } + @UiThread + fun updateLastMessageInfo() { + coreContext.postOnCoreThread { + updateLastMessage() + } + } + @WorkerThread private fun updateLastMessageStatus(message: ChatMessage) { val isOutgoing = message.isOutgoing @@ -341,6 +350,11 @@ class ConversationModel lastMessage = message } } else { + lastMessage = null + lastMessageTextSender.postValue("") + lastMessageContentIcon.postValue(0) + lastMessageText.postValue(SpannableStringBuilder("").toSpannable()) + isLastMessageOutgoing.postValue(false) Log.w("$TAG No last message to display for conversation [$id]") } } diff --git a/app/src/main/java/org/linphone/ui/main/viewmodel/SharedMainViewModel.kt b/app/src/main/java/org/linphone/ui/main/viewmodel/SharedMainViewModel.kt index 1712bc624..69b1c8708 100644 --- a/app/src/main/java/org/linphone/ui/main/viewmodel/SharedMainViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/viewmodel/SharedMainViewModel.kt @@ -138,15 +138,11 @@ class SharedMainViewModel MutableLiveData>() } - val forceRefreshDisplayedConversation: MutableLiveData> by lazy { + val forceRefreshDisplayedConversationEvent: MutableLiveData> by lazy { MutableLiveData>() } - val forceRefreshConversations: MutableLiveData> by lazy { - MutableLiveData>() - } - - val forceRefreshConversationInfo: MutableLiveData> by lazy { + val forceRefreshConversationInfoEvent: MutableLiveData> by lazy { MutableLiveData>() } @@ -154,10 +150,14 @@ class SharedMainViewModel MutableLiveData>() } - val newChatMessageEphemeralLifetimeToSet: MutableLiveData> by lazy { + val newChatMessageEphemeralLifetimeToSetEvent: MutableLiveData> by lazy { MutableLiveData>() } + val updateConversationLastMessageEvent: MutableLiveData> by lazy { + MutableLiveData>() + } + val updateUnreadMessageCountForCurrentConversationEvent: MutableLiveData> by lazy { MutableLiveData>() }