Updated on 2026-08-14

This commit is contained in:
Tangem 2024-05-28 19:05:46 +08:00
parent 10ba20b045
commit c849c203b1
6 changed files with 134 additions and 5 deletions

View file

@ -9,6 +9,7 @@ import com.tangem.domain.demo.IsDemoCardUseCase
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.wallets.usecase.IsNeedToBackupUseCase
import com.tangem.tap.domain.card.DefaultDeleteSavedAccessCodesUseCase
import com.tangem.tap.domain.card.DefaultResetCardUseCase
import com.tangem.tap.domain.sdk.TangemSdkManager
import dagger.Module
import dagger.Provides
@ -77,4 +78,10 @@ internal object CardDomainModule {
fun provideDeleteSavedAccessCodesUseCase(tangemSdkManager: TangemSdkManager): DeleteSavedAccessCodesUseCase {
return DefaultDeleteSavedAccessCodesUseCase(tangemSdkManager)
}
@Provides
@ViewModelScoped
fun provideResetCardUseCase(tangemSdkManager: TangemSdkManager): ResetCardUseCase {
return DefaultResetCardUseCase(tangemSdkManager)
}
}

View file

@ -0,0 +1,55 @@
package com.tangem.tap.domain.card
import arrow.core.Either
import arrow.core.raise.either
import arrow.core.right
import com.tangem.common.CompletionResult
import com.tangem.common.UserCodeType
import com.tangem.common.core.TangemSdkError
import com.tangem.common.core.UserCodeRequestPolicy
import com.tangem.common.doOnResult
import com.tangem.domain.card.ResetCardUseCase
import com.tangem.domain.card.models.ResetCardError
import com.tangem.domain.models.scan.CardDTO
import com.tangem.tap.domain.sdk.TangemSdkManager
internal class DefaultResetCardUseCase(
private val tangemSdkManager: TangemSdkManager,
) : ResetCardUseCase {
override suspend fun invoke(card: CardDTO): Either<ResetCardError, Unit> = either {
val policyBeforeReset = tangemSdkManager.userCodeRequestPolicy
requestMandatoryAccessCodeEntry(card)
val result = tangemSdkManager.resetToFactorySettings(
cardId = card.cardId,
allowsRequestAccessCodeFromRepository = true,
)
.doOnResult { tangemSdkManager.setUserCodeRequestPolicy(policyBeforeReset) }
when (result) {
is CompletionResult.Success -> Unit.right()
is CompletionResult.Failure -> {
if (result.error is TangemSdkError.UserCancelled) {
raise(ResetCardError.UserCanceled)
} else {
raise(ResetCardError.AnotherSdkError)
}
}
}
}
private fun requestMandatoryAccessCodeEntry(card: CardDTO) {
val type = if (card.isAccessCodeSet) {
UserCodeType.AccessCode
} else if (card.isPasscodeSet == true) {
UserCodeType.Passcode
} else {
null
}
type?.let {
tangemSdkManager.setUserCodeRequestPolicy(policy = UserCodeRequestPolicy.Always(type))
}
}
}

View file

@ -4,6 +4,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Modifier
import androidx.fragment.app.viewModels
import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.UiDependencies
import com.tangem.core.ui.screen.ComposeFragment
@ -19,7 +20,7 @@ internal class ResetCardFragment : ComposeFragment(), StoreSubscriber<DetailsSta
@Inject
override lateinit var uiDependencies: UiDependencies
private val viewModel = ResetCardViewModel(store)
private val viewModel: ResetCardViewModel by viewModels()
private var screenState: MutableState<ResetCardScreenState> =
mutableStateOf(ResetCardScreenState.InitialState)

View file

@ -1,13 +1,32 @@
package com.tangem.tap.features.details.ui.resetcard
import com.tangem.tap.common.redux.AppState
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import arrow.core.raise.either
import com.tangem.domain.card.DeleteSavedAccessCodesUseCase
import com.tangem.domain.card.ResetCardUseCase
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.usecase.DeleteWalletUseCase
import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
import com.tangem.tap.common.extensions.onUserWalletSelected
import com.tangem.tap.features.details.redux.CardSettingsState
import com.tangem.tap.features.details.redux.DetailsAction
import com.tangem.tap.features.details.ui.cardsettings.TextReference
import com.tangem.tap.features.details.ui.resetcard.featuretoggles.ResetCardFeatureToggles
import com.tangem.tap.features.details.ui.utils.toResetCardDescriptionText
import org.rekotlin.Store
import com.tangem.tap.store
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
internal class ResetCardViewModel(private val store: Store<AppState>) {
@HiltViewModel
internal class ResetCardViewModel @Inject constructor(
private val resetCardFeatureToggles: ResetCardFeatureToggles,
private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase,
private val resetCardUseCase: ResetCardUseCase,
private val deleteSavedAccessCodesUseCase: DeleteSavedAccessCodesUseCase,
private val deleteWalletUseCase: DeleteWalletUseCase,
) : ViewModel() {
fun updateState(state: CardSettingsState?): ResetCardScreenState.ResetCardScreenContent {
val descriptionText = state?.cardInfo
@ -45,7 +64,31 @@ internal class ResetCardViewModel(private val store: Store<AppState>) {
private fun onLastWarningDialogResetClicked() {
store.dispatch(DetailsAction.ResetToFactory.LastWarningDialogVisibility(isShown = false))
store.dispatch(DetailsAction.ResetToFactory.Proceed)
if (resetCardFeatureToggles.isFullResetEnabled) {
makeFullReset()
} else {
store.dispatch(DetailsAction.ResetToFactory.Proceed)
}
}
private fun makeFullReset() {
val currentUserWallet = getSelectedWalletSyncUseCase().getOrNull() ?: return
viewModelScope.launch {
resetCurrentCard(userWallet = currentUserWallet).onRight {
val newSelectedWallet = getSelectedWalletSyncUseCase().getOrNull()
if (newSelectedWallet != null) {
store.onUserWalletSelected(newSelectedWallet)
}
}
}
}
private suspend fun resetCurrentCard(userWallet: UserWallet) = either {
resetCardUseCase(userWallet.scanResponse.card).bind()
deleteSavedAccessCodesUseCase(userWallet.cardId).bind()
deleteWalletUseCase(userWallet.walletId).bind()
}
private fun onLastWarningDialogDismiss() {

View file

@ -0,0 +1,15 @@
package com.tangem.domain.card
import arrow.core.Either
import com.tangem.domain.card.models.ResetCardError
import com.tangem.domain.models.scan.CardDTO
/**
* Use case for resetting card to factory settings
*
[REDACTED_AUTHOR]
*/
interface ResetCardUseCase {
suspend operator fun invoke(card: CardDTO): Either<ResetCardError, Unit>
}

View file

@ -0,0 +1,8 @@
package com.tangem.domain.card.models
sealed interface ResetCardError {
data object UserCanceled : ResetCardError
data object AnotherSdkError : ResetCardError
}