Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-03 20:46:58 +04:00
commit 09c52231e2
25 changed files with 447 additions and 85 deletions

View file

@ -57,6 +57,7 @@ internal class CreateMobileWalletModel @Inject constructor(
onImportClick = ::onImportClick,
onCreateClick = ::onCreateClick,
createButtonLoading = false,
onTermsClick = { router.push(AppRoute.Disclaimer(isTosAccepted = true)) },
),
)

View file

@ -5,4 +5,5 @@ internal data class CreateMobileWalletUM(
val onBackClick: () -> Unit,
val onImportClick: () -> Unit,
val onCreateClick: () -> Unit,
val onTermsClick: () -> Unit,
)

View file

@ -9,7 +9,13 @@ import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.LinkAnnotation
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextLinkStyles
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.withLink
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.R
@ -19,6 +25,8 @@ 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.appendColored
import com.tangem.core.ui.extensions.appendWithStyledPlaceholder
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
@ -92,6 +100,33 @@ internal fun CreateMobileWalletContent(state: CreateMobileWalletUM, modifier: Mo
iconRes = R.drawable.ic_tangem_card_24,
)
}
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(
text = buildAnnotatedString {
appendWithStyledPlaceholder(template = termsTemplate) {
withLink(
LinkAnnotation.Clickable(
tag = "tos_link",
styles = TextLinkStyles(SpanStyle(textDecoration = TextDecoration.None)),
) { state.onTermsClick() },
) {
appendColored(text = termsLinkText, color = termsLinkColor)
}
}
},
modifier = Modifier
.fillMaxWidth()
.padding(
start = 16.dp,
top = 16.dp,
end = 16.dp,
),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
textAlign = TextAlign.Center,
)
SecondaryButton(
modifier = Modifier
.fillMaxWidth()
@ -130,6 +165,7 @@ private fun PreviewCreateWalletContent() {
createButtonLoading = false,
onImportClick = {},
onCreateClick = {},
onTermsClick = {},
),
)
}

View file

@ -3,6 +3,7 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.mo
import androidx.compose.runtime.Stable
import com.tangem.common.CompletionResult
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
@ -10,6 +11,7 @@ import com.tangem.core.analytics.models.event.OnboardingAnalyticsEvent
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.core.ui.extensions.resourceReference
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
import com.tangem.domain.card.repository.CardRepository
@ -39,6 +41,7 @@ import javax.inject.Inject
@ModelScoped
internal class MultiWalletCreateWalletModel @Inject constructor(
paramsContainer: ParamsContainer,
private val router: Router,
override val dispatchers: CoroutineDispatcherProvider,
private val tangemSdkManager: TangemSdkManager,
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
@ -77,6 +80,7 @@ internal class MultiWalletCreateWalletModel @Inject constructor(
onDone.emit(Step.SeedPhrase)
}
},
onTermsOfUseClick = { router.push(AppRoute.Disclaimer(isTosAccepted = true)) },
dialog = null,
),
)

View file

@ -8,13 +8,22 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.LinkAnnotation
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextLinkStyles
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.withLink
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.R as CoreUiR
import com.tangem.core.ui.components.BasicDialog
import com.tangem.core.ui.components.DialogButtonUM
import com.tangem.core.ui.components.PrimaryButtonIconEnd
import com.tangem.core.ui.components.SecondaryButton
import com.tangem.core.ui.extensions.appendColored
import com.tangem.core.ui.extensions.appendWithStyledPlaceholder
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.stringResourceSafe
@ -24,24 +33,10 @@ import com.tangem.core.ui.test.StoriesScreenTestTags
import com.tangem.features.onboarding.v2.impl.R
import com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.ui.state.MultiWalletCreateWalletUM
@Suppress("LongMethod")
@Composable
internal fun MultiWalletCreateWallet(state: MultiWalletCreateWalletUM, modifier: Modifier = Modifier) {
if (state.dialog != null) {
BasicDialog(
title = state.dialog.title.resolveReference(),
message = state.dialog.message.resolveReference(),
confirmButton = DialogButtonUM(
title = state.dialog.confirmButtonText.resolveReference(),
onClick = state.dialog.onConfirmClick,
),
dismissButton = DialogButtonUM(
title = state.dialog.dismissButtonText.resolveReference(),
isWarning = state.dialog.dismissWarningColor,
onClick = state.dialog.onDismissButtonClick,
),
onDismissDialog = state.dialog.onDismiss,
)
}
MultiWalletCreateWalletDialog(state)
Column(
modifier = modifier
@ -78,9 +73,33 @@ internal fun MultiWalletCreateWallet(state: MultiWalletCreateWalletUM, modifier:
)
}
val termsTemplate = stringResourceSafe(CoreUiR.string.onboarding_create_wallet_term_of_conditions_text)
val termsLinkText = stringResourceSafe(CoreUiR.string.disclaimer_title)
val termsLinkColor = TangemTheme.colors.text.accent
Text(
text = buildAnnotatedString {
appendWithStyledPlaceholder(template = termsTemplate) {
withLink(
LinkAnnotation.Clickable(
tag = "tos_link",
styles = TextLinkStyles(SpanStyle(textDecoration = TextDecoration.None)),
) { state.onTermsOfUseClick() },
) {
appendColored(text = termsLinkText, color = termsLinkColor)
}
}
},
modifier = Modifier
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
.fillMaxWidth(),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
textAlign = TextAlign.Center,
)
PrimaryButtonIconEnd(
modifier = Modifier
.padding(start = 16.dp, end = 16.dp, bottom = 12.dp)
.padding(start = 16.dp, end = 16.dp, bottom = 8.dp)
.fillMaxWidth(),
iconResId = R.drawable.ic_tangem_24,
text = stringResourceSafe(R.string.onboarding_create_wallet_button_create_wallet),
@ -90,7 +109,7 @@ internal fun MultiWalletCreateWallet(state: MultiWalletCreateWalletUM, modifier:
if (state.showOtherOptionsButton) {
SecondaryButton(
modifier = Modifier
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
.padding(start = 16.dp, end = 16.dp, bottom = 8.dp)
.fillMaxWidth(),
text = stringResourceSafe(R.string.onboarding_create_wallet_options_button_options),
onClick = state.onOtherOptionsClick,
@ -99,6 +118,26 @@ internal fun MultiWalletCreateWallet(state: MultiWalletCreateWalletUM, modifier:
}
}
@Composable
private fun MultiWalletCreateWalletDialog(state: MultiWalletCreateWalletUM) {
if (state.dialog != null) {
BasicDialog(
title = state.dialog.title.resolveReference(),
message = state.dialog.message.resolveReference(),
confirmButton = DialogButtonUM(
title = state.dialog.confirmButtonText.resolveReference(),
onClick = state.dialog.onConfirmClick,
),
dismissButton = DialogButtonUM(
title = state.dialog.dismissButtonText.resolveReference(),
isWarning = state.dialog.dismissWarningColor,
onClick = state.dialog.onDismissButtonClick,
),
onDismissDialog = state.dialog.onDismiss,
)
}
}
@Preview(showBackground = true)
@Composable
private fun Preview() {
@ -110,6 +149,7 @@ private fun Preview() {
onCreateWalletClick = {},
showOtherOptionsButton = true,
onOtherOptionsClick = {},
onTermsOfUseClick = {},
dialog = null,
),
)

View file

@ -9,5 +9,6 @@ internal data class MultiWalletCreateWalletUM(
val showOtherOptionsButton: Boolean,
val onCreateWalletClick: () -> Unit,
val onOtherOptionsClick: () -> Unit,
val onTermsOfUseClick: () -> Unit,
val dialog: OnboardingDialogUM?,
)

View file

@ -62,7 +62,7 @@ internal object TangemPayTxHistoryDetailsConverter :
is TangemPayTxHistoryItem.Payment -> ImageReference.Res(R.drawable.ic_arrow_up_24)
is TangemPayTxHistoryItem.Spend -> {
val merchantIcon = this.enrichedMerchantIconUrl
if (merchantIcon != null) {
if (!merchantIcon.isNullOrEmpty()) {
ImageReference.Url(merchantIcon)
} else {
ImageReference.Res(R.drawable.ic_category_24)

View file

@ -61,9 +61,7 @@ internal class DefaultTangemPayMainDeepLinkHandler @AssistedInject constructor(
onComplete = {
walletDeepLinkActionTrigger.selectWallet(userWalletId)
when (pushAction) {
is TangemPayPushAction.CardReady,
is TangemPayPushAction.TopUp,
-> navigateToTangemPayDetails(userWalletId)
is TangemPayPushAction.CardReady -> navigateToTangemPayDetails(userWalletId)
is TangemPayPushAction.TransactionSpend -> {
walletDeepLinkActionTrigger.showTangemPayTransaction(
transaction = pushAction.transaction,
@ -89,12 +87,14 @@ internal class DefaultTangemPayMainDeepLinkHandler @AssistedInject constructor(
return when (type) {
TangemPayPushNotificationType.CARD_READY -> TangemPayPushAction.CardReady
TangemPayPushNotificationType.TRANSACTION_SPEND -> {
TangemPayPushNotificationType.TRANSACTION_SPEND,
TangemPayPushNotificationType.TRANSACTION_SPEND_REFUND,
TangemPayPushNotificationType.DECLINED_TOP_UP,
-> {
val transaction = TangemPayPushPayloadToTxHistoryItemConverter.convertSpend(payload)
if (transaction != null) TangemPayPushAction.TransactionSpend(transaction, customerId) else null
}
TangemPayPushNotificationType.TOP_UP -> TangemPayPushAction.TopUp
TangemPayPushNotificationType.COLLATERAL -> {
TangemPayPushNotificationType.COLLATERAL_DEPOSIT, TangemPayPushNotificationType.COLLATERAL_WITHDRAW -> {
val transaction = TangemPayPushPayloadToTxHistoryItemConverter.convertCollateral(payload)
if (transaction != null) TangemPayPushAction.CollateralTransaction(transaction, customerId) else null
}

View file

@ -7,14 +7,12 @@ internal sealed class TangemPayPushAction {
data object CardReady : TangemPayPushAction()
data class TransactionSpend(
val transaction: TangemPayTxHistoryItem,
val transaction: TangemPayTxHistoryItem.Spend,
val customerId: String,
) : TangemPayPushAction()
data object TopUp : TangemPayPushAction()
data class CollateralTransaction(
val transaction: TangemPayTxHistoryItem,
val transaction: TangemPayTxHistoryItem.Collateral,
val customerId: String,
) : TangemPayPushAction()
}

View file

@ -422,4 +422,16 @@ internal enum class Wallet2CobrandImage(
cards3ResId = R.drawable.ill_stronghold_card3_120_106,
batchIds = setOf("BB000054"),
),
Superteam(
cards2ResId = R.drawable.ill_superteam_card2_120_106,
cards3ResId = R.drawable.ill_superteam_card3_120_106,
batchIds = setOf("BB000051"),
),
Nanovest(
cards2ResId = R.drawable.ill_nanovest_card2_120_106,
cards3ResId = R.drawable.ill_nanovest_card3_120_106,
batchIds = setOf("BB000052"),
),
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB