From 333640b3a759dba4244de0c21ea8529258bc54b9 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 21 Apr 2026 11:50:28 +0100 Subject: [PATCH 1/2] Updated on 2026-08-14 --- .../tangem/tap/routing/utils/ChildFactory.kt | 11 +- .../com/tangem/common/routing/AppRoute.kt | 4 +- .../CreateWalletStartModel.kt | 5 +- .../CreateWalletStartModelTest.kt | 18 ++- .../v2/entry/OnboardingEntryComponent.kt | 1 + features/onboarding-v2/impl/build.gradle.kts | 12 ++ .../v2/addresssync/AddressSyncComponent.kt | 10 +- .../DefaultAddressSyncComponent.kt | 141 +++++++++++++++--- .../di/AddressSyncComponentModule.kt | 18 --- .../v2/addresssync/entity/AddressSyncUM.kt | 5 - .../v2/addresssync/model/AddressSyncIntent.kt | 8 + .../v2/addresssync/model/AddressSyncModel.kt | 60 +++++++- .../addresssync/navigation/AddressSyncStep.kt | 7 + .../v2/addresssync/ui/AddressSyncContent.kt | 38 ++--- .../entry/impl/model/OnboardingEntryModel.kt | 1 + .../api/OnboardingMultiWalletComponent.kt | 1 + .../DefaultOnboardingMultiWalletComponent.kt | 13 +- .../model/MultiWalletFinalizeModel.kt | 1 + .../impl/model/OnboardingMultiWalletModel.kt | 6 +- .../impl/model/OnboardingMultiWalletState.kt | 1 + .../v2/multiwallet/impl/model/Utils.kt | 1 + .../addresssync/model/AddressSyncModelTest.kt | 134 +++++++++++++++++ 22 files changed, 393 insertions(+), 103 deletions(-) delete mode 100644 features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/di/AddressSyncComponentModule.kt delete mode 100644 features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/entity/AddressSyncUM.kt create mode 100644 features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncIntent.kt create mode 100644 features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/navigation/AddressSyncStep.kt create mode 100644 features/onboarding-v2/impl/src/test/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModelTest.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 72e8f32bb6..743496098a 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 @@ -25,7 +25,6 @@ import com.tangem.features.managetokens.component.ManageTokensComponent import com.tangem.features.managetokens.component.ManageTokensMode import com.tangem.features.managetokens.component.ManageTokensSource import com.tangem.features.nft.component.NFTComponent -import com.tangem.features.onboarding.v2.addresssync.AddressSyncComponent import com.tangem.features.onboarding.v2.entry.OnboardingEntryComponent import com.tangem.features.onramp.component.* import com.tangem.features.pushnotifications.api.PushNotificationsComponent @@ -112,7 +111,6 @@ internal class ChildFactory @Inject constructor( private val kycComponentFactory: KycComponent.Factory, private val yieldSupplyEntryComponentFactory: YieldSupplyEntryComponent.Factory, private val feedEntryComponentFactory: FeedEntryComponent.Factory, - private val addressSyncComponentFactory: AddressSyncComponent.Factory, ) { @Suppress("LongMethod", "CyclomaticComplexMethod") @@ -262,6 +260,8 @@ internal class ChildFactory @Inject constructor( OnboardingEntryComponent.Mode.ContinueFinalize is AppRoute.Onboarding.Mode.UpgradeHotWallet -> OnboardingEntryComponent.Mode.UpgradeHotWallet(mode.userWalletId) + is AppRoute.Onboarding.Mode.AddressSync -> + OnboardingEntryComponent.Mode.AddressSync }, ), componentFactory = onboardingEntryComponentFactory, @@ -694,13 +694,6 @@ internal class ChildFactory @Inject constructor( componentFactory = feedEntryComponentFactory, ) } - is AppRoute.AddressSync -> { - createComponentChild( - context = context, - params = AddressSyncComponent.Params(data = Unit), - componentFactory = addressSyncComponentFactory, - ) - } } } } 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 fd3d57f697..165823622e 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 @@ -330,6 +330,7 @@ sealed class AppRoute(val path: String) : Route { data object RecreateWalletTwin : Mode() // reset twins data object ContinueFinalize : Mode() // continue finalize process (unfinished backup dialog) data class UpgradeHotWallet(val userWalletId: UserWalletId) : Mode() // upgrade hot wallet + data object AddressSync : Mode() } } @@ -484,7 +485,4 @@ sealed class AppRoute(val path: String) : Route { @Serializable data class NewsDetails(val newsId: Int) : AppRoute(path = "/news_details/$newsId") - - @Serializable - data object AddressSync : AppRoute(path = "/address_sync") } \ No newline at end of file diff --git a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt index 4344425538..b438774c00 100644 --- a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt +++ b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt @@ -237,7 +237,10 @@ internal class CreateWalletStartModel @Inject constructor( ifRight = { setLoading(false) val route = if (onboardingV2FeatureToggles.isAddressSyncEnabled) { - AppRoute.AddressSync + AppRoute.Onboarding( + scanResponse = scanResponse, + mode = AppRoute.Onboarding.Mode.AddressSync + ) } else { AppRoute.Wallet } diff --git a/features/create-wallet-start/impl/src/test/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModelTest.kt b/features/create-wallet-start/impl/src/test/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModelTest.kt index 2d780979b5..bd7640bef5 100644 --- a/features/create-wallet-start/impl/src/test/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModelTest.kt +++ b/features/create-wallet-start/impl/src/test/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModelTest.kt @@ -531,7 +531,17 @@ internal class CreateWalletStartModelTest { model.uiState.value.onScanClick.invoke() advanceUntilIdle() - verify { appRouter.replaceAll(routes = arrayOf(AppRoute.AddressSync), onComplete = any()) } + verify { + appRouter.replaceAll( + routes = arrayOf( + AppRoute.Onboarding( + scanResponse = testScanResponse, + mode = AppRoute.Onboarding.Mode.AddressSync, + ) + ), + onComplete = any() + ) + } } @Test @@ -573,9 +583,9 @@ internal class CreateWalletStartModelTest { ) assert(state.imageResId == R.drawable.img_hardware_wallet) assert(state.shouldShowScanSecondaryButton) - assert(state.primaryButtonText == resourceReference(R.string.details_buy_wallet),) - assert(state.otherMethodTitle == resourceReference(R.string.welcome_create_wallet_mobile_title),) - assert(state.otherMethodDescription == null,) + assert(state.primaryButtonText == resourceReference(R.string.details_buy_wallet)) + assert(state.otherMethodTitle == resourceReference(R.string.welcome_create_wallet_mobile_title)) + assert(state.otherMethodDescription == null) assert(state.isScanInProgress.not()) } diff --git a/features/onboarding-v2/api/src/main/kotlin/com/tangem/features/onboarding/v2/entry/OnboardingEntryComponent.kt b/features/onboarding-v2/api/src/main/kotlin/com/tangem/features/onboarding/v2/entry/OnboardingEntryComponent.kt index a21785815f..d4776bf833 100644 --- a/features/onboarding-v2/api/src/main/kotlin/com/tangem/features/onboarding/v2/entry/OnboardingEntryComponent.kt +++ b/features/onboarding-v2/api/src/main/kotlin/com/tangem/features/onboarding/v2/entry/OnboardingEntryComponent.kt @@ -19,6 +19,7 @@ interface OnboardingEntryComponent : ComposableContentComponent { data object RecreateWalletTwin : Mode() data object ContinueFinalize : Mode() data class UpgradeHotWallet(val userWalletId: UserWalletId) : Mode() + data object AddressSync : Mode() } interface Factory : ComponentFactory diff --git a/features/onboarding-v2/impl/build.gradle.kts b/features/onboarding-v2/impl/build.gradle.kts index 917e123120..f4022573af 100644 --- a/features/onboarding-v2/impl/build.gradle.kts +++ b/features/onboarding-v2/impl/build.gradle.kts @@ -11,11 +11,16 @@ android { namespace = "com.tangem.features.onboarding.v2.impl" } +tasks.withType().configureEach { + useJUnitPlatform() +} + dependencies { /** Api */ implementation(projects.features.onboardingV2.api) implementation(projects.features.manageTokens.api) implementation(projects.features.biometry.api) + implementation(projects.features.pushNotifications.api) implementation(projects.features.hotWallet.api) implementation(projects.features.tokenRecieve.api) @@ -87,4 +92,11 @@ dependencies { /** DI */ implementation(deps.hilt.android) kapt(deps.hilt.kapt) + + /** Test */ + testImplementation(deps.test.junit5) + testRuntimeOnly(deps.test.junit5.engine) + testImplementation(deps.test.mockk) + testImplementation(deps.test.truth) + testImplementation(deps.test.coroutine) } \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/AddressSyncComponent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/AddressSyncComponent.kt index d097548938..d951a3e058 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/AddressSyncComponent.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/AddressSyncComponent.kt @@ -1,13 +1,5 @@ package com.tangem.features.onboarding.v2.addresssync -import com.tangem.core.decompose.factory.ComponentFactory import com.tangem.core.ui.decompose.ComposableContentComponent -interface AddressSyncComponent : ComposableContentComponent { - - data class Params( - val data: Any, // TODO("Will be implemented during [REDACTED_TASK_KEY]") - ) - - interface Factory : ComponentFactory -} \ No newline at end of file +interface AddressSyncComponent : ComposableContentComponent \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/DefaultAddressSyncComponent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/DefaultAddressSyncComponent.kt index 78d1c659fe..8357eb37d4 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/DefaultAddressSyncComponent.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/DefaultAddressSyncComponent.kt @@ -2,38 +2,141 @@ package com.tangem.features.onboarding.v2.addresssync import androidx.activity.compose.BackHandler import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier -import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.arkivanov.decompose.DelicateDecomposeApi +import com.arkivanov.decompose.extensions.compose.stack.Children +import com.arkivanov.decompose.router.stack.ChildStack +import com.arkivanov.decompose.router.stack.childStack +import com.arkivanov.decompose.value.Value +import com.tangem.common.routing.AppRoute import com.tangem.core.decompose.context.AppComponentContext +import com.tangem.core.decompose.context.childByContext import com.tangem.core.decompose.model.getOrCreateModel +import com.tangem.core.ui.decompose.ComposableContentComponent +import com.tangem.features.biometry.AskBiometryComponent +import com.tangem.features.onboarding.v2.addresssync.model.AddressSyncIntent import com.tangem.features.onboarding.v2.addresssync.model.AddressSyncModel +import com.tangem.features.onboarding.v2.addresssync.navigation.AddressSyncStep import com.tangem.features.onboarding.v2.addresssync.ui.AddressSyncContent -import dagger.assisted.Assisted -import dagger.assisted.AssistedFactory -import dagger.assisted.AssistedInject +import com.tangem.features.pushnotifications.api.PushNotificationsComponent +import com.tangem.features.pushnotifications.api.PushNotificationsModelCallbacks +import com.tangem.features.pushnotifications.api.PushNotificationsParams -internal class DefaultAddressSyncComponent @AssistedInject constructor( - @Assisted appComponentContext: AppComponentContext, - @Assisted params: AddressSyncComponent.Params, +@OptIn(DelicateDecomposeApi::class) +internal class DefaultAddressSyncComponent( + appComponentContext: AppComponentContext, + private val askBiometryComponentFactory: AskBiometryComponent.Factory, + private val pushNotificationsComponentFactory: PushNotificationsComponent.Factory, ) : AppComponentContext by appComponentContext, AddressSyncComponent { - private val model: AddressSyncModel = getOrCreateModel(params) + private val model: AddressSyncModel = getOrCreateModel() + + private val childStack: Value> = + childStack( + key = "innerStack", + source = model.stackNavigation, + serializer = null, + initialConfiguration = AddressSyncStep.ASK_BIOMETRY, + handleBackButton = true, + childFactory = { configuration, factoryContext -> + createChild( + step = configuration, + childContext = childByContext(factoryContext), + ) + }, + ) @Composable override fun Content(modifier: Modifier) { - val state by model.uiState.collectAsStateWithLifecycle() + AddressSyncContent( + modifier = modifier, + childContent = { + Children( + stack = childStack + ) { + it.instance.Content(modifier = modifier) + } + } + ) - AddressSyncContent(modifier = modifier, state = state) - - BackHandler(onBack = state.onBackClick) + BackHandler { + model.onIntent(AddressSyncIntent.Back) + } } - @AssistedFactory - interface Factory : AddressSyncComponent.Factory { - override fun create( - context: AppComponentContext, - params: AddressSyncComponent.Params, - ): DefaultAddressSyncComponent + private fun createChild( + step: AddressSyncStep, + childContext: AppComponentContext, + ): ComposableContentComponent { + return when (step) { + AddressSyncStep.ASK_BIOMETRY -> createAskBiometryComponent(childContext) + AddressSyncStep.ASK_NOTIFICATIONS -> createPushNotificationComponent(childContext) + AddressSyncStep.ADDRESS_SYNC -> TODO("Will be implemented during [REDACTED_TASK_KEY]") + } + } + + private fun createAskBiometryComponent(childContext: AppComponentContext): AskBiometryComponent { + return askBiometryComponentFactory.create( + context = childContext, + params = AskBiometryComponent.Params( + isBottomSheetVariant = false, + modelCallbacks = object : AskBiometryComponent.ModelCallbacks { + override fun onAllowed() { + model.onIntent( + AddressSyncIntent.Next( + step = AddressSyncStep.ASK_NOTIFICATIONS, + replace = true + ) + ) + } + + override fun onDenied() { + model.onIntent( + AddressSyncIntent.Next( + step = AddressSyncStep.ASK_NOTIFICATIONS, + replace = false + ) + ) + } + } + ) + ) + } + + private fun createPushNotificationComponent(childContext: AppComponentContext): PushNotificationsComponent { + return pushNotificationsComponentFactory.create( + context = childContext, + params = PushNotificationsParams( + modelCallbacks = object : PushNotificationsModelCallbacks { + override fun onAllowSystemPermission() { + model.onIntent( + AddressSyncIntent.Next( + step = AddressSyncStep.ADDRESS_SYNC, + replace = true + ) + ) + } + + override fun onDenySystemPermission() { + model.onIntent( + AddressSyncIntent.Next( + step = AddressSyncStep.ADDRESS_SYNC, + replace = false + ) + ) + } + + override fun onDismiss() { + model.onIntent( + AddressSyncIntent.Next( + step = AddressSyncStep.ADDRESS_SYNC, + replace = false + ) + ) + } + }, + source = AppRoute.PushNotification.Source.Onboarding, + ) + ) } } \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/di/AddressSyncComponentModule.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/di/AddressSyncComponentModule.kt deleted file mode 100644 index a9f22b031e..0000000000 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/di/AddressSyncComponentModule.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.tangem.features.onboarding.v2.addresssync.di - -import com.tangem.features.onboarding.v2.addresssync.AddressSyncComponent -import com.tangem.features.onboarding.v2.addresssync.DefaultAddressSyncComponent -import dagger.Binds -import dagger.Module -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import javax.inject.Singleton - -@Module -@InstallIn(SingletonComponent::class) -internal interface AddressSyncComponentModule { - - @Binds - @Singleton - fun bindAddressSyncComponentFactory(factory: DefaultAddressSyncComponent.Factory): AddressSyncComponent.Factory -} \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/entity/AddressSyncUM.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/entity/AddressSyncUM.kt deleted file mode 100644 index bc58a40b89..0000000000 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/entity/AddressSyncUM.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.tangem.features.onboarding.v2.addresssync.entity - -internal data class AddressSyncUM( - val onBackClick: () -> Unit, -) \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncIntent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncIntent.kt new file mode 100644 index 0000000000..47ecbbb69d --- /dev/null +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncIntent.kt @@ -0,0 +1,8 @@ +package com.tangem.features.onboarding.v2.addresssync.model + +import com.tangem.features.onboarding.v2.addresssync.navigation.AddressSyncStep + +sealed interface AddressSyncIntent { + data class Next(val step: AddressSyncStep, val replace: Boolean) : AddressSyncIntent + data object Back : AddressSyncIntent +} \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModel.kt index b214cef29e..773be2996e 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModel.kt @@ -1,22 +1,68 @@ package com.tangem.features.onboarding.v2.addresssync.model +import com.arkivanov.decompose.DelicateDecomposeApi +import com.arkivanov.decompose.router.stack.StackNavigation +import com.arkivanov.decompose.router.stack.pop +import com.arkivanov.decompose.router.stack.push +import com.arkivanov.decompose.router.stack.replaceCurrent import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model -import com.tangem.features.onboarding.v2.addresssync.entity.AddressSyncUM +import com.tangem.domain.settings.CanUseBiometryUseCase +import com.tangem.domain.settings.ShouldAskPermissionUseCase +import com.tangem.domain.settings.ShouldShowAskBiometryUseCase +import com.tangem.features.onboarding.v2.addresssync.navigation.AddressSyncStep +import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch import javax.inject.Inject +@OptIn(DelicateDecomposeApi::class) @ModelScoped internal class AddressSyncModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, + private val shouldShowAskBiometryUseCase: ShouldShowAskBiometryUseCase, + private val canUseBiometryUseCase: CanUseBiometryUseCase, + private val shouldAskPermissionUseCase: ShouldAskPermissionUseCase, ) : Model() { - val uiState: StateFlow - field: MutableStateFlow = MutableStateFlow(getInitialState()) + val stackNavigation = StackNavigation() - private fun getInitialState(): AddressSyncUM { - TODO("Will be implemented during [REDACTED_TASK_KEY]") + fun onIntent(intent: AddressSyncIntent) { + when (intent) { + is AddressSyncIntent.Next -> nextScreen(intent) + AddressSyncIntent.Back -> goBack() + } + } + + private fun nextScreen(next: AddressSyncIntent.Next) { + val (nextStep, replace) = next + if (replace) { + stackNavigation.replaceCurrent(configuration = nextStep) + } else { + stackNavigation.push(configuration = nextStep) + } + modelScope.launch { trySkippingScreen(next) } + } + + private suspend fun trySkippingScreen(next: AddressSyncIntent.Next) { + when (next.step) { + AddressSyncStep.ASK_BIOMETRY -> { + val showBiometry = canUseBiometryUseCase.strict() && shouldShowAskBiometryUseCase() + if (showBiometry.not()) { + nextScreen(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS, replace = true)) + } + } + AddressSyncStep.ASK_NOTIFICATIONS -> { + val showNotification = shouldAskPermissionUseCase(PUSH_PERMISSION) + if (showNotification.not()) { + nextScreen(AddressSyncIntent.Next(step = AddressSyncStep.ADDRESS_SYNC, replace = true)) + } + } + AddressSyncStep.ADDRESS_SYNC -> Unit + } + } + + private fun goBack() { + stackNavigation.pop() } } \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/navigation/AddressSyncStep.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/navigation/AddressSyncStep.kt new file mode 100644 index 0000000000..edd056ce90 --- /dev/null +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/navigation/AddressSyncStep.kt @@ -0,0 +1,7 @@ +package com.tangem.features.onboarding.v2.addresssync.navigation + +enum class AddressSyncStep { + ASK_BIOMETRY, + ASK_NOTIFICATIONS, + ADDRESS_SYNC, +} \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/ui/AddressSyncContent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/ui/AddressSyncContent.kt index 40b0b158eb..3da4b6d12e 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/ui/AddressSyncContent.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/ui/AddressSyncContent.kt @@ -2,20 +2,22 @@ package com.tangem.features.onboarding.v2.addresssync.ui import android.content.res.Configuration import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment 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 com.tangem.core.ui.components.appbar.AppBarWithBackButton import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.features.onboarding.v2.addresssync.entity.AddressSyncUM @Composable -internal fun AddressSyncContent(state: AddressSyncUM, modifier: Modifier = Modifier) { +internal fun AddressSyncContent( + modifier: Modifier = Modifier, + childContent: @Composable (Modifier) -> Unit = {}, +) { Column( modifier = modifier .background(color = TangemTheme.colors.background.secondary) @@ -24,31 +26,15 @@ internal fun AddressSyncContent(state: AddressSyncUM, modifier: Modifier = Modif .systemBarsPadding(), horizontalAlignment = Alignment.CenterHorizontally, ) { - AppBarWithBackButton( - onBackClick = state.onBackClick, - modifier = Modifier.height(TangemTheme.dimens.size56), - ) - - Column( - modifier = Modifier - .fillMaxSize() - .padding(horizontal = TangemTheme.dimens.spacing16) - .weight(1f), - ) {} + childContent(modifier) } } @Preview(showBackground = true, widthDp = 360) @Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable -private fun AddressSyncContentPreview(@PreviewParameter(PreviewStateProvider::class) state: AddressSyncUM) { +private fun AddressSyncContentPreview() { TangemThemePreview { - AddressSyncContent(state = state) + AddressSyncContent() } -} - -private class PreviewStateProvider : CollectionPreviewParameterProvider( - buildList { - TODO("Will be implemented during [REDACTED_TASK_KEY]") - }, -) \ No newline at end of file +} \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/model/OnboardingEntryModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/model/OnboardingEntryModel.kt index d3a679ae26..5747977a6d 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/model/OnboardingEntryModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/model/OnboardingEntryModel.kt @@ -82,6 +82,7 @@ internal class OnboardingEntryModel @Inject constructor( is Mode.UpgradeHotWallet -> OnboardingMultiWalletComponent.Mode.UpgradeHotWallet( userWalletId = mode.userWalletId, ) + is Mode.AddressSync -> OnboardingMultiWalletComponent.Mode.AddressSync else -> error("Incorrect onboarding type") } diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/api/OnboardingMultiWalletComponent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/api/OnboardingMultiWalletComponent.kt index 268966cf50..9e4e023699 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/api/OnboardingMultiWalletComponent.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/api/OnboardingMultiWalletComponent.kt @@ -24,6 +24,7 @@ interface OnboardingMultiWalletComponent : ComposableContentComponent, InnerNavi data object AddBackup : Mode() data object ContinueFinalize : Mode() data class UpgradeHotWallet(val userWalletId: UserWalletId) : Mode() + data object AddressSync : Mode() } interface Factory : ComponentFactory diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/DefaultOnboardingMultiWalletComponent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/DefaultOnboardingMultiWalletComponent.kt index 6526071a17..4fe733a371 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/DefaultOnboardingMultiWalletComponent.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/DefaultOnboardingMultiWalletComponent.kt @@ -25,8 +25,10 @@ import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.decompose.navigation.inner.InnerNavigation import com.tangem.core.decompose.navigation.inner.InnerNavigationState import com.tangem.core.ui.decompose.ComposableContentComponent -import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent +import com.tangem.features.biometry.AskBiometryComponent +import com.tangem.features.onboarding.v2.addresssync.DefaultAddressSyncComponent import com.tangem.features.onboarding.v2.common.analytics.OnboardingEvent +import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams import com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.MultiWalletAccessCodeComponent import com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.MultiWalletBackupComponent @@ -42,6 +44,7 @@ import com.tangem.features.onboarding.v2.multiwallet.impl.model.OnboardingMultiW import com.tangem.features.onboarding.v2.multiwallet.impl.ui.OnboardingMultiWallet import com.tangem.features.onboarding.v2.multiwallet.impl.ui.WalletArtworksState import com.tangem.features.onboarding.v2.util.ResetCardsComponent +import com.tangem.features.pushnotifications.api.PushNotificationsComponent import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -53,6 +56,8 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor @Assisted private val params: OnboardingMultiWalletComponent.Params, private val analyticsHandler: AnalyticsEventHandler, private val resetCardsComponentFactory: ResetCardsComponent.Factory, + private val askBiometryComponentFactory: AskBiometryComponent.Factory, + private val pushNotificationsComponentFactory: PushNotificationsComponent.Factory, ) : OnboardingMultiWalletComponent, AppComponentContext by context { private val model: OnboardingMultiWalletModel = getOrCreateModel(params) @@ -60,6 +65,7 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor private val artworksState = instanceKeeper.getOrCreateSimple(key = "artworksState") { MutableStateFlow( when (model.state.value.currentStep) { + AddressSync -> WalletArtworksState.Hidden UpgradeWallet -> WalletArtworksState.Folded CreateWallet -> WalletArtworksState.Folded ChooseBackupOption -> WalletArtworksState.Fan @@ -186,6 +192,11 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor onBack = { model.onBack() }, onEvent = ::handleFinalizeComponentEvent, ) + AddressSync -> DefaultAddressSyncComponent( + appComponentContext = childContext, + askBiometryComponentFactory = askBiometryComponentFactory, + pushNotificationsComponentFactory = pushNotificationsComponentFactory, + ) Done -> error("Unexpected Done state") } } diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/finalize/model/MultiWalletFinalizeModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/finalize/model/MultiWalletFinalizeModel.kt index 61d26b089e..9dc1d725b0 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/finalize/model/MultiWalletFinalizeModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/finalize/model/MultiWalletFinalizeModel.kt @@ -265,6 +265,7 @@ internal class MultiWalletFinalizeModel @Inject constructor( val userWallet = when (params.parentParams.mode) { OnboardingMultiWalletComponent.Mode.Onboarding, OnboardingMultiWalletComponent.Mode.ContinueFinalize, + OnboardingMultiWalletComponent.Mode.AddressSync, -> { saveWalletUseCase.invoke( userWallet = userWalletCreated.copy( diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletModel.kt index d254fca350..cb903802ce 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletModel.kt @@ -120,8 +120,12 @@ internal class OnboardingMultiWalletModel @Inject constructor( params.mode is OnboardingMultiWalletComponent.Mode.UpgradeHotWallet -> { OnboardingMultiWalletState.Step.UpgradeWallet } - params.mode == OnboardingMultiWalletComponent.Mode.ContinueFinalize -> + params.mode == OnboardingMultiWalletComponent.Mode.ContinueFinalize -> { OnboardingMultiWalletState.Step.Finalize + } + params.mode == OnboardingMultiWalletComponent.Mode.AddressSync -> { + OnboardingMultiWalletState.Step.AddressSync + } // Add backup button // Wallet1 without backup and userwallet's scanResponse doesn't contain primary card. card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup && diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletState.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletState.kt index d1fa192d94..7da46f2dfb 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletState.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletState.kt @@ -38,6 +38,7 @@ data class OnboardingMultiWalletState( SeedPhrase, ScanPrimary, AddBackupDevice, + AddressSync, Finalize, Done, } diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/Utils.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/Utils.kt index 9a7b2c1476..aff07ca039 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/Utils.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/Utils.kt @@ -15,4 +15,5 @@ fun screenTitleByStep(step: OnboardingMultiWalletState.Step): TextReference = wh OnboardingMultiWalletState.Step.Finalize -> resourceReference(R.string.onboarding_button_finalize_backup) OnboardingMultiWalletState.Step.Done -> resourceReference(R.string.common_done) OnboardingMultiWalletState.Step.UpgradeWallet -> resourceReference(R.string.common_tangem) + OnboardingMultiWalletState.Step.AddressSync -> TODO("Will be implemented during [REDACTED_TASK_KEY]") } \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/test/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModelTest.kt b/features/onboarding-v2/impl/src/test/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModelTest.kt new file mode 100644 index 0000000000..5f5797cc29 --- /dev/null +++ b/features/onboarding-v2/impl/src/test/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModelTest.kt @@ -0,0 +1,134 @@ +package com.tangem.features.onboarding.v2.addresssync.model + +import com.arkivanov.decompose.router.stack.StackNavigation +import com.tangem.domain.settings.CanUseBiometryUseCase +import com.tangem.domain.settings.ShouldAskPermissionUseCase +import com.tangem.domain.settings.ShouldShowAskBiometryUseCase +import com.tangem.features.onboarding.v2.addresssync.navigation.AddressSyncStep +import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION +import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider +import io.mockk.coEvery +import io.mockk.mockk +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.advanceUntilIdle +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +@OptIn(ExperimentalCoroutinesApi::class) +internal class AddressSyncModelTest { + + private val shouldShowAskBiometryUseCase: ShouldShowAskBiometryUseCase = mockk() + private val canUseBiometryUseCase: CanUseBiometryUseCase = mockk() + private val shouldAskPermissionUseCase: ShouldAskPermissionUseCase = mockk() + + @BeforeEach + fun setUp() { + coEvery { canUseBiometryUseCase.strict() } returns false + coEvery { shouldShowAskBiometryUseCase() } returns false + coEvery { shouldAskPermissionUseCase(PUSH_PERMISSION) } returns false + } + + @Test + fun `GIVEN biometry allowed AND should show biometry WHEN Next ASK_BIOMETRY THEN ASK_BIOMETRY on top`() = runTest { + coEvery { canUseBiometryUseCase.strict() } returns true + coEvery { shouldShowAskBiometryUseCase() } returns true + + val model = createModel(this) + val stack = model.stackNavigation.trackStack() + + model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY, replace = false)) + advanceUntilIdle() + + assert(stack == listOf(AddressSyncStep.ASK_BIOMETRY)) + } + + @Test + fun `GIVEN biometry skipped AND notifications required WHEN Next ASK_BIOMETRY THEN ASK_NOTIFICATIONS on top`() = + runTest { + coEvery { canUseBiometryUseCase.strict() } returns true + coEvery { shouldShowAskBiometryUseCase() } returns false + coEvery { shouldAskPermissionUseCase(PUSH_PERMISSION) } returns true + + val model = createModel(this) + val stack = model.stackNavigation.trackStack() + + model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY, replace = false)) + advanceUntilIdle() + + assert(stack == listOf(AddressSyncStep.ASK_NOTIFICATIONS)) + } + + @Test + fun `GIVEN biometry skipped AND notifications skipped WHEN Next ASK_BIOMETRY THEN ADDRESS_SYNC on top`() = runTest { + coEvery { canUseBiometryUseCase.strict() } returns true + coEvery { shouldShowAskBiometryUseCase() } returns false + coEvery { shouldAskPermissionUseCase(PUSH_PERMISSION) } returns false + + val model = createModel(this) + val stack = model.stackNavigation.trackStack() + + model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY, replace = false)) + advanceUntilIdle() + + assert(stack == listOf(AddressSyncStep.ADDRESS_SYNC)) + } + + @Test + fun `GIVEN notifications required WHEN Next ASK_NOTIFICATIONS THEN ASK_NOTIFICATIONS on top`() = runTest { + coEvery { shouldAskPermissionUseCase(PUSH_PERMISSION) } returns true + + val model = createModel(this) + val stack = model.stackNavigation.trackStack() + + model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS, replace = false)) + advanceUntilIdle() + + assert(stack == listOf(AddressSyncStep.ASK_NOTIFICATIONS)) + } + + @Test + fun `GIVEN notifications skipped WHEN Next ASK_NOTIFICATIONS THEN ADDRESS_SYNC on top`() = runTest { + coEvery { shouldAskPermissionUseCase(PUSH_PERMISSION) } returns false + + val model = createModel(this) + val stack = model.stackNavigation.trackStack() + + model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS, replace = false)) + advanceUntilIdle() + + assert(stack == listOf(AddressSyncStep.ADDRESS_SYNC)) + } + + private fun StackNavigation.trackStack(): List { + val tracked = mutableListOf() + subscribe { event -> + val newStack = event.transformer(tracked.toList()) + tracked.clear() + tracked.addAll(newStack) + } + return tracked + } + + private fun createModel(testScope: TestScope): AddressSyncModel { + return AddressSyncModel( + dispatchers = testScope.createTestingCoroutineDispatcherProvider(), + shouldShowAskBiometryUseCase = shouldShowAskBiometryUseCase, + canUseBiometryUseCase = canUseBiometryUseCase, + shouldAskPermissionUseCase = shouldAskPermissionUseCase, + ) + } + + private fun TestScope.createTestingCoroutineDispatcherProvider(): TestingCoroutineDispatcherProvider { + val testDispatcher = StandardTestDispatcher(testScheduler) + return TestingCoroutineDispatcherProvider( + main = testDispatcher, + mainImmediate = testDispatcher, + io = testDispatcher, + default = testDispatcher, + single = testDispatcher, + ) + } +} \ No newline at end of file From 9736fa301caaa1637ba17a1d2651e1afdd801e0a Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 21 Apr 2026 12:23:19 +0100 Subject: [PATCH 2/2] Updated on 2026-08-14 --- .../CreateWalletStartModel.kt | 2 +- .../DefaultAddressSyncComponent.kt | 39 +++++++++---------- .../v2/addresssync/model/AddressSyncIntent.kt | 2 +- .../v2/addresssync/model/AddressSyncModel.kt | 12 +++--- .../v2/addresssync/ui/AddressSyncContent.kt | 7 +--- .../addresssync/model/AddressSyncModelTest.kt | 10 ++--- 6 files changed, 33 insertions(+), 39 deletions(-) diff --git a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt index b438774c00..8c15de536f 100644 --- a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt +++ b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt @@ -239,7 +239,7 @@ internal class CreateWalletStartModel @Inject constructor( val route = if (onboardingV2FeatureToggles.isAddressSyncEnabled) { AppRoute.Onboarding( scanResponse = scanResponse, - mode = AppRoute.Onboarding.Mode.AddressSync + mode = AppRoute.Onboarding.Mode.AddressSync, ) } else { AppRoute.Wallet diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/DefaultAddressSyncComponent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/DefaultAddressSyncComponent.kt index 8357eb37d4..255027abc8 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/DefaultAddressSyncComponent.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/DefaultAddressSyncComponent.kt @@ -52,11 +52,11 @@ internal class DefaultAddressSyncComponent( modifier = modifier, childContent = { Children( - stack = childStack - ) { - it.instance.Content(modifier = modifier) + stack = childStack, + ) { child -> + child.instance.Content(Modifier) } - } + }, ) BackHandler { @@ -64,10 +64,7 @@ internal class DefaultAddressSyncComponent( } } - private fun createChild( - step: AddressSyncStep, - childContext: AppComponentContext, - ): ComposableContentComponent { + private fun createChild(step: AddressSyncStep, childContext: AppComponentContext): ComposableContentComponent { return when (step) { AddressSyncStep.ASK_BIOMETRY -> createAskBiometryComponent(childContext) AddressSyncStep.ASK_NOTIFICATIONS -> createPushNotificationComponent(childContext) @@ -85,8 +82,8 @@ internal class DefaultAddressSyncComponent( model.onIntent( AddressSyncIntent.Next( step = AddressSyncStep.ASK_NOTIFICATIONS, - replace = true - ) + shouldReplace = true, + ), ) } @@ -94,12 +91,12 @@ internal class DefaultAddressSyncComponent( model.onIntent( AddressSyncIntent.Next( step = AddressSyncStep.ASK_NOTIFICATIONS, - replace = false - ) + shouldReplace = false, + ), ) } - } - ) + }, + ), ) } @@ -112,8 +109,8 @@ internal class DefaultAddressSyncComponent( model.onIntent( AddressSyncIntent.Next( step = AddressSyncStep.ADDRESS_SYNC, - replace = true - ) + shouldReplace = true, + ), ) } @@ -121,8 +118,8 @@ internal class DefaultAddressSyncComponent( model.onIntent( AddressSyncIntent.Next( step = AddressSyncStep.ADDRESS_SYNC, - replace = false - ) + shouldReplace = false, + ), ) } @@ -130,13 +127,13 @@ internal class DefaultAddressSyncComponent( model.onIntent( AddressSyncIntent.Next( step = AddressSyncStep.ADDRESS_SYNC, - replace = false - ) + shouldReplace = false, + ), ) } }, source = AppRoute.PushNotification.Source.Onboarding, - ) + ), ) } } \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncIntent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncIntent.kt index 47ecbbb69d..1293c244d5 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncIntent.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncIntent.kt @@ -3,6 +3,6 @@ package com.tangem.features.onboarding.v2.addresssync.model import com.tangem.features.onboarding.v2.addresssync.navigation.AddressSyncStep sealed interface AddressSyncIntent { - data class Next(val step: AddressSyncStep, val replace: Boolean) : AddressSyncIntent + data class Next(val step: AddressSyncStep, val shouldReplace: Boolean) : AddressSyncIntent data object Back : AddressSyncIntent } \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModel.kt index 773be2996e..b06e54736c 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModel.kt @@ -47,15 +47,15 @@ internal class AddressSyncModel @Inject constructor( private suspend fun trySkippingScreen(next: AddressSyncIntent.Next) { when (next.step) { AddressSyncStep.ASK_BIOMETRY -> { - val showBiometry = canUseBiometryUseCase.strict() && shouldShowAskBiometryUseCase() - if (showBiometry.not()) { - nextScreen(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS, replace = true)) + val shouldShowAskBiometry = canUseBiometryUseCase.strict() && shouldShowAskBiometryUseCase() + if (shouldShowAskBiometry.not()) { + nextScreen(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS, shouldReplace = true)) } } AddressSyncStep.ASK_NOTIFICATIONS -> { - val showNotification = shouldAskPermissionUseCase(PUSH_PERMISSION) - if (showNotification.not()) { - nextScreen(AddressSyncIntent.Next(step = AddressSyncStep.ADDRESS_SYNC, replace = true)) + val shouldShowAskNotification = shouldAskPermissionUseCase(PUSH_PERMISSION) + if (shouldShowAskNotification.not()) { + nextScreen(AddressSyncIntent.Next(step = AddressSyncStep.ADDRESS_SYNC, shouldReplace = true)) } } AddressSyncStep.ADDRESS_SYNC -> Unit diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/ui/AddressSyncContent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/ui/AddressSyncContent.kt index 3da4b6d12e..9c0c693d4e 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/ui/AddressSyncContent.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/ui/AddressSyncContent.kt @@ -14,10 +14,7 @@ import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview @Composable -internal fun AddressSyncContent( - modifier: Modifier = Modifier, - childContent: @Composable (Modifier) -> Unit = {}, -) { +internal fun AddressSyncContent(modifier: Modifier = Modifier, childContent: @Composable (Modifier) -> Unit = {}) { Column( modifier = modifier .background(color = TangemTheme.colors.background.secondary) @@ -26,7 +23,7 @@ internal fun AddressSyncContent( .systemBarsPadding(), horizontalAlignment = Alignment.CenterHorizontally, ) { - childContent(modifier) + childContent(Modifier) } } diff --git a/features/onboarding-v2/impl/src/test/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModelTest.kt b/features/onboarding-v2/impl/src/test/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModelTest.kt index 5f5797cc29..0e4a8acc7d 100644 --- a/features/onboarding-v2/impl/src/test/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModelTest.kt +++ b/features/onboarding-v2/impl/src/test/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModelTest.kt @@ -39,7 +39,7 @@ internal class AddressSyncModelTest { val model = createModel(this) val stack = model.stackNavigation.trackStack() - model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY, replace = false)) + model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY, shouldReplace = false)) advanceUntilIdle() assert(stack == listOf(AddressSyncStep.ASK_BIOMETRY)) @@ -55,7 +55,7 @@ internal class AddressSyncModelTest { val model = createModel(this) val stack = model.stackNavigation.trackStack() - model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY, replace = false)) + model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY, shouldReplace = false)) advanceUntilIdle() assert(stack == listOf(AddressSyncStep.ASK_NOTIFICATIONS)) @@ -70,7 +70,7 @@ internal class AddressSyncModelTest { val model = createModel(this) val stack = model.stackNavigation.trackStack() - model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY, replace = false)) + model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY, shouldReplace = false)) advanceUntilIdle() assert(stack == listOf(AddressSyncStep.ADDRESS_SYNC)) @@ -83,7 +83,7 @@ internal class AddressSyncModelTest { val model = createModel(this) val stack = model.stackNavigation.trackStack() - model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS, replace = false)) + model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS, shouldReplace = false)) advanceUntilIdle() assert(stack == listOf(AddressSyncStep.ASK_NOTIFICATIONS)) @@ -96,7 +96,7 @@ internal class AddressSyncModelTest { val model = createModel(this) val stack = model.stackNavigation.trackStack() - model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS, replace = false)) + model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS, shouldReplace = false)) advanceUntilIdle() assert(stack == listOf(AddressSyncStep.ADDRESS_SYNC))