Updated on 2026-08-14
This commit is contained in:
parent
52d1ed4312
commit
7883fcc2c6
12 changed files with 128 additions and 93 deletions
|
|
@ -29,6 +29,7 @@ internal class TangemPayAddToWalletComponent(
|
|||
initialStatus = params.initialStatus,
|
||||
userWalletId = params.initialStatus.userWalletId,
|
||||
isEditingNameEnabled = false,
|
||||
shouldShowCardDetailsButtonOnCard = true,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -37,7 +38,10 @@ internal class TangemPayAddToWalletComponent(
|
|||
val state by model.uiState.collectAsStateWithLifecycle()
|
||||
BackHandler(onBack = router::pop)
|
||||
if (model.isRedesignEnabled()) {
|
||||
TangemPayAddToWalletScreenV2(state = state)
|
||||
TangemPayAddToWalletScreenV2(
|
||||
state = state,
|
||||
cardDetailsBlockComponent = cardDetailsBlockComponent,
|
||||
)
|
||||
} else {
|
||||
TangemPayAddToWalletScreen(
|
||||
state = state,
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ internal class TangemPayCardPageScreenComponent(
|
|||
initialStatus = params.initialStatus,
|
||||
userWalletId = params.initialStatus.userWalletId,
|
||||
isEditingNameEnabled = true,
|
||||
shouldShowCardDetailsButtonOnCard = false,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ internal class TangemPayEditDisplayNameComponent(
|
|||
initialStatus = params.initialStatus,
|
||||
userWalletId = params.initialStatus.userWalletId,
|
||||
isEditingNameEnabled = false,
|
||||
shouldShowCardDetailsButtonOnCard = false,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -19,5 +19,6 @@ internal interface TangemPayCardDetailsBlockComponent {
|
|||
val initialStatus: AccountStatus.Payment,
|
||||
val userWalletId: UserWalletId,
|
||||
val isEditingNameEnabled: Boolean,
|
||||
val shouldShowCardDetailsButtonOnCard: Boolean,
|
||||
)
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import com.tangem.features.tangempay.details.impl.R
|
|||
import com.tangem.features.tangempay.model.CardDataType
|
||||
import com.tangem.utils.StringsSigns
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class TangemPayCardDetailsBlockStateFactory(
|
||||
private val cardNumberEnd: String,
|
||||
private val displayName: CardDisplayName?,
|
||||
|
|
@ -14,6 +15,7 @@ internal class TangemPayCardDetailsBlockStateFactory(
|
|||
private val onEditNameClick: () -> Unit,
|
||||
private val onReveal: () -> Unit,
|
||||
private val onCopy: (String, CardDataType) -> Unit,
|
||||
private val shouldShowCardDetailsButtonOnCard: Boolean,
|
||||
) {
|
||||
|
||||
fun getInitialState(): TangemPayCardDetailsUM {
|
||||
|
|
@ -36,6 +38,7 @@ internal class TangemPayCardDetailsBlockStateFactory(
|
|||
} else {
|
||||
null
|
||||
},
|
||||
shouldShowCardDetailsButtonOnCard = shouldShowCardDetailsButtonOnCard,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -33,6 +33,7 @@ internal data class TangemPayCardDetailsUM(
|
|||
val cardFrozenState: TangemPayCardFrozenState,
|
||||
val displayNameState: DisplayNameState?,
|
||||
val isActionsAvailable: Boolean = false,
|
||||
val shouldShowCardDetailsButtonOnCard: Boolean = false,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ internal class TangemPayCardDetailsBlockModel @Inject constructor(
|
|||
onEditNameClick = ::startEditingDisplayName,
|
||||
onReveal = ::requestReveal,
|
||||
onCopy = ::copyData,
|
||||
shouldShowCardDetailsButtonOnCard = params.shouldShowCardDetailsButtonOnCard,
|
||||
)
|
||||
|
||||
val uiState: StateFlow<TangemPayCardDetailsUM>
|
||||
|
|
@ -153,7 +154,12 @@ internal class TangemPayCardDetailsBlockModel @Inject constructor(
|
|||
launchShowDetailsTimer()
|
||||
}
|
||||
.onLeft {
|
||||
uiState.transformerUpdate(transformer = DetailsHiddenStateTransformer(stateFactory))
|
||||
uiState.transformerUpdate(
|
||||
transformer = DetailsHiddenStateTransformer(
|
||||
stateFactory = stateFactory,
|
||||
shouldShowCardDetailsButtonOnCard = params.shouldShowCardDetailsButtonOnCard,
|
||||
),
|
||||
)
|
||||
showError()
|
||||
}
|
||||
}.saveIn(revealCardDetailsJobHolder)
|
||||
|
|
@ -168,7 +174,12 @@ internal class TangemPayCardDetailsBlockModel @Inject constructor(
|
|||
|
||||
private fun hideCardDetails() {
|
||||
revealCardDetailsJobHolder.cancel()
|
||||
uiState.transformerUpdate(transformer = DetailsHiddenStateTransformer(stateFactory))
|
||||
uiState.transformerUpdate(
|
||||
transformer = DetailsHiddenStateTransformer(
|
||||
stateFactory = stateFactory,
|
||||
shouldShowCardDetailsButtonOnCard = params.shouldShowCardDetailsButtonOnCard,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun showError() {
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ internal class TangemPayCardPageModel @Inject constructor(
|
|||
return persistentListOf(
|
||||
TangemPayCardPageSettingV2(
|
||||
id = TangemPayCardPageSettingV2.Id.Details,
|
||||
title = TextReference.Res(R.string.details_title),
|
||||
title = TextReference.Res(R.string.tangempay_card_details_title),
|
||||
onClick = ::onClickViewDetails,
|
||||
iconRes = CoreUiR.drawable.ic_visa_card_details_24,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.utils.transformer.Transformer
|
|||
|
||||
internal class DetailsHiddenStateTransformer(
|
||||
private val stateFactory: TangemPayCardDetailsBlockStateFactory,
|
||||
private val shouldShowCardDetailsButtonOnCard: Boolean,
|
||||
) : Transformer<TangemPayCardDetailsUM> {
|
||||
|
||||
override fun transform(prevState: TangemPayCardDetailsUM): TangemPayCardDetailsUM {
|
||||
|
|
@ -15,6 +16,7 @@ internal class DetailsHiddenStateTransformer(
|
|||
onClick = initialState.onClick,
|
||||
isHidden = initialState.isHidden,
|
||||
isLoading = initialState.isLoading,
|
||||
shouldShowCardDetailsButtonOnCard = shouldShowCardDetailsButtonOnCard,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,20 @@
|
|||
package com.tangem.features.tangempay.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
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 androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||
import com.tangem.core.ui.ds.topbar.TangemTopBar
|
||||
import com.tangem.core.ui.ds2.button.TangemButton
|
||||
|
|
@ -21,15 +26,24 @@ import com.tangem.core.ui.res.TangemTheme
|
|||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import com.tangem.core.ui.res.generated.icons.Icons
|
||||
import com.tangem.core.ui.res.generated.icons.ic_cross_20
|
||||
import com.tangem.domain.models.pay.TangemPayCardFrozenState
|
||||
import com.tangem.features.tangempay.components.cardDetails.PreviewTangemPayCardDetailsBlockComponent
|
||||
import com.tangem.features.tangempay.components.cardDetails.TangemPayCardDetailsBlockComponent
|
||||
import com.tangem.features.tangempay.details.impl.R
|
||||
import com.tangem.features.tangempay.entity.TangemPayAddToWalletStepItemUM
|
||||
import com.tangem.features.tangempay.entity.TangemPayAddToWalletUM
|
||||
import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@Composable
|
||||
internal fun TangemPayAddToWalletScreenV2(state: TangemPayAddToWalletUM, modifier: Modifier = Modifier) {
|
||||
internal fun TangemPayAddToWalletScreenV2(
|
||||
state: TangemPayAddToWalletUM,
|
||||
cardDetailsBlockComponent: TangemPayCardDetailsBlockComponent,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val scrollState = rememberScrollState()
|
||||
val cardDetailsState by cardDetailsBlockComponent.state.collectAsStateWithLifecycle()
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
|
|
@ -38,13 +52,24 @@ internal fun TangemPayAddToWalletScreenV2(state: TangemPayAddToWalletUM, modifie
|
|||
.systemBarsPadding(),
|
||||
) {
|
||||
AddToWalletTopBar(onBackClick = state.onBackClick)
|
||||
AddToWalletContent(
|
||||
scrollState = scrollState,
|
||||
steps = state.steps,
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f),
|
||||
)
|
||||
.weight(1f)
|
||||
.verticalScroll(scrollState)
|
||||
.padding(top = 8.dp, bottom = 12.dp),
|
||||
) {
|
||||
cardDetailsBlockComponent.CardDetailsBlockContent(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.padding(bottom = 12.dp),
|
||||
state = cardDetailsState,
|
||||
)
|
||||
DynamicSpacer(scrollState = scrollState)
|
||||
AddToWalletTitle()
|
||||
AddToWalletSteps(steps = state.steps)
|
||||
}
|
||||
AddToWalletBottomBar(state = state)
|
||||
}
|
||||
}
|
||||
|
|
@ -65,43 +90,17 @@ private fun AddToWalletTopBar(onBackClick: () -> Unit, modifier: Modifier = Modi
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun AddToWalletContent(
|
||||
scrollState: ScrollState,
|
||||
steps: ImmutableList<TangemPayAddToWalletStepItemUM>,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.verticalScroll(scrollState)
|
||||
.padding(horizontal = TangemTheme.dimens2.x6)
|
||||
.padding(bottom = TangemTheme.dimens2.x3),
|
||||
) {
|
||||
AddToWalletCardImage()
|
||||
DynamicSpacer(scrollState = scrollState)
|
||||
AddToWalletTitle()
|
||||
AddToWalletSteps(steps = steps)
|
||||
private fun ColumnScope.DynamicSpacer(scrollState: ScrollState) {
|
||||
if (!scrollState.canScrollBackward && !scrollState.canScrollForward) {
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AddToWalletCardImage(modifier: Modifier = Modifier) {
|
||||
Image(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
end = TangemTheme.dimens2.x22,
|
||||
bottom = TangemTheme.dimens2.x25,
|
||||
),
|
||||
painter = painterResource(R.drawable.img_tangem_pay_visa),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AddToWalletTitle(modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
modifier = modifier
|
||||
.padding(vertical = TangemTheme.dimens2.x3)
|
||||
.padding(vertical = 12.dp, horizontal = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
text = stringResourceSafe(R.string.tangempay_card_details_open_wallet_title),
|
||||
style = TangemTheme.typography3.heading.medium,
|
||||
|
|
@ -115,12 +114,10 @@ private fun AddToWalletSteps(steps: ImmutableList<TangemPayAddToWalletStepItemUM
|
|||
steps.forEachIndexed { idx, step ->
|
||||
StepItem(
|
||||
modifier = Modifier.padding(
|
||||
top = if (idx == 0) TangemTheme.dimens2.x3 else TangemTheme.dimens2.x0,
|
||||
bottom = if (idx < steps.lastIndex) {
|
||||
TangemTheme.dimens2.x4
|
||||
} else {
|
||||
TangemTheme.dimens2.x3
|
||||
},
|
||||
top = if (idx == 0) 12.dp else 0.dp,
|
||||
bottom = if (idx < steps.lastIndex) 16.dp else 12.dp,
|
||||
start = 16.dp,
|
||||
end = 16.dp,
|
||||
),
|
||||
stepNumber = step.count,
|
||||
title = step.text,
|
||||
|
|
@ -129,51 +126,16 @@ private fun AddToWalletSteps(steps: ImmutableList<TangemPayAddToWalletStepItemUM
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AddToWalletBottomBar(state: TangemPayAddToWalletUM, modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier) {
|
||||
TangemButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = TangemTheme.dimens2.x4)
|
||||
.padding(top = TangemTheme.dimens2.x3, bottom = TangemTheme.dimens2.x2),
|
||||
variant = TangemButton.Variant.Secondary,
|
||||
size = TangemButton.Size.X12,
|
||||
text = resourceReference(R.string.common_got_it),
|
||||
onClick = state.onBackClick,
|
||||
)
|
||||
|
||||
if (state.showAddToWalletButton) {
|
||||
TangemButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = TangemTheme.dimens2.x4)
|
||||
.padding(bottom = TangemTheme.dimens2.x3),
|
||||
text = resourceReference(R.string.tangempay_card_details_open_wallet_button),
|
||||
size = TangemButton.Size.X12,
|
||||
onClick = state.onClickOpenWallet,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ColumnScope.DynamicSpacer(scrollState: ScrollState) {
|
||||
if (!scrollState.canScrollBackward && !scrollState.canScrollForward) {
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun StepItem(stepNumber: Int, title: TextReference, modifier: Modifier = Modifier) {
|
||||
Row(
|
||||
modifier = modifier,
|
||||
modifier = modifier.padding(vertical = 2.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x3),
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(TangemTheme.dimens2.x4)
|
||||
.size(16.dp)
|
||||
.background(color = TangemTheme.colors3.bg.inverse, shape = CircleShape),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
|
|
@ -192,6 +154,34 @@ private fun StepItem(stepNumber: Int, title: TextReference, modifier: Modifier =
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AddToWalletBottomBar(state: TangemPayAddToWalletUM, modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier) {
|
||||
TangemButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp)
|
||||
.padding(top = 12.dp, bottom = 8.dp),
|
||||
variant = TangemButton.Variant.Secondary,
|
||||
size = TangemButton.Size.X12,
|
||||
text = resourceReference(R.string.common_got_it),
|
||||
onClick = state.onBackClick,
|
||||
)
|
||||
|
||||
if (state.showAddToWalletButton) {
|
||||
TangemButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp)
|
||||
.padding(bottom = 12.dp),
|
||||
text = resourceReference(R.string.tangempay_card_details_open_wallet_button),
|
||||
size = TangemButton.Size.X12,
|
||||
onClick = state.onClickOpenWallet,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
|
|
@ -225,6 +215,19 @@ private fun PreviewTangemPayAddToWalletScreen() {
|
|||
onBackClick = {},
|
||||
onClickOpenWallet = {},
|
||||
),
|
||||
cardDetailsBlockComponent = PreviewTangemPayCardDetailsBlockComponent(
|
||||
TangemPayCardDetailsUM(
|
||||
number = "",
|
||||
numberShort = "*1245",
|
||||
expiry = "••/••",
|
||||
cvv = "•••",
|
||||
onCopy = { _, _ -> },
|
||||
onClick = {},
|
||||
buttonText = TextReference.Res(R.string.tangempay_card_details_hide_text),
|
||||
cardFrozenState = TangemPayCardFrozenState.Unfrozen,
|
||||
displayNameState = null,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -186,7 +186,9 @@ private fun TangemPayCardDetailsHiddenBlock(state: TangemPayCardDetailsUM, modif
|
|||
bottom.linkTo(parent.bottom)
|
||||
}
|
||||
.testTag(TangemPayTestTags.CARD_DETAILS_SHOW_BUTTON),
|
||||
visible = !LocalVisaRedesignEnabled.current || state.isLoading,
|
||||
visible = !LocalVisaRedesignEnabled.current ||
|
||||
state.isLoading ||
|
||||
state.shouldShowCardDetailsButtonOnCard,
|
||||
) {
|
||||
TangemPayCardDetailsCustomButton(
|
||||
text = stringResourceSafe(id = R.string.tangempay_card_details_show_details),
|
||||
|
|
|
|||
|
|
@ -170,12 +170,18 @@ private fun GroupTitleBlock(
|
|||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
if (state.isLoading) {
|
||||
TextShimmer(
|
||||
modifier = modifier.width(TangemTheme.dimens2.x10),
|
||||
text = state.title,
|
||||
style = TextShimmerStyle.SUBHEADING,
|
||||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
Row(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 6.dp, start = 16.dp),
|
||||
) {
|
||||
TextShimmer(
|
||||
modifier = Modifier.width(TangemTheme.dimens2.x10),
|
||||
text = state.title,
|
||||
style = TextShimmerStyle.SUBHEADING,
|
||||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Text(
|
||||
modifier = modifier
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue