Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-03 13:39:31 +02:00
parent 1c1509640a
commit 5a4fb583bd
6 changed files with 233 additions and 15 deletions

View file

@ -9,6 +9,7 @@ import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.pay.model.TangemPayTopUpData
import com.tangem.features.tangempay.model.TangemPayAddFundsModel
import com.tangem.features.tangempay.ui.TangemPayAddFundsContent
import com.tangem.features.tangempay.ui.TangemPayAddFundsContentV2
import java.math.BigDecimal
internal class TangemPayAddFundsComponent(
@ -24,7 +25,11 @@ internal class TangemPayAddFundsComponent(
@Composable
override fun BottomSheet() {
TangemPayAddFundsContent(state = model.uiState)
if (model.isRedesignEnabled()) {
TangemPayAddFundsContentV2(state = model.uiState)
} else {
TangemPayAddFundsContent(state = model.uiState)
}
}
data class Params(

View file

@ -1,7 +1,7 @@
package com.tangem.features.tangempay.entity
import androidx.annotation.DrawableRes
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetUM
import com.tangem.core.ui.ds.image.TangemIconUM
import com.tangem.core.ui.extensions.TextReference
import kotlinx.collections.immutable.ImmutableList
@ -12,7 +12,7 @@ internal data class TangemPayAddFundsUM(
)
internal data class TangemPayAddFundsItemUM(
@DrawableRes val iconRes: Int,
val icon: TangemIconUM,
val title: TextReference,
val description: TextReference,
val onClick: () -> Unit,

View file

@ -7,6 +7,7 @@ import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.models.ReceiveAddressModel
import com.tangem.domain.models.ReceiveAddressModel.DisplayType
import com.tangem.domain.pay.model.TangemPayTopUpData
import com.tangem.features.tangempay.TangemPayFeatureToggles
import com.tangem.features.tangempay.components.TangemPayAddFundsComponent
import com.tangem.features.tangempay.entity.TangemPayAddFundsUM
import com.tangem.features.tangempay.model.transformers.TangemPayAddFundsUMConverter
@ -18,6 +19,7 @@ import javax.inject.Inject
internal class TangemPayAddFundsModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
) : Model() {
private val params = paramsContainer.require<TangemPayAddFundsComponent.Params>()
@ -38,9 +40,14 @@ internal class TangemPayAddFundsModel @Inject constructor(
),
),
)
return TangemPayAddFundsUMConverter(listener = params.listener).convert(data)
return TangemPayAddFundsUMConverter(
listener = params.listener,
isRedesignEnabled = tangemPayFeatureToggles.isRedesignEnabled,
).convert(data)
}
fun isRedesignEnabled(): Boolean = tangemPayFeatureToggles.isRedesignEnabled
fun onDismiss() {
params.listener.onDismissAddFunds()
}

View file

@ -1,6 +1,11 @@
package com.tangem.features.tangempay.model.transformers
import com.tangem.core.ui.ds.image.TangemIconUM
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.generated.icons.Icons
import com.tangem.core.ui.res.generated.icons.ic_card_20
import com.tangem.core.ui.res.generated.icons.ic_logo_tangem_20
import com.tangem.domain.pay.model.TangemPayTopUpData
import com.tangem.features.tangempay.components.AddFundsListener
import com.tangem.features.tangempay.details.impl.R
@ -13,6 +18,7 @@ import kotlinx.collections.immutable.persistentListOf
internal class TangemPayAddFundsUMConverter(
val listener: AddFundsListener,
val isRedesignEnabled: Boolean,
) : Converter<TangemPayTopUpData?, TangemPayAddFundsUM> {
override fun convert(value: TangemPayTopUpData?): TangemPayAddFundsUM {
@ -28,13 +34,41 @@ internal class TangemPayAddFundsUMConverter(
TangemPayAddFundsUM(
items = persistentListOf(
TangemPayAddFundsItemUM(
iconRes = R.drawable.ic_exchange_vertical_24,
icon = if (isRedesignEnabled) {
TangemIconUM.Icon(
imageVector = Icons.ic_logo_tangem_20,
tintReference = {
TangemTheme.colors3.icon.brand
},
)
} else {
TangemIconUM.Icon(
iconRes = R.drawable.ic_exchange_vertical_24,
tintReference = {
TangemTheme.colors.icon.accent
},
)
},
title = TextReference.Res(R.string.tangempay_topup_swap_title),
description = TextReference.Res(R.string.tangempay_topup_swap_body),
onClick = { listener.onClickSwap(value) },
),
TangemPayAddFundsItemUM(
iconRes = R.drawable.ic_arrow_down_24,
icon = if (isRedesignEnabled) {
TangemIconUM.Icon(
imageVector = Icons.ic_card_20,
tintReference = {
TangemTheme.colors3.icon.brand
},
)
} else {
TangemIconUM.Icon(
iconRes = R.drawable.ic_arrow_down_24,
tintReference = {
TangemTheme.colors.icon.accent
},
)
},
title = TextReference.Res(R.string.tangempay_topup_receive_title),
description = TextReference.Res(R.string.tangempay_topup_receive_body),
onClick = { listener.onClickReceive(value) },

View file

@ -5,15 +5,12 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Icon
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.key
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEach
@ -23,6 +20,8 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetContent
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
import com.tangem.core.ui.ds.image.TangemIcon
import com.tangem.core.ui.ds.image.TangemIconUM
import com.tangem.core.ui.extensions.TextReference.Res
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
@ -102,11 +101,9 @@ private fun TangemPayTopUpItem(state: TangemPayAddFundsItemUM, modifier: Modifie
)
.size(36.dp),
) {
Icon(
TangemIcon(
modifier = Modifier.size(16.dp),
imageVector = ImageVector.vectorResource(id = state.iconRes),
contentDescription = null,
tint = TangemTheme.colors.icon.accent,
tangemIconUM = state.icon,
)
}
Column(
@ -135,13 +132,23 @@ private fun TangemPayAddFundsContentPreview() {
state = TangemPayAddFundsUM(
items = persistentListOf(
TangemPayAddFundsItemUM(
iconRes = R.drawable.ic_exchange_vertical_24,
icon = TangemIconUM.Icon(
iconRes = R.drawable.ic_exchange_vertical_24,
tintReference = {
TangemTheme.colors.icon.accent
},
),
title = Res(R.string.common_exchange),
description = Res(R.string.exсhange_token_description),
onClick = {},
),
TangemPayAddFundsItemUM(
iconRes = R.drawable.ic_arrow_down_24,
icon = TangemIconUM.Icon(
iconRes = R.drawable.ic_arrow_down_24,
tintReference = {
TangemTheme.colors.icon.accent
},
),
title = Res(R.string.common_receive),
description = Res(R.string.receive_token_description),
onClick = {},

View file

@ -0,0 +1,165 @@
package com.tangem.features.tangempay.ui
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.key
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.util.fastForEach
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetType
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetContent
import com.tangem.core.ui.ds.image.TangemIcon
import com.tangem.core.ui.ds.image.TangemIconUM
import com.tangem.core.ui.ds.topbar.TangemTopBar
import com.tangem.core.ui.ds.topbar.TangemTopBarType
import com.tangem.core.ui.ds2.button.TangemButton
import com.tangem.core.ui.extensions.TextReference.Res
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.res.LocalRedesignEnabled
import com.tangem.core.ui.res.LocalVisaRedesignEnabled
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_card_20
import com.tangem.core.ui.res.generated.icons.ic_logo_tangem_20
import com.tangem.features.tangempay.details.impl.R
import com.tangem.features.tangempay.entity.TangemPayAddFundsItemUM
import com.tangem.features.tangempay.entity.TangemPayAddFundsUM
import kotlinx.collections.immutable.persistentListOf
@Composable
internal fun TangemPayAddFundsContentV2(state: TangemPayAddFundsUM) {
TangemBottomSheet<TangemBottomSheetConfigContent.Empty>(
config = TangemBottomSheetConfig(
isShown = true,
onDismissRequest = state.dismiss,
content = TangemBottomSheetConfigContent.Empty,
),
onBack = state.dismiss,
type = TangemBottomSheetType.Modal,
containerColor = TangemTheme.colors3.bg.secondary,
title = {
TangemTopBar(
title = resourceReference(R.string.tangempay_card_details_add_funds),
type = TangemTopBarType.BottomSheet,
endContent = {
TangemButton(
iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_close_24),
onClick = state.dismiss,
size = TangemButton.Size.X11,
variant = TangemButton.Variant.Material,
)
},
)
},
content = {
if (state.errorMessage != null) {
MessageBottomSheetContent(state.errorMessage)
} else {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = TangemTheme.dimens2.x4, vertical = TangemTheme.dimens2.x3),
) {
state.items.fastForEach { item ->
key(item.title) {
TangemPayTopUpItem(state = item)
}
}
}
}
},
)
}
@Composable
private fun TangemPayTopUpItem(state: TangemPayAddFundsItemUM, modifier: Modifier = Modifier) {
Row(
modifier = modifier
.fillMaxWidth()
.clickable(onClick = state.onClick)
.padding(vertical = TangemTheme.dimens2.x3),
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x3),
) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.background(
color = TangemTheme.colors3.bg.status.infoSubtle,
shape = CircleShape,
)
.size(TangemTheme.dimens2.x10),
) {
TangemIcon(
modifier = Modifier.size(TangemTheme.dimens2.x5),
tangemIconUM = state.icon,
)
}
Column(verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x0_5)) {
Text(
text = state.title.resolveReference(),
style = TangemTheme.typography3.subheading.medium,
color = TangemTheme.colors3.text.primary,
)
Text(
text = state.description.resolveReference(),
style = TangemTheme.typography3.caption.medium,
color = TangemTheme.colors3.text.secondary,
)
}
}
}
@Preview(showBackground = true)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun TangemPayAddFundsContentPreview() {
TangemThemePreviewRedesign {
CompositionLocalProvider(
LocalVisaRedesignEnabled provides true,
LocalRedesignEnabled provides true,
) {
TangemPayAddFundsContentV2(
state = TangemPayAddFundsUM(
items = persistentListOf(
TangemPayAddFundsItemUM(
icon = TangemIconUM.Icon(
imageVector = Icons.ic_logo_tangem_20,
tintReference = {
TangemTheme.colors3.icon.brand
},
),
title = Res(R.string.common_exchange),
description = Res(R.string.exсhange_token_description),
onClick = {},
),
TangemPayAddFundsItemUM(
icon = TangemIconUM.Icon(
imageVector = Icons.ic_card_20,
tintReference = {
TangemTheme.colors3.icon.brand
},
),
title = Res(R.string.common_receive),
description = Res(R.string.receive_token_description),
onClick = {},
),
),
dismiss = {},
errorMessage = null,
),
)
}
}
}