From 1fbad779af8de9c55ef2971bbf0ee6695099153a Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 7 Nov 2023 12:18:39 +0100 Subject: [PATCH] Performance improvements for chat --- .../chat/adapter/ConversationEventAdapter.kt | 8 ++- .../ConversationParticipantsAdapter.kt | 57 +++++++++++++++++++ .../chat/fragment/ConversationFragment.kt | 50 +++++++++------- .../chat/fragment/ConversationInfoFragment.kt | 25 ++++++-- .../chat/fragment/ConversationsFragment.kt | 12 ++-- .../fragment/ConversationsListFragment.kt | 1 + .../ui/main/chat/model/ConversationModel.kt | 2 +- .../viewmodel/ConversationInfoViewModel.kt | 17 +++++- .../chat/viewmodel/ConversationViewModel.kt | 25 ++++++-- .../contacts/fragment/ContactsFragment.kt | 12 ++-- .../main/history/fragment/HistoryFragment.kt | 12 ++-- .../meetings/fragment/MeetingsFragment.kt | 12 ++-- .../ui/main/viewmodel/SharedMainViewModel.kt | 2 + .../main/res/layout/chat_info_fragment.xml | 8 +-- 14 files changed, 187 insertions(+), 56 deletions(-) create mode 100644 app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationParticipantsAdapter.kt diff --git a/app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationEventAdapter.kt b/app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationEventAdapter.kt index 1c8ad92d5..b1d2722bc 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationEventAdapter.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationEventAdapter.kt @@ -36,9 +36,9 @@ import org.linphone.ui.main.chat.model.EventLogModel import org.linphone.ui.main.chat.model.EventModel import org.linphone.utils.Event -class ConversationEventAdapter( - private val viewLifecycleOwner: LifecycleOwner -) : ListAdapter(EventLogDiffCallback()) { +class ConversationEventAdapter : ListAdapter( + EventLogDiffCallback() +) { companion object { const val INCOMING_CHAT_MESSAGE = 1 const val OUTGOING_CHAT_MESSAGE = 2 @@ -57,6 +57,8 @@ class ConversationEventAdapter( MutableLiveData>() } + lateinit var viewLifecycleOwner: LifecycleOwner + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return when (viewType) { INCOMING_CHAT_MESSAGE -> createIncomingChatBubble(parent) diff --git a/app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationParticipantsAdapter.kt b/app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationParticipantsAdapter.kt new file mode 100644 index 000000000..4ada7b77e --- /dev/null +++ b/app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationParticipantsAdapter.kt @@ -0,0 +1,57 @@ +package org.linphone.ui.main.chat.adapter + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.annotation.UiThread +import androidx.databinding.DataBindingUtil +import androidx.lifecycle.LifecycleOwner +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import org.linphone.R +import org.linphone.databinding.ChatParticipantListCellBinding +import org.linphone.ui.main.chat.model.ParticipantModel + +class ConversationParticipantsAdapter( + private val viewLifecycleOwner: LifecycleOwner +) : ListAdapter(ChatRoomParticipantDiffCallback()) { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + val binding: ChatParticipantListCellBinding = DataBindingUtil.inflate( + LayoutInflater.from(parent.context), + R.layout.chat_participant_list_cell, + parent, + false + ) + return ViewHolder(binding) + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + (holder as ViewHolder).bind(getItem(position)) + } + + inner class ViewHolder( + val binding: ChatParticipantListCellBinding + ) : RecyclerView.ViewHolder(binding.root) { + @UiThread + fun bind(participantModel: ParticipantModel) { + with(binding) { + model = participantModel + + lifecycleOwner = viewLifecycleOwner + + executePendingBindings() + } + } + } + + private class ChatRoomParticipantDiffCallback : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: ParticipantModel, newItem: ParticipantModel): Boolean { + return oldItem.sipUri == newItem.sipUri + } + + override fun areContentsTheSame(oldItem: ParticipantModel, newItem: ParticipantModel): Boolean { + return oldItem.avatarModel.id == newItem.avatarModel.id + } + } +} 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 485496a12..f89855c12 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 @@ -62,6 +62,7 @@ import org.linphone.ui.main.chat.model.ChatMessageDeliveryModel import org.linphone.ui.main.chat.model.ChatMessageModel import org.linphone.ui.main.chat.model.ChatMessageReactionsModel import org.linphone.ui.main.chat.viewmodel.ConversationViewModel +import org.linphone.ui.main.chat.viewmodel.ConversationViewModel.Companion.SCROLLING_POSITION_NOT_SET import org.linphone.ui.main.fragment.GenericFragment import org.linphone.utils.AppUtils import org.linphone.utils.Event @@ -80,12 +81,12 @@ class ConversationFragment : GenericFragment() { private lateinit var viewModel: ConversationViewModel - private val args: ConversationFragmentArgs by navArgs() - private lateinit var adapter: ConversationEventAdapter private lateinit var bottomSheetAdapter: ChatMessageBottomSheetAdapter + private val args: ConversationFragmentArgs by navArgs() + private val pickMedia = registerForActivityResult( ActivityResultContracts.PickMultipleVisualMedia() ) { list -> @@ -98,6 +99,12 @@ class ConversationFragment : GenericFragment() { } } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + adapter = ConversationEventAdapter() + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -138,19 +145,12 @@ class ConversationFragment : GenericFragment() { Log.i( "$TAG Looking up for conversation with local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]" ) - viewModel.findChatRoom(localSipUri, remoteSipUri) + val chatRoom = sharedViewModel.displayedChatRoom + viewModel.findChatRoom(chatRoom, localSipUri, remoteSipUri) viewModel.chatRoomFoundEvent.observe(viewLifecycleOwner) { it.consume { found -> - if (found) { - Log.i( - "$TAG Found matching chat room for local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]" - ) - (view.parent as? ViewGroup)?.doOnPreDraw { - startPostponedEnterTransition() - sharedViewModel.openSlidingPaneEvent.value = Event(true) - } - } else { + if (!found) { (view.parent as? ViewGroup)?.doOnPreDraw { Log.e("$TAG Failed to find chat room, going back") goBack() @@ -160,9 +160,8 @@ class ConversationFragment : GenericFragment() { } } - adapter = ConversationEventAdapter(viewLifecycleOwner) + adapter.viewLifecycleOwner = viewLifecycleOwner binding.eventsList.setHasFixedSize(true) - binding.eventsList.adapter = adapter binding.eventsList.layoutManager = LinearLayoutManager(requireContext()) bottomSheetAdapter = ChatMessageBottomSheetAdapter(viewLifecycleOwner) @@ -172,17 +171,20 @@ class ConversationFragment : GenericFragment() { val bottomSheetLayoutManager = LinearLayoutManager(requireContext()) binding.messageBottomSheet.bottomSheetList.layoutManager = bottomSheetLayoutManager - adapter.chatMessageLongPressEvent.observe(viewLifecycleOwner) { - it.consume { model -> - showChatMessageLongPressMenu(model) - } - } - viewModel.events.observe(viewLifecycleOwner) { items -> val currentCount = adapter.itemCount adapter.submitList(items) Log.i("$TAG Events (messages) list updated with [${items.size}] items") + if (binding.eventsList.adapter != adapter) { + binding.eventsList.adapter = adapter + } + + (view.parent as? ViewGroup)?.doOnPreDraw { + startPostponedEnterTransition() + sharedViewModel.openSlidingPaneEvent.value = Event(true) + } + if (currentCount < items.size) { binding.eventsList.scrollToPosition(items.size - 1) } @@ -192,6 +194,12 @@ class ConversationFragment : GenericFragment() { emojisBottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED emojisBottomSheetBehavior.isDraggable = false // To allow scrolling through the emojis + adapter.chatMessageLongPressEvent.observe(viewLifecycleOwner) { + it.consume { model -> + showChatMessageLongPressMenu(model) + } + } + adapter.showDeliveryForChatMessageModelEvent.observe(viewLifecycleOwner) { it.consume { model -> showDeliveryBottomSheetDialog(model, showDelivery = true) @@ -284,7 +292,7 @@ class ConversationFragment : GenericFragment() { Log.i("$TAG Asking notifications manager not to notify chat messages for chat room [$id]") coreContext.notificationsManager.setCurrentlyDisplayedChatRoomId(id) - if (viewModel.scrollingPosition != -1) { + if (viewModel.scrollingPosition != SCROLLING_POSITION_NOT_SET) { binding.eventsList.scrollToPosition(viewModel.scrollingPosition) } } 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 ceb97c465..5ffffaf92 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 @@ -31,10 +31,12 @@ import androidx.databinding.DataBindingUtil import androidx.lifecycle.ViewModelProvider import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs +import androidx.recyclerview.widget.LinearLayoutManager import org.linphone.R import org.linphone.core.tools.Log import org.linphone.databinding.ChatInfoFragmentBinding import org.linphone.databinding.ChatParticipantAdminPopupMenuBinding +import org.linphone.ui.main.chat.adapter.ConversationParticipantsAdapter import org.linphone.ui.main.chat.model.ConversationEditSubjectDialogModel import org.linphone.ui.main.chat.model.ParticipantModel import org.linphone.ui.main.chat.viewmodel.ConversationInfoViewModel @@ -51,6 +53,8 @@ class ConversationInfoFragment : GenericFragment() { private lateinit var viewModel: ConversationInfoViewModel + private lateinit var adapter: ConversationParticipantsAdapter + private val args: ConversationInfoFragmentArgs by navArgs() override fun onCreateView( @@ -71,6 +75,7 @@ class ConversationInfoFragment : GenericFragment() { isSlidingPaneChild = true super.onViewCreated(view, savedInstanceState) + postponeEnterTransition() binding.lifecycleOwner = viewLifecycleOwner @@ -82,7 +87,13 @@ class ConversationInfoFragment : GenericFragment() { Log.i( "$TAG Looking up for conversation with local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]" ) - viewModel.findChatRoom(localSipUri, remoteSipUri) + val chatRoom = sharedViewModel.displayedChatRoom + viewModel.findChatRoom(chatRoom, localSipUri, remoteSipUri) + + adapter = ConversationParticipantsAdapter(viewLifecycleOwner) + binding.participants.setHasFixedSize(true) + binding.participants.layoutManager = LinearLayoutManager(requireContext()) + binding.participants.adapter = adapter viewModel.chatRoomFoundEvent.observe(viewLifecycleOwner) { it.consume { found -> @@ -90,9 +101,6 @@ class ConversationInfoFragment : GenericFragment() { Log.i( "$TAG Found matching chat room for local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]" ) - (view.parent as? ViewGroup)?.doOnPreDraw { - startPostponedEnterTransition() - } } else { (view.parent as? ViewGroup)?.doOnPreDraw { Log.e("$TAG Failed to find chat room, going back") @@ -102,6 +110,15 @@ class ConversationInfoFragment : GenericFragment() { } } + viewModel.participants.observe(viewLifecycleOwner) { items -> + adapter.submitList(items) + Log.i("$TAG Participants list updated with [${items.size}] items") + + (view.parent as? ViewGroup)?.doOnPreDraw { + startPostponedEnterTransition() + } + } + viewModel.groupLeftEvent.observe(viewLifecycleOwner) { it.consume { // TODO: show toast ? diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationsFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationsFragment.kt index d576889d2..10f542e0b 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationsFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationsFragment.kt @@ -95,8 +95,10 @@ class ConversationsFragment : GenericFragment() { viewLifecycleOwner ) { it.consume { - Log.i("$TAG Closing sliding pane") - binding.slidingPaneLayout.closePane() + if (binding.slidingPaneLayout.isOpen) { + Log.i("$TAG Closing sliding pane") + binding.slidingPaneLayout.closePane() + } } } @@ -104,8 +106,10 @@ class ConversationsFragment : GenericFragment() { viewLifecycleOwner ) { it.consume { - Log.i("$TAG Opening sliding pane") - binding.slidingPaneLayout.openPane() + if (!binding.slidingPaneLayout.isOpen) { + Log.i("$TAG Opening sliding pane") + binding.slidingPaneLayout.openPane() + } } } 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 e61164b8c..5539a0306 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 @@ -108,6 +108,7 @@ class ConversationsListFragment : AbstractTopBarFragment() { adapter.conversationClickedEvent.observe(viewLifecycleOwner) { it.consume { model -> Log.i("$TAG Show conversation with ID [${model.id}]") + sharedViewModel.displayedChatRoom = model.chatRoom sharedViewModel.showConversationEvent.value = Event( Pair(model.localSipUri, model.remoteSipUri) ) 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 e2efd3ad1..4835a283a 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 @@ -38,7 +38,7 @@ import org.linphone.utils.AppUtils import org.linphone.utils.LinphoneUtils import org.linphone.utils.TimestampUtils -class ConversationModel @WorkerThread constructor(private val chatRoom: ChatRoom) { +class ConversationModel @WorkerThread constructor(val chatRoom: ChatRoom) { companion object { private const val TAG = "[Conversation Model]" } diff --git a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationInfoViewModel.kt b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationInfoViewModel.kt index 3fbfbc821..40b900f1d 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationInfoViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationInfoViewModel.kt @@ -124,15 +124,30 @@ class ConversationInfoViewModel @UiThread constructor() : ViewModel() { } @UiThread - fun findChatRoom(localSipUri: String, remoteSipUri: String) { + fun findChatRoom(room: ChatRoom?, localSipUri: String, remoteSipUri: String) { coreContext.postOnCoreThread { core -> Log.i( "$TAG Looking for chat room with local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]" ) + if (room != null && ::chatRoom.isInitialized && chatRoom == room) { + Log.i("$TAG Chat room object already in memory, skipping") + chatRoomFoundEvent.postValue(Event(true)) + return@postOnCoreThread + } + + if (room != null && (!::chatRoom.isInitialized || chatRoom != room)) { + Log.i("$TAG Chat room object available in sharedViewModel, using it") + chatRoom = room + chatRoom.addListener(chatRoomListener) + configureChatRoom() + chatRoomFoundEvent.postValue(Event(true)) + return@postOnCoreThread + } val localAddress = Factory.instance().createAddress(localSipUri) val remoteAddress = Factory.instance().createAddress(remoteSipUri) if (localAddress != null && remoteAddress != null) { + Log.i("$TAG Searching for chat room in Core using local & peer SIP addresses") val found = core.searchChatRoom( null, localAddress, diff --git a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt index 5d33ba86e..f0466949a 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt @@ -45,6 +45,7 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { private const val TAG = "[Conversation ViewModel]" const val MAX_TIME_TO_GROUP_MESSAGES = 60 // 1 minute + const val SCROLLING_POSITION_NOT_SET = -1 } val showBackButton = MutableLiveData() @@ -75,7 +76,7 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { val isReplyingToMessage = MutableLiveData() - var scrollingPosition: Int = -1 + var scrollingPosition: Int = SCROLLING_POSITION_NOT_SET val requestKeyboardHidingEvent: MutableLiveData> by lazy { MutableLiveData>() @@ -91,7 +92,7 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { val chatRoomFoundEvent = MutableLiveData>() - private lateinit var chatRoom: ChatRoom + lateinit var chatRoom: ChatRoom private var chatMessageToReplyTo: ChatMessage? = null @@ -202,15 +203,30 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { } @UiThread - fun findChatRoom(localSipUri: String, remoteSipUri: String) { + fun findChatRoom(room: ChatRoom?, localSipUri: String, remoteSipUri: String) { coreContext.postOnCoreThread { core -> Log.i( "$TAG Looking for chat room with local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]" ) + if (room != null && ::chatRoom.isInitialized && chatRoom == room) { + Log.i("$TAG Chat room object already in memory, skipping") + chatRoomFoundEvent.postValue(Event(true)) + return@postOnCoreThread + } + + if (room != null && (!::chatRoom.isInitialized || chatRoom != room)) { + Log.i("$TAG Chat room object available in sharedViewModel, using it") + chatRoom = room + chatRoom.addListener(chatRoomListener) + configureChatRoom() + chatRoomFoundEvent.postValue(Event(true)) + return@postOnCoreThread + } val localAddress = Factory.instance().createAddress(localSipUri) val remoteAddress = Factory.instance().createAddress(remoteSipUri) if (localAddress != null && remoteAddress != null) { + Log.i("$TAG Searching for chat room in Core using local & peer SIP addresses") val found = core.searchChatRoom( null, localAddress, @@ -324,6 +340,7 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { @WorkerThread private fun configureChatRoom() { + scrollingPosition = SCROLLING_POSITION_NOT_SET computeComposingLabel() val empty = chatRoom.hasCapability(ChatRoom.Capabilities.Conference.toInt()) && chatRoom.participants.isEmpty() @@ -408,11 +425,11 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { @WorkerThread private fun getEventsListFromHistory(history: Array, filter: String = ""): ArrayList { + var xFirstEventsSubmitted = false val eventsList = arrayListOf() val groupedEventLogs = arrayListOf() for (event in history) { if (filter.isNotEmpty()) { - // TODO: let the SDK do it if (event.type == EventLog.Type.ConferenceChatMessage) { val message = event.chatMessage ?: continue val fromAddress = message.fromAddress diff --git a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsFragment.kt b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsFragment.kt index 2ef9f5331..cb4480b4a 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsFragment.kt @@ -82,8 +82,10 @@ class ContactsFragment : GenericFragment() { viewLifecycleOwner ) { it.consume { - Log.i("$TAG Closing sliding pane") - binding.slidingPaneLayout.closePane() + if (binding.slidingPaneLayout.isOpen) { + Log.i("$TAG Closing sliding pane") + binding.slidingPaneLayout.closePane() + } } } @@ -91,8 +93,10 @@ class ContactsFragment : GenericFragment() { viewLifecycleOwner ) { it.consume { - Log.i("$TAG Opening sliding pane") - binding.slidingPaneLayout.openPane() + if (!binding.slidingPaneLayout.isOpen) { + Log.i("$TAG Opening sliding pane") + binding.slidingPaneLayout.openPane() + } } } diff --git a/app/src/main/java/org/linphone/ui/main/history/fragment/HistoryFragment.kt b/app/src/main/java/org/linphone/ui/main/history/fragment/HistoryFragment.kt index 3a319d82a..03bb38296 100644 --- a/app/src/main/java/org/linphone/ui/main/history/fragment/HistoryFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/history/fragment/HistoryFragment.kt @@ -82,8 +82,10 @@ class HistoryFragment : GenericFragment() { viewLifecycleOwner ) { it.consume { - Log.i("$TAG Closing sliding pane") - binding.slidingPaneLayout.closePane() + if (binding.slidingPaneLayout.isOpen) { + Log.i("$TAG Closing sliding pane") + binding.slidingPaneLayout.closePane() + } } } @@ -91,8 +93,10 @@ class HistoryFragment : GenericFragment() { viewLifecycleOwner ) { it.consume { - Log.i("$TAG Opening sliding pane") - binding.slidingPaneLayout.openPane() + if (!binding.slidingPaneLayout.isOpen) { + Log.i("$TAG Opening sliding pane") + binding.slidingPaneLayout.openPane() + } } } diff --git a/app/src/main/java/org/linphone/ui/main/meetings/fragment/MeetingsFragment.kt b/app/src/main/java/org/linphone/ui/main/meetings/fragment/MeetingsFragment.kt index 9bb51213c..3acdded19 100644 --- a/app/src/main/java/org/linphone/ui/main/meetings/fragment/MeetingsFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/meetings/fragment/MeetingsFragment.kt @@ -82,8 +82,10 @@ class MeetingsFragment : GenericFragment() { viewLifecycleOwner ) { it.consume { - Log.i("$TAG Closing sliding pane") - binding.slidingPaneLayout.closePane() + if (binding.slidingPaneLayout.isOpen) { + Log.i("$TAG Closing sliding pane") + binding.slidingPaneLayout.closePane() + } } } @@ -91,8 +93,10 @@ class MeetingsFragment : GenericFragment() { viewLifecycleOwner ) { it.consume { - Log.i("$TAG Opening sliding pane") - binding.slidingPaneLayout.openPane() + if (!binding.slidingPaneLayout.isOpen) { + Log.i("$TAG Opening sliding pane") + binding.slidingPaneLayout.openPane() + } } } 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 e9440cb15..923761faa 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 @@ -22,6 +22,7 @@ package org.linphone.ui.main.viewmodel import androidx.annotation.UiThread import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import org.linphone.core.ChatRoom import org.linphone.utils.Event class SharedMainViewModel @UiThread constructor() : ViewModel() { @@ -105,6 +106,7 @@ class SharedMainViewModel @UiThread constructor() : ViewModel() { MutableLiveData>() } + var displayedChatRoom: ChatRoom? = null val showConversationEvent: MutableLiveData>> by lazy { MutableLiveData>>() } diff --git a/app/src/main/res/layout/chat_info_fragment.xml b/app/src/main/res/layout/chat_info_fragment.xml index 38d2ce033..df96044d6 100644 --- a/app/src/main/res/layout/chat_info_fragment.xml +++ b/app/src/main/res/layout/chat_info_fragment.xml @@ -220,19 +220,15 @@ app:layout_constraintTop_toTopOf="@id/participants" app:layout_constraintBottom_toBottomOf="@id/participants_anchor" /> -