mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-23 12:38:33 +00:00
Use state to support back pressed callback.
This commit is contained in:
@@ -47,10 +47,6 @@ public final class ConversationReactionDelegate {
|
|||||||
overlayStub.get().hide();
|
overlayStub.get().hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hideForReactWithAny() {
|
|
||||||
overlayStub.get().hideForReactWithAny();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnReactionSelectedListener(@NonNull ConversationReactionOverlay.OnReactionSelectedListener onReactionSelectedListener) {
|
public void setOnReactionSelectedListener(@NonNull ConversationReactionOverlay.OnReactionSelectedListener onReactionSelectedListener) {
|
||||||
this.onReactionSelectedListener = onReactionSelectedListener;
|
this.onReactionSelectedListener = onReactionSelectedListener;
|
||||||
|
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ import io.reactivex.rxjava3.disposables.Disposable
|
|||||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.flowOn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -511,13 +512,18 @@ class ConversationFragment :
|
|||||||
private lateinit var threadHeaderMarginDecoration: ThreadHeaderMarginDecoration
|
private lateinit var threadHeaderMarginDecoration: ThreadHeaderMarginDecoration
|
||||||
private lateinit var conversationItemDecorations: ConversationItemDecorations
|
private lateinit var conversationItemDecorations: ConversationItemDecorations
|
||||||
private lateinit var optionsMenuCallback: ConversationOptionsMenuCallback
|
private lateinit var optionsMenuCallback: ConversationOptionsMenuCallback
|
||||||
private lateinit var backPressedCallback: BackPressedDelegate
|
|
||||||
|
|
||||||
private var animationsAllowed = false
|
private var animationsAllowed = false
|
||||||
private var actionMode: ActionMode? = null
|
private var actionMode: ActionMode? = null
|
||||||
private var pinnedShortcutReceiver: BroadcastReceiver? = null
|
private var pinnedShortcutReceiver: BroadcastReceiver? = null
|
||||||
private var searchMenuItem: MenuItem? = null
|
private var searchMenuItem: MenuItem? = null
|
||||||
|
|
||||||
private var isSearchRequested: Boolean = false
|
private var isSearchRequested: Boolean = false
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
viewModel.setIsSearchRequested(value)
|
||||||
|
}
|
||||||
|
|
||||||
private var previousPage: KeyboardPage? = null
|
private var previousPage: KeyboardPage? = null
|
||||||
private var previousPages: Set<KeyboardPage>? = null
|
private var previousPages: Set<KeyboardPage>? = null
|
||||||
private var reShowScheduleMessagesBar: Boolean = false
|
private var reShowScheduleMessagesBar: Boolean = false
|
||||||
@@ -939,8 +945,16 @@ class ConversationFragment :
|
|||||||
|
|
||||||
activity?.supportStartPostponedEnterTransition()
|
activity?.supportStartPostponedEnterTransition()
|
||||||
|
|
||||||
backPressedCallback = BackPressedDelegate()
|
val backPressedDelegate = BackPressedDelegate()
|
||||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, backPressedCallback)
|
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, backPressedDelegate)
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||||
|
viewModel.backPressedState.collectLatest {
|
||||||
|
backPressedDelegate.isEnabled = it.shouldHandleBackPressed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
menuProvider?.afterFirstRenderMode = true
|
menuProvider?.afterFirstRenderMode = true
|
||||||
|
|
||||||
@@ -2217,6 +2231,7 @@ class ConversationFragment :
|
|||||||
reactionDelegate.setOnActionSelectedListener(onActionSelectedListener)
|
reactionDelegate.setOnActionSelectedListener(onActionSelectedListener)
|
||||||
reactionDelegate.setOnHideListener(onHideListener)
|
reactionDelegate.setOnHideListener(onHideListener)
|
||||||
reactionDelegate.show(requireActivity(), viewModel.recipientSnapshot!!, conversationMessage, conversationGroupViewModel.isNonAdminInAnnouncementGroup(), selectedConversationModel)
|
reactionDelegate.show(requireActivity(), viewModel.recipientSnapshot!!, conversationMessage, conversationGroupViewModel.isNonAdminInAnnouncementGroup(), selectedConversationModel)
|
||||||
|
viewModel.setIsReactionDelegateShowing(true)
|
||||||
composeText.clearFocus()
|
composeText.clearFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2344,18 +2359,15 @@ class ConversationFragment :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class BackPressedDelegate : OnBackPressedCallback(true) {
|
private inner class BackPressedDelegate : OnBackPressedCallback(false) {
|
||||||
override fun handleOnBackPressed() {
|
override fun handleOnBackPressed() {
|
||||||
Log.d(TAG, "onBackPressed()")
|
Log.d(TAG, "onBackPressed()")
|
||||||
if (reactionDelegate.isShowing) {
|
val state = viewModel.backPressedState.value
|
||||||
|
|
||||||
|
if (state.isReactionDelegateShowing) {
|
||||||
reactionDelegate.hide()
|
reactionDelegate.hide()
|
||||||
} else if (isSearchRequested) {
|
} else if (state.isSearchRequested) {
|
||||||
searchMenuItem?.collapseActionView()
|
searchMenuItem?.collapseActionView()
|
||||||
} else if (args.conversationScreenType.isInBubble) {
|
|
||||||
isEnabled = false
|
|
||||||
requireActivity().onBackPressed()
|
|
||||||
} else {
|
|
||||||
requireActivity().finish()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3255,6 +3267,8 @@ class ConversationFragment :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onHide() {
|
override fun onHide() {
|
||||||
|
viewModel.setIsReactionDelegateShowing(false)
|
||||||
|
|
||||||
if (!lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED) || activity == null || activity?.isFinishing == true) {
|
if (!lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED) || activity == null || activity?.isFinishing == true) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,11 +32,14 @@ import io.reactivex.rxjava3.subjects.PublishSubject
|
|||||||
import io.reactivex.rxjava3.subjects.Subject
|
import io.reactivex.rxjava3.subjects.Subject
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.flow.flowOn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.mapNotNull
|
import kotlinx.coroutines.flow.mapNotNull
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.rx3.asFlow
|
import kotlinx.coroutines.rx3.asFlow
|
||||||
import org.signal.core.util.orNull
|
import org.signal.core.util.orNull
|
||||||
@@ -191,6 +194,9 @@ class ConversationViewModel(
|
|||||||
val jumpToDateValidator: JumpToDateValidator
|
val jumpToDateValidator: JumpToDateValidator
|
||||||
get() = _jumpToDateValidator
|
get() = _jumpToDateValidator
|
||||||
|
|
||||||
|
private val internalBackPressedState = MutableStateFlow(BackPressedState())
|
||||||
|
val backPressedState: StateFlow<BackPressedState> = internalBackPressedState
|
||||||
|
|
||||||
init {
|
init {
|
||||||
disposables += recipient
|
disposables += recipient
|
||||||
.subscribeBy {
|
.subscribeBy {
|
||||||
@@ -604,4 +610,23 @@ class ConversationViewModel(
|
|||||||
.getEarliestMessageSentDate(threadId)
|
.getEarliestMessageSentDate(threadId)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user