Updated on 2026-08-14
This commit is contained in:
parent
ce52c600ff
commit
a14f93ab82
9 changed files with 192 additions and 68 deletions
|
|
@ -26,7 +26,9 @@ sealed class DetailsAction : Action {
|
|||
data object Failure : ResetToFactory()
|
||||
data object Success : ResetToFactory()
|
||||
|
||||
data class LastWarningDialogVisibility(val isShown: Boolean) : ResetToFactory()
|
||||
data class ShowDialog(val dialog: CardSettingsState.Dialog) : ResetToFactory()
|
||||
|
||||
data object DismissDialog : ResetToFactory()
|
||||
}
|
||||
|
||||
data object ScanCard : DetailsAction()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.tap.features.details.redux
|
||||
|
||||
import com.tangem.core.navigation.AppScreen
|
||||
import com.tangem.domain.apptheme.model.AppThemeMode
|
||||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
|
|
@ -25,7 +26,7 @@ private fun internalReduce(action: Action, state: AppState): DetailsState {
|
|||
val detailsState = state.detailsState
|
||||
return when (action) {
|
||||
is DetailsAction.PrepareScreen -> {
|
||||
handlePrepareScreen(action)
|
||||
handlePrepareScreen(action, state)
|
||||
}
|
||||
is DetailsAction.PrepareCardSettingsData -> {
|
||||
handlePrepareCardSettingsScreen(
|
||||
|
|
@ -67,9 +68,15 @@ private fun internalReduce(action: Action, state: AppState): DetailsState {
|
|||
}
|
||||
}
|
||||
|
||||
private fun handlePrepareScreen(action: DetailsAction.PrepareScreen): DetailsState {
|
||||
private fun handlePrepareScreen(action: DetailsAction.PrepareScreen, state: AppState): DetailsState {
|
||||
return DetailsState(
|
||||
scanResponse = action.scanResponse,
|
||||
// If the current screen is ResetToFactory, we must save the ResetToFactory's state
|
||||
cardSettingsState = if (store.state.navigationState.backStack.lastOrNull() == AppScreen.ResetToFactory) {
|
||||
state.detailsState.cardSettingsState
|
||||
} else {
|
||||
null
|
||||
},
|
||||
createBackupAllowed = action.scanResponse.card.backupStatus == CardDTO.BackupStatus.NoBackup,
|
||||
appSettingsState = AppSettingsState(
|
||||
isBiometricsAvailable = tangemSdkManager.canUseBiometry,
|
||||
|
|
@ -115,7 +122,7 @@ private fun handlePrepareCardSettingsScreen(
|
|||
null
|
||||
},
|
||||
isShowPasswordResetRadioButton = isShowPasswordResetRadioButton,
|
||||
isLastWarningDialogShown = false,
|
||||
dialog = null,
|
||||
)
|
||||
return state.copy(cardSettingsState = cardSettingsState)
|
||||
}
|
||||
|
|
@ -183,14 +190,12 @@ private fun handleEraseWallet(action: DetailsAction.ResetToFactory, state: Detai
|
|||
),
|
||||
)
|
||||
}
|
||||
is DetailsAction.ResetToFactory.LastWarningDialogVisibility -> {
|
||||
state.copy(
|
||||
cardSettingsState = cardSettingsState?.copy(
|
||||
isLastWarningDialogShown = action.isShown,
|
||||
),
|
||||
)
|
||||
is DetailsAction.ResetToFactory.ShowDialog -> {
|
||||
state.copy(cardSettingsState = cardSettingsState?.copy(dialog = action.dialog))
|
||||
}
|
||||
is DetailsAction.ResetToFactory.DismissDialog -> {
|
||||
state.copy(cardSettingsState = cardSettingsState?.copy(dialog = null))
|
||||
}
|
||||
|
||||
else -> state
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,8 +46,16 @@ data class CardSettingsState(
|
|||
val condition2Checked: Boolean,
|
||||
val accessCodeRecovery: AccessCodeRecoveryState? = null,
|
||||
val isShowPasswordResetRadioButton: Boolean,
|
||||
val isLastWarningDialogShown: Boolean,
|
||||
)
|
||||
val dialog: Dialog?,
|
||||
) {
|
||||
|
||||
sealed interface Dialog {
|
||||
data object StartResetDialog : Dialog
|
||||
data object ContinueResetDialog : Dialog
|
||||
data object InterruptedResetDialog : Dialog
|
||||
data object CompletedResetDialog : Dialog
|
||||
}
|
||||
}
|
||||
|
||||
data class ManageSecurityState(
|
||||
val currentOption: SecurityOption = SecurityOption.LongTap,
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
package com.tangem.tap.features.details.ui.resetcard
|
||||
|
||||
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 androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.navigation.NavigationAction
|
||||
import com.tangem.core.ui.UiDependencies
|
||||
import com.tangem.core.ui.screen.ComposeFragment
|
||||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
import com.tangem.tap.store
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import org.rekotlin.StoreSubscriber
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -22,13 +22,14 @@ internal class ResetCardFragment : ComposeFragment(), StoreSubscriber<DetailsSta
|
|||
|
||||
private val viewModel: ResetCardViewModel by viewModels()
|
||||
|
||||
private var screenState: MutableState<ResetCardScreenState> =
|
||||
mutableStateOf(ResetCardScreenState.InitialState)
|
||||
private var screenState = MutableStateFlow<ResetCardScreenState>(ResetCardScreenState.InitialState)
|
||||
|
||||
@Composable
|
||||
override fun ScreenContent(modifier: Modifier) {
|
||||
val state = screenState.collectAsStateWithLifecycle().value
|
||||
|
||||
ResetCardScreen(
|
||||
state = screenState.value,
|
||||
state = state,
|
||||
onBackClick = { store.dispatch(NavigationAction.PopBackTo()) },
|
||||
modifier = modifier,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -4,22 +4,23 @@ import android.content.res.Configuration
|
|||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconToggleButton
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconToggleButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.components.*
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.tap.features.details.ui.cardsettings.TextReference
|
||||
import com.tangem.tap.features.details.ui.cardsettings.resolveReference
|
||||
import com.tangem.tap.features.details.ui.common.DetailsMainButton
|
||||
import com.tangem.tap.features.details.ui.common.SettingsScreensScaffold
|
||||
import com.tangem.wallet.R
|
||||
import com.tangem.tap.features.details.ui.resetcard.ResetCardScreenState.ResetCardScreenContent.Dialog as ResetCardDialog
|
||||
|
||||
@Composable
|
||||
internal fun ResetCardScreen(state: ResetCardScreenState, onBackClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||
|
|
@ -36,7 +37,14 @@ internal fun ResetCardScreen(state: ResetCardScreenState, onBackClick: () -> Uni
|
|||
onBackClick = onBackClick,
|
||||
)
|
||||
|
||||
LastWarningDialog(state = state)
|
||||
when (val dialog = (state as? ResetCardScreenState.ResetCardScreenContent)?.dialog) {
|
||||
is ResetCardDialog.StartReset,
|
||||
is ResetCardDialog.ContinueReset,
|
||||
is ResetCardDialog.InterruptedReset,
|
||||
-> CommonResetDialog(dialog = dialog)
|
||||
is ResetCardDialog.CompletedReset -> CompletedResetDialog(dialog = dialog)
|
||||
null -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -184,23 +192,35 @@ private fun ResetButton(enabled: Boolean, onResetButtonClick: () -> Unit) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun LastWarningDialog(state: ResetCardScreenState) {
|
||||
if (state is ResetCardScreenState.ResetCardScreenContent && state.lastWarningDialog.isShown) {
|
||||
BasicDialog(
|
||||
title = stringResource(id = R.string.common_attention),
|
||||
message = stringResource(id = R.string.card_settings_action_sheet_title),
|
||||
dismissButton = DialogButton(
|
||||
title = stringResource(id = R.string.card_settings_action_sheet_reset),
|
||||
warning = true,
|
||||
onClick = state.lastWarningDialog.onResetButtonClick,
|
||||
),
|
||||
confirmButton = DialogButton(
|
||||
title = stringResource(id = R.string.common_cancel),
|
||||
onClick = state.lastWarningDialog.onDismiss,
|
||||
),
|
||||
onDismissDialog = state.lastWarningDialog.onDismiss,
|
||||
)
|
||||
}
|
||||
private fun CommonResetDialog(dialog: ResetCardScreenState.ResetCardScreenContent.Dialog) {
|
||||
BasicDialog(
|
||||
title = stringResource(dialog.titleResId),
|
||||
message = stringResource(dialog.messageResId),
|
||||
dismissButton = DialogButton(
|
||||
title = stringResource(id = R.string.common_cancel),
|
||||
onClick = dialog.onDismiss,
|
||||
),
|
||||
confirmButton = DialogButton(
|
||||
title = stringResource(id = R.string.card_settings_action_sheet_reset),
|
||||
warning = true,
|
||||
onClick = dialog.onConfirmClick,
|
||||
),
|
||||
onDismissDialog = dialog.onDismiss,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun CompletedResetDialog(dialog: ResetCardDialog) {
|
||||
BasicDialog(
|
||||
title = stringResource(id = dialog.titleResId),
|
||||
message = stringResource(id = dialog.messageResId),
|
||||
confirmButton = DialogButton(
|
||||
title = stringResource(id = R.string.common_ok),
|
||||
onClick = dialog.onConfirmClick,
|
||||
),
|
||||
onDismissDialog = {},
|
||||
isDismissable = false,
|
||||
)
|
||||
}
|
||||
|
||||
// region Preview
|
||||
|
|
@ -218,11 +238,7 @@ private fun ResetCardScreenSample(modifier: Modifier = Modifier) {
|
|||
onAcceptCondition1ToggleClick = {},
|
||||
onAcceptCondition2ToggleClick = {},
|
||||
onResetButtonClick = {},
|
||||
lastWarningDialog = ResetCardScreenState.ResetCardScreenContent.LastWarningDialog(
|
||||
isShown = false,
|
||||
onResetButtonClick = {},
|
||||
onDismiss = {},
|
||||
),
|
||||
dialog = null,
|
||||
),
|
||||
onBackClick = {},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package com.tangem.tap.features.details.ui.resetcard
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import com.tangem.tap.features.details.ui.cardsettings.TextReference
|
||||
import com.tangem.wallet.R
|
||||
|
||||
internal sealed class ResetCardScreenState {
|
||||
|
||||
|
|
@ -15,16 +17,51 @@ internal sealed class ResetCardScreenState {
|
|||
val onAcceptCondition1ToggleClick: (Boolean) -> Unit,
|
||||
val onAcceptCondition2ToggleClick: (Boolean) -> Unit,
|
||||
val onResetButtonClick: () -> Unit,
|
||||
val lastWarningDialog: LastWarningDialog,
|
||||
val dialog: Dialog? = null,
|
||||
) : ResetCardScreenState() {
|
||||
val resetButtonEnabled: Boolean
|
||||
get() = accepted
|
||||
|
||||
data class LastWarningDialog(
|
||||
val isShown: Boolean,
|
||||
val onResetButtonClick: () -> Unit,
|
||||
val onDismiss: () -> Unit,
|
||||
)
|
||||
sealed class Dialog(
|
||||
@StringRes val titleResId: Int,
|
||||
@StringRes val messageResId: Int,
|
||||
) {
|
||||
|
||||
abstract val onConfirmClick: () -> Unit
|
||||
abstract val onDismiss: () -> Unit
|
||||
|
||||
data class StartReset(
|
||||
override val onConfirmClick: () -> Unit,
|
||||
override val onDismiss: () -> Unit,
|
||||
) : Dialog(
|
||||
titleResId = R.string.common_attention,
|
||||
messageResId = R.string.card_settings_action_sheet_title,
|
||||
)
|
||||
|
||||
data class ContinueReset(
|
||||
override val onConfirmClick: () -> Unit,
|
||||
override val onDismiss: () -> Unit,
|
||||
) : Dialog(
|
||||
titleResId = R.string.card_settings_continue_reset_alert_title,
|
||||
messageResId = R.string.card_settings_continue_reset_alert_message,
|
||||
)
|
||||
|
||||
data class InterruptedReset(
|
||||
override val onConfirmClick: () -> Unit,
|
||||
override val onDismiss: () -> Unit,
|
||||
) : Dialog(
|
||||
titleResId = R.string.card_settings_interrupted_reset_alert_title,
|
||||
messageResId = R.string.card_settings_interrupted_reset_alert_message,
|
||||
)
|
||||
|
||||
data class CompletedReset(override val onConfirmClick: () -> Unit) : Dialog(
|
||||
titleResId = R.string.card_settings_completed_reset_alert_title,
|
||||
messageResId = R.string.card_settings_completed_reset_alert_message,
|
||||
) {
|
||||
|
||||
override val onDismiss: () -> Unit = {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal enum class WarningsToReset {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ 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.redux.DetailsAction.ResetToFactory
|
||||
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
|
||||
|
|
@ -18,6 +18,7 @@ import com.tangem.tap.store
|
|||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import com.tangem.tap.features.details.redux.CardSettingsState.Dialog as CardSettingsDialog
|
||||
|
||||
@HiltViewModel
|
||||
internal class ResetCardViewModel @Inject constructor(
|
||||
|
|
@ -47,28 +48,48 @@ internal class ResetCardViewModel @Inject constructor(
|
|||
warningsToShow = warningsToShow,
|
||||
acceptCondition1Checked = state?.condition1Checked ?: false,
|
||||
acceptCondition2Checked = state?.condition2Checked ?: false,
|
||||
onAcceptCondition1ToggleClick = { store.dispatch(DetailsAction.ResetToFactory.AcceptCondition1(it)) },
|
||||
onAcceptCondition2ToggleClick = { store.dispatch(DetailsAction.ResetToFactory.AcceptCondition2(it)) },
|
||||
onResetButtonClick = { showLastWarningDialog() },
|
||||
lastWarningDialog = ResetCardScreenState.ResetCardScreenContent.LastWarningDialog(
|
||||
isShown = state?.isLastWarningDialogShown ?: false,
|
||||
onResetButtonClick = ::onLastWarningDialogResetClicked,
|
||||
onDismiss = ::onLastWarningDialogDismiss,
|
||||
),
|
||||
onAcceptCondition1ToggleClick = { store.dispatch(ResetToFactory.AcceptCondition1(it)) },
|
||||
onAcceptCondition2ToggleClick = { store.dispatch(ResetToFactory.AcceptCondition2(it)) },
|
||||
onResetButtonClick = { showDialog(CardSettingsDialog.StartResetDialog) },
|
||||
dialog = state?.dialog?.let(::createDialog),
|
||||
)
|
||||
}
|
||||
|
||||
private fun showLastWarningDialog() {
|
||||
store.dispatch(DetailsAction.ResetToFactory.LastWarningDialogVisibility(isShown = true))
|
||||
private fun createDialog(dialog: CardSettingsDialog): ResetCardScreenState.ResetCardScreenContent.Dialog {
|
||||
return when (dialog) {
|
||||
CardSettingsDialog.StartResetDialog -> {
|
||||
ResetCardScreenState.ResetCardScreenContent.Dialog.StartReset(
|
||||
onConfirmClick = ::onStartResetClick,
|
||||
onDismiss = ::dismissDialog,
|
||||
)
|
||||
}
|
||||
CardSettingsDialog.ContinueResetDialog -> {
|
||||
ResetCardScreenState.ResetCardScreenContent.Dialog.ContinueReset(
|
||||
onConfirmClick = ::onContinueResetClick,
|
||||
onDismiss = ::onContinueResetDialogDismiss,
|
||||
)
|
||||
}
|
||||
CardSettingsDialog.InterruptedResetDialog -> {
|
||||
ResetCardScreenState.ResetCardScreenContent.Dialog.InterruptedReset(
|
||||
onConfirmClick = ::onContinueResetClick,
|
||||
onDismiss = ::dismissAndFinishFullReset,
|
||||
)
|
||||
}
|
||||
CardSettingsDialog.CompletedResetDialog -> {
|
||||
ResetCardScreenState.ResetCardScreenContent.Dialog.CompletedReset(
|
||||
onConfirmClick = ::dismissAndFinishFullReset,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onLastWarningDialogResetClicked() {
|
||||
store.dispatch(DetailsAction.ResetToFactory.LastWarningDialogVisibility(isShown = false))
|
||||
private fun onStartResetClick() {
|
||||
dismissDialog()
|
||||
|
||||
if (resetCardFeatureToggles.isFullResetEnabled) {
|
||||
makeFullReset()
|
||||
} else {
|
||||
store.dispatch(DetailsAction.ResetToFactory.Proceed)
|
||||
store.dispatch(ResetToFactory.Proceed)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -85,13 +106,35 @@ internal class ResetCardViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun onContinueResetClick() {
|
||||
dismissDialog()
|
||||
|
||||
// TODO: [REDACTED_TASK_KEY]
|
||||
}
|
||||
|
||||
private fun onContinueResetDialogDismiss() {
|
||||
dismissDialog()
|
||||
|
||||
showDialog(CardSettingsDialog.InterruptedResetDialog)
|
||||
}
|
||||
|
||||
private suspend fun resetCurrentCard(userWallet: UserWallet) = either {
|
||||
resetCardUseCase(userWallet.scanResponse.card).bind()
|
||||
deleteSavedAccessCodesUseCase(userWallet.cardId).bind()
|
||||
deleteWalletUseCase(userWallet.walletId).bind()
|
||||
}
|
||||
|
||||
private fun onLastWarningDialogDismiss() {
|
||||
store.dispatch(DetailsAction.ResetToFactory.LastWarningDialogVisibility(isShown = false))
|
||||
private fun dismissAndFinishFullReset() {
|
||||
dismissDialog()
|
||||
|
||||
// TODO: [REDACTED_TASK_KEY]
|
||||
}
|
||||
|
||||
private fun showDialog(dialog: CardSettingsDialog) {
|
||||
store.dispatch(ResetToFactory.ShowDialog(dialog))
|
||||
}
|
||||
|
||||
private fun dismissDialog() {
|
||||
store.dispatch(ResetToFactory.DismissDialog)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue