From e8cd53de9cc3499a11cf1e0afba7619bffabc068 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 10 Jun 2026 00:30:35 -0700 Subject: [PATCH] Updated on 2026-08-14 --- .../component/impl/DefaultRoutingComponent.kt | 38 ++++++++------- .../TangemPayHotWalletOnboardingModel.kt | 5 +- .../TangemPayHotWalletOnboardingScreen.kt | 46 +++++++++++++------ .../TangemPayHotWalletOnboardingModelTest.kt | 8 +--- 4 files changed, 53 insertions(+), 44 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt b/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt index 6be9860e0c..00c73a1027 100644 --- a/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt +++ b/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt @@ -214,33 +214,18 @@ internal class DefaultRoutingComponent @AssistedInject constructor( FeatureToggles.AND_15101_TANGEM_PAY_HOT_WALLET_ONBOARDING, ) TangemLogger.i("[TangemPay][HWO] Feature toggle enabled=$isHotWalletOnboardingEnabled") - if (isHotWalletOnboardingEnabled) { + val afterEmptyRoute: AppRoute = if (isHotWalletOnboardingEnabled) { val tangemPayHotWalletOnboardingDeepLink = withTimeoutOrNull(2.seconds) { appsFlyerReferralParamsHandler.waitForDeeplink(AppsFlyerDeeplinkSource.TangemPayHotWalletOnboarding) } TangemLogger.i("[TangemPay][HWO] Deep link present=${tangemPayHotWalletOnboardingDeepLink != null}") if (tangemPayHotWalletOnboardingDeepLink != null) { - val hotWalletRoute = AppRoute.TangemPayHotWalletOnboarding - val shouldShowTos = !cardRepository.isTangemTOSAccepted() - val route = if (shouldShowTos) "Disclaimer" else "HotWalletOnboarding" - TangemLogger.i("[TangemPay][HWO] TOS accepted=${!shouldShowTos}, navigating to $route") - return if (shouldShowTos) { - AppRoute.Disclaimer(isTosAccepted = false, nextRoute = hotWalletRoute) - } else { - hotWalletRoute - } + AppRoute.TangemPayHotWalletOnboarding + } else { + getDefaultRoute() } - } - - val isHideStoriesForReferralEnabled = featureTogglesManager.isFeatureEnabled( - FeatureToggles.TWI_1512_HIDE_STORIES_FOR_REFERRAL_ENABLED, - ) - // Referral users skip the Home stories screen and land directly on the - // mobile wallet creation flow. - val afterEmptyRoute: AppRoute = if (isHideStoriesForReferralEnabled && shouldShowMobileWalletPromoUseCase()) { - AppRoute.CreateWalletStart(mode = AppRoute.CreateWalletStart.Mode.HotWallet) } else { - AppRoute.Home(launchMode = launchMode) + getDefaultRoute() } val shouldAskPushPermission = shouldInitiallyAskPermissionUseCase(PUSH_PERMISSION).getOrNull() @@ -261,6 +246,19 @@ internal class DefaultRoutingComponent @AssistedInject constructor( } } + private suspend fun getDefaultRoute(): AppRoute { + val isHideStoriesForReferralEnabled = featureTogglesManager.isFeatureEnabled( + FeatureToggles.TWI_1512_HIDE_STORIES_FOR_REFERRAL_ENABLED, + ) + // Referral users skip the Home stories screen and land directly on the + // mobile wallet creation flow. + return if (isHideStoriesForReferralEnabled && shouldShowMobileWalletPromoUseCase()) { + AppRoute.CreateWalletStart(mode = AppRoute.CreateWalletStart.Mode.HotWallet) + } else { + AppRoute.Home(launchMode = launchMode) + } + } + @Composable override fun Content(modifier: Modifier) { RootContent( diff --git a/features/tangempay/onboarding/impl/src/main/kotlin/com/tangem/features/tangempay/hotwallet/TangemPayHotWalletOnboardingModel.kt b/features/tangempay/onboarding/impl/src/main/kotlin/com/tangem/features/tangempay/hotwallet/TangemPayHotWalletOnboardingModel.kt index f0585fb4f5..acead48f67 100644 --- a/features/tangempay/onboarding/impl/src/main/kotlin/com/tangem/features/tangempay/hotwallet/TangemPayHotWalletOnboardingModel.kt +++ b/features/tangempay/onboarding/impl/src/main/kotlin/com/tangem/features/tangempay/hotwallet/TangemPayHotWalletOnboardingModel.kt @@ -7,7 +7,6 @@ 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.extensions.TextReference import com.tangem.core.ui.message.DialogMessage import com.tangem.core.ui.message.dialog.Dialogs @@ -16,7 +15,6 @@ import com.tangem.domain.appsflyer.usecase.ClearAppsFlyerDeeplinkUseCase import com.tangem.domain.hotwallet.IsHotWalletCreationSupported import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents import com.tangem.domain.wallets.usecase.CreateHotWalletUseCase -import com.tangem.features.tangempay.TangemPayConstants import com.tangem.features.tangempay.onboarding.api.R import com.tangem.hot.sdk.model.HotAuth import com.tangem.hot.sdk.model.MnemonicType @@ -38,7 +36,6 @@ internal class TangemPayHotWalletOnboardingModel @Inject constructor( private val clearAppsFlyerDeeplinkUseCase: ClearAppsFlyerDeeplinkUseCase, private val router: Router, private val uiMessageSender: UiMessageSender, - private val urlOpener: UrlOpener, ) : Model() { val uiState: StateFlow @@ -51,7 +48,7 @@ internal class TangemPayHotWalletOnboardingModel @Inject constructor( ) private fun onTermsClick() { - urlOpener.openUrl(TangemPayConstants.TERMS_AND_LIMITS_LINK) + router.push(AppRoute.Disclaimer(isTosAccepted = true)) } private fun onGetCardClick() { diff --git a/features/tangempay/onboarding/impl/src/main/kotlin/com/tangem/features/tangempay/hotwallet/TangemPayHotWalletOnboardingScreen.kt b/features/tangempay/onboarding/impl/src/main/kotlin/com/tangem/features/tangempay/hotwallet/TangemPayHotWalletOnboardingScreen.kt index 6435e64bb2..3b769db3ba 100644 --- a/features/tangempay/onboarding/impl/src/main/kotlin/com/tangem/features/tangempay/hotwallet/TangemPayHotWalletOnboardingScreen.kt +++ b/features/tangempay/onboarding/impl/src/main/kotlin/com/tangem/features/tangempay/hotwallet/TangemPayHotWalletOnboardingScreen.kt @@ -14,17 +14,16 @@ import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.* import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.tangem.common.ui.navigationButtons.NavigationButton import com.tangem.common.ui.navigationButtons.NavigationPrimaryButton import com.tangem.core.ui.R -import com.tangem.core.ui.components.TextButton -import com.tangem.core.ui.components.buttons.common.TangemButtonsDefaults -import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.extensions.stringResourceSafe +import com.tangem.core.ui.components.SpacerH16 +import com.tangem.core.ui.extensions.* import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.utils.WindowInsetsZero @@ -80,10 +79,11 @@ private fun Content(state: TangemPayHotWalletOnboardingUM, modifier: Modifier = .fillMaxWidth() .padding(horizontal = 40.dp), ) + SpacerH16() Spacer(Modifier.weight(1f)) Column( modifier = Modifier.padding(16.dp), - verticalArrangement = Arrangement.spacedBy(8.dp), + verticalArrangement = Arrangement.spacedBy(16.dp), ) { NavigationPrimaryButton( primaryButton = NavigationButton( @@ -94,18 +94,36 @@ private fun Content(state: TangemPayHotWalletOnboardingUM, modifier: Modifier = onClick = state.onGetCardClick, ), ) - TextButton( - modifier = Modifier.fillMaxWidth(), - text = stringResourceSafe(R.string.tangem_pay_terms_fees_limits), - onClick = state.onTermsClick, - colors = TangemButtonsDefaults.defaultTextButtonColors.copy( - contentColor = TangemTheme.colors.text.primary1, - ), - ) + TosText(onClick = state.onTermsClick) } } } +@Composable +private fun TosText(onClick: () -> Unit, modifier: Modifier = Modifier) { + val termsTemplate = stringResourceSafe(R.string.onboarding_create_wallet_term_of_conditions_text) + val termsLinkText = stringResourceSafe(R.string.disclaimer_title) + val termsLinkColor = TangemTheme.colors.text.accent + Text( + modifier = modifier.fillMaxWidth(), + text = buildAnnotatedString { + appendWithStyledPlaceholder(template = termsTemplate) { + withLink( + LinkAnnotation.Clickable( + tag = "tos_link", + styles = TextLinkStyles(SpanStyle(textDecoration = TextDecoration.None)), + ) { onClick() }, + ) { + appendColored(text = termsLinkText, color = termsLinkColor) + } + } + }, + style = TangemTheme.typography.caption2, + color = TangemTheme.colors.text.tertiary, + textAlign = TextAlign.Center, + ) +} + @Composable private fun Features(modifier: Modifier = Modifier) { Column( diff --git a/features/tangempay/onboarding/impl/src/test/kotlin/com/tangem/features/tangempay/hotwallet/TangemPayHotWalletOnboardingModelTest.kt b/features/tangempay/onboarding/impl/src/test/kotlin/com/tangem/features/tangempay/hotwallet/TangemPayHotWalletOnboardingModelTest.kt index a2d4591f4d..cb1af5576e 100644 --- a/features/tangempay/onboarding/impl/src/test/kotlin/com/tangem/features/tangempay/hotwallet/TangemPayHotWalletOnboardingModelTest.kt +++ b/features/tangempay/onboarding/impl/src/test/kotlin/com/tangem/features/tangempay/hotwallet/TangemPayHotWalletOnboardingModelTest.kt @@ -6,7 +6,6 @@ import com.google.common.truth.Truth.assertThat import com.tangem.common.routing.AppRoute 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.message.DialogMessage import com.tangem.domain.appsflyer.AppsFlyerDeeplinkSource import com.tangem.domain.appsflyer.usecase.ClearAppsFlyerDeeplinkUseCase @@ -14,7 +13,6 @@ import com.tangem.domain.hotwallet.IsHotWalletCreationSupported import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.wallets.usecase.CreateHotWalletUseCase -import com.tangem.features.tangempay.TangemPayConstants import com.tangem.hot.sdk.model.HotAuth import com.tangem.hot.sdk.model.MnemonicType import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider @@ -32,7 +30,6 @@ internal class TangemPayHotWalletOnboardingModelTest { private val clearAppsFlyerDeeplinkUseCase: ClearAppsFlyerDeeplinkUseCase = mockk() private val router: Router = mockk(relaxed = true) private val uiMessageSender: UiMessageSender = mockk(relaxed = true) - private val urlOpener: UrlOpener = mockk(relaxed = true) private val testUserWalletId = UserWalletId("1234567890ABCDEF") private val testUserWallet: UserWallet.Hot = mockk(relaxed = true) { @@ -43,12 +40,12 @@ internal class TangemPayHotWalletOnboardingModelTest { inner class OnTermsClick { @Test - fun `WHEN onTermsClick THEN urlOpener called with terms link`() = runTest { + fun `WHEN onTermsClick THEN navigate to Disclaimer`() = runTest { val model = createModel() model.uiState.value.onTermsClick.invoke() - verify { urlOpener.openUrl(TangemPayConstants.TERMS_AND_LIMITS_LINK) } + verify { router.push(AppRoute.Disclaimer(isTosAccepted = true)) } } } @@ -118,7 +115,6 @@ internal class TangemPayHotWalletOnboardingModelTest { clearAppsFlyerDeeplinkUseCase = clearAppsFlyerDeeplinkUseCase, router = router, uiMessageSender = uiMessageSender, - urlOpener = urlOpener, ) } } \ No newline at end of file