Use state to support back pressed callback.

This commit is contained in:
Alex Hart
2025-04-02 14:26:14 -03:00
committed by Michelle Tang
parent fcc6032ee0
commit cc346351f7
3 changed files with 50 additions and 15 deletions

View File

@@ -47,10 +47,6 @@ public final class ConversationReactionDelegate {
overlayStub.get().hide();
}
public void hideForReactWithAny() {
overlayStub.get().hideForReactWithAny();
}
public void setOnReactionSelectedListener(@NonNull ConversationReactionOverlay.OnReactionSelectedListener onReactionSelectedListener) {
this.onReactionSelectedListener = onReactionSelectedListener;

View File

@@ -86,6 +86,7 @@ import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.kotlin.subscribeBy
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch
@@ -511,13 +512,18 @@ class ConversationFragment :
private lateinit var threadHeaderMarginDecoration: ThreadHeaderMarginDecoration
private lateinit var conversationItemDecorations: ConversationItemDecorations
private lateinit var optionsMenuCallback: ConversationOptionsMenuCallback
private lateinit var backPressedCallback: BackPressedDelegate
private var animationsAllowed = false
private var actionMode: ActionMode? = null
private var pinnedShortcutReceiver: BroadcastReceiver? = null
private var searchMenuItem: MenuItem? = null
private var isSearchRequested: Boolean = false
set(value) {
field = value
viewModel.setIsSearchRequested(value)
}
private var previousPage: KeyboardPage? = null
private var previousPages: Set<KeyboardPage>? = null
private var reShowScheduleMessagesBar: Boolean = false
@@ -939,8 +945,16 @@ class ConversationFragment :
activity?.supportStartPostponedEnterTransition()
backPressedCallback = BackPressedDelegate()
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, backPressedCallback)
val backPressedDelegate = BackPressedDelegate()
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, backPressedDelegate)
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.RESUMED) {
viewModel.backPressedState.collectLatest {
backPressedDelegate.isEnabled = it.shouldHandleBackPressed()
}
}
}
menuProvider?.afterFirstRenderMode = true
@@ -2217,6 +2231,7 @@ class ConversationFragment :
reactionDelegate.setOnActionSelectedListener(onActionSelectedListener)
reactionDelegate.setOnHideListener(onHideListener)
reactionDelegate.show(requireActivity(), viewModel.recipientSnapshot!!, conversationMessage, conversationGroupViewModel.isNonAdminInAnnouncementGroup(), selectedConversationModel)
viewModel.setIsReactionDelegateShowing(true)
composeText.clearFocus()
}
@@ -2344,18 +2359,15 @@ class ConversationFragment :
}
}
private inner class BackPressedDelegate : OnBackPressedCallback(true) {
private inner class BackPressedDelegate : OnBackPressedCallback(false) {
override fun handleOnBackPressed() {
Log.d(TAG, "onBackPressed()")
if (reactionDelegate.isShowing) {
val state = viewModel.backPressedState.value
if (state.isReactionDelegateShowing) {
reactionDelegate.hide()
} else if (isSearchRequested) {
} else if (state.isSearchRequested) {
searchMenuItem?.collapseActionView()
} else if (args.conversationScreenType.isInBubble) {
isEnabled = false
requireActivity().onBackPressed()
} else {
requireActivity().finish()
}
}
}
@@ -3255,6 +3267,8 @@ class ConversationFragment :
}
override fun onHide() {
viewModel.setIsReactionDelegateShowing(false)
if (!lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED) || activity == null || activity?.isFinishing == true) {
return
}

View File

@@ -32,11 +32,14 @@ import io.reactivex.rxjava3.subjects.PublishSubject
import io.reactivex.rxjava3.subjects.Subject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.rx3.asFlow
import org.signal.core.util.orNull
@@ -191,6 +194,9 @@ class ConversationViewModel(
val jumpToDateValidator: JumpToDateValidator
get() = _jumpToDateValidator
private val internalBackPressedState = MutableStateFlow(BackPressedState())
val backPressedState: StateFlow<BackPressedState> = internalBackPressedState
init {
disposables += recipient
.subscribeBy {
@@ -604,4 +610,23 @@ class ConversationViewModel(
.getEarliestMessageSentDate(threadId)
.observeOn(AndroidSchedulers.mainThread())
}
fun setIsReactionDelegateShowing(isReactionDelegateShowing: Boolean) {
internalBackPressedState.update {
it.copy(isReactionDelegateShowing = isReactionDelegateShowing)
}
}
fun setIsSearchRequested(isSearchRequested: Boolean) {
internalBackPressedState.update {
it.copy(isSearchRequested = isSearchRequested)
}
}
data class BackPressedState(
val isReactionDelegateShowing: Boolean = false,
val isSearchRequested: Boolean = false
) {
fun shouldHandleBackPressed() = isSearchRequested || isReactionDelegateShowing
}
}