From 4d55b089a62aa1d99dc7d73f9c938769a0e38576 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 14 Aug 2025 10:38:48 +0200 Subject: [PATCH] Scroll to latest match during chat message search in case user scrolled away --- .../main/chat/fragment/ConversationFragment.kt | 16 ++++++++++++++-- .../main/chat/viewmodel/ConversationViewModel.kt | 16 +++++++++------- 2 files changed, 23 insertions(+), 9 deletions(-) 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 e3f645728..2c7e47177 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 @@ -832,9 +832,21 @@ open class ConversationFragment : SlidingPaneChildFragment() { viewModel.itemToScrollTo.observe(viewLifecycleOwner) { position -> if (position >= 0) { - Log.i("$TAG Scrolling to message/event at position [$position]") val recyclerView = binding.eventsList - recyclerView.scrollToPosition(position) + val layoutManager = recyclerView.layoutManager as LinearLayoutManager + val firstDisplayedItemPosition = layoutManager.findFirstVisibleItemPosition() + val lastDisplayedItemPosition = layoutManager.findLastVisibleItemPosition() + Log.i( + "$TAG Scrolling to message/event at position [$position], " + + "display show events between positions [$firstDisplayedItemPosition] and [$lastDisplayedItemPosition]" + ) + if (firstDisplayedItemPosition > position && position > 0) { + recyclerView.scrollToPosition(position - 1) + } else if (lastDisplayedItemPosition < position && position < layoutManager.itemCount - 1) { + recyclerView.scrollToPosition(position + 1) + } else { + recyclerView.scrollToPosition(position) + } } } 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 92e963311..886d2b2d1 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 @@ -968,6 +968,14 @@ class ConversationViewModel val message = if (latestMatch == null) { R.string.conversation_search_no_match_found } else { + // Scroll to last matching event anyway, user may have scrolled away + val found = eventsList.find { + it.eventLog == latestMatch + } + if (found != null) { // This should always be true + val index = eventsList.indexOf(found) + itemToScrollTo.postValue(index) + } R.string.conversation_search_no_more_match } showRedToast(message, R.drawable.magnifying_glass) @@ -987,13 +995,7 @@ class ConversationViewModel Log.i("$TAG Found result is already in history, no need to load more history") (found.model as? MessageModel)?.highlightText(textToSearch) val index = eventsList.indexOf(found) - if (direction == SearchDirection.Down && index < eventsList.size - 1) { - // Go to next message to prevent the message we are looking for to be behind the scroll to bottom button - itemToScrollTo.postValue(index + 1) - } else { - // Go to previous message so target message won't be displayed stuck to the top - itemToScrollTo.postValue(index - 1) - } + itemToScrollTo.postValue(index) searchInProgress.postValue(false) }