Updated on 2026-08-14
This commit is contained in:
parent
8e16f4e332
commit
c29afa8164
5 changed files with 55 additions and 77 deletions
|
|
@ -7,7 +7,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.features.hotwallet.WalletBackupComponent
|
||||
import com.tangem.features.hotwallet.walletbackup.entity.Action
|
||||
import com.tangem.features.hotwallet.walletbackup.model.WalletBackupModel
|
||||
import com.tangem.features.hotwallet.walletbackup.ui.WalletBackupContent
|
||||
import dagger.assisted.Assisted
|
||||
|
|
@ -27,21 +26,6 @@ internal class DefaultWalletBackupComponent @AssistedInject constructor(
|
|||
WalletBackupContent(
|
||||
state = state,
|
||||
modifier = modifier,
|
||||
onBackClick = {
|
||||
model.onAction(Action.OnBack)
|
||||
},
|
||||
onHardwareWalletClick = {
|
||||
model.onAction(Action.HardwareWallet)
|
||||
},
|
||||
onRecoveryPhraseClick = {
|
||||
model.onAction(Action.RecoveryPhrase)
|
||||
},
|
||||
onGoogleDriveClick = {
|
||||
model.onAction(Action.GoogleDriveBackup(isDialogShown = true))
|
||||
},
|
||||
onGoogleDriveFakeDoorDialogDismiss = {
|
||||
model.onAction(Action.GoogleDriveBackup(isDialogShown = false))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,14 @@ package com.tangem.features.hotwallet.walletbackup.entity
|
|||
import com.tangem.core.ui.components.label.entity.LabelUM
|
||||
|
||||
internal data class WalletBackupUM(
|
||||
val onBackClick: () -> Unit,
|
||||
val hardwareWalletOption: LabelUM?,
|
||||
val recoveryPhraseOption: LabelUM?,
|
||||
val googleDriveOption: LabelUM?,
|
||||
val googleDriveStatus: BackupStatus,
|
||||
val onRecoveryPhraseClick: () -> Unit,
|
||||
val onGoogleDriveAction: (Boolean) -> Unit, // boolean is for show and hide dialog
|
||||
val onHardwareWalletClick: () -> Unit,
|
||||
val isGoogleDriveDialogShown: Boolean,
|
||||
val isBackedUp: Boolean,
|
||||
)
|
||||
|
|
@ -15,11 +19,4 @@ internal sealed class BackupStatus {
|
|||
object Done : BackupStatus()
|
||||
object ComingSoon : BackupStatus()
|
||||
object NoBackup : BackupStatus()
|
||||
}
|
||||
|
||||
internal sealed interface Action {
|
||||
data object RecoveryPhrase : Action
|
||||
data object HardwareWallet : Action
|
||||
data class GoogleDriveBackup(val isDialogShown: Boolean) : Action
|
||||
data object OnBack : Action
|
||||
}
|
||||
|
|
@ -16,13 +16,12 @@ import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents
|
|||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.domain.wallets.usecase.UnlockHotWalletContextualUseCase
|
||||
import com.tangem.features.hotwallet.WalletBackupComponent
|
||||
import com.tangem.features.hotwallet.walletbackup.entity.Action
|
||||
import com.tangem.features.hotwallet.walletbackup.entity.BackupStatus
|
||||
import com.tangem.features.hotwallet.walletbackup.entity.WalletBackupUM
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -45,6 +44,7 @@ internal class WalletBackupModel @Inject constructor(
|
|||
val uiState: StateFlow<WalletBackupUM>
|
||||
field = MutableStateFlow(
|
||||
WalletBackupUM(
|
||||
onBackClick = { router.pop() },
|
||||
hardwareWalletOption = LabelUM(
|
||||
text = resourceReference(R.string.common_recommended),
|
||||
style = LabelStyle.ACCENT,
|
||||
|
|
@ -58,7 +58,16 @@ internal class WalletBackupModel @Inject constructor(
|
|||
style = LabelStyle.REGULAR,
|
||||
),
|
||||
googleDriveStatus = BackupStatus.ComingSoon,
|
||||
onRecoveryPhraseClick = ::onRecoveryPhraseClick,
|
||||
onGoogleDriveAction = { shouldShowDialog ->
|
||||
if (shouldShowDialog) {
|
||||
onGoogleDriveBackupClick()
|
||||
} else {
|
||||
dismissGoogleDriveFakeDoorDialog()
|
||||
}
|
||||
},
|
||||
isGoogleDriveDialogShown = false,
|
||||
onHardwareWalletClick = ::onHardwareWalletClick,
|
||||
isBackedUp = false,
|
||||
),
|
||||
)
|
||||
|
|
@ -90,20 +99,6 @@ internal class WalletBackupModel @Inject constructor(
|
|||
trackingContextProxy.removeContext()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
fun onAction(action: Action) {
|
||||
when (action) {
|
||||
Action.RecoveryPhrase -> onRecoveryPhraseClick()
|
||||
Action.HardwareWallet -> onHardwareWalletClick()
|
||||
is Action.GoogleDriveBackup -> if (action.isDialogShown) {
|
||||
onGoogleDriveBackupClick()
|
||||
} else {
|
||||
dismissGoogleDriveFakeDoorDialog()
|
||||
}
|
||||
Action.OnBack -> router.pop()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateBackupStatuses(userWallet: UserWallet) {
|
||||
uiState.update { currentState ->
|
||||
if (userWallet is UserWallet.Hot) {
|
||||
|
|
|
|||
|
|
@ -27,17 +27,9 @@ import com.tangem.features.hotwallet.walletbackup.entity.BackupStatus
|
|||
import com.tangem.features.hotwallet.walletbackup.entity.WalletBackupUM
|
||||
import com.tangem.features.hotwallet.walletbackup.ui.component.GoogleDriveFakeDoorDialog
|
||||
|
||||
@Suppress("LongMethod", "LongParameterList")
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
internal fun WalletBackupContent(
|
||||
state: WalletBackupUM,
|
||||
modifier: Modifier = Modifier,
|
||||
onBackClick: () -> Unit,
|
||||
onHardwareWalletClick: () -> Unit,
|
||||
onRecoveryPhraseClick: () -> Unit,
|
||||
onGoogleDriveClick: () -> Unit,
|
||||
onGoogleDriveFakeDoorDialogDismiss: () -> Unit,
|
||||
) {
|
||||
internal fun WalletBackupContent(state: WalletBackupUM, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.background(TangemTheme.colors.background.secondary)
|
||||
|
|
@ -46,7 +38,7 @@ internal fun WalletBackupContent(
|
|||
) {
|
||||
AppBarWithBackButton(
|
||||
text = stringResourceSafe(R.string.common_backup),
|
||||
onBackClick = onBackClick,
|
||||
onBackClick = state.onBackClick,
|
||||
)
|
||||
|
||||
Column(
|
||||
|
|
@ -67,7 +59,7 @@ internal fun WalletBackupContent(
|
|||
title = stringResourceSafe(R.string.hw_backup_upgrade_title),
|
||||
description = stringResourceSafe(R.string.hw_backup_upgrade_description),
|
||||
badge = { Label(state.hardwareWalletOption) },
|
||||
onClick = onHardwareWalletClick,
|
||||
onClick = state.onHardwareWalletClick,
|
||||
enabled = true,
|
||||
backgroundColor = TangemTheme.colors.background.primary,
|
||||
)
|
||||
|
|
@ -91,7 +83,7 @@ internal fun WalletBackupContent(
|
|||
badge = {
|
||||
state.recoveryPhraseOption?.let { Label(it) }
|
||||
},
|
||||
onClick = onRecoveryPhraseClick,
|
||||
onClick = state.onRecoveryPhraseClick,
|
||||
enabled = true,
|
||||
backgroundColor = TangemTheme.colors.background.primary,
|
||||
)
|
||||
|
|
@ -103,7 +95,9 @@ internal fun WalletBackupContent(
|
|||
badge = {
|
||||
state.googleDriveOption?.let { Label(it) }
|
||||
},
|
||||
onClick = onGoogleDriveClick,
|
||||
onClick = {
|
||||
state.onGoogleDriveAction(true)
|
||||
},
|
||||
enabled = state.googleDriveStatus != BackupStatus.ComingSoon,
|
||||
backgroundColor = TangemTheme.colors.background.primary,
|
||||
)
|
||||
|
|
@ -111,7 +105,11 @@ internal fun WalletBackupContent(
|
|||
}
|
||||
}
|
||||
if (state.isGoogleDriveDialogShown) {
|
||||
GoogleDriveFakeDoorDialog(onDismiss = onGoogleDriveFakeDoorDialogDismiss)
|
||||
GoogleDriveFakeDoorDialog(
|
||||
onDismiss = {
|
||||
state.onGoogleDriveAction(false)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -120,14 +118,7 @@ internal fun WalletBackupContent(
|
|||
@Composable
|
||||
private fun WalletBackupContentPreview(@PreviewParameter(WalletBackupUMProvider::class) state: WalletBackupUM) {
|
||||
TangemThemePreview {
|
||||
WalletBackupContent(
|
||||
state = state,
|
||||
onBackClick = {},
|
||||
onHardwareWalletClick = {},
|
||||
onRecoveryPhraseClick = {},
|
||||
onGoogleDriveClick = {},
|
||||
onGoogleDriveFakeDoorDialogDismiss = {},
|
||||
)
|
||||
WalletBackupContent(state)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -147,7 +138,11 @@ private class WalletBackupUMProvider : CollectionPreviewParameterProvider<Wallet
|
|||
style = LabelStyle.REGULAR,
|
||||
),
|
||||
googleDriveStatus = BackupStatus.ComingSoon,
|
||||
onBackClick = {},
|
||||
onRecoveryPhraseClick = {},
|
||||
onGoogleDriveAction = {},
|
||||
isGoogleDriveDialogShown = false,
|
||||
onHardwareWalletClick = {},
|
||||
isBackedUp = false,
|
||||
),
|
||||
WalletBackupUM(
|
||||
|
|
@ -164,7 +159,11 @@ private class WalletBackupUMProvider : CollectionPreviewParameterProvider<Wallet
|
|||
style = LabelStyle.WARNING,
|
||||
),
|
||||
googleDriveStatus = BackupStatus.NoBackup,
|
||||
onBackClick = {},
|
||||
onRecoveryPhraseClick = {},
|
||||
onGoogleDriveAction = {},
|
||||
isGoogleDriveDialogShown = false,
|
||||
onHardwareWalletClick = {},
|
||||
isBackedUp = false,
|
||||
),
|
||||
WalletBackupUM(
|
||||
|
|
@ -181,7 +180,11 @@ private class WalletBackupUMProvider : CollectionPreviewParameterProvider<Wallet
|
|||
style = LabelStyle.ACCENT,
|
||||
),
|
||||
googleDriveStatus = BackupStatus.Done,
|
||||
onBackClick = {},
|
||||
onRecoveryPhraseClick = {},
|
||||
onGoogleDriveAction = {},
|
||||
isGoogleDriveDialogShown = false,
|
||||
onHardwareWalletClick = {},
|
||||
isBackedUp = false,
|
||||
),
|
||||
WalletBackupUM(
|
||||
|
|
@ -195,7 +198,11 @@ private class WalletBackupUMProvider : CollectionPreviewParameterProvider<Wallet
|
|||
style = LabelStyle.ACCENT,
|
||||
),
|
||||
googleDriveStatus = BackupStatus.Done,
|
||||
onBackClick = {},
|
||||
onRecoveryPhraseClick = {},
|
||||
onGoogleDriveAction = {},
|
||||
isGoogleDriveDialogShown = false,
|
||||
onHardwareWalletClick = {},
|
||||
isBackedUp = false,
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -14,16 +14,11 @@ import com.tangem.domain.wallets.models.GetUserWalletError
|
|||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.domain.wallets.usecase.UnlockHotWalletContextualUseCase
|
||||
import com.tangem.features.hotwallet.WalletBackupComponent
|
||||
import com.tangem.features.hotwallet.walletbackup.entity.Action
|
||||
import com.tangem.features.hotwallet.walletbackup.entity.BackupStatus
|
||||
import com.tangem.hot.sdk.model.HotWalletId
|
||||
import com.tangem.hot.sdk.model.UnlockHotWallet
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import io.mockk.*
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
|
|
@ -136,7 +131,7 @@ internal class WalletBackupModelTest {
|
|||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
model.onAction(Action.RecoveryPhrase)
|
||||
model.uiState.value.onRecoveryPhraseClick()
|
||||
advanceUntilIdle()
|
||||
|
||||
verify { analyticsEventHandler.send(match<WalletSettingsAnalyticEvents.ButtonRecoveryPhrase> { true }) }
|
||||
|
|
@ -154,7 +149,7 @@ internal class WalletBackupModelTest {
|
|||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
model.onAction(Action.RecoveryPhrase)
|
||||
model.uiState.value.onRecoveryPhraseClick()
|
||||
advanceUntilIdle()
|
||||
|
||||
verify { analyticsEventHandler.send(match<WalletSettingsAnalyticEvents.ButtonRecoveryPhrase> { true }) }
|
||||
|
|
@ -172,7 +167,7 @@ internal class WalletBackupModelTest {
|
|||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
model.onAction(Action.RecoveryPhrase)
|
||||
model.uiState.value.onRecoveryPhraseClick()
|
||||
advanceUntilIdle()
|
||||
|
||||
verify { analyticsEventHandler.send(match<WalletSettingsAnalyticEvents.ButtonRecoveryPhrase> { true }) }
|
||||
|
|
@ -185,7 +180,7 @@ internal class WalletBackupModelTest {
|
|||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
model.onAction(Action.RecoveryPhrase)
|
||||
model.uiState.value.onRecoveryPhraseClick()
|
||||
advanceUntilIdle()
|
||||
|
||||
verify { analyticsEventHandler.send(match<WalletSettingsAnalyticEvents.ButtonRecoveryPhrase> { true }) }
|
||||
|
|
@ -204,7 +199,7 @@ internal class WalletBackupModelTest {
|
|||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
model.onAction(Action.HardwareWallet)
|
||||
model.uiState.value.onHardwareWalletClick()
|
||||
|
||||
verify { analyticsEventHandler.send(match<WalletSettingsAnalyticEvents.ButtonHardwareUpdate> { true }) }
|
||||
verify {
|
||||
|
|
@ -220,7 +215,7 @@ internal class WalletBackupModelTest {
|
|||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
model.onAction(Action.GoogleDriveBackup(isDialogShown = true))
|
||||
model.uiState.value.onGoogleDriveAction(true)
|
||||
|
||||
verify { analyticsEventHandler.send(match<WalletSettingsAnalyticEvents.ButtonGoogleDriveBackup> { true }) }
|
||||
Assertions.assertTrue(model.uiState.value.isGoogleDriveDialogShown)
|
||||
|
|
@ -230,10 +225,10 @@ internal class WalletBackupModelTest {
|
|||
fun `WHEN GoogleDriveBackup with isDialogShown false THEN dialog hidden AND no analytics sent`() = runTest {
|
||||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
model.onAction(Action.GoogleDriveBackup(isDialogShown = true))
|
||||
model.uiState.value.onGoogleDriveAction(true)
|
||||
advanceUntilIdle()
|
||||
|
||||
model.onAction(Action.GoogleDriveBackup(isDialogShown = false))
|
||||
model.uiState.value.onGoogleDriveAction(false)
|
||||
|
||||
verify(exactly = 1) {
|
||||
analyticsEventHandler.send(match<WalletSettingsAnalyticEvents.ButtonGoogleDriveBackup> { true })
|
||||
|
|
@ -246,7 +241,7 @@ internal class WalletBackupModelTest {
|
|||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
model.onAction(Action.OnBack)
|
||||
model.uiState.value.onBackClick()
|
||||
|
||||
verify { router.pop(onComplete = any()) }
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue