Updated on 2026-08-14
This commit is contained in:
parent
68d3a813e2
commit
f5d9dab282
17 changed files with 439 additions and 61 deletions
|
|
@ -8,6 +8,7 @@ import com.tangem.feature.referral.api.ReferralComponent
|
|||
import com.tangem.feature.stories.api.StoriesComponent
|
||||
import com.tangem.feature.usedesk.api.UsedeskComponent
|
||||
import com.tangem.feature.walletsettings.component.WalletSettingsComponent
|
||||
import com.tangem.features.hotwallet.WalletBackupComponent
|
||||
import com.tangem.features.createwalletselection.CreateWalletSelectionComponent
|
||||
import com.tangem.features.details.component.DetailsComponent
|
||||
import com.tangem.features.disclaimer.api.components.DisclaimerComponent
|
||||
|
|
@ -51,6 +52,7 @@ import com.tangem.features.walletconnect.components.WalletConnectEntryComponent
|
|||
internal class ChildFactory @Inject constructor(
|
||||
private val detailsComponentFactory: DetailsComponent.Factory,
|
||||
private val walletSettingsComponentFactory: WalletSettingsComponent.Factory,
|
||||
private val walletBackupComponentFactory: WalletBackupComponent.Factory,
|
||||
private val disclaimerComponentFactory: DisclaimerComponent.Factory,
|
||||
private val manageTokensComponentFactory: ManageTokensComponent.Factory,
|
||||
private val marketsTokenDetailsComponentFactory: MarketsTokenDetailsComponent.Factory,
|
||||
|
|
@ -141,6 +143,15 @@ internal class ChildFactory @Inject constructor(
|
|||
componentFactory = walletSettingsComponentFactory,
|
||||
)
|
||||
}
|
||||
is AppRoute.WalletBackup -> {
|
||||
createComponentChild(
|
||||
context = context,
|
||||
params = WalletBackupComponent.Params(
|
||||
userWalletId = route.userWalletId,
|
||||
),
|
||||
componentFactory = walletBackupComponentFactory,
|
||||
)
|
||||
}
|
||||
is AppRoute.MarketsTokenDetails -> {
|
||||
createComponentChild(
|
||||
context = context,
|
||||
|
|
|
|||
|
|
@ -191,6 +191,11 @@ sealed class AppRoute(val path: String) : Route {
|
|||
val userWalletId: UserWalletId,
|
||||
) : AppRoute(path = "/wallet_settings/${userWalletId.stringValue}")
|
||||
|
||||
@Serializable
|
||||
data class WalletBackup(
|
||||
val userWalletId: UserWalletId,
|
||||
) : AppRoute(path = "/wallet_backup/${userWalletId.stringValue}")
|
||||
|
||||
@Serializable
|
||||
data object Markets : AppRoute(path = "/markets")
|
||||
|
||||
|
|
|
|||
|
|
@ -425,8 +425,8 @@
|
|||
<string name="hw_activation_need_description">To complete setup, back up your wallet and secure app access with a Access Code.</string>
|
||||
<string name="hw_activation_need_finish">Finish Now</string>
|
||||
<string name="hw_activation_need_title">Finish Wallet Activation</string>
|
||||
<string name="hw_backup_icloud_description">Recover an existing wallet stored in your iCloud backup</string>
|
||||
<string name="hw_backup_icloud_title">iCloud backup</string>
|
||||
<string name="hw_backup_google_drive_description">Recover an existing wallet stored in your Google Drive backup</string>
|
||||
<string name="hw_backup_google_drive_title">Google Drive Backup</string>
|
||||
<string name="hw_backup_need_action">Go to backup</string>
|
||||
<string name="hw_backup_need_description">To secure your wallet with a Access Code, complete the backup first.</string>
|
||||
<string name="hw_backup_need_title">Finish Backup First</string>
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ private fun WalletBlock(
|
|||
Row {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.weight(1f, fill = false)
|
||||
.padding(end = 8.dp),
|
||||
text = title,
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ dependencies {
|
|||
|
||||
/* Project - Domain */
|
||||
implementation(projects.domain.models)
|
||||
implementation(projects.domain.wallets.models)
|
||||
|
||||
/* Project - Core */
|
||||
implementation(projects.core.decompose)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
package com.tangem.features.hotwallet
|
||||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
interface WalletBackupComponent : ComposableContentComponent {
|
||||
|
||||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, WalletBackupComponent>
|
||||
}
|
||||
|
|
@ -3,27 +3,27 @@ package com.tangem.features.hotwallet.addexistingwallet.start.ui
|
|||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.appbar.TangemTopAppBar
|
||||
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButtonSize
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButtonsDefaults
|
||||
import com.tangem.core.ui.extensions.clickableSingle
|
||||
import com.tangem.core.ui.extensions.conditional
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.hotwallet.addexistingwallet.start.entity.AddExistingWalletStartUM
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.features.hotwallet.common.ui.OptionBlock
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
|
|
@ -62,6 +62,7 @@ internal fun AddExistingWalletStartContent(state: AddExistingWalletStartUM, modi
|
|||
OptionBlock(
|
||||
modifier = Modifier
|
||||
.padding(top = 24.dp),
|
||||
backgroundColor = TangemTheme.colors.background.secondary,
|
||||
title = stringResourceSafe(R.string.wallet_import_seed_title),
|
||||
description = stringResourceSafe(R.string.wallet_import_seed_description),
|
||||
badge = null,
|
||||
|
|
@ -69,6 +70,7 @@ internal fun AddExistingWalletStartContent(state: AddExistingWalletStartUM, modi
|
|||
enabled = true,
|
||||
)
|
||||
OptionBlock(
|
||||
backgroundColor = TangemTheme.colors.background.secondary,
|
||||
title = stringResourceSafe(R.string.wallet_import_scan_title),
|
||||
description = stringResourceSafe(R.string.wallet_import_scan_description),
|
||||
badge = {
|
||||
|
|
@ -85,6 +87,7 @@ internal fun AddExistingWalletStartContent(state: AddExistingWalletStartUM, modi
|
|||
enabled = true,
|
||||
)
|
||||
OptionBlock(
|
||||
backgroundColor = TangemTheme.colors.background.secondary,
|
||||
title = stringResourceSafe(R.string.wallet_import_google_drive_title),
|
||||
description = stringResourceSafe(R.string.wallet_import_google_drive_description),
|
||||
badge = {
|
||||
|
|
@ -114,58 +117,6 @@ internal fun AddExistingWalletStartContent(state: AddExistingWalletStartUM, modi
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun OptionBlock(
|
||||
title: String,
|
||||
description: String,
|
||||
badge: (@Composable () -> Unit)?,
|
||||
onClick: (() -> Unit)?,
|
||||
enabled: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 8.dp)
|
||||
.clip(TangemTheme.shapes.roundedCornersXMedium)
|
||||
.background(
|
||||
color = TangemTheme.colors.background.secondary,
|
||||
shape = TangemTheme.shapes.roundedCornersXMedium,
|
||||
)
|
||||
.conditional(onClick != null) {
|
||||
onClick?.let { clickableSingle(onClick = it) } ?: Modifier
|
||||
}
|
||||
.padding(16.dp),
|
||||
) {
|
||||
Row {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.weight(1f, fill = false)
|
||||
.padding(end = 4.dp),
|
||||
text = title,
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
color = if (enabled) {
|
||||
TangemTheme.colors.text.primary1
|
||||
} else {
|
||||
TangemTheme.colors.text.secondary
|
||||
},
|
||||
)
|
||||
badge?.invoke()
|
||||
}
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(top = 4.dp),
|
||||
text = description,
|
||||
style = TangemTheme.typography.body2,
|
||||
color = if (enabled) {
|
||||
TangemTheme.colors.text.tertiary
|
||||
} else {
|
||||
TangemTheme.colors.text.disabled
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BuyTangemWalletBlock(onScanClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||
Row(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
package com.tangem.features.hotwallet.common.ui
|
||||
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.extensions.clickableSingle
|
||||
import com.tangem.core.ui.extensions.conditional
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
internal const val DISABLED_COLORS_ALPHA = 0.5f
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Composable
|
||||
internal fun OptionBlock(
|
||||
title: String,
|
||||
description: String,
|
||||
badge: (@Composable () -> Unit)?,
|
||||
onClick: (() -> Unit)?,
|
||||
enabled: Boolean,
|
||||
backgroundColor: Color,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val backgroundColor by animateColorAsState(
|
||||
targetValue = if (enabled) {
|
||||
backgroundColor
|
||||
} else {
|
||||
backgroundColor.copy(alpha = DISABLED_COLORS_ALPHA)
|
||||
},
|
||||
)
|
||||
val titleColor by animateColorAsState(
|
||||
targetValue = if (enabled) {
|
||||
TangemTheme.colors.text.primary1
|
||||
} else {
|
||||
TangemTheme.colors.text.primary1.copy(alpha = DISABLED_COLORS_ALPHA)
|
||||
},
|
||||
)
|
||||
val descriptionColor by animateColorAsState(
|
||||
targetValue = if (enabled) {
|
||||
TangemTheme.colors.text.tertiary
|
||||
} else {
|
||||
TangemTheme.colors.text.tertiary.copy(alpha = DISABLED_COLORS_ALPHA)
|
||||
},
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 8.dp)
|
||||
.clip(TangemTheme.shapes.roundedCornersXMedium)
|
||||
.background(
|
||||
color = backgroundColor,
|
||||
shape = TangemTheme.shapes.roundedCornersXMedium,
|
||||
)
|
||||
.conditional(onClick != null) {
|
||||
onClick?.let { clickableSingle(onClick = it) } ?: Modifier
|
||||
}
|
||||
.padding(16.dp),
|
||||
) {
|
||||
Row {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.weight(1f, fill = false)
|
||||
.padding(end = 4.dp),
|
||||
text = title,
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
color = titleColor,
|
||||
)
|
||||
badge?.invoke()
|
||||
}
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(top = 4.dp),
|
||||
text = description,
|
||||
style = TangemTheme.typography.body2,
|
||||
color = descriptionColor,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package com.tangem.features.hotwallet.walletbackup.component
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
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.model.WalletBackupModel
|
||||
import com.tangem.features.hotwallet.walletbackup.ui.WalletBackupContent
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
||||
internal class DefaultWalletBackupComponent @AssistedInject constructor(
|
||||
@Assisted private val context: AppComponentContext,
|
||||
@Assisted private val params: WalletBackupComponent.Params,
|
||||
) : WalletBackupComponent, AppComponentContext by context {
|
||||
|
||||
private val model: WalletBackupModel = getOrCreateModel(params)
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val state by model.uiState.collectAsStateWithLifecycle()
|
||||
WalletBackupContent(
|
||||
state = state,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : WalletBackupComponent.Factory {
|
||||
override fun create(
|
||||
context: AppComponentContext,
|
||||
params: WalletBackupComponent.Params,
|
||||
): DefaultWalletBackupComponent
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.tangem.features.hotwallet.walletbackup.di
|
||||
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.features.hotwallet.WalletBackupComponent
|
||||
import com.tangem.features.hotwallet.walletbackup.component.DefaultWalletBackupComponent
|
||||
import com.tangem.features.hotwallet.walletbackup.model.WalletBackupModel
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import dagger.multibindings.ClassKey
|
||||
import dagger.multibindings.IntoMap
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal interface WalletBackupModule {
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(WalletBackupModel::class)
|
||||
fun bindWalletBackupModel(model: WalletBackupModel): Model
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindWalletBackupComponentFactory(factory: DefaultWalletBackupComponent.Factory): WalletBackupComponent.Factory
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.features.hotwallet.walletbackup.entity
|
||||
|
||||
internal data class WalletBackupUM(
|
||||
val onBackClick: () -> Unit,
|
||||
val recoveryPhraseStatus: BackupStatus,
|
||||
val googleDriveStatus: BackupStatus,
|
||||
val onRecoveryPhraseClick: () -> Unit,
|
||||
val onGoogleDriveClick: () -> Unit,
|
||||
)
|
||||
|
||||
internal sealed class BackupStatus {
|
||||
object Done : BackupStatus()
|
||||
object ComingSoon : BackupStatus()
|
||||
object NoBackup : BackupStatus()
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package com.tangem.features.hotwallet.walletbackup.model
|
||||
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.features.hotwallet.WalletBackupComponent
|
||||
import com.tangem.features.hotwallet.walletbackup.entity.BackupStatus
|
||||
import com.tangem.features.hotwallet.walletbackup.entity.WalletBackupUM
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.*
|
||||
import javax.inject.Inject
|
||||
|
||||
@ModelScoped
|
||||
internal class WalletBackupModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
getWalletUseCase: GetUserWalletUseCase,
|
||||
private val router: Router,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
) : Model() {
|
||||
|
||||
private val params: WalletBackupComponent.Params = paramsContainer.require()
|
||||
|
||||
val uiState: StateFlow<WalletBackupUM>
|
||||
field = MutableStateFlow(
|
||||
WalletBackupUM(
|
||||
onBackClick = { router.pop() },
|
||||
recoveryPhraseStatus = BackupStatus.NoBackup,
|
||||
googleDriveStatus = BackupStatus.ComingSoon,
|
||||
onRecoveryPhraseClick = { },
|
||||
onGoogleDriveClick = { },
|
||||
),
|
||||
)
|
||||
|
||||
init {
|
||||
getWalletUseCase.invokeFlow(params.userWalletId)
|
||||
.map { it.getOrNull() }
|
||||
.distinctUntilChanged()
|
||||
.onEach {
|
||||
updateBackupStatuses()
|
||||
}
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun updateBackupStatuses() {
|
||||
uiState.update { currentState ->
|
||||
currentState.copy(
|
||||
recoveryPhraseStatus = BackupStatus.NoBackup,
|
||||
googleDriveStatus = BackupStatus.ComingSoon,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
package com.tangem.features.hotwallet.walletbackup.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.hotwallet.walletbackup.entity.BackupStatus
|
||||
import com.tangem.features.hotwallet.walletbackup.entity.WalletBackupUM
|
||||
import com.tangem.features.hotwallet.common.ui.OptionBlock
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.features.hotwallet.common.ui.DISABLED_COLORS_ALPHA
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
internal fun WalletBackupContent(state: WalletBackupUM, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.background(TangemTheme.colors.background.secondary)
|
||||
.fillMaxSize()
|
||||
.systemBarsPadding(),
|
||||
) {
|
||||
AppBarWithBackButton(
|
||||
text = stringResourceSafe(R.string.common_backup),
|
||||
onBackClick = state.onBackClick,
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(horizontal = 16.dp),
|
||||
) {
|
||||
OptionBlock(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
title = stringResourceSafe(R.string.hw_backup_seed_title),
|
||||
description = stringResourceSafe(R.string.hw_backup_seed_description),
|
||||
badge = {
|
||||
BackupStatusBadge(status = state.recoveryPhraseStatus)
|
||||
},
|
||||
onClick = state.onRecoveryPhraseClick,
|
||||
enabled = true,
|
||||
backgroundColor = TangemTheme.colors.background.primary,
|
||||
)
|
||||
|
||||
OptionBlock(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
title = stringResourceSafe(R.string.hw_backup_google_drive_title),
|
||||
description = stringResourceSafe(R.string.hw_backup_google_drive_description),
|
||||
badge = {
|
||||
BackupStatusBadge(status = state.googleDriveStatus)
|
||||
},
|
||||
onClick = state.onGoogleDriveClick,
|
||||
enabled = state.googleDriveStatus != BackupStatus.ComingSoon,
|
||||
backgroundColor = TangemTheme.colors.background.primary,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BackupStatusBadge(status: BackupStatus, modifier: Modifier = Modifier) {
|
||||
val text = when (status) {
|
||||
BackupStatus.Done -> stringResourceSafe(R.string.common_done)
|
||||
BackupStatus.ComingSoon -> stringResourceSafe(R.string.common_coming_soon)
|
||||
BackupStatus.NoBackup -> stringResourceSafe(R.string.hw_backup_no_backup)
|
||||
}
|
||||
|
||||
val backgroundColor by animateColorAsState(
|
||||
targetValue = when (status) {
|
||||
BackupStatus.Done -> TangemTheme.colors.text.accent.copy(alpha = 0.1f)
|
||||
BackupStatus.ComingSoon -> TangemTheme.colors.control.unchecked.copy(DISABLED_COLORS_ALPHA)
|
||||
BackupStatus.NoBackup -> TangemTheme.colors.text.warning.copy(alpha = 0.1f)
|
||||
},
|
||||
)
|
||||
|
||||
val textColor by animateColorAsState(
|
||||
targetValue = when (status) {
|
||||
BackupStatus.Done -> TangemTheme.colors.text.accent
|
||||
BackupStatus.ComingSoon -> TangemTheme.colors.text.secondary.copy(DISABLED_COLORS_ALPHA)
|
||||
BackupStatus.NoBackup -> TangemTheme.colors.text.warning
|
||||
},
|
||||
)
|
||||
|
||||
AnimatedContent(targetState = text) { text ->
|
||||
Box(
|
||||
modifier = modifier
|
||||
.padding(horizontal = 4.dp)
|
||||
.background(
|
||||
color = backgroundColor,
|
||||
shape = TangemTheme.shapes.roundedCorners8,
|
||||
)
|
||||
.padding(horizontal = 8.dp, vertical = 4.dp),
|
||||
) {
|
||||
Text(
|
||||
text = text,
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = textColor,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun WalletBackupContentPreview(@PreviewParameter(WalletBackupUMProvider::class) state: WalletBackupUM) {
|
||||
TangemThemePreview {
|
||||
WalletBackupContent(state)
|
||||
}
|
||||
}
|
||||
|
||||
private class WalletBackupUMProvider : CollectionPreviewParameterProvider<WalletBackupUM>(
|
||||
collection = listOf(
|
||||
WalletBackupUM(
|
||||
recoveryPhraseStatus = BackupStatus.NoBackup,
|
||||
googleDriveStatus = BackupStatus.ComingSoon,
|
||||
onBackClick = {},
|
||||
onRecoveryPhraseClick = {},
|
||||
onGoogleDriveClick = {},
|
||||
),
|
||||
WalletBackupUM(
|
||||
recoveryPhraseStatus = BackupStatus.NoBackup,
|
||||
googleDriveStatus = BackupStatus.NoBackup,
|
||||
onBackClick = {},
|
||||
onRecoveryPhraseClick = {},
|
||||
onGoogleDriveClick = {},
|
||||
),
|
||||
WalletBackupUM(
|
||||
recoveryPhraseStatus = BackupStatus.Done,
|
||||
googleDriveStatus = BackupStatus.Done,
|
||||
onBackClick = {},
|
||||
onRecoveryPhraseClick = {},
|
||||
onGoogleDriveClick = {},
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -19,6 +19,7 @@ dependencies {
|
|||
implementation(projects.features.nft.api)
|
||||
implementation(projects.features.onboardingV2.api)
|
||||
implementation(projects.features.pushNotifications.api)
|
||||
implementation(projects.features.hotWallet.api)
|
||||
|
||||
/* Project - Core */
|
||||
implementation(projects.core.decompose)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ internal class PreviewWalletSettingsComponent : WalletSettingsComponent {
|
|||
onCheckedNotificationsChanged = {},
|
||||
onNotificationsDescriptionClick = {},
|
||||
isNotificationsPermissionGranted = false,
|
||||
isHotWalletEnabled = false,
|
||||
),
|
||||
requestPushNotificationsPermission = false,
|
||||
onPushNotificationPermissionGranted = {},
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import com.tangem.feature.walletsettings.entity.WalletSettingsItemUM
|
|||
import com.tangem.feature.walletsettings.entity.WalletSettingsUM
|
||||
import com.tangem.feature.walletsettings.impl.R
|
||||
import com.tangem.feature.walletsettings.utils.ItemsBuilder
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.features.pushnotifications.api.analytics.PushNotificationAnalyticEvents
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
|
|
@ -72,6 +73,7 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
private val setNotificationsEnabledUseCase: SetNotificationsEnabledUseCase,
|
||||
private val settingsManager: SettingsManager,
|
||||
private val permissionsRepository: PermissionRepository,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
) : Model() {
|
||||
|
||||
val params: WalletSettingsComponent.Params = paramsContainer.require()
|
||||
|
|
@ -105,6 +107,7 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
isNotificationsEnabled = notificationsEnabled,
|
||||
isNotificationsFeatureEnabled = notificationsToggles.isNotificationsEnabled,
|
||||
isNotificationsPermissionGranted = isNotificationsPermissionGranted(),
|
||||
isHotWalletEnabled = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -130,6 +133,7 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
isNotificationsFeatureEnabled: Boolean,
|
||||
isNotificationsEnabled: Boolean,
|
||||
isNotificationsPermissionGranted: Boolean,
|
||||
isHotWalletEnabled: Boolean,
|
||||
): PersistentList<WalletSettingsItemUM> = itemsBuilder.buildItems(
|
||||
userWalletId = userWallet.walletId,
|
||||
userWalletName = userWallet.name,
|
||||
|
|
@ -167,6 +171,7 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
isNotificationsPermissionGranted = isNotificationsPermissionGranted,
|
||||
onCheckedNotificationsChanged = ::onCheckedNotificationsChange,
|
||||
onNotificationsDescriptionClick = ::onNotificationsDescriptionClick,
|
||||
isHotWalletEnabled = isHotWalletEnabled,
|
||||
)
|
||||
|
||||
private fun openRenameWalletDialog(userWallet: UserWallet, dialogNavigation: SlotNavigation<DialogConfig>) {
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ internal class ItemsBuilder @Inject constructor(
|
|||
renameWallet: () -> Unit,
|
||||
onLinkMoreCardsClick: () -> Unit,
|
||||
onReferralClick: () -> Unit,
|
||||
isHotWalletEnabled: Boolean,
|
||||
): PersistentList<WalletSettingsItemUM> = persistentListOf<WalletSettingsItemUM>()
|
||||
.add(buildNameItem(userWalletName, isRenameWalletAvailable, renameWallet))
|
||||
.run {
|
||||
|
|
@ -60,6 +61,7 @@ internal class ItemsBuilder @Inject constructor(
|
|||
isManageTokensAvailable = isManageTokensAvailable,
|
||||
onLinkMoreCardsClick = onLinkMoreCardsClick,
|
||||
onReferralClick = onReferralClick,
|
||||
isHotWalletEnabled = isHotWalletEnabled,
|
||||
),
|
||||
)
|
||||
.addAll(
|
||||
|
|
@ -137,6 +139,7 @@ internal class ItemsBuilder @Inject constructor(
|
|||
isManageTokensAvailable: Boolean,
|
||||
onLinkMoreCardsClick: () -> Unit,
|
||||
onReferralClick: () -> Unit,
|
||||
isHotWalletEnabled: Boolean,
|
||||
) = WalletSettingsItemUM.WithItems(
|
||||
id = "card",
|
||||
description = resourceReference(R.string.settings_card_settings_footer),
|
||||
|
|
@ -166,6 +169,14 @@ internal class ItemsBuilder @Inject constructor(
|
|||
onClick = { router.push(AppRoute.CardSettings(userWalletId)) },
|
||||
).let(::add)
|
||||
|
||||
if (isHotWalletEnabled) {
|
||||
BlockUM(
|
||||
text = resourceReference(R.string.common_backup),
|
||||
iconRes = R.drawable.ic_more_cards_24,
|
||||
onClick = { router.push(AppRoute.WalletBackup(userWalletId)) },
|
||||
).let(::add)
|
||||
}
|
||||
|
||||
if (isReferralAvailable) {
|
||||
BlockUM(
|
||||
text = resourceReference(R.string.details_referral_title),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue