diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/accessfactorsources/derivepublickey/DerivePublicKeyDialog.kt b/app/src/main/java/com/babylon/wallet/android/presentation/accessfactorsources/derivepublickey/DerivePublicKeyDialog.kt index e31ce0b58e..4846dacad7 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/accessfactorsources/derivepublickey/DerivePublicKeyDialog.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/accessfactorsources/derivepublickey/DerivePublicKeyDialog.kt @@ -1,5 +1,6 @@ package com.babylon.wallet.android.presentation.accessfactorsources.derivepublickey +import androidx.activity.compose.BackHandler import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -45,6 +46,10 @@ fun DerivePublicKeyDialog( val state by viewModel.state.collectAsState() val context = LocalContext.current + BackHandler { + viewModel.onUserDismiss() + } + LaunchedEffect(Unit) { viewModel.oneOffEvent.collect { event -> when (event) { @@ -58,6 +63,7 @@ fun DerivePublicKeyDialog( } } DerivePublicKeyViewModel.Event.AccessingFactorSourceCompleted -> onDismiss() + DerivePublicKeyViewModel.Event.UserDismissed -> onDismiss() } } } @@ -66,7 +72,7 @@ fun DerivePublicKeyDialog( modifier = modifier, showContentForFactorSource = state.showContentForFactorSource, shouldShowRetryButton = state.shouldShowRetryButton, - onDismiss = onDismiss, + onDismiss = viewModel::onUserDismiss, onRetryClick = viewModel::onRetryClick ) } @@ -81,9 +87,7 @@ private fun DerivePublicKeyBottomSheetContent( ) { BottomSheetDialogWrapper( modifier = modifier, - onDismiss = { - onDismiss() - } + onDismiss = onDismiss ) { Column( modifier = Modifier diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/accessfactorsources/derivepublickey/DerivePublicKeyViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/accessfactorsources/derivepublickey/DerivePublicKeyViewModel.kt index 5d25212913..57859ccfa1 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/accessfactorsources/derivepublickey/DerivePublicKeyViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/accessfactorsources/derivepublickey/DerivePublicKeyViewModel.kt @@ -21,6 +21,7 @@ import com.radixdlt.sargon.PublicKey import com.radixdlt.sargon.extensions.init import com.radixdlt.sargon.extensions.string import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Job import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @@ -114,6 +115,16 @@ class DerivePublicKeyViewModel @Inject constructor( } } + fun onUserDismiss() { + viewModelScope.launch { + derivePublicKeyJob?.cancel() + accessFactorSourcesUiProxy.setOutput( + output = AccessFactorSourcesOutput.Failure(CancellationException("User cancelled")) + ) + sendEvent(Event.UserDismissed) + } + } + private suspend fun derivePublicKey(): Result { return when (val factorSource = input.factorSource) { is FactorSource.Device -> { @@ -192,5 +203,6 @@ class DerivePublicKeyViewModel @Inject constructor( sealed interface Event : OneOffEvent { data object RequestBiometricPrompt : Event data object AccessingFactorSourceCompleted : Event + data object UserDismissed : Event } } diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/account/createaccount/CreateAccountViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/account/createaccount/CreateAccountViewModel.kt index 63214d517c..24815e8dbd 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/account/createaccount/CreateAccountViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/account/createaccount/CreateAccountViewModel.kt @@ -22,6 +22,8 @@ import com.radixdlt.sargon.FactorSource import com.radixdlt.sargon.extensions.asGeneral import com.radixdlt.sargon.extensions.string import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.Job import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.update @@ -63,6 +65,8 @@ class CreateAccountViewModel @Inject constructor( val buttonEnabled = savedStateHandle.getStateFlow(CREATE_ACCOUNT_BUTTON_ENABLED, false) val isAccountNameLengthMoreThanTheMax = savedStateHandle.getStateFlow(IS_ACCOUNT_NAME_LENGTH_MORE_THAN_THE_MAX, false) + private var accessFactorSourcesJob: Job? = null + override fun initialState(): CreateAccountUiState = CreateAccountUiState( isFirstAccount = args.requestSource?.isFirstTime() == true ) @@ -115,40 +119,43 @@ class CreateAccountViewModel @Inject constructor( } // when called the access factor source bottom sheet dialog is presented - private suspend fun accessFactorSourceForAccountCreation( + private fun accessFactorSourceForAccountCreation( isFirstAccount: Boolean, isWithLedger: Boolean ) { - val selectedFactorSource = if (isWithLedger) { // then get the selected ledger device - sendEvent(CreateAccountEvent.AddLedgerDevice) - appEventBus.events - .filterIsInstance() - .first() - .ledgerFactorSource - } else { - getProfileUseCase().mainBabylonFactorSource ?: return - } + accessFactorSourcesJob?.cancel() + accessFactorSourcesJob = viewModelScope.launch { + val selectedFactorSource = if (isWithLedger) { // then get the selected ledger device + sendEvent(CreateAccountEvent.AddLedgerDevice) + appEventBus.events + .filterIsInstance() + .first() + .ledgerFactorSource + } else { + getProfileUseCase().mainBabylonFactorSource ?: return@launch + } - accessFactorSourcesProxy.getPublicKeyAndDerivationPathForFactorSource( - accessFactorSourcesInput = AccessFactorSourcesInput.ToDerivePublicKey( - forNetworkId = args.networkIdToSwitch ?: getProfileUseCase().currentGateway.network.id, - factorSource = selectedFactorSource, - isBiometricsProvided = isFirstAccount - ) - ).onSuccess { - handleAccountCreation { nameOfAccount -> - val factorSourceId = when (selectedFactorSource) { - is FactorSource.Device -> selectedFactorSource.value.id.asGeneral() - is FactorSource.Ledger -> selectedFactorSource.value.id.asGeneral() - } - createAccountUseCase( - displayName = DisplayName(nameOfAccount), - factorSourceId = factorSourceId, - hdPublicKey = it.value + accessFactorSourcesProxy.getPublicKeyAndDerivationPathForFactorSource( + accessFactorSourcesInput = AccessFactorSourcesInput.ToDerivePublicKey( + forNetworkId = args.networkIdToSwitch ?: getProfileUseCase().currentGateway.network.id, + factorSource = selectedFactorSource, + isBiometricsProvided = isFirstAccount ) + ).onSuccess { + handleAccountCreation { nameOfAccount -> + val factorSourceId = when (selectedFactorSource) { + is FactorSource.Device -> selectedFactorSource.value.id.asGeneral() + is FactorSource.Ledger -> selectedFactorSource.value.id.asGeneral() + } + createAccountUseCase( + displayName = DisplayName(nameOfAccount), + factorSourceId = factorSourceId, + hdPublicKey = it.value + ) + } + }.onFailure { throwable -> + handleAccountCreationError(throwable) } - }.onFailure { throwable -> - handleAccountCreationError(throwable) } } @@ -160,6 +167,9 @@ class CreateAccountViewModel @Inject constructor( if (throwable is ProfileException.NoMnemonic) { state.copy(shouldShowNoMnemonicError = true) } else { + if (throwable is CancellationException) { // user cancelled, don't print it + return + } state.copy( uiMessage = UiMessage.ErrorMessage(throwable) )