From d66d86dd8257512c32b146f394d52610d77736f5 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 15 Oct 2025 22:15:31 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../tangem/tap/routing/utils/ChildFactory.kt | 8 + .../com/tangem/common/routing/AppRoute.kt | 3 + .../ui/components/feature/FeatureBlock.kt | 79 ++++++++ .../CreateWalletSelectionModel.kt | 2 +- .../CreateHardwareWalletComponent.kt | 9 + .../CreateHardwareWalletModel.kt | 183 ++++++++++++++++++ .../DefaultCreateHardwareWalletComponent.kt | 36 ++++ .../di/CreateHardwareWalletModule.kt | 27 +++ .../entity/CreateHardwareWalletUM.kt | 8 + .../ui/CreateHardwareWalletContent.kt | 130 +++++++++++++ .../ui/CreateMobileWalletContent.kt | 34 +--- .../start/ui/ManualBackupStartContent.kt | 36 +--- .../upgradewallet/ui/UpgradeWalletContent.kt | 34 +--- 13 files changed, 487 insertions(+), 102 deletions(-) create mode 100644 core/ui/src/main/java/com/tangem/core/ui/components/feature/FeatureBlock.kt create mode 100644 features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/CreateHardwareWalletComponent.kt create mode 100644 features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/CreateHardwareWalletModel.kt create mode 100644 features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/DefaultCreateHardwareWalletComponent.kt create mode 100644 features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/di/CreateHardwareWalletModule.kt create mode 100644 features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/entity/CreateHardwareWalletUM.kt create mode 100644 features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/ui/CreateHardwareWalletContent.kt diff --git a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt index 3713ecba7b..9bb9901db3 100644 --- a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt +++ b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt @@ -101,6 +101,7 @@ internal class ChildFactory @Inject constructor( private val chooseManagedTokensComponentFactory: ChooseManagedTokensComponent.Factory, private val createWalletSelectionComponentFactory: CreateWalletSelectionComponent.Factory, private val createWalletStartComponentFactory: CreateWalletStartComponent.Factory, + private val createHardwareWalletComponentFactory: CreateHardwareWalletComponent.Factory, private val createMobileWalletComponentFactory: CreateMobileWalletComponent.Factory, private val upgradeWalletComponentFactory: UpgradeWalletComponent.Factory, private val addExistingWalletComponentFactory: AddExistingWalletComponent.Factory, @@ -498,6 +499,13 @@ internal class ChildFactory @Inject constructor( componentFactory = createWalletSelectionComponentFactory, ) } + is AppRoute.CreateHardwareWallet -> { + createComponentChild( + context = context, + params = Unit, + componentFactory = createHardwareWalletComponentFactory, + ) + } is AppRoute.CreateMobileWallet -> { createComponentChild( context = context, diff --git a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt index 74f9b32244..1183cfb70a 100644 --- a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt +++ b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt @@ -322,6 +322,9 @@ sealed class AppRoute(val path: String) : Route { } } + @Serializable + object CreateHardwareWallet : AppRoute(path = "/create_hardware_wallet") + @Serializable object CreateMobileWallet : AppRoute(path = "/create_mobile_wallet") diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/feature/FeatureBlock.kt b/core/ui/src/main/java/com/tangem/core/ui/components/feature/FeatureBlock.kt new file mode 100644 index 0000000000..b85ad0dd6e --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/feature/FeatureBlock.kt @@ -0,0 +1,79 @@ +package com.tangem.core.ui.components.feature + +import android.content.res.Configuration +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Icon +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.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.tangem.core.ui.R +import com.tangem.core.ui.extensions.stringResourceSafe +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreview + +@Composable +fun FeatureBlock(title: String, description: String, iconRes: Int, modifier: Modifier = Modifier) { + Row( + modifier = modifier, + ) { + Icon( + modifier = Modifier + .padding(horizontal = 12.dp), + painter = painterResource(iconRes), + contentDescription = null, + tint = TangemTheme.colors.icon.primary1, + ) + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 8.dp), + ) { + Text( + text = title, + style = TangemTheme.typography.subtitle1, + color = TangemTheme.colors.text.primary1, + ) + Text( + modifier = Modifier + .padding(top = 4.dp), + text = description, + style = TangemTheme.typography.body2, + color = TangemTheme.colors.text.secondary, + ) + } + } +} + +@Preview(showBackground = true, widthDp = 360) +@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun PreviewFeatureBlock() { + TangemThemePreview { + Column( + modifier = Modifier + .background(TangemTheme.colors.background.primary) + .padding(16.dp), + ) { + FeatureBlock( + title = stringResourceSafe(R.string.backup_info_save_title), + description = stringResourceSafe(R.string.backup_info_save_description, "12"), + iconRes = R.drawable.ic_lock_24, + ) + Spacer(modifier = Modifier.height(24.dp)) + FeatureBlock( + title = stringResourceSafe(R.string.backup_info_keep_title), + description = stringResourceSafe(R.string.backup_info_keep_description), + iconRes = R.drawable.ic_settings_24, + ) + } + } +} \ No newline at end of file diff --git a/features/create-wallet-selection/impl/src/main/kotlin/com/tangem/features/createwalletselection/CreateWalletSelectionModel.kt b/features/create-wallet-selection/impl/src/main/kotlin/com/tangem/features/createwalletselection/CreateWalletSelectionModel.kt index 20b64f77ca..9a81297bdd 100644 --- a/features/create-wallet-selection/impl/src/main/kotlin/com/tangem/features/createwalletselection/CreateWalletSelectionModel.kt +++ b/features/create-wallet-selection/impl/src/main/kotlin/com/tangem/features/createwalletselection/CreateWalletSelectionModel.kt @@ -94,7 +94,7 @@ internal class CreateWalletSelectionModel @Inject constructor( } private fun onHardwareWalletClick() { - // TODO [REDACTED_TASK_KEY] + router.push(AppRoute.CreateHardwareWallet) } private fun onBuyClick() { diff --git a/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/CreateHardwareWalletComponent.kt b/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/CreateHardwareWalletComponent.kt new file mode 100644 index 0000000000..ec266c8c2f --- /dev/null +++ b/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/CreateHardwareWalletComponent.kt @@ -0,0 +1,9 @@ +package com.tangem.features.hotwallet + +import com.tangem.core.decompose.factory.ComponentFactory +import com.tangem.core.ui.decompose.ComposableContentComponent + +interface CreateHardwareWalletComponent : ComposableContentComponent { + + interface Factory : ComponentFactory +} \ No newline at end of file diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/CreateHardwareWalletModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/CreateHardwareWalletModel.kt new file mode 100644 index 0000000000..992eefd69f --- /dev/null +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/CreateHardwareWalletModel.kt @@ -0,0 +1,183 @@ +package com.tangem.features.hotwallet.createhardwarewallet + +import com.tangem.common.core.TangemError +import com.tangem.common.core.TangemSdkError +import com.tangem.common.routing.AppRoute +import com.tangem.core.analytics.api.AnalyticsEventHandler +import com.tangem.core.analytics.models.AnalyticsParam +import com.tangem.core.analytics.models.Basic.SignedIn +import com.tangem.core.analytics.models.Basic.SignedIn.SignInType +import com.tangem.core.decompose.di.ModelScoped +import com.tangem.core.decompose.model.Model +import com.tangem.core.decompose.navigation.Router +import com.tangem.core.decompose.ui.UiMessageSender +import com.tangem.core.navigation.url.UrlOpener +import com.tangem.core.ui.R +import com.tangem.core.ui.extensions.resourceReference +import com.tangem.core.ui.message.DialogMessage +import com.tangem.domain.card.ScanCardProcessor +import com.tangem.domain.card.analytics.ParamCardCurrencyConverter +import com.tangem.domain.card.common.util.cardTypesResolver +import com.tangem.domain.card.repository.CardSdkConfigRepository +import com.tangem.domain.common.wallets.UserWalletsListRepository +import com.tangem.domain.common.wallets.error.SaveWalletError +import com.tangem.domain.models.scan.ScanResponse +import com.tangem.domain.settings.repositories.SettingsRepository +import com.tangem.domain.wallets.builder.ColdUserWalletBuilder +import com.tangem.domain.wallets.usecase.GenerateBuyTangemCardLinkUseCase +import com.tangem.domain.wallets.usecase.SaveWalletUseCase +import com.tangem.features.hotwallet.createhardwarewallet.entity.CreateHardwareWalletUM +import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import timber.log.Timber +import javax.inject.Inject + +private const val HIDE_PROGRESS_DELAY = 400L + +@Suppress("LongParameterList") +@ModelScoped +internal class CreateHardwareWalletModel @Inject constructor( + override val dispatchers: CoroutineDispatcherProvider, + private val router: Router, + private val generateBuyTangemCardLinkUseCase: GenerateBuyTangemCardLinkUseCase, + private val urlOpener: UrlOpener, + private val settingsRepository: SettingsRepository, + private val cardSdkConfigRepository: CardSdkConfigRepository, + private val uiMessageSender: UiMessageSender, + private val scanCardProcessor: ScanCardProcessor, + private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory, + private val saveWalletUseCase: SaveWalletUseCase, + private val userWalletsListRepository: UserWalletsListRepository, + private val analyticsEventHandler: AnalyticsEventHandler, +) : Model() { + + val uiState: StateFlow + field = MutableStateFlow( + CreateHardwareWalletUM( + onBackClick = { router.pop() }, + onBuyTangemWalletClick = ::onBuyTangemWalletClick, + onScanDeviceClick = ::onScanDeviceClick, + ), + ) + + override fun onDestroy() { + super.onDestroy() + } + + private fun onBuyTangemWalletClick() { + modelScope.launch { + generateBuyTangemCardLinkUseCase.invoke().let { urlOpener.openUrl(it) } + } + } + + private fun onScanDeviceClick() { + scanCard() + } + + private fun scanCard() { + modelScope.launch { + setLoading(true) + + val shouldSaveAccessCodes = settingsRepository.shouldSaveAccessCodes() + cardSdkConfigRepository.setAccessCodeRequestPolicy( + isBiometricsRequestPolicy = shouldSaveAccessCodes, + ) + + val analyticsSource = AnalyticsParam.ScreensSources.Intro + + scanCardProcessor.scan( + analyticsSource = analyticsSource, + onProgressStateChange = { showProgress -> + if (!showProgress) { + delay(HIDE_PROGRESS_DELAY) + setLoading(false) + } else { + setLoading(true) + } + }, + onFailure = { error -> + handleScanError(error) + delay(HIDE_PROGRESS_DELAY) + setLoading(false) + }, + onSuccess = { scanResponse -> + proceedWithScanResponse(scanResponse) + }, + ) + } + } + + private suspend fun proceedWithScanResponse(scanResponse: ScanResponse) { + val userWallet = coldUserWalletBuilderFactory.create(scanResponse = scanResponse).build() + + if (userWallet == null) { + Timber.e("User wallet not created") + setLoading(false) + return + } + + saveWalletUseCase(userWallet = userWallet).fold( + ifLeft = { + delay(HIDE_PROGRESS_DELAY) + setLoading(false) + when (it) { + is SaveWalletError.DataError -> Timber.e(it.toString(), "Unable to save user wallet") + is SaveWalletError.WalletAlreadySaved -> { + userWalletsListRepository.unlock( + userWalletId = userWallet.walletId, + unlockMethod = UserWalletsListRepository.UnlockMethod.Scan(scanResponse), + ).onRight { + router.replaceAll(AppRoute.Wallet) + } + } + } + }, + ifRight = { + setLoading(false) + sendSignedInCardAnalyticsEvent(scanResponse = scanResponse, isImported = userWallet.isImported) + router.replaceAll(AppRoute.Wallet) + }, + ) + } + + private suspend fun sendSignedInCardAnalyticsEvent(scanResponse: ScanResponse, isImported: Boolean) { + val currency = ParamCardCurrencyConverter().convert(value = scanResponse.cardTypesResolver) + if (currency != null) { + analyticsEventHandler.send( + SignedIn( + currency = currency, + batch = scanResponse.card.batchId, + signInType = SignInType.Card, + walletsCount = userWalletsListRepository.userWalletsSync().size.toString(), + isImported = isImported, + hasBackup = scanResponse.card.backupStatus?.isActive, + ), + ) + } + } + + private fun setLoading(isLoading: Boolean) { + uiState.update { it.copy(isScanInProgress = isLoading) } + } + + private fun handleScanError(error: TangemError) { + when (error) { + is TangemSdkError.NfcFeatureIsUnavailable -> handleNfcFeatureUnavailable() + is TangemSdkError -> Timber.e(error, "Scan error occurred") + else -> Timber.e(error, "Error happened") + } + } + + private fun handleNfcFeatureUnavailable() { + uiMessageSender.send( + message = DialogMessage( + message = resourceReference(R.string.nfc_error_unavailable), + title = resourceReference(id = R.string.common_error), + ), + ) + } +} \ No newline at end of file diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/DefaultCreateHardwareWalletComponent.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/DefaultCreateHardwareWalletComponent.kt new file mode 100644 index 0000000000..0f83065531 --- /dev/null +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/DefaultCreateHardwareWalletComponent.kt @@ -0,0 +1,36 @@ +package com.tangem.features.hotwallet.createhardwarewallet + +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.CreateHardwareWalletComponent +import com.tangem.features.hotwallet.createhardwarewallet.ui.CreateHardwareWalletContent +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject + +@Suppress("UnusedPrivateMember") +internal class DefaultCreateHardwareWalletComponent @AssistedInject constructor( + @Assisted private val context: AppComponentContext, + @Assisted private val params: Unit, +) : CreateHardwareWalletComponent, AppComponentContext by context { + + private val model: CreateHardwareWalletModel = getOrCreateModel(params) + + @Composable + override fun Content(modifier: Modifier) { + val state by model.uiState.collectAsStateWithLifecycle() + CreateHardwareWalletContent( + state = state, + modifier = modifier, + ) + } + + @AssistedFactory + interface Factory : CreateHardwareWalletComponent.Factory { + override fun create(context: AppComponentContext, params: Unit): DefaultCreateHardwareWalletComponent + } +} \ No newline at end of file diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/di/CreateHardwareWalletModule.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/di/CreateHardwareWalletModule.kt new file mode 100644 index 0000000000..6440dc7bb6 --- /dev/null +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/di/CreateHardwareWalletModule.kt @@ -0,0 +1,27 @@ +package com.tangem.features.hotwallet.createhardwarewallet.di + +import com.tangem.core.decompose.model.Model +import com.tangem.features.hotwallet.CreateHardwareWalletComponent +import com.tangem.features.hotwallet.createhardwarewallet.CreateHardwareWalletModel +import com.tangem.features.hotwallet.createhardwarewallet.DefaultCreateHardwareWalletComponent +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import dagger.multibindings.ClassKey +import dagger.multibindings.IntoMap + +@Module +@InstallIn(SingletonComponent::class) +internal interface CreateHardwareWalletModule { + + @Binds + fun bindCreateHardwareWalletComponentFactory( + impl: DefaultCreateHardwareWalletComponent.Factory, + ): CreateHardwareWalletComponent.Factory + + @Binds + @IntoMap + @ClassKey(CreateHardwareWalletModel::class) + fun bindCreateHardwareWalletModel(model: CreateHardwareWalletModel): Model +} \ No newline at end of file diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/entity/CreateHardwareWalletUM.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/entity/CreateHardwareWalletUM.kt new file mode 100644 index 0000000000..814ead9ec4 --- /dev/null +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/entity/CreateHardwareWalletUM.kt @@ -0,0 +1,8 @@ +package com.tangem.features.hotwallet.createhardwarewallet.entity + +internal data class CreateHardwareWalletUM( + val onBackClick: () -> Unit, + val onBuyTangemWalletClick: () -> Unit, + val onScanDeviceClick: () -> Unit, + val isScanInProgress: Boolean = false, +) \ No newline at end of file diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/ui/CreateHardwareWalletContent.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/ui/CreateHardwareWalletContent.kt new file mode 100644 index 0000000000..8f2ce41cfd --- /dev/null +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/ui/CreateHardwareWalletContent.kt @@ -0,0 +1,130 @@ +package com.tangem.features.hotwallet.createhardwarewallet.ui + +import android.content.res.Configuration +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.material3.* +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +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.PrimaryButtonIconEnd +import com.tangem.core.ui.components.SecondaryButton +import com.tangem.core.ui.components.appbar.TangemTopAppBar +import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM +import com.tangem.core.ui.components.feature.FeatureBlock +import com.tangem.core.ui.extensions.TextReference +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.createhardwarewallet.entity.CreateHardwareWalletUM + +@Suppress("LongMethod") +@OptIn(ExperimentalMaterial3Api::class) +@Composable +internal fun CreateHardwareWalletContent(state: CreateHardwareWalletUM, modifier: Modifier = Modifier) { + Column( + modifier = modifier + .background(TangemTheme.colors.background.primary) + .fillMaxSize() + .systemBarsPadding(), + ) { + TangemTopAppBar( + modifier = Modifier + .statusBarsPadding(), + startButton = TopAppBarButtonUM.Back(state.onBackClick), + title = TextReference.EMPTY, + ) + Column( + modifier = Modifier + .weight(1f) + .padding( + start = 16.dp, + top = 24.dp, + end = 16.dp, + ), + ) { + Icon( + modifier = Modifier + .fillMaxWidth(), + painter = painterResource(R.drawable.ic_tangem_64), + contentDescription = null, + tint = Color.Unspecified, + ) + Text( + modifier = Modifier + .fillMaxWidth() + .padding( + start = 16.dp, + top = 20.dp, + end = 16.dp, + ), + text = stringResourceSafe(R.string.wallet_create_common_title), + style = TangemTheme.typography.h2, + color = TangemTheme.colors.text.primary1, + textAlign = TextAlign.Center, + ) + FeatureBlock( + modifier = Modifier + .padding(top = 32.dp), + title = stringResourceSafe(R.string.hw_upgrade_key_migration_title), + description = stringResourceSafe(R.string.hw_upgrade_key_migration_description), + iconRes = R.drawable.ic_mobile_security_24, + ) + FeatureBlock( + modifier = Modifier + .padding(top = 24.dp), + title = stringResourceSafe(R.string.hw_upgrade_funds_access_title), + description = stringResourceSafe(R.string.hw_upgrade_funds_access_description), + iconRes = R.drawable.ic_knight_shield_24, + ) + FeatureBlock( + modifier = Modifier + .padding(top = 24.dp), + title = stringResourceSafe(R.string.hw_upgrade_general_security_title), + description = stringResourceSafe(R.string.hw_upgrade_general_security_description), + iconRes = R.drawable.ic_protect_24, + ) + } + Column( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + verticalArrangement = Arrangement.spacedBy(12.dp), + ) { + SecondaryButton( + modifier = Modifier + .fillMaxWidth(), + text = stringResourceSafe(R.string.details_buy_wallet), + onClick = state.onBuyTangemWalletClick, + ) + PrimaryButtonIconEnd( + modifier = Modifier + .fillMaxWidth(), + text = stringResourceSafe(R.string.home_button_scan), + onClick = state.onScanDeviceClick, + iconResId = R.drawable.ic_tangem_24, + showProgress = state.isScanInProgress, + ) + } + } +} + +@Preview(showBackground = true, widthDp = 360) +@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun PreviewCreateHardwareWalletContent() { + TangemThemePreview { + CreateHardwareWalletContent( + state = CreateHardwareWalletUM( + onBackClick = {}, + onBuyTangemWalletClick = {}, + onScanDeviceClick = {}, + ), + ) + } +} \ No newline at end of file diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createmobilewallet/ui/CreateMobileWalletContent.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createmobilewallet/ui/CreateMobileWalletContent.kt index a53d0f587d..1cdcdcf836 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createmobilewallet/ui/CreateMobileWalletContent.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createmobilewallet/ui/CreateMobileWalletContent.kt @@ -15,6 +15,7 @@ import com.tangem.core.ui.components.PrimaryButton import com.tangem.core.ui.components.SecondaryButton import com.tangem.core.ui.components.appbar.TangemTopAppBar import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM +import com.tangem.core.ui.components.feature.FeatureBlock import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.TangemTheme @@ -103,39 +104,6 @@ internal fun CreateMobileWalletContent(state: CreateMobileWalletUM, modifier: Mo } } -@Composable -private fun FeatureBlock(title: String, description: String, iconRes: Int, modifier: Modifier = Modifier) { - Row( - modifier = modifier, - ) { - Icon( - modifier = Modifier - .padding(horizontal = 12.dp), - painter = painterResource(iconRes), - contentDescription = null, - tint = TangemTheme.colors.icon.primary1, - ) - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 8.dp), - ) { - Text( - text = title, - style = TangemTheme.typography.subtitle1, - color = TangemTheme.colors.text.primary1, - ) - Text( - modifier = Modifier - .padding(top = 4.dp), - text = description, - style = TangemTheme.typography.body2, - color = TangemTheme.colors.text.secondary, - ) - } - } -} - @Preview(showBackground = true, widthDp = 360) @Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/manualbackup/start/ui/ManualBackupStartContent.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/manualbackup/start/ui/ManualBackupStartContent.kt index 435a9dfbb3..56486d5ef7 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/manualbackup/start/ui/ManualBackupStartContent.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/manualbackup/start/ui/ManualBackupStartContent.kt @@ -4,16 +4,15 @@ import android.content.res.Configuration import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon 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.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.feature.FeatureBlock import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview @@ -91,39 +90,6 @@ internal fun ManualBackupStartContent(state: ManualBackupStartUM, modifier: Modi } } -@Composable -private fun FeatureBlock(title: String, description: String, iconRes: Int, modifier: Modifier = Modifier) { - Row( - modifier = modifier, - ) { - Icon( - modifier = Modifier - .padding(horizontal = 12.dp), - painter = painterResource(iconRes), - contentDescription = null, - tint = TangemTheme.colors.icon.primary1, - ) - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 8.dp), - ) { - Text( - text = title, - style = TangemTheme.typography.subtitle1, - color = TangemTheme.colors.text.primary1, - ) - Text( - modifier = Modifier - .padding(top = 4.dp), - text = description, - style = TangemTheme.typography.body2, - color = TangemTheme.colors.text.secondary, - ) - } - } -} - @Preview(showBackground = true, widthDp = 360) @Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/ui/UpgradeWalletContent.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/ui/UpgradeWalletContent.kt index 2ae6ae5d0c..b8e01bb64d 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/ui/UpgradeWalletContent.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/ui/UpgradeWalletContent.kt @@ -16,6 +16,7 @@ import com.tangem.core.ui.components.PrimaryButtonIconEnd import com.tangem.core.ui.components.SecondaryButton import com.tangem.core.ui.components.appbar.TangemTopAppBar import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM +import com.tangem.core.ui.components.feature.FeatureBlock import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.TangemTheme @@ -112,39 +113,6 @@ internal fun UpgradeWalletContent(state: UpgradeWalletUM, modifier: Modifier = M } } -@Composable -private fun FeatureBlock(title: String, description: String, iconRes: Int, modifier: Modifier = Modifier) { - Row( - modifier = modifier, - ) { - Icon( - modifier = Modifier - .padding(horizontal = 12.dp), - painter = painterResource(iconRes), - contentDescription = null, - tint = TangemTheme.colors.icon.primary1, - ) - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 8.dp), - ) { - Text( - text = title, - style = TangemTheme.typography.subtitle1, - color = TangemTheme.colors.text.primary1, - ) - Text( - modifier = Modifier - .padding(top = 4.dp), - text = description, - style = TangemTheme.typography.body2, - color = TangemTheme.colors.text.secondary, - ) - } - } -} - @Preview(showBackground = true, widthDp = 360) @Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable