mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-05-14 20:20:38 +01:00
Clean up back-pressed behavior which could result in an empty backstack and crash.
Co-authored-by: Greyson Parrelli <greyson@signal.org> Co-authored-by: jeffrey-signal <jeffrey@signal.org>
This commit is contained in:
committed by
Greyson Parrelli
parent
07329c5b0d
commit
1d36ecafe1
+8
@@ -6,6 +6,7 @@
|
||||
package org.thoughtcrime.securesms.registration.olddevice
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
@@ -49,6 +50,13 @@ fun TransferAccountNavHost(
|
||||
) {
|
||||
val backStack by viewModel.backStack.collectAsStateWithLifecycle()
|
||||
|
||||
val backDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher
|
||||
LaunchedEffect(viewModel, backDispatcher) {
|
||||
viewModel.finishRequests.collect {
|
||||
backDispatcher?.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
val entryProvider = entryProvider {
|
||||
navigationEntries(
|
||||
viewModel = viewModel,
|
||||
|
||||
+17
-2
@@ -8,8 +8,12 @@ package org.thoughtcrime.securesms.registration.olddevice
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import org.signal.core.util.logging.Log
|
||||
@@ -41,8 +45,11 @@ class QuickTransferOldDeviceViewModel(reRegisterUri: String) : ViewModel() {
|
||||
private val _backStack: MutableStateFlow<List<TransferAccountRoute>> = MutableStateFlow(listOf(TransferAccountRoute.Transfer))
|
||||
val backStack: StateFlow<List<TransferAccountRoute>> = _backStack
|
||||
|
||||
private val finishChannel = Channel<Unit>(capacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
|
||||
val finishRequests: Flow<Unit> = finishChannel.receiveAsFlow()
|
||||
|
||||
fun goBack() {
|
||||
_backStack.update { it.dropLast(1) }
|
||||
popOrFinish()
|
||||
}
|
||||
|
||||
fun onEvent(event: PrepareDeviceScreenEvents) {
|
||||
@@ -51,7 +58,7 @@ class QuickTransferOldDeviceViewModel(reRegisterUri: String) : ViewModel() {
|
||||
store.update { it.copy(navigateToBackupCreation = true) }
|
||||
}
|
||||
PrepareDeviceScreenEvents.NavigateBack -> {
|
||||
_backStack.update { it.dropLast(1) }
|
||||
popOrFinish()
|
||||
}
|
||||
PrepareDeviceScreenEvents.SkipAndContinue -> {
|
||||
_backStack.update { listOf(TransferAccountRoute.Transfer) }
|
||||
@@ -96,6 +103,14 @@ class QuickTransferOldDeviceViewModel(reRegisterUri: String) : ViewModel() {
|
||||
store.update { it.copy(navigateToBackupCreation = false) }
|
||||
}
|
||||
|
||||
private fun popOrFinish() {
|
||||
if (_backStack.value.size > 1) {
|
||||
_backStack.update { it.dropLast(1) }
|
||||
} else {
|
||||
finishChannel.trySend(Unit)
|
||||
}
|
||||
}
|
||||
|
||||
private fun transferAccount() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val restoreMethodToken = UUID.randomUUID().toString()
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
package org.signal.registration
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
@@ -231,6 +232,13 @@ fun RegistrationNavHost(
|
||||
return
|
||||
}
|
||||
|
||||
val backDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher
|
||||
LaunchedEffect(viewModel, backDispatcher) {
|
||||
viewModel.finishRequests.collect {
|
||||
backDispatcher?.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
val entryProvider = entryProvider {
|
||||
navigationEntries(
|
||||
registrationRepository = registrationRepository,
|
||||
|
||||
+15
-1
@@ -13,9 +13,13 @@ import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.createSavedStateHandle
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.viewmodel.CreationExtras
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import org.signal.core.ui.navigation.ResultEventBus
|
||||
import org.signal.core.util.logging.Log
|
||||
@@ -35,6 +39,9 @@ class RegistrationViewModel(private val repository: RegistrationRepository, save
|
||||
private var _state: MutableStateFlow<RegistrationFlowState> = savedStateHandle.getMutableStateFlow("registration_state", initialValue = RegistrationFlowState())
|
||||
val state: StateFlow<RegistrationFlowState> = _state.asStateFlow()
|
||||
|
||||
private val finishChannel = Channel<Unit>(capacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
|
||||
val finishRequests: Flow<Unit> = finishChannel.receiveAsFlow()
|
||||
|
||||
val resultBus = ResultEventBus()
|
||||
|
||||
init {
|
||||
@@ -66,7 +73,14 @@ class RegistrationViewModel(private val repository: RegistrationRepository, save
|
||||
is RegistrationFlowEvent.Registered -> state.copy(accountEntropyPool = event.accountEntropyPool)
|
||||
is RegistrationFlowEvent.MasterKeyRestoredFromSvr -> state.copy(temporaryMasterKey = event.masterKey)
|
||||
is RegistrationFlowEvent.NavigateToScreen -> applyNavigationToScreenEvent(state, event)
|
||||
is RegistrationFlowEvent.NavigateBack -> state.copy(backStack = state.backStack.dropLast(1))
|
||||
is RegistrationFlowEvent.NavigateBack -> {
|
||||
if (state.backStack.size > 1) {
|
||||
state.copy(backStack = state.backStack.dropLast(1))
|
||||
} else {
|
||||
finishChannel.trySend(Unit)
|
||||
state
|
||||
}
|
||||
}
|
||||
is RegistrationFlowEvent.RecoveryPasswordInvalid -> state.copy(doNotAttemptRecoveryPassword = true)
|
||||
is RegistrationFlowEvent.PendingRestoreOptionSelected -> state.copy(pendingRestoreOption = event.option)
|
||||
is RegistrationFlowEvent.UserSuppliedAepSubmitted -> state.copy(unverifiedRestoredAep = event.aep)
|
||||
|
||||
Reference in New Issue
Block a user