From 435be7c63dcc5fc25432cbff6c3806bda26a382f Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Fri, 17 Oct 2025 11:38:34 -0300 Subject: [PATCH] Fix auto-expansion of panes on click. --- .../thoughtcrime/securesms/MainActivity.kt | 21 +++++++++++++------ .../securesms/calls/log/CallLogFragment.kt | 2 +- .../ConversationListFragment.java | 2 +- .../securesms/main/MainNavigationViewModel.kt | 6 ++---- .../stories/landing/StoriesLandingFragment.kt | 2 +- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/MainActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/MainActivity.kt index cc26c11163..1df9a3ffb7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/MainActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/MainActivity.kt @@ -66,6 +66,8 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.distinctUntilChangedBy import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.merge import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.signal.core.ui.compose.theme.SignalTheme @@ -403,15 +405,22 @@ class MainActivity : PassphraseRequiredActivity(), VoiceNoteMediaControllerOwner } } - LaunchedEffect(mainNavigationDetailLocation) { - if (paneExpansionState.currentAnchor == listOnlyAnchor && wrappedNavigator.currentDestination?.pane == ThreePaneScaffoldRole.Primary) { - paneExpansionState.animateTo(detailOnlyAnchor) + LaunchedEffect(paneExpansionState, detailOnlyAnchor, listOnlyAnchor, wrappedNavigator) { + mainNavigationViewModel.detailLocation.collect { + if (paneExpansionState.currentAnchor == listOnlyAnchor) { + paneExpansionState.animateTo(detailOnlyAnchor) + } } } - LaunchedEffect(mainNavigationState.currentListLocation) { - if (paneExpansionState.currentAnchor == detailOnlyAnchor && wrappedNavigator.currentDestination?.pane == ThreePaneScaffoldRole.Secondary) { - paneExpansionState.animateTo(listOnlyAnchor) + LaunchedEffect(paneExpansionState, detailOnlyAnchor, listOnlyAnchor, wrappedNavigator) { + val a = mainNavigationViewModel.mainNavigationState.map { it.currentListLocation } + val b = mainNavigationViewModel.tabClickEvents + + merge(a, b).collect { + if (paneExpansionState.currentAnchor == detailOnlyAnchor) { + paneExpansionState.animateTo(listOnlyAnchor) + } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogFragment.kt index 7a45ef2fa0..91f4719068 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogFragment.kt @@ -206,7 +206,7 @@ class CallLogFragment : Fragment(R.layout.call_log_fragment), CallLogAdapter.Cal } private fun initializeTapToScrollToTop(scrollToPositionDelegate: ScrollToPositionDelegate) { - disposables += mainNavigationViewModel.tabClickEvents + disposables += mainNavigationViewModel.tabClickEventsObservable .filter { it == MainNavigationListLocation.CALLS } .subscribeBy(onNext = { scrollToPositionDelegate.resetScrollPosition() diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java index 6d13669561..bed90c68dc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java @@ -398,7 +398,7 @@ public class ConversationListFragment extends MainFragment implements Conversati requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), chatListBackHandler); lifecycleDisposable.bindTo(getViewLifecycleOwner()); - lifecycleDisposable.add(mainNavigationViewModel.getTabClickEvents().filter(tab -> tab == MainNavigationListLocation.CHATS) + lifecycleDisposable.add(mainNavigationViewModel.getTabClickEventsObservable().filter(tab -> tab == MainNavigationListLocation.CHATS) .subscribe(unused -> { Log.d(TAG, "Scroll to top please"); LinearLayoutManager layoutManager = (LinearLayoutManager) list.getLayoutManager(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/main/MainNavigationViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/main/MainNavigationViewModel.kt index c13e197101..22d7901969 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/main/MainNavigationViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/main/MainNavigationViewModel.kt @@ -46,9 +46,6 @@ class MainNavigationViewModel( private var navigatorScope: CoroutineScope? = null private var goToLegacyDetailLocation: ((MainNavigationDetailLocation) -> Unit)? = null - /** - * The latest detail location that has been requested, for consumption by other components. - */ private val internalDetailLocation = MutableSharedFlow() val detailLocation: SharedFlow = internalDetailLocation @@ -76,7 +73,8 @@ class MainNavigationViewModel( * This is Rx because these are still accessed from Java. */ private val internalTabClickEvents: MutableSharedFlow = MutableSharedFlow() - val tabClickEvents: Observable = internalTabClickEvents.asObservable() + val tabClickEvents: SharedFlow = internalTabClickEvents + val tabClickEventsObservable: Observable = internalTabClickEvents.asObservable() private var earlyNavigationListLocationRequested: MainNavigationListLocation? = null var earlyNavigationDetailLocationRequested: MainNavigationDetailLocation? = null diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/landing/StoriesLandingFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/landing/StoriesLandingFragment.kt index 9ba4e60cc6..403a4241b3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/landing/StoriesLandingFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/landing/StoriesLandingFragment.kt @@ -159,7 +159,7 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l } ) - lifecycleDisposable += mainNavigationViewModel.tabClickEvents + lifecycleDisposable += mainNavigationViewModel.tabClickEventsObservable .filter { it == MainNavigationListLocation.STORIES } .subscribeBy(onNext = { val layoutManager = recyclerView?.layoutManager as? LinearLayoutManager ?: return@subscribeBy