From ceecacb47e934d4c41de349ca892ad59ba17311d Mon Sep 17 00:00:00 2001 From: jeffrey-signal Date: Mon, 27 Apr 2026 16:09:56 -0400 Subject: [PATCH] Fix pull-to-refresh triggering when attempting to scroll up in contact search. Resolves signalapp/Signal-Android#14742 --- .../contacts/paged/ContactSearchView.kt | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchView.kt b/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchView.kt index 72d44b6e04..27d5830d98 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/paged/ContactSearchView.kt @@ -41,10 +41,6 @@ class ContactSearchView : AbstractComposeView { fun onRecyclerViewReady(recyclerView: RecyclerView) } - init { - setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) - } - private var viewModel: ContactSearchViewModel? by mutableStateOf(null) private var currentFragmentManager: FragmentManager? = null private var currentDisplayOptions: ContactSearchAdapter.DisplayOptions? = null @@ -54,8 +50,13 @@ class ContactSearchView : AbstractComposeView { private var currentContentBottomPadding: Dp = 0.dp private var currentAdapterFactory: ContactSearchAdapter.AdapterFactory = ContactSearchAdapter.DefaultAdapterFactory private var currentScrollListeners: List = emptyList() + private var recyclerView: RecyclerView? = null private var currentOnRecyclerViewReady: RecyclerViewReadyCallback? = null + init { + setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) + } + /** * Configures and activates the contact search. Must be called exactly once from the host * fragment's `onViewCreated`. The [viewModel] must be created and held by the caller so it @@ -106,6 +107,10 @@ class ContactSearchView : AbstractComposeView { this.viewModel = viewModel // triggers recomposition } + override fun canScrollVertically(direction: Int): Boolean { + return recyclerView?.canScrollVertically(direction) ?: super.canScrollVertically(direction) + } + @Composable override fun Content() { val vm = viewModel ?: return @@ -123,7 +128,10 @@ class ContactSearchView : AbstractComposeView { contentBottomPadding = currentContentBottomPadding, adapterFactory = currentAdapterFactory, scrollListeners = currentScrollListeners, - onRecyclerViewReady = currentOnRecyclerViewReady + onRecyclerViewReady = RecyclerViewReadyCallback { recyclerView -> + this@ContactSearchView.recyclerView = recyclerView + currentOnRecyclerViewReady?.onRecyclerViewReady(recyclerView) + } ) } }