From 90abe449d69853cec8e9ecb6bd8b513a55dffc3e Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 4 Mar 2026 15:19:16 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/di/domain/WalletsDomainModule.kt | 6 + .../converter/WalletIconUMConverter.kt | 55 + .../com/tangem/core/ui/ds/image/DeviceIcon.kt | 202 +++ .../tangem/core/ui/ds/image/DeviceIconUM.kt | 24 + .../ui/ds/image/WalletIconVectorBuilders.kt | 1131 +++++++++++++++++ .../com/tangem/core/ui/res/TangemColors2.kt | 4 + .../tangem/core/ui/res/TangemThemeRedesign.kt | 2 + .../ui/src/main/res/drawable/ic_shield_24.xml | 5 + .../domain/models/wallet/UserWalletIcon.kt | 21 + .../wallets/usecase/GetWalletIconUseCase.kt | 242 ++++ .../wallet/child/wallet/model/WalletModel.kt | 7 + .../preview/WalletBalancePreview.kt | 4 + .../wallet/domain/WalletImageResolver.kt | 1 + .../wallet/state/model/WalletBalanceUM.kt | 7 + .../transformers/AddWalletTransformer.kt | 3 + .../InitializeWalletsTransformer.kt | 6 + .../ReinitializeNewWalletTransformer.kt | 3 + .../ReinitializeWalletTransformer.kt | 3 + .../SetTokenListErrorTransformer.kt | 1 + .../transformers/UnlockWalletTransformer.kt | 3 + .../MultiWalletBalanceUMTransformer.kt | 3 + .../state/utils/WalletLoadingStateFactory.kt | 5 + .../ui/components/common/WalletBalance.kt | 14 +- 23 files changed, 1741 insertions(+), 11 deletions(-) create mode 100644 common/ui/src/main/java/com/tangem/common/ui/userwallet/converter/WalletIconUMConverter.kt create mode 100644 core/ui/src/main/java/com/tangem/core/ui/ds/image/DeviceIcon.kt create mode 100644 core/ui/src/main/java/com/tangem/core/ui/ds/image/DeviceIconUM.kt create mode 100644 core/ui/src/main/java/com/tangem/core/ui/ds/image/WalletIconVectorBuilders.kt create mode 100644 core/ui/src/main/res/drawable/ic_shield_24.xml create mode 100644 domain/models/src/main/kotlin/com/tangem/domain/models/wallet/UserWalletIcon.kt create mode 100644 domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletIconUseCase.kt diff --git a/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt index 5e55ebdd54..c63293cda2 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt @@ -66,6 +66,12 @@ internal object WalletsDomainModule { return GetUserWalletUseCase(userWalletsListRepository = userWalletsListRepository) } + @Provides + @Singleton + fun provideGetWalletIconUseCase(walletsRepository: WalletsRepository): GetWalletIconUseCase { + return GetWalletIconUseCase(walletsRepository = walletsRepository) + } + @Provides @Singleton fun providesGetSelectedWalletSyncUseCase( diff --git a/common/ui/src/main/java/com/tangem/common/ui/userwallet/converter/WalletIconUMConverter.kt b/common/ui/src/main/java/com/tangem/common/ui/userwallet/converter/WalletIconUMConverter.kt new file mode 100644 index 0000000000..0a7afcbb8d --- /dev/null +++ b/common/ui/src/main/java/com/tangem/common/ui/userwallet/converter/WalletIconUMConverter.kt @@ -0,0 +1,55 @@ +package com.tangem.common.ui.userwallet.converter + +import androidx.compose.ui.graphics.Color +import androidx.core.graphics.toColorInt +import com.tangem.core.ui.ds.image.DeviceIconUM +import com.tangem.domain.models.wallet.UserWalletIcon +import com.tangem.utils.converter.Converter +import javax.inject.Inject + +/** + * Converter for mapping [UserWalletIcon] to [DeviceIconUM], + * which is used for displaying the wallet icon in the UI. + */ +class WalletIconUMConverter @Inject constructor() : Converter { + + override fun convert(value: UserWalletIcon): DeviceIconUM = with(value) { + fun String.parseHexColor(): Color = try { + Color(this.toColorInt()) + } catch (_: IllegalArgumentException) { + Color.Unspecified + } + + return when (this) { + UserWalletIcon.Hot -> DeviceIconUM.Mobile + is UserWalletIcon.Stub -> + DeviceIconUM.Stub(cardsCount = this.cardsCount) + is UserWalletIcon.Default -> if (isRing) { + DeviceIconUM.Ring( + mainColor = Color.Unspecified, + cardColor = Color.Unspecified, + secondCardColor = if (cardsCount > 2) Color.Unspecified else null, + ) + } else { + DeviceIconUM.Card( + mainColor = Color.Unspecified, + secondColor = if (cardsCount > 1) Color.Unspecified else null, + thirdColor = if (cardsCount > 2) Color.Unspecified else null, + ) + } + is UserWalletIcon.Colored -> if (isRing) { + DeviceIconUM.Ring( + mainColor = mainColor.parseHexColor(), + cardColor = secondColor?.parseHexColor(), + secondCardColor = thirdColor?.parseHexColor(), + ) + } else { + DeviceIconUM.Card( + mainColor = mainColor.parseHexColor(), + secondColor = secondColor?.parseHexColor(), + thirdColor = thirdColor?.parseHexColor(), + ) + } + } + } +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds/image/DeviceIcon.kt b/core/ui/src/main/java/com/tangem/core/ui/ds/image/DeviceIcon.kt new file mode 100644 index 0000000000..6d6d6f046d --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/ds/image/DeviceIcon.kt @@ -0,0 +1,202 @@ +package com.tangem.core.ui.ds.image + +import android.content.res.Configuration +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.takeOrElse +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 com.tangem.core.ui.R +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreviewRedesign + +/** + * Composable function for displaying a wallet icon based on the provided [DeviceIconUM] state. + * + * The icon can represent different types of devices, such as cards, rings, stubs, or mobile wallet, + * with customizable colors and styles. + * + * @param state The state of the device icon, which determines its appearance. + * @param modifier Optional [Modifier] for styling the composable. + */ +@Composable +fun TangemDeviceIcon(state: DeviceIconUM, modifier: Modifier = Modifier) { + when (state) { + is DeviceIconUM.Card -> DeviceIcon( + modifier = modifier, + isRing = false, + mainColor = state.mainColor, + secondColor = state.secondColor, + thirdColor = state.thirdColor, + tColor = null, + ) + is DeviceIconUM.Ring -> DeviceIcon( + modifier = modifier, + isRing = true, + mainColor = state.mainColor, + secondColor = state.cardColor, + thirdColor = state.secondCardColor, + tColor = null, + ) + is DeviceIconUM.Stub -> DeviceIcon( + modifier = modifier, + isRing = false, + mainColor = Color.Unspecified, + secondColor = Color.Unspecified.takeIf { state.cardsCount > 1 }, + thirdColor = Color.Unspecified.takeIf { state.cardsCount > 2 }, + tColor = TangemTheme.colors2.graphic.neutral.secondary, + ) + DeviceIconUM.Mobile -> Icon( + modifier = modifier, + imageVector = ImageVector.vectorResource(R.drawable.ic_shield_24), + contentDescription = null, + tint = TangemTheme.colors2.graphic.status.attention, + ) + } +} + +@Composable +private fun DeviceIcon( + isRing: Boolean, + mainColor: Color, + secondColor: Color?, + thirdColor: Color?, + tColor: Color?, + modifier: Modifier = Modifier, +) { + val main = mainColor.takeOrElse { TangemTheme.colors2.graphic.neutral.tertiaryConstant } + val second = secondColor?.takeOrElse { TangemTheme.colors2.graphic.neutral.tertiaryConstant } + val third = thirdColor?.takeOrElse { TangemTheme.colors2.graphic.neutral.tertiaryConstant } + val borderColor = TangemTheme.colors2.border.walletIcon + + val imageVector = remember(isRing, main, second, third, borderColor, tColor) { + when { + isRing && second != null && third != null -> WalletIconVectorBuilders.buildRingWithCard2( + mainColor = main, + cardColor = second, + secondCardColor = third, + borderColor = borderColor, + ) + !isRing && second != null && third != null -> WalletIconVectorBuilders.buildCard3( + mainColor = main, + secondColor = second, + thirdColor = third, + tColor = tColor, + borderColor = borderColor, + ) + isRing && second != null -> WalletIconVectorBuilders.buildRingWithCard( + mainColor = main, + cardColor = second, + borderColor = borderColor, + ) + !isRing && second != null -> WalletIconVectorBuilders.buildCard2( + mainColor = main, + secondColor = second, + tColor = tColor, + borderColor = borderColor, + ) + isRing -> WalletIconVectorBuilders.buildRing( + mainColor = main, + borderColor = borderColor, + ) + else -> WalletIconVectorBuilders.buildCard( + mainColor = main, + borderColor = borderColor, + tColor = tColor, + ) + } + } + + Icon( + imageVector = imageVector, + contentDescription = null, + modifier = modifier, + tint = Color.Unspecified, + ) +} + +// region Preview + +private val previewCardBlue + get() = Color(0xFF1C5FBF) +private val previewCardGold + get() = Color(0xFFD4A017) +private val previewCardPurple + get() = Color(0xFF7B2FBE) +private val previewRingGreen + get() = Color(0xFF2ECC71) + +private val previewStates: List> + get() = listOf( + "Card 1" to DeviceIconUM.Card( + mainColor = previewCardBlue, + secondColor = null, + ), + "Card 2" to DeviceIconUM.Card( + mainColor = previewCardBlue, + secondColor = previewCardGold, + ), + "Card 3" to DeviceIconUM.Card( + mainColor = previewCardBlue, + secondColor = previewCardGold, + thirdColor = previewCardPurple, + ), + "Ring" to DeviceIconUM.Ring( + mainColor = previewRingGreen, + ), + "Ring + Card" to DeviceIconUM.Ring( + mainColor = previewRingGreen, + cardColor = previewCardBlue, + ), + "Ring + 2 Cards" to DeviceIconUM.Ring( + mainColor = previewRingGreen, + cardColor = previewCardBlue, + secondCardColor = previewCardGold, + ), + "Stub 1" to DeviceIconUM.Stub(cardsCount = 1), + "Stub 2" to DeviceIconUM.Stub(cardsCount = 2), + "Stub 3" to DeviceIconUM.Stub(cardsCount = 3), + "Mobile" to DeviceIconUM.Mobile, + ) + +@Composable +@Preview(showBackground = true, widthDp = 360) +@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) +private fun TangemDeviceIcon_Preview() { + TangemThemePreviewRedesign { + Column( + modifier = Modifier + .background(TangemTheme.colors.background.primary) + .padding(16.dp), + verticalArrangement = Arrangement.spacedBy(12.dp), + ) { + previewStates.forEach { (label, state) -> + Row( + horizontalArrangement = Arrangement.spacedBy(12.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + TangemDeviceIcon( + modifier = Modifier.size(40.dp), + state = state, + ) + Text( + text = label, + style = TangemTheme.typography.body1, + color = TangemTheme.colors.text.primary1, + ) + } + } + } + } +} + +// endregion \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds/image/DeviceIconUM.kt b/core/ui/src/main/java/com/tangem/core/ui/ds/image/DeviceIconUM.kt new file mode 100644 index 0000000000..0007a0f1a8 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/ds/image/DeviceIconUM.kt @@ -0,0 +1,24 @@ +package com.tangem.core.ui.ds.image + +import androidx.compose.runtime.Immutable +import androidx.compose.ui.graphics.Color + +@Immutable +sealed interface DeviceIconUM { + + data class Card( + val mainColor: Color, + val secondColor: Color?, + val thirdColor: Color? = null, + ) : DeviceIconUM + + data class Ring( + val mainColor: Color = Color.Unspecified, + val cardColor: Color? = null, + val secondCardColor: Color? = null, + ) : DeviceIconUM + + data class Stub(val cardsCount: Int) : DeviceIconUM + + data object Mobile : DeviceIconUM +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds/image/WalletIconVectorBuilders.kt b/core/ui/src/main/java/com/tangem/core/ui/ds/image/WalletIconVectorBuilders.kt new file mode 100644 index 0000000000..993fdf132f --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/ds/image/WalletIconVectorBuilders.kt @@ -0,0 +1,1131 @@ +@file:Suppress("MagicNumber", "LargeClass", "LongMethod", "NamedArguments") +package com.tangem.core.ui.ds.image + +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.PathFillType +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.graphics.vector.PathData +import androidx.compose.ui.graphics.vector.group +import androidx.compose.ui.graphics.vector.path +import androidx.compose.ui.unit.dp + +/** + * Builders for creating [ImageVector] instances for wallet icons. + * These builders are used to generate the vector graphics for the wallet icons + * + * Generated based on SVG paths. + */ +internal object WalletIconVectorBuilders { + + fun buildRing(mainColor: Color, borderColor: Color): ImageVector = ImageVector.Builder( + name = "Ring", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f, + ).apply { + path( + fill = SolidColor(mainColor), + pathFillType = PathFillType.EvenOdd, + ) { + moveTo(10.333f, 3f) + curveTo(7.94f, 3f, 6f, 7.029f, 6f, 12f) + curveTo(6f, 16.971f, 7.94f, 21f, 10.333f, 21f) + horizontalLineTo(14.667f) + curveTo(17.06f, 21f, 19f, 16.971f, 19f, 12f) + curveTo(19f, 7.029f, 17.06f, 3f, 14.667f, 3f) + horizontalLineTo(10.333f) + close() + moveTo(10.574f, 3.9f) + curveTo(16.403f, 3.9f, 16.498f, 20.1f, 10.574f, 20.1f) + curveTo(10.541f, 20.1f, 10.539f, 20.052f, 10.571f, 20.045f) + curveTo(11.037f, 19.937f, 11.478f, 19.675f, 11.883f, 19.285f) + curveTo(11.961f, 19.21f, 11.96f, 19.087f, 11.889f, 19.005f) + curveTo(10.671f, 17.602f, 9.852f, 14.99f, 9.852f, 12f) + curveTo(9.852f, 9.009f, 10.671f, 6.397f, 11.89f, 4.994f) + curveTo(11.961f, 4.913f, 11.961f, 4.789f, 11.883f, 4.714f) + curveTo(11.479f, 4.324f, 11.037f, 4.062f, 10.571f, 3.955f) + curveTo(10.539f, 3.948f, 10.541f, 3.9f, 10.574f, 3.9f) + close() + } + path( + stroke = SolidColor(borderColor), + strokeLineWidth = 1f, + ) { + moveTo(14.667f, 3.5f) + horizontalLineTo(11.398f) + curveTo(12.705f, 3.818f, 13.671f, 4.88f, 14.316f, 6.213f) + curveTo(15.094f, 7.818f, 15.475f, 9.923f, 15.481f, 11.998f) + curveTo(15.488f, 14.073f, 15.118f, 16.179f, 14.343f, 17.786f) + curveTo(13.698f, 19.122f, 12.728f, 20.183f, 11.407f, 20.5f) + horizontalLineTo(14.667f) + curveTo(15.562f, 20.5f, 16.518f, 19.73f, 17.28f, 18.147f) + curveTo(18.025f, 16.6f, 18.5f, 14.427f, 18.5f, 12f) + curveTo(18.5f, 9.573f, 18.025f, 7.4f, 17.28f, 5.853f) + curveTo(16.518f, 4.27f, 15.562f, 3.5f, 14.667f, 3.5f) + close() + moveTo(10.264f, 3.503f) + curveTo(9.389f, 3.542f, 8.462f, 4.311f, 7.72f, 5.853f) + curveTo(6.975f, 7.4f, 6.5f, 9.573f, 6.5f, 12f) + curveTo(6.5f, 14.427f, 6.975f, 16.6f, 7.72f, 18.147f) + curveTo(8.462f, 19.688f, 9.388f, 20.457f, 10.263f, 20.496f) + curveTo(10.238f, 20.478f, 10.212f, 20.458f, 10.19f, 20.435f) + curveTo(10.094f, 20.332f, 10.054f, 20.208f, 10.049f, 20.101f) + curveTo(10.038f, 19.888f, 10.168f, 19.625f, 10.459f, 19.558f) + curveTo(10.748f, 19.491f, 11.04f, 19.341f, 11.329f, 19.106f) + curveTo(10.111f, 17.543f, 9.352f, 14.913f, 9.352f, 12f) + curveTo(9.352f, 9.086f, 10.111f, 6.455f, 11.33f, 4.892f) + curveTo(11.041f, 4.657f, 10.748f, 4.509f, 10.459f, 4.442f) + curveTo(10.171f, 4.376f, 10.038f, 4.115f, 10.049f, 3.898f) + curveTo(10.055f, 3.79f, 10.096f, 3.666f, 10.192f, 3.563f) + curveTo(10.214f, 3.54f, 10.239f, 3.521f, 10.264f, 3.503f) + close() + } + }.build() + + fun buildRingWithCard(mainColor: Color, cardColor: Color, borderColor: Color): ImageVector = ImageVector.Builder( + name = "RingWithCard", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f, + ).apply { + path( + fill = SolidColor(mainColor), + pathFillType = PathFillType.EvenOdd, + ) { + moveTo(4.667f, 10f) + curveTo(3.194f, 10f, 2f, 12.462f, 2f, 15.5f) + curveTo(2f, 18.538f, 3.194f, 21f, 4.667f, 21f) + horizontalLineTo(7.333f) + curveTo(8.806f, 21f, 10f, 18.538f, 10f, 15.5f) + curveTo(10f, 12.462f, 8.806f, 10f, 7.333f, 10f) + horizontalLineTo(4.667f) + close() + moveTo(4.815f, 10.55f) + curveTo(8.402f, 10.55f, 8.46f, 20.45f, 4.815f, 20.45f) + curveTo(4.795f, 20.45f, 4.793f, 20.421f, 4.813f, 20.416f) + curveTo(5.099f, 20.351f, 5.371f, 20.19f, 5.62f, 19.952f) + curveTo(5.668f, 19.906f, 5.668f, 19.83f, 5.624f, 19.781f) + curveTo(4.874f, 18.923f, 4.37f, 17.327f, 4.37f, 15.5f) + curveTo(4.37f, 13.672f, 4.875f, 12.076f, 5.624f, 11.219f) + curveTo(5.668f, 11.169f, 5.668f, 11.093f, 5.62f, 11.047f) + curveTo(5.371f, 10.809f, 5.1f, 10.649f, 4.813f, 10.584f) + curveTo(4.793f, 10.579f, 4.795f, 10.55f, 4.815f, 10.55f) + close() + } + path( + stroke = SolidColor(borderColor), + strokeLineWidth = 1f, + ) { + moveTo(7.333f, 10.5f) + horizontalLineTo(6.192f) + curveTo(6.657f, 10.835f, 7.021f, 11.328f, 7.29f, 11.878f) + curveTo(7.785f, 12.893f, 8.023f, 14.21f, 8.027f, 15.498f) + curveTo(8.031f, 16.786f, 7.801f, 18.106f, 7.307f, 19.122f) + curveTo(7.038f, 19.674f, 6.674f, 20.166f, 6.207f, 20.5f) + horizontalLineTo(7.333f) + curveTo(7.77f, 20.5f, 8.31f, 20.119f, 8.77f, 19.171f) + curveTo(9.212f, 18.257f, 9.5f, 16.96f, 9.5f, 15.5f) + curveTo(9.5f, 14.04f, 9.212f, 12.743f, 8.77f, 11.829f) + curveTo(8.31f, 10.881f, 7.77f, 10.5f, 7.333f, 10.5f) + close() + moveTo(4.302f, 10.584f) + curveTo(3.95f, 10.742f, 3.568f, 11.132f, 3.23f, 11.829f) + curveTo(2.788f, 12.743f, 2.5f, 14.04f, 2.5f, 15.5f) + curveTo(2.5f, 16.96f, 2.788f, 18.257f, 3.23f, 19.171f) + curveTo(3.568f, 19.868f, 3.95f, 20.257f, 4.302f, 20.415f) + curveTo(4.31f, 20.216f, 4.436f, 19.99f, 4.701f, 19.929f) + curveTo(4.8f, 19.906f, 4.902f, 19.863f, 5.008f, 19.798f) + curveTo(4.295f, 18.785f, 3.87f, 17.209f, 3.87f, 15.5f) + curveTo(3.87f, 13.791f, 4.294f, 12.215f, 5.007f, 11.201f) + curveTo(4.901f, 11.137f, 4.799f, 11.094f, 4.701f, 11.071f) + curveTo(4.438f, 11.011f, 4.31f, 10.785f, 4.302f, 10.584f) + close() + } + path(fill = SolidColor(cardColor)) { + moveTo(16.2f, 4.998f) + curveTo(17.88f, 4.998f, 18.721f, 4.997f, 19.362f, 5.324f) + curveTo(19.927f, 5.612f, 20.385f, 6.071f, 20.673f, 6.636f) + curveTo(21f, 7.277f, 21f, 8.118f, 21f, 9.798f) + verticalLineTo(14.197f) + curveTo(21f, 15.877f, 21f, 16.718f, 20.673f, 17.359f) + curveTo(20.385f, 17.924f, 19.927f, 18.383f, 19.362f, 18.671f) + curveTo(18.721f, 18.998f, 17.88f, 18.998f, 16.2f, 18.998f) + horizontalLineTo(10.509f) + curveTo(10.851f, 17.983f, 11.044f, 16.778f, 11.044f, 15.5f) + curveTo(11.044f, 13.809f, 10.707f, 12.245f, 10.132f, 11.081f) + curveTo(9.58f, 9.963f, 8.688f, 9f, 7.488f, 9f) + horizontalLineTo(4.6f) + curveTo(3.984f, 9f, 3.449f, 9.254f, 3f, 9.652f) + curveTo(3f, 8.068f, 3.01f, 7.259f, 3.327f, 6.636f) + curveTo(3.615f, 6.071f, 4.073f, 5.612f, 4.638f, 5.324f) + curveTo(5.279f, 4.997f, 6.12f, 4.998f, 7.8f, 4.998f) + horizontalLineTo(16.2f) + close() + } + group( + clipPathData = PathData { + moveTo(16.2f, 4.998f) + curveTo(17.88f, 4.998f, 18.721f, 4.997f, 19.362f, 5.324f) + curveTo(19.927f, 5.612f, 20.385f, 6.071f, 20.673f, 6.636f) + curveTo(21f, 7.277f, 21f, 8.118f, 21f, 9.798f) + verticalLineTo(14.197f) + curveTo(21f, 15.877f, 21f, 16.718f, 20.673f, 17.359f) + curveTo(20.385f, 17.924f, 19.927f, 18.383f, 19.362f, 18.671f) + curveTo(18.721f, 18.998f, 17.88f, 18.998f, 16.2f, 18.998f) + horizontalLineTo(10.509f) + curveTo(10.851f, 17.983f, 11.044f, 16.778f, 11.044f, 15.5f) + curveTo(11.044f, 13.809f, 10.707f, 12.245f, 10.132f, 11.081f) + curveTo(9.58f, 9.963f, 8.688f, 9f, 7.488f, 9f) + horizontalLineTo(4.6f) + curveTo(3.984f, 9f, 3.449f, 9.254f, 3f, 9.652f) + curveTo(3f, 8.068f, 3.01f, 7.259f, 3.327f, 6.636f) + curveTo(3.615f, 6.071f, 4.073f, 5.612f, 4.638f, 5.324f) + curveTo(5.279f, 4.997f, 6.12f, 4.998f, 7.8f, 4.998f) + horizontalLineTo(16.2f) + close() + }, + ) { + path( + fill = SolidColor(borderColor), + ) { + moveTo(16.2f, 4.998f) + verticalLineTo(3.998f) + verticalLineTo(4.998f) + close() + moveTo(19.362f, 5.324f) + lineTo(19.816f, 4.433f) + lineTo(19.816f, 4.433f) + lineTo(19.362f, 5.324f) + close() + moveTo(20.673f, 6.636f) + lineTo(21.564f, 6.182f) + lineTo(21.564f, 6.182f) + lineTo(20.673f, 6.636f) + close() + moveTo(20.673f, 17.359f) + lineTo(21.564f, 17.813f) + lineTo(21.564f, 17.813f) + lineTo(20.673f, 17.359f) + close() + moveTo(19.362f, 18.671f) + lineTo(19.816f, 19.562f) + lineTo(19.816f, 19.562f) + lineTo(19.362f, 18.671f) + close() + moveTo(16.2f, 18.998f) + verticalLineTo(19.998f) + verticalLineTo(18.998f) + close() + moveTo(10.509f, 18.998f) + lineTo(9.561f, 18.679f) + lineTo(9.116f, 19.998f) + horizontalLineTo(10.509f) + verticalLineTo(18.998f) + close() + moveTo(10.132f, 11.081f) + lineTo(11.028f, 10.638f) + lineTo(11.028f, 10.638f) + lineTo(10.132f, 11.081f) + close() + moveTo(7.488f, 9f) + lineTo(7.488f, 8f) + horizontalLineTo(7.488f) + verticalLineTo(9f) + close() + moveTo(4.6f, 9f) + verticalLineTo(8f) + horizontalLineTo(4.6f) + lineTo(4.6f, 9f) + close() + moveTo(3f, 9.652f) + lineTo(2f, 9.652f) + lineTo(2f, 11.875f) + lineTo(3.663f, 10.401f) + lineTo(3f, 9.652f) + close() + moveTo(3.327f, 6.636f) + lineTo(2.436f, 6.182f) + lineTo(2.436f, 6.182f) + lineTo(3.327f, 6.636f) + close() + moveTo(4.638f, 5.324f) + lineTo(4.184f, 4.433f) + lineTo(4.184f, 4.433f) + lineTo(4.638f, 5.324f) + close() + moveTo(7.8f, 4.998f) + verticalLineTo(3.998f) + verticalLineTo(4.998f) + close() + moveTo(16.2f, 4.998f) + verticalLineTo(5.998f) + curveTo(17.057f, 5.998f, 17.639f, 5.999f, 18.09f, 6.035f) + curveTo(18.528f, 6.071f, 18.752f, 6.136f, 18.908f, 6.215f) + lineTo(19.362f, 5.324f) + lineTo(19.816f, 4.433f) + curveTo(19.331f, 4.186f, 18.814f, 4.087f, 18.252f, 4.042f) + curveTo(17.701f, 3.997f, 17.024f, 3.998f, 16.2f, 3.998f) + verticalLineTo(4.998f) + close() + moveTo(19.362f, 5.324f) + lineTo(18.908f, 6.215f) + curveTo(19.284f, 6.407f, 19.59f, 6.713f, 19.782f, 7.09f) + lineTo(20.673f, 6.636f) + lineTo(21.564f, 6.182f) + curveTo(21.181f, 5.43f, 20.569f, 4.817f, 19.816f, 4.433f) + lineTo(19.362f, 5.324f) + close() + moveTo(20.673f, 6.636f) + lineTo(19.782f, 7.09f) + curveTo(19.861f, 7.246f, 19.927f, 7.47f, 19.962f, 7.909f) + curveTo(19.999f, 8.359f, 20f, 8.941f, 20f, 9.798f) + horizontalLineTo(21f) + horizontalLineTo(22f) + curveTo(22f, 8.974f, 22.001f, 8.296f, 21.956f, 7.746f) + curveTo(21.91f, 7.184f, 21.811f, 6.667f, 21.564f, 6.182f) + lineTo(20.673f, 6.636f) + close() + moveTo(21f, 9.798f) + horizontalLineTo(20f) + verticalLineTo(14.197f) + horizontalLineTo(21f) + horizontalLineTo(22f) + verticalLineTo(9.798f) + horizontalLineTo(21f) + close() + moveTo(21f, 14.197f) + horizontalLineTo(20f) + curveTo(20f, 15.054f, 19.999f, 15.636f, 19.962f, 16.086f) + curveTo(19.927f, 16.525f, 19.861f, 16.749f, 19.782f, 16.905f) + lineTo(20.673f, 17.359f) + lineTo(21.564f, 17.813f) + curveTo(21.811f, 17.328f, 21.91f, 16.811f, 21.956f, 16.249f) + curveTo(22.001f, 15.699f, 22f, 15.021f, 22f, 14.197f) + horizontalLineTo(21f) + close() + moveTo(20.673f, 17.359f) + lineTo(19.782f, 16.905f) + curveTo(19.59f, 17.282f, 19.284f, 17.588f, 18.908f, 17.78f) + lineTo(19.362f, 18.671f) + lineTo(19.816f, 19.562f) + curveTo(20.569f, 19.178f, 21.181f, 18.565f, 21.564f, 17.813f) + lineTo(20.673f, 17.359f) + close() + moveTo(19.362f, 18.671f) + lineTo(18.908f, 17.78f) + curveTo(18.752f, 17.86f, 18.528f, 17.925f, 18.089f, 17.96f) + curveTo(17.639f, 17.997f, 17.057f, 17.998f, 16.2f, 17.998f) + verticalLineTo(18.998f) + verticalLineTo(19.998f) + curveTo(17.024f, 19.998f, 17.702f, 19.999f, 18.252f, 19.954f) + curveTo(18.814f, 19.908f, 19.331f, 19.809f, 19.816f, 19.562f) + lineTo(19.362f, 18.671f) + close() + moveTo(16.2f, 18.998f) + verticalLineTo(17.998f) + horizontalLineTo(10.509f) + verticalLineTo(18.998f) + verticalLineTo(19.998f) + horizontalLineTo(16.2f) + verticalLineTo(18.998f) + close() + moveTo(10.509f, 18.998f) + lineTo(11.456f, 19.317f) + curveTo(11.837f, 18.188f, 12.044f, 16.874f, 12.044f, 15.5f) + horizontalLineTo(11.044f) + horizontalLineTo(10.044f) + curveTo(10.044f, 16.682f, 9.865f, 17.778f, 9.561f, 18.679f) + lineTo(10.509f, 18.998f) + close() + moveTo(11.044f, 15.5f) + horizontalLineTo(12.044f) + curveTo(12.044f, 13.689f, 11.685f, 11.968f, 11.028f, 10.638f) + lineTo(10.132f, 11.081f) + lineTo(9.235f, 11.524f) + curveTo(9.729f, 12.523f, 10.044f, 13.929f, 10.044f, 15.5f) + horizontalLineTo(11.044f) + close() + moveTo(10.132f, 11.081f) + lineTo(11.028f, 10.638f) + curveTo(10.428f, 9.423f, 9.28f, 8f, 7.488f, 8f) + lineTo(7.488f, 9f) + lineTo(7.488f, 10f) + curveTo(8.095f, 10f, 8.731f, 10.503f, 9.235f, 11.524f) + lineTo(10.132f, 11.081f) + close() + moveTo(7.488f, 9f) + verticalLineTo(8f) + horizontalLineTo(4.6f) + verticalLineTo(9f) + verticalLineTo(10f) + horizontalLineTo(7.488f) + verticalLineTo(9f) + close() + moveTo(4.6f, 9f) + lineTo(4.6f, 8f) + curveTo(3.687f, 8f, 2.925f, 8.382f, 2.337f, 8.904f) + lineTo(3f, 9.652f) + lineTo(3.663f, 10.401f) + curveTo(3.973f, 10.126f, 4.281f, 10f, 4.6f, 10f) + lineTo(4.6f, 9f) + close() + moveTo(3f, 9.652f) + lineTo(4f, 9.653f) + curveTo(4f, 8.847f, 4.003f, 8.297f, 4.041f, 7.871f) + curveTo(4.077f, 7.457f, 4.141f, 7.241f, 4.218f, 7.09f) + lineTo(3.327f, 6.636f) + lineTo(2.436f, 6.182f) + curveTo(2.196f, 6.653f, 2.096f, 7.153f, 2.049f, 7.696f) + curveTo(2.002f, 8.227f, 2f, 8.874f, 2f, 9.652f) + lineTo(3f, 9.652f) + close() + moveTo(3.327f, 6.636f) + lineTo(4.218f, 7.09f) + curveTo(4.41f, 6.713f, 4.716f, 6.407f, 5.092f, 6.215f) + lineTo(4.638f, 5.324f) + lineTo(4.184f, 4.433f) + curveTo(3.43f, 4.817f, 2.819f, 5.43f, 2.436f, 6.182f) + lineTo(3.327f, 6.636f) + close() + moveTo(4.638f, 5.324f) + lineTo(5.092f, 6.215f) + curveTo(5.248f, 6.136f, 5.472f, 6.071f, 5.91f, 6.035f) + curveTo(6.361f, 5.999f, 6.943f, 5.998f, 7.8f, 5.998f) + verticalLineTo(4.998f) + verticalLineTo(3.998f) + curveTo(6.977f, 3.998f, 6.299f, 3.997f, 5.748f, 4.042f) + curveTo(5.186f, 4.087f, 4.669f, 4.186f, 4.184f, 4.433f) + lineTo(4.638f, 5.324f) + close() + moveTo(7.8f, 4.998f) + verticalLineTo(5.998f) + horizontalLineTo(16.2f) + verticalLineTo(4.998f) + verticalLineTo(3.998f) + horizontalLineTo(7.8f) + verticalLineTo(4.998f) + close() + } + } + }.build() + + fun buildRingWithCard2( + mainColor: Color, + cardColor: Color, + secondCardColor: Color, + borderColor: Color, + ): ImageVector = ImageVector.Builder( + name = "RingTwoCards", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f, + ).apply { + path( + fill = SolidColor(mainColor), + pathFillType = PathFillType.EvenOdd, + ) { + moveTo(3.667f, 10f) + curveTo(2.194f, 10f, 1f, 12.462f, 1f, 15.5f) + curveTo(1f, 18.538f, 2.194f, 21f, 3.667f, 21f) + horizontalLineTo(6.333f) + curveTo(7.806f, 21f, 9f, 18.538f, 9f, 15.5f) + curveTo(9f, 12.462f, 7.806f, 10f, 6.333f, 10f) + horizontalLineTo(3.667f) + close() + moveTo(3.815f, 10.55f) + curveTo(7.402f, 10.55f, 7.46f, 20.45f, 3.815f, 20.45f) + curveTo(3.795f, 20.45f, 3.793f, 20.421f, 3.813f, 20.416f) + curveTo(4.099f, 20.351f, 4.371f, 20.19f, 4.62f, 19.952f) + curveTo(4.668f, 19.906f, 4.668f, 19.83f, 4.624f, 19.781f) + curveTo(3.874f, 18.923f, 3.37f, 17.327f, 3.37f, 15.5f) + curveTo(3.37f, 13.672f, 3.875f, 12.076f, 4.624f, 11.219f) + curveTo(4.668f, 11.169f, 4.668f, 11.093f, 4.62f, 11.047f) + curveTo(4.371f, 10.809f, 4.1f, 10.649f, 3.813f, 10.584f) + curveTo(3.793f, 10.579f, 3.795f, 10.55f, 3.815f, 10.55f) + close() + } + path( + stroke = SolidColor(borderColor), + strokeLineWidth = 1f, + ) { + moveTo(6.333f, 10.5f) + horizontalLineTo(5.192f) + curveTo(5.657f, 10.835f, 6.021f, 11.328f, 6.29f, 11.878f) + curveTo(6.785f, 12.893f, 7.023f, 14.21f, 7.027f, 15.498f) + curveTo(7.031f, 16.786f, 6.801f, 18.106f, 6.307f, 19.122f) + curveTo(6.038f, 19.674f, 5.674f, 20.166f, 5.207f, 20.5f) + horizontalLineTo(6.333f) + curveTo(6.77f, 20.5f, 7.31f, 20.119f, 7.77f, 19.171f) + curveTo(8.212f, 18.257f, 8.5f, 16.96f, 8.5f, 15.5f) + curveTo(8.5f, 14.04f, 8.212f, 12.743f, 7.77f, 11.829f) + curveTo(7.31f, 10.881f, 6.77f, 10.5f, 6.333f, 10.5f) + close() + moveTo(3.302f, 10.584f) + curveTo(2.95f, 10.742f, 2.568f, 11.132f, 2.23f, 11.829f) + curveTo(1.788f, 12.743f, 1.5f, 14.04f, 1.5f, 15.5f) + curveTo(1.5f, 16.96f, 1.788f, 18.257f, 2.23f, 19.171f) + curveTo(2.568f, 19.868f, 2.95f, 20.257f, 3.302f, 20.415f) + curveTo(3.31f, 20.216f, 3.436f, 19.99f, 3.701f, 19.929f) + curveTo(3.8f, 19.906f, 3.902f, 19.863f, 4.008f, 19.798f) + curveTo(3.295f, 18.785f, 2.87f, 17.209f, 2.87f, 15.5f) + curveTo(2.87f, 13.791f, 3.294f, 12.215f, 4.007f, 11.201f) + curveTo(3.901f, 11.137f, 3.799f, 11.094f, 3.701f, 11.071f) + curveTo(3.438f, 11.011f, 3.31f, 10.785f, 3.302f, 10.584f) + close() + } + path(fill = SolidColor(cardColor)) { + moveTo(15.2f, 4.998f) + curveTo(16.88f, 4.998f, 17.721f, 4.997f, 18.362f, 5.324f) + curveTo(18.927f, 5.612f, 19.385f, 6.071f, 19.673f, 6.636f) + curveTo(20f, 7.277f, 20f, 8.118f, 20f, 9.798f) + verticalLineTo(14.197f) + curveTo(20f, 15.877f, 20f, 16.718f, 19.673f, 17.359f) + curveTo(19.385f, 17.924f, 18.927f, 18.383f, 18.362f, 18.671f) + curveTo(17.721f, 18.998f, 16.88f, 18.998f, 15.2f, 18.998f) + horizontalLineTo(9.509f) + curveTo(9.851f, 17.983f, 10.044f, 16.778f, 10.044f, 15.5f) + curveTo(10.044f, 13.809f, 9.707f, 12.245f, 9.132f, 11.081f) + curveTo(8.58f, 9.963f, 7.688f, 9f, 6.488f, 9f) + horizontalLineTo(3.6f) + curveTo(2.984f, 9f, 2.449f, 9.254f, 2f, 9.652f) + curveTo(2f, 8.068f, 2.01f, 7.259f, 2.327f, 6.636f) + curveTo(2.615f, 6.071f, 3.073f, 5.612f, 3.638f, 5.324f) + curveTo(4.279f, 4.997f, 5.12f, 4.998f, 6.8f, 4.998f) + horizontalLineTo(15.2f) + close() + } + group( + clipPathData = PathData { + moveTo(15.2f, 4.998f) + curveTo(16.88f, 4.998f, 17.721f, 4.997f, 18.362f, 5.324f) + curveTo(18.927f, 5.612f, 19.385f, 6.071f, 19.673f, 6.636f) + curveTo(20f, 7.277f, 20f, 8.118f, 20f, 9.798f) + verticalLineTo(14.197f) + curveTo(20f, 15.877f, 20f, 16.718f, 19.673f, 17.359f) + curveTo(19.385f, 17.924f, 18.927f, 18.383f, 18.362f, 18.671f) + curveTo(17.721f, 18.998f, 16.88f, 18.998f, 15.2f, 18.998f) + horizontalLineTo(9.509f) + curveTo(9.851f, 17.983f, 10.044f, 16.778f, 10.044f, 15.5f) + curveTo(10.044f, 13.809f, 9.707f, 12.245f, 9.132f, 11.081f) + curveTo(8.58f, 9.963f, 7.688f, 9f, 6.488f, 9f) + horizontalLineTo(3.6f) + curveTo(2.984f, 9f, 2.449f, 9.254f, 2f, 9.652f) + curveTo(2f, 8.068f, 2.01f, 7.259f, 2.327f, 6.636f) + curveTo(2.615f, 6.071f, 3.073f, 5.612f, 3.638f, 5.324f) + curveTo(4.279f, 4.997f, 5.12f, 4.998f, 6.8f, 4.998f) + horizontalLineTo(15.2f) + close() + }, + ) { + path( + fill = SolidColor(secondCardColor), + fillAlpha = 0.1f, + ) { + moveTo(15.2f, 4.998f) + verticalLineTo(3.998f) + verticalLineTo(4.998f) + close() + moveTo(18.362f, 5.324f) + lineTo(18.816f, 4.433f) + lineTo(18.816f, 4.433f) + lineTo(18.362f, 5.324f) + close() + moveTo(19.673f, 6.636f) + lineTo(20.564f, 6.182f) + lineTo(20.564f, 6.182f) + lineTo(19.673f, 6.636f) + close() + moveTo(19.673f, 17.359f) + lineTo(20.564f, 17.813f) + lineTo(20.564f, 17.813f) + lineTo(19.673f, 17.359f) + close() + moveTo(18.362f, 18.671f) + lineTo(18.816f, 19.562f) + lineTo(18.816f, 19.562f) + lineTo(18.362f, 18.671f) + close() + moveTo(15.2f, 18.998f) + verticalLineTo(19.998f) + verticalLineTo(18.998f) + close() + moveTo(9.509f, 18.998f) + lineTo(8.561f, 18.679f) + lineTo(8.116f, 19.998f) + horizontalLineTo(9.509f) + verticalLineTo(18.998f) + close() + moveTo(9.132f, 11.081f) + lineTo(10.028f, 10.638f) + lineTo(10.028f, 10.638f) + lineTo(9.132f, 11.081f) + close() + moveTo(6.488f, 9f) + lineTo(6.488f, 8f) + horizontalLineTo(6.488f) + verticalLineTo(9f) + close() + moveTo(3.6f, 9f) + verticalLineTo(8f) + horizontalLineTo(3.6f) + lineTo(3.6f, 9f) + close() + moveTo(2f, 9.652f) + lineTo(1f, 9.652f) + lineTo(1f, 11.875f) + lineTo(2.663f, 10.401f) + lineTo(2f, 9.652f) + close() + moveTo(2.327f, 6.636f) + lineTo(1.436f, 6.182f) + lineTo(1.436f, 6.182f) + lineTo(2.327f, 6.636f) + close() + moveTo(3.638f, 5.324f) + lineTo(3.184f, 4.433f) + lineTo(3.184f, 4.433f) + lineTo(3.638f, 5.324f) + close() + moveTo(6.8f, 4.998f) + verticalLineTo(3.998f) + verticalLineTo(4.998f) + close() + moveTo(15.2f, 4.998f) + verticalLineTo(5.998f) + curveTo(16.057f, 5.998f, 16.639f, 5.999f, 17.09f, 6.035f) + curveTo(17.528f, 6.071f, 17.752f, 6.136f, 17.908f, 6.215f) + lineTo(18.362f, 5.324f) + lineTo(18.816f, 4.433f) + curveTo(18.331f, 4.186f, 17.814f, 4.087f, 17.252f, 4.042f) + curveTo(16.701f, 3.997f, 16.024f, 3.998f, 15.2f, 3.998f) + verticalLineTo(4.998f) + close() + moveTo(18.362f, 5.324f) + lineTo(17.908f, 6.215f) + curveTo(18.284f, 6.407f, 18.59f, 6.713f, 18.782f, 7.09f) + lineTo(19.673f, 6.636f) + lineTo(20.564f, 6.182f) + curveTo(20.181f, 5.43f, 19.569f, 4.817f, 18.816f, 4.433f) + lineTo(18.362f, 5.324f) + close() + moveTo(19.673f, 6.636f) + lineTo(18.782f, 7.09f) + curveTo(18.861f, 7.246f, 18.927f, 7.47f, 18.962f, 7.909f) + curveTo(18.999f, 8.359f, 19f, 8.941f, 19f, 9.798f) + horizontalLineTo(20f) + horizontalLineTo(21f) + curveTo(21f, 8.974f, 21.001f, 8.296f, 20.956f, 7.746f) + curveTo(20.91f, 7.184f, 20.811f, 6.667f, 20.564f, 6.182f) + lineTo(19.673f, 6.636f) + close() + moveTo(20f, 9.798f) + horizontalLineTo(19f) + verticalLineTo(14.197f) + horizontalLineTo(20f) + horizontalLineTo(21f) + verticalLineTo(9.798f) + horizontalLineTo(20f) + close() + moveTo(20f, 14.197f) + horizontalLineTo(19f) + curveTo(19f, 15.054f, 18.999f, 15.636f, 18.962f, 16.086f) + curveTo(18.927f, 16.525f, 18.861f, 16.749f, 18.782f, 16.905f) + lineTo(19.673f, 17.359f) + lineTo(20.564f, 17.813f) + curveTo(20.811f, 17.328f, 20.91f, 16.811f, 20.956f, 16.249f) + curveTo(21.001f, 15.699f, 21f, 15.021f, 21f, 14.197f) + horizontalLineTo(20f) + close() + moveTo(19.673f, 17.359f) + lineTo(18.782f, 16.905f) + curveTo(18.59f, 17.282f, 18.284f, 17.588f, 17.908f, 17.78f) + lineTo(18.362f, 18.671f) + lineTo(18.816f, 19.562f) + curveTo(19.569f, 19.178f, 20.181f, 18.565f, 20.564f, 17.813f) + lineTo(19.673f, 17.359f) + close() + moveTo(18.362f, 18.671f) + lineTo(17.908f, 17.78f) + curveTo(17.752f, 17.86f, 17.528f, 17.925f, 17.089f, 17.96f) + curveTo(16.639f, 17.997f, 16.057f, 17.998f, 15.2f, 17.998f) + verticalLineTo(18.998f) + verticalLineTo(19.998f) + curveTo(16.024f, 19.998f, 16.702f, 19.999f, 17.252f, 19.954f) + curveTo(17.814f, 19.908f, 18.331f, 19.809f, 18.816f, 19.562f) + lineTo(18.362f, 18.671f) + close() + moveTo(15.2f, 18.998f) + verticalLineTo(17.998f) + horizontalLineTo(9.509f) + verticalLineTo(18.998f) + verticalLineTo(19.998f) + horizontalLineTo(15.2f) + verticalLineTo(18.998f) + close() + moveTo(9.509f, 18.998f) + lineTo(10.456f, 19.317f) + curveTo(10.837f, 18.188f, 11.044f, 16.874f, 11.044f, 15.5f) + horizontalLineTo(10.044f) + horizontalLineTo(9.044f) + curveTo(9.044f, 16.682f, 8.865f, 17.778f, 8.561f, 18.679f) + lineTo(9.509f, 18.998f) + close() + moveTo(10.044f, 15.5f) + horizontalLineTo(11.044f) + curveTo(11.044f, 13.689f, 10.685f, 11.968f, 10.028f, 10.638f) + lineTo(9.132f, 11.081f) + lineTo(8.235f, 11.524f) + curveTo(8.729f, 12.523f, 9.044f, 13.929f, 9.044f, 15.5f) + horizontalLineTo(10.044f) + close() + moveTo(9.132f, 11.081f) + lineTo(10.028f, 10.638f) + curveTo(9.428f, 9.423f, 8.28f, 8f, 6.488f, 8f) + lineTo(6.488f, 9f) + lineTo(6.488f, 10f) + curveTo(7.095f, 10f, 7.731f, 10.503f, 8.235f, 11.524f) + lineTo(9.132f, 11.081f) + close() + moveTo(6.488f, 9f) + verticalLineTo(8f) + horizontalLineTo(3.6f) + verticalLineTo(9f) + verticalLineTo(10f) + horizontalLineTo(6.488f) + verticalLineTo(9f) + close() + moveTo(3.6f, 9f) + lineTo(3.6f, 8f) + curveTo(2.687f, 8f, 1.925f, 8.382f, 1.337f, 8.904f) + lineTo(2f, 9.652f) + lineTo(2.663f, 10.401f) + curveTo(2.973f, 10.126f, 3.281f, 10f, 3.6f, 10f) + lineTo(3.6f, 9f) + close() + moveTo(2f, 9.652f) + lineTo(3f, 9.653f) + curveTo(3f, 8.847f, 3.003f, 8.297f, 3.041f, 7.871f) + curveTo(3.077f, 7.457f, 3.141f, 7.241f, 3.218f, 7.09f) + lineTo(2.327f, 6.636f) + lineTo(1.436f, 6.182f) + curveTo(1.196f, 6.653f, 1.096f, 7.153f, 1.048f, 7.696f) + curveTo(1.002f, 8.227f, 1f, 8.874f, 1f, 9.652f) + lineTo(2f, 9.652f) + close() + moveTo(2.327f, 6.636f) + lineTo(3.218f, 7.09f) + curveTo(3.41f, 6.713f, 3.716f, 6.407f, 4.092f, 6.215f) + lineTo(3.638f, 5.324f) + lineTo(3.184f, 4.433f) + curveTo(2.43f, 4.817f, 1.819f, 5.43f, 1.436f, 6.182f) + lineTo(2.327f, 6.636f) + close() + moveTo(3.638f, 5.324f) + lineTo(4.092f, 6.215f) + curveTo(4.248f, 6.136f, 4.472f, 6.071f, 4.91f, 6.035f) + curveTo(5.361f, 5.999f, 5.943f, 5.998f, 6.8f, 5.998f) + verticalLineTo(4.998f) + verticalLineTo(3.998f) + curveTo(5.977f, 3.998f, 5.299f, 3.997f, 4.748f, 4.042f) + curveTo(4.186f, 4.087f, 3.669f, 4.186f, 3.184f, 4.433f) + lineTo(3.638f, 5.324f) + close() + moveTo(6.8f, 4.998f) + verticalLineTo(5.998f) + horizontalLineTo(15.2f) + verticalLineTo(4.998f) + verticalLineTo(3.998f) + horizontalLineTo(6.8f) + verticalLineTo(4.998f) + close() + } + } + path(fill = SolidColor(secondCardColor)) { + moveTo(18.035f, 5f) + curveTo(19.772f, 5f, 20.642f, 5f, 21.306f, 5.327f) + curveTo(21.889f, 5.615f, 22.364f, 6.073f, 22.662f, 6.638f) + curveTo(23f, 7.279f, 23f, 8.12f, 23f, 9.8f) + verticalLineTo(14.2f) + curveTo(23f, 15.88f, 23f, 16.721f, 22.662f, 17.362f) + curveTo(22.364f, 17.927f, 21.889f, 18.385f, 21.306f, 18.673f) + curveTo(20.642f, 19f, 19.772f, 19f, 18.035f, 19f) + horizontalLineTo(17f) + curveTo(18.738f, 19f, 19.607f, 19f, 20.271f, 18.673f) + curveTo(20.855f, 18.385f, 21.33f, 17.927f, 21.627f, 17.362f) + curveTo(21.965f, 16.721f, 21.965f, 15.88f, 21.965f, 14.2f) + verticalLineTo(9.8f) + curveTo(21.965f, 8.12f, 21.965f, 7.279f, 21.627f, 6.638f) + curveTo(21.33f, 6.073f, 20.855f, 5.615f, 20.271f, 5.327f) + curveTo(19.607f, 5f, 18.738f, 5f, 17f, 5f) + horizontalLineTo(18.035f) + close() + } + path( + stroke = SolidColor(borderColor), + strokeLineWidth = 1f, + ) { + moveTo(22.331f, 7.153f) + curveTo(22.39f, 7.342f, 22.434f, 7.57f, 22.459f, 7.871f) + curveTo(22.499f, 8.345f, 22.5f, 8.951f, 22.5f, 9.8f) + verticalLineTo(14.2f) + lineTo(22.495f, 15.305f) + curveTo(22.49f, 15.621f, 22.479f, 15.892f, 22.459f, 16.129f) + curveTo(22.434f, 16.429f, 22.39f, 16.657f, 22.331f, 16.846f) + curveTo(22.373f, 16.648f, 22.402f, 16.438f, 22.421f, 16.213f) + curveTo(22.465f, 15.687f, 22.466f, 15.032f, 22.466f, 14.2f) + verticalLineTo(9.8f) + lineTo(22.46f, 8.679f) + curveTo(22.455f, 8.345f, 22.443f, 8.05f, 22.421f, 7.787f) + curveTo(22.402f, 7.561f, 22.373f, 7.351f, 22.331f, 7.153f) + close() + } + }.build() + + fun buildCard(mainColor: Color, borderColor: Color, tColor: Color?): ImageVector = ImageVector.Builder( + name = "KeyCard", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f, + ).apply { + path(fill = SolidColor(mainColor)) { + moveTo(3f, 9.8f) + curveTo(3f, 8.12f, 3f, 7.28f, 3.327f, 6.638f) + curveTo(3.615f, 6.074f, 4.074f, 5.615f, 4.638f, 5.327f) + curveTo(5.28f, 5f, 6.12f, 5f, 7.8f, 5f) + horizontalLineTo(16.2f) + curveTo(17.88f, 5f, 18.72f, 5f, 19.362f, 5.327f) + curveTo(19.927f, 5.615f, 20.385f, 6.074f, 20.673f, 6.638f) + curveTo(21f, 7.28f, 21f, 8.12f, 21f, 9.8f) + verticalLineTo(14.2f) + curveTo(21f, 15.88f, 21f, 16.72f, 20.673f, 17.362f) + curveTo(20.385f, 17.927f, 19.927f, 18.385f, 19.362f, 18.673f) + curveTo(18.72f, 19f, 17.88f, 19f, 16.2f, 19f) + horizontalLineTo(7.8f) + curveTo(6.12f, 19f, 5.28f, 19f, 4.638f, 18.673f) + curveTo(4.074f, 18.385f, 3.615f, 17.927f, 3.327f, 17.362f) + curveTo(3f, 16.72f, 3f, 15.88f, 3f, 14.2f) + verticalLineTo(9.8f) + close() + } + path( + stroke = SolidColor(borderColor), + strokeLineWidth = 1f, + ) { + moveTo(7.8f, 5.5f) + horizontalLineTo(16.2f) + curveTo(17.048f, 5.5f, 17.655f, 5.5f, 18.13f, 5.539f) + curveTo(18.599f, 5.577f, 18.896f, 5.651f, 19.135f, 5.772f) + curveTo(19.605f, 6.012f, 19.988f, 6.395f, 20.228f, 6.865f) + curveTo(20.349f, 7.104f, 20.423f, 7.401f, 20.461f, 7.87f) + curveTo(20.5f, 8.345f, 20.5f, 8.952f, 20.5f, 9.8f) + verticalLineTo(14.2f) + curveTo(20.5f, 15.048f, 20.5f, 15.655f, 20.461f, 16.13f) + curveTo(20.423f, 16.599f, 20.349f, 16.896f, 20.228f, 17.135f) + curveTo(19.988f, 17.605f, 19.605f, 17.988f, 19.135f, 18.228f) + curveTo(18.896f, 18.349f, 18.599f, 18.423f, 18.13f, 18.461f) + curveTo(17.655f, 18.5f, 17.048f, 18.5f, 16.2f, 18.5f) + horizontalLineTo(7.8f) + curveTo(6.952f, 18.5f, 6.345f, 18.5f, 5.87f, 18.461f) + curveTo(5.401f, 18.423f, 5.104f, 18.349f, 4.865f, 18.228f) + curveTo(4.395f, 17.988f, 4.012f, 17.605f, 3.772f, 17.135f) + curveTo(3.651f, 16.896f, 3.577f, 16.599f, 3.539f, 16.13f) + curveTo(3.5f, 15.655f, 3.5f, 15.048f, 3.5f, 14.2f) + verticalLineTo(9.8f) + curveTo(3.5f, 8.952f, 3.5f, 8.345f, 3.539f, 7.87f) + curveTo(3.577f, 7.401f, 3.651f, 7.104f, 3.772f, 6.865f) + curveTo(4.012f, 6.395f, 4.395f, 6.012f, 4.865f, 5.772f) + curveTo(5.104f, 5.651f, 5.401f, 5.577f, 5.87f, 5.539f) + curveTo(6.345f, 5.5f, 6.952f, 5.5f, 7.8f, 5.5f) + close() + } + if (tColor != null) { + path(fill = SolidColor(tColor)) { + moveTo(11.082f, 16f) + verticalLineTo(9.635f) + horizontalLineTo(9f) + verticalLineTo(8f) + horizontalLineTo(15f) + verticalLineTo(9.635f) + horizontalLineTo(12.913f) + verticalLineTo(16f) + horizontalLineTo(11.082f) + close() + } + } + }.build() + + fun buildCard2(mainColor: Color, secondColor: Color, borderColor: Color, tColor: Color?): ImageVector = + ImageVector.Builder( + name = "KeyCard2", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f, + ).apply { + path(fill = SolidColor(mainColor)) { + moveTo(2f, 9.8f) + curveTo(2f, 8.12f, 2f, 7.28f, 2.327f, 6.638f) + curveTo(2.615f, 6.074f, 3.074f, 5.615f, 3.638f, 5.327f) + curveTo(4.28f, 5f, 5.12f, 5f, 6.8f, 5f) + horizontalLineTo(15.2f) + curveTo(16.88f, 5f, 17.72f, 5f, 18.362f, 5.327f) + curveTo(18.927f, 5.615f, 19.385f, 6.074f, 19.673f, 6.638f) + curveTo(20f, 7.28f, 20f, 8.12f, 20f, 9.8f) + verticalLineTo(14.2f) + curveTo(20f, 15.88f, 20f, 16.72f, 19.673f, 17.362f) + curveTo(19.385f, 17.927f, 18.927f, 18.385f, 18.362f, 18.673f) + curveTo(17.72f, 19f, 16.88f, 19f, 15.2f, 19f) + horizontalLineTo(6.8f) + curveTo(5.12f, 19f, 4.28f, 19f, 3.638f, 18.673f) + curveTo(3.074f, 18.385f, 2.615f, 17.927f, 2.327f, 17.362f) + curveTo(2f, 16.72f, 2f, 15.88f, 2f, 14.2f) + verticalLineTo(9.8f) + close() + } + path( + stroke = SolidColor(borderColor), + strokeLineWidth = 1f, + ) { + moveTo(6.8f, 5.5f) + horizontalLineTo(15.2f) + curveTo(16.048f, 5.5f, 16.655f, 5.5f, 17.13f, 5.539f) + curveTo(17.599f, 5.577f, 17.896f, 5.651f, 18.135f, 5.772f) + curveTo(18.605f, 6.012f, 18.988f, 6.395f, 19.228f, 6.865f) + curveTo(19.349f, 7.104f, 19.423f, 7.401f, 19.461f, 7.87f) + curveTo(19.5f, 8.345f, 19.5f, 8.952f, 19.5f, 9.8f) + verticalLineTo(14.2f) + curveTo(19.5f, 15.048f, 19.5f, 15.655f, 19.461f, 16.13f) + curveTo(19.423f, 16.599f, 19.349f, 16.896f, 19.228f, 17.135f) + curveTo(18.988f, 17.605f, 18.605f, 17.988f, 18.135f, 18.228f) + curveTo(17.896f, 18.349f, 17.599f, 18.423f, 17.13f, 18.461f) + curveTo(16.655f, 18.5f, 16.048f, 18.5f, 15.2f, 18.5f) + horizontalLineTo(6.8f) + curveTo(5.952f, 18.5f, 5.345f, 18.5f, 4.87f, 18.461f) + curveTo(4.401f, 18.423f, 4.104f, 18.349f, 3.865f, 18.228f) + curveTo(3.395f, 17.988f, 3.012f, 17.605f, 2.772f, 17.135f) + curveTo(2.651f, 16.896f, 2.577f, 16.599f, 2.539f, 16.13f) + curveTo(2.5f, 15.655f, 2.5f, 15.048f, 2.5f, 14.2f) + verticalLineTo(9.8f) + curveTo(2.5f, 8.952f, 2.5f, 8.345f, 2.539f, 7.87f) + curveTo(2.577f, 7.401f, 2.651f, 7.104f, 2.772f, 6.865f) + curveTo(3.012f, 6.395f, 3.395f, 6.012f, 3.865f, 5.772f) + curveTo(4.104f, 5.651f, 4.401f, 5.577f, 4.87f, 5.539f) + curveTo(5.345f, 5.5f, 5.952f, 5.5f, 6.8f, 5.5f) + close() + } + if (tColor != null) { + path(fill = SolidColor(tColor)) { + moveTo(10.082f, 16f) + verticalLineTo(9.635f) + horizontalLineTo(8f) + verticalLineTo(8f) + horizontalLineTo(14f) + verticalLineTo(9.635f) + horizontalLineTo(11.913f) + verticalLineTo(16f) + horizontalLineTo(10.082f) + close() + } + } + path(fill = SolidColor(secondColor)) { + moveTo(17.535f, 5f) + curveTo(19.272f, 5f, 20.142f, 5f, 20.806f, 5.327f) + curveTo(21.389f, 5.615f, 21.864f, 6.073f, 22.162f, 6.638f) + curveTo(22.5f, 7.279f, 22.5f, 8.12f, 22.5f, 9.8f) + verticalLineTo(14.2f) + curveTo(22.5f, 15.88f, 22.5f, 16.721f, 22.162f, 17.362f) + curveTo(21.864f, 17.927f, 21.389f, 18.385f, 20.806f, 18.673f) + curveTo(20.142f, 19f, 19.272f, 19f, 17.535f, 19f) + horizontalLineTo(16.5f) + curveTo(18.238f, 19f, 19.107f, 19f, 19.771f, 18.673f) + curveTo(20.355f, 18.385f, 20.83f, 17.927f, 21.127f, 17.362f) + curveTo(21.465f, 16.721f, 21.465f, 15.88f, 21.465f, 14.2f) + verticalLineTo(9.8f) + curveTo(21.465f, 8.12f, 21.465f, 7.279f, 21.127f, 6.638f) + curveTo(20.83f, 6.073f, 20.355f, 5.615f, 19.771f, 5.327f) + curveTo(19.107f, 5f, 18.238f, 5f, 16.5f, 5f) + horizontalLineTo(17.535f) + close() + } + path( + stroke = SolidColor(borderColor), + strokeLineWidth = 1f, + ) { + moveTo(21.831f, 7.153f) + curveTo(21.89f, 7.342f, 21.934f, 7.57f, 21.959f, 7.871f) + curveTo(21.999f, 8.345f, 22f, 8.951f, 22f, 9.8f) + verticalLineTo(14.2f) + lineTo(21.995f, 15.305f) + curveTo(21.99f, 15.621f, 21.979f, 15.892f, 21.959f, 16.129f) + curveTo(21.934f, 16.429f, 21.89f, 16.657f, 21.831f, 16.846f) + curveTo(21.873f, 16.648f, 21.902f, 16.438f, 21.921f, 16.213f) + curveTo(21.965f, 15.687f, 21.966f, 15.032f, 21.966f, 14.2f) + verticalLineTo(9.8f) + lineTo(21.96f, 8.679f) + curveTo(21.955f, 8.345f, 21.943f, 8.05f, 21.921f, 7.787f) + curveTo(21.902f, 7.561f, 21.873f, 7.351f, 21.831f, 7.153f) + close() + } + }.build() + + fun buildCard3( + mainColor: Color, + secondColor: Color, + thirdColor: Color, + borderColor: Color, + tColor: Color?, + ): ImageVector = ImageVector.Builder( + name = "KeyCard3", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f, + ).apply { + path(fill = SolidColor(mainColor)) { + moveTo(0f, 9.8f) + curveTo(0f, 8.12f, 0f, 7.28f, 0.327f, 6.638f) + curveTo(0.615f, 6.074f, 1.074f, 5.615f, 1.638f, 5.327f) + curveTo(2.28f, 5f, 3.12f, 5f, 4.8f, 5f) + horizontalLineTo(13.2f) + curveTo(14.88f, 5f, 15.72f, 5f, 16.362f, 5.327f) + curveTo(16.927f, 5.615f, 17.385f, 6.074f, 17.673f, 6.638f) + curveTo(18f, 7.28f, 18f, 8.12f, 18f, 9.8f) + verticalLineTo(14.2f) + curveTo(18f, 15.88f, 18f, 16.72f, 17.673f, 17.362f) + curveTo(17.385f, 17.927f, 16.927f, 18.385f, 16.362f, 18.673f) + curveTo(15.72f, 19f, 14.88f, 19f, 13.2f, 19f) + horizontalLineTo(4.8f) + curveTo(3.12f, 19f, 2.28f, 19f, 1.638f, 18.673f) + curveTo(1.074f, 18.385f, 0.615f, 17.927f, 0.327f, 17.362f) + curveTo(0f, 16.72f, 0f, 15.88f, 0f, 14.2f) + verticalLineTo(9.8f) + close() + } + path( + stroke = SolidColor(borderColor), + strokeLineWidth = 1f, + ) { + moveTo(4.8f, 5.5f) + horizontalLineTo(13.2f) + curveTo(14.048f, 5.5f, 14.655f, 5.5f, 15.13f, 5.539f) + curveTo(15.599f, 5.577f, 15.896f, 5.651f, 16.135f, 5.772f) + curveTo(16.605f, 6.012f, 16.988f, 6.395f, 17.228f, 6.865f) + curveTo(17.349f, 7.104f, 17.423f, 7.401f, 17.461f, 7.87f) + curveTo(17.5f, 8.345f, 17.5f, 8.952f, 17.5f, 9.8f) + verticalLineTo(14.2f) + curveTo(17.5f, 15.048f, 17.5f, 15.655f, 17.461f, 16.13f) + curveTo(17.423f, 16.599f, 17.349f, 16.896f, 17.228f, 17.135f) + curveTo(16.988f, 17.605f, 16.605f, 17.988f, 16.135f, 18.228f) + curveTo(15.896f, 18.349f, 15.599f, 18.423f, 15.13f, 18.461f) + curveTo(14.655f, 18.5f, 14.048f, 18.5f, 13.2f, 18.5f) + horizontalLineTo(4.8f) + curveTo(3.952f, 18.5f, 3.345f, 18.5f, 2.87f, 18.461f) + curveTo(2.401f, 18.423f, 2.104f, 18.349f, 1.865f, 18.228f) + curveTo(1.395f, 17.988f, 1.012f, 17.605f, 0.772f, 17.135f) + curveTo(0.651f, 16.896f, 0.577f, 16.599f, 0.539f, 16.13f) + curveTo(0.5f, 15.655f, 0.5f, 15.048f, 0.5f, 14.2f) + verticalLineTo(9.8f) + curveTo(0.5f, 8.952f, 0.5f, 8.345f, 0.539f, 7.87f) + curveTo(0.577f, 7.401f, 0.651f, 7.104f, 0.772f, 6.865f) + curveTo(1.012f, 6.395f, 1.395f, 6.012f, 1.865f, 5.772f) + curveTo(2.104f, 5.651f, 2.401f, 5.577f, 2.87f, 5.539f) + curveTo(3.345f, 5.5f, 3.952f, 5.5f, 4.8f, 5.5f) + close() + } + if (tColor != null) { + path(fill = SolidColor(tColor)) { + moveTo(8.082f, 16f) + verticalLineTo(9.635f) + horizontalLineTo(6f) + verticalLineTo(8f) + horizontalLineTo(12f) + verticalLineTo(9.635f) + horizontalLineTo(9.913f) + verticalLineTo(16f) + horizontalLineTo(8.082f) + close() + } + } + path(fill = SolidColor(secondColor)) { + moveTo(16.035f, 5f) + curveTo(17.772f, 5f, 18.642f, 5f, 19.306f, 5.327f) + curveTo(19.889f, 5.615f, 20.364f, 6.073f, 20.662f, 6.638f) + curveTo(21f, 7.279f, 21f, 8.12f, 21f, 9.8f) + verticalLineTo(14.2f) + curveTo(21f, 15.88f, 21f, 16.721f, 20.662f, 17.362f) + curveTo(20.364f, 17.927f, 19.889f, 18.385f, 19.306f, 18.673f) + curveTo(18.642f, 19f, 17.772f, 19f, 16.035f, 19f) + horizontalLineTo(15f) + curveTo(16.738f, 19f, 17.607f, 19f, 18.271f, 18.673f) + curveTo(18.855f, 18.385f, 19.33f, 17.927f, 19.627f, 17.362f) + curveTo(19.965f, 16.721f, 19.965f, 15.88f, 19.965f, 14.2f) + verticalLineTo(9.8f) + curveTo(19.965f, 8.12f, 19.965f, 7.279f, 19.627f, 6.638f) + curveTo(19.33f, 6.073f, 18.855f, 5.615f, 18.271f, 5.327f) + curveTo(17.607f, 5f, 16.738f, 5f, 15f, 5f) + horizontalLineTo(16.035f) + close() + } + path( + stroke = SolidColor(borderColor), + strokeLineWidth = 1f, + ) { + moveTo(20.331f, 7.153f) + curveTo(20.39f, 7.342f, 20.434f, 7.57f, 20.459f, 7.871f) + curveTo(20.499f, 8.345f, 20.5f, 8.951f, 20.5f, 9.8f) + verticalLineTo(14.2f) + lineTo(20.495f, 15.305f) + curveTo(20.49f, 15.621f, 20.479f, 15.892f, 20.459f, 16.129f) + curveTo(20.434f, 16.429f, 20.39f, 16.657f, 20.331f, 16.846f) + curveTo(20.373f, 16.648f, 20.402f, 16.438f, 20.421f, 16.213f) + curveTo(20.465f, 15.687f, 20.466f, 15.032f, 20.466f, 14.2f) + verticalLineTo(9.8f) + lineTo(20.46f, 8.679f) + curveTo(20.455f, 8.345f, 20.443f, 8.05f, 20.421f, 7.787f) + curveTo(20.402f, 7.561f, 20.373f, 7.351f, 20.331f, 7.153f) + close() + } + path(fill = SolidColor(thirdColor)) { + moveTo(19.035f, 5f) + curveTo(20.772f, 5f, 21.642f, 5f, 22.306f, 5.327f) + curveTo(22.889f, 5.615f, 23.364f, 6.073f, 23.662f, 6.638f) + curveTo(24f, 7.279f, 24f, 8.12f, 24f, 9.8f) + verticalLineTo(14.2f) + curveTo(24f, 15.88f, 24f, 16.721f, 23.662f, 17.362f) + curveTo(23.364f, 17.927f, 22.889f, 18.385f, 22.306f, 18.673f) + curveTo(21.642f, 19f, 20.772f, 19f, 19.035f, 19f) + horizontalLineTo(18f) + curveTo(19.738f, 19f, 20.607f, 19f, 21.271f, 18.673f) + curveTo(21.855f, 18.385f, 22.33f, 17.927f, 22.627f, 17.362f) + curveTo(22.965f, 16.721f, 22.965f, 15.88f, 22.965f, 14.2f) + verticalLineTo(9.8f) + curveTo(22.965f, 8.12f, 22.965f, 7.279f, 22.627f, 6.638f) + curveTo(22.33f, 6.073f, 21.855f, 5.615f, 21.271f, 5.327f) + curveTo(20.607f, 5f, 19.738f, 5f, 18f, 5f) + horizontalLineTo(19.035f) + close() + } + path( + stroke = SolidColor(borderColor), + strokeLineWidth = 1f, + ) { + moveTo(23.331f, 7.153f) + curveTo(23.39f, 7.342f, 23.434f, 7.57f, 23.459f, 7.871f) + curveTo(23.499f, 8.345f, 23.5f, 8.951f, 23.5f, 9.8f) + verticalLineTo(14.2f) + curveTo(23.5f, 15.049f, 23.499f, 15.655f, 23.459f, 16.129f) + curveTo(23.434f, 16.429f, 23.39f, 16.657f, 23.331f, 16.846f) + curveTo(23.373f, 16.648f, 23.402f, 16.438f, 23.421f, 16.213f) + curveTo(23.465f, 15.687f, 23.466f, 15.032f, 23.466f, 14.2f) + verticalLineTo(9.8f) + curveTo(23.466f, 8.968f, 23.465f, 8.313f, 23.421f, 7.787f) + curveTo(23.402f, 7.561f, 23.373f, 7.351f, 23.331f, 7.153f) + close() + } + }.build() +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/TangemColors2.kt b/core/ui/src/main/java/com/tangem/core/ui/res/TangemColors2.kt index b9b0c54c51..1f0df03ae4 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/res/TangemColors2.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/res/TangemColors2.kt @@ -326,7 +326,10 @@ class TangemColors2 internal constructor( class Border internal constructor( val neutral: Neutral, val status: Status, + walletIcon: Color, ) { + var walletIcon by mutableStateOf(walletIcon) + private set @Stable class Neutral internal constructor( @@ -367,6 +370,7 @@ class TangemColors2 internal constructor( fun update(other: Border) { neutral.update(other.neutral) status.update(other.status) + walletIcon = other.walletIcon } } diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/TangemThemeRedesign.kt b/core/ui/src/main/java/com/tangem/core/ui/res/TangemThemeRedesign.kt index 93a3647d65..ef46023d32 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/res/TangemThemeRedesign.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/res/TangemThemeRedesign.kt @@ -85,6 +85,7 @@ private fun lightThemeColors2(): TangemColors2 { warning = TangemColorPalette.Amaranth, attention = TangemColorPalette.Tangerine, ), + walletIcon = TangemColorPalette.Dark_10, ) val overlay = TangemColors2.Overlay( overlayPrimary = TangemColorPalette.Overlay1, @@ -247,6 +248,7 @@ private fun darkThemeColors2(): TangemColors2 { warning = TangemColorPalette.Flamingo, attention = TangemColorPalette.Mustard, ), + walletIcon = TangemColorPalette.Light_10, ) val overlay = TangemColors2.Overlay( overlayPrimary = TangemColorPalette.Overlay1, diff --git a/core/ui/src/main/res/drawable/ic_shield_24.xml b/core/ui/src/main/res/drawable/ic_shield_24.xml new file mode 100644 index 0000000000..129f023c2e --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_shield_24.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/domain/models/src/main/kotlin/com/tangem/domain/models/wallet/UserWalletIcon.kt b/domain/models/src/main/kotlin/com/tangem/domain/models/wallet/UserWalletIcon.kt new file mode 100644 index 0000000000..dc5417d014 --- /dev/null +++ b/domain/models/src/main/kotlin/com/tangem/domain/models/wallet/UserWalletIcon.kt @@ -0,0 +1,21 @@ +package com.tangem.domain.models.wallet + +/** + * Represents the icon of a user wallet, which can be of different types such as hot, stub, default, or colored. + */ +sealed class UserWalletIcon { + data object Hot : UserWalletIcon() + data class Stub(val cardsCount: Int) : UserWalletIcon() + + data class Default( + val isRing: Boolean, + val cardsCount: Int, + ) : UserWalletIcon() + + data class Colored( + val isRing: Boolean, + val mainColor: String, + val secondColor: String? = null, + val thirdColor: String? = null, + ) : UserWalletIcon() +} \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletIconUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletIconUseCase.kt new file mode 100644 index 0000000000..c370657bd3 --- /dev/null +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletIconUseCase.kt @@ -0,0 +1,242 @@ +package com.tangem.domain.wallets.usecase + +import com.tangem.blockchain.common.Blockchain +import com.tangem.domain.card.common.util.cardTypesResolver +import com.tangem.domain.card.common.util.getCardsCount +import com.tangem.domain.demo.models.DemoConfig +import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.models.wallet.UserWalletIcon +import com.tangem.domain.models.wallet.isHotWallet +import com.tangem.domain.models.wallet.requireColdWallet +import com.tangem.domain.wallets.repository.WalletsRepository +import kotlinx.coroutines.runBlocking + +class GetWalletIconUseCase( + private val walletsRepository: WalletsRepository, +) { + + @Suppress("CyclomaticComplexMethod", "UnsafeCallOnNullableType") + operator fun invoke(userWallet: UserWallet): UserWalletIcon { + if (userWallet.isHotWallet) { + return UserWalletIcon.Hot + } + + userWallet.requireColdWallet() + + val cardTypesResolver = userWallet.scanResponse.cardTypesResolver + val cardsCount = userWallet.getCardsCount() ?: 1 + + val cobrandColor by lazy { + colorByBatchId(userWallet.scanResponse.card.batchId) + } + + return when { + cardTypesResolver.isDevKit() -> otherColor(OtherCardType.Devkit) + userWallet.isRing() -> UserWalletIcon.Default(isRing = true, cardsCount = cardsCount) + cobrandColor != null -> cobrandColor!!.withCount(cardsCount) + cardTypesResolver.isWallet2() -> UserWalletIcon.Default(isRing = false, cardsCount = cardsCount) + cardTypesResolver.isShibaWallet() -> otherColor(OtherCardType.Shiba, cardsCount) + cardTypesResolver.isTangemWallet() -> otherColor(OtherCardType.Wallet1, cardsCount) + cardTypesResolver.isWhiteWallet() -> otherColor(OtherCardType.WhiteWallet, cardsCount) + cardTypesResolver.isTangemTwins() -> otherColor(OtherCardType.Twins, cardsCount) + cardTypesResolver.isStart2Coin() -> otherColor(OtherCardType.Starts2com, cardsCount) + cardTypesResolver.isTangemNote() -> + resolveNoteColor(userWallet) ?: UserWalletIcon.Stub(cardsCount = cardsCount) + DemoConfig.isDemoCardId(cardId = userWallet.cardId) -> + UserWalletIcon.Default(isRing = false, cardsCount = cardsCount) + else -> UserWalletIcon.Stub(cardsCount = cardsCount) + } + } + + private fun resolveNoteColor(userWallet: UserWallet.Cold): UserWalletIcon? { + val noteBlockchain = userWallet.scanResponse.cardTypesResolver.getBlockchain() + + val otherCardType = when (noteBlockchain) { + Blockchain.Bitcoin -> OtherCardType.NoteBitcoin + Blockchain.Ethereum -> OtherCardType.NoteEthereum + Blockchain.XRP -> OtherCardType.NoteXRP + Blockchain.Binance -> OtherCardType.NoteBinance + Blockchain.Cardano -> OtherCardType.NoteCardano + Blockchain.Dogecoin -> OtherCardType.NoteDoge + else -> return null + } + + return otherColor(otherCardType) + } + + private fun otherColor(otherCardType: OtherCardType, cardsCount: Int = 1): UserWalletIcon.Colored { + return UserWalletIcon.Colored( + isRing = false, + mainColor = otherCardType.mainColor, + secondColor = if (cardsCount > 1) otherCardType.mainColor else null, + thirdColor = if (cardsCount > 2) otherCardType.mainColor else null, + ) + } + + private fun UserWalletIcon.Colored.withCount(count: Int): UserWalletIcon.Colored { + return this.copy( + mainColor = mainColor, + secondColor = if (count > 1) secondColor else null, + thirdColor = if (count > 2) thirdColor else null, + ) + } + + private fun UserWallet.Cold.isRing(): Boolean { + return scanResponse.cardTypesResolver.isRing() || + runBlocking { walletsRepository.isWalletWithRing(userWalletId = this@isRing.walletId) } + } + + @Suppress("CyclomaticComplexMethod") + private fun colorByBatchId(batchId: String): UserWalletIcon.Colored? { + fun color(main: String, second: String = main, third: String = main) = + UserWalletIcon.Colored(isRing = false, mainColor = main, secondColor = second, thirdColor = third) + + val cobrandType = CobrandType.entries.firstOrNull { it.batchIds.contains(batchId) } + + return when (cobrandType) { + CobrandType.Avrora -> color("#1E1E1C") + CobrandType.BabyDoge -> color("#E7D34C") + CobrandType.Bad -> color("#395467") + CobrandType.BitcoinGold -> color("#F08A1F") + CobrandType.BitcoinPizzaDay -> color("#AF4D37") + CobrandType.BitcoinPizza2 -> color("#F3C63A") + CobrandType.BTC365 -> color("#191E3E") + CobrandType.CashClubGold -> color("#D1BF78") + CobrandType.Changenow -> color("#191B2C") + CobrandType.Chilliz -> color("#49324A") + CobrandType.CoinMetrica -> color("#A140C7") + CobrandType.COQ -> color("#ED1F3A") + CobrandType.CryptoCasey -> color("#301E45") + CobrandType.CryptoOrg -> color("#27B39A") + CobrandType.CryptoSeth -> color("#414954") + CobrandType.GetsMine -> color("#AFC3CE") + CobrandType.Grim -> color("#131313") + CobrandType.Hodl -> color("#111111") + CobrandType.Jr -> color("#1C1C1C") + CobrandType.Kaspa -> color("#545C5C") + CobrandType.Kaspa2 -> color("#353535") + CobrandType.KaspaReseller -> color("#3B3D3A") + CobrandType.Kaspa3 -> color("#85CBC1") + CobrandType.Kasper -> color("#34302E") + CobrandType.Kaspy -> color("#DEC764") + CobrandType.Keiro -> color("#4D645C") + CobrandType.KishuInu -> color("#2DA4CE") + CobrandType.Kango -> color("#5BA495") + CobrandType.Konan -> color("#64C9C9") + CobrandType.Kroak -> color("#8EB8AF") + CobrandType.Neiro -> color("#E7A524") + CobrandType.NewWorldElite -> color("#292722") + CobrandType.PassimPay -> color("#6A4361") + CobrandType.Pastel -> color("#FFC7A4", "#84A479", "#6FB5BB") + CobrandType.Pepecoin -> color("#303439") + CobrandType.RamenCat -> color("#DEBE88") + CobrandType.RedPanda -> color("#C5C5C5") + CobrandType.Rizo -> color("#1765A7") + CobrandType.Sakura -> color("#F0E9C4") + CobrandType.SatoshiFriends -> color("#242424") + CobrandType.SinCity -> color("#D3C487") + CobrandType.SpringBloom -> color("#FAC73A") + CobrandType.StealthCard -> color("#555557") + CobrandType.SunDrop -> color("#FEC035") + CobrandType.Trillant -> color("#955091") + CobrandType.Tron -> color("#D4221D") + CobrandType.Upbit -> color("#2B2B2B") + CobrandType.USA -> color("#0D185F") + CobrandType.VeChain -> color("#5186A2") + CobrandType.Vivid -> color("#D3CF09", "#F76952", "#2BCAD1") + CobrandType.Vnish -> color("#292522") + CobrandType.VoltInu -> color("#34312B") + CobrandType.WhiteTangem -> color("#D3D3D3") + CobrandType.WildGoat -> color("#1B1B1B") + CobrandType.Winter -> color("#7FB9C8", "#80BDE8", "#B2C6E4") + CobrandType.WinterSakura -> color("#88B9E9") + CobrandType.LockedMoney -> color("#272625") + CobrandType.Ghoad -> color("#6EC5C5") + CobrandType.BlushSky -> color("#C1E9E8", "#FACAD3", "#DCCEE0") + CobrandType.ElectraSea -> color("#0D5A67", "#29939E", "#30C6B1") + CobrandType.HyperBlue -> color("#0F397C", "#1474D3", "#0BC9EC") + CobrandType.Lunar -> color("#B0313A") + null -> null + } + } +} + +private enum class CobrandType(val batchIds: List) { + Avrora(listOf("AF18")), + BabyDoge(listOf("AF51")), + Bad(listOf("AF09")), + BitcoinGold(listOf("AF71", "AF990016", "AF990009")), + BitcoinPizzaDay(listOf("AF33")), + BitcoinPizza2(listOf("AF990019")), + BTC365(listOf("AF97")), + CashClubGold(listOf("BB000004")), + Changenow(listOf("BB000013")), + Chilliz(listOf("BB000016")), + CoinMetrica(listOf("AF27")), + COQ(listOf("AF28")), + CryptoCasey(listOf("AF21", "AF22", "AF23")), + CryptoOrg(listOf("AF57")), + CryptoSeth(listOf("AF32")), + GetsMine(listOf("BB000008")), + Grim(listOf("AF13")), + Hodl(listOf("BB000009")), + Jr(listOf("AF14")), + Kaspa(listOf("AF08")), + Kaspa2(listOf("AF25", "AF61", "AF72")), + KaspaReseller(listOf("AF31")), + Kaspa3(listOf("AF73")), + Kasper(listOf("AF96")), + Kaspy(listOf("AF95")), + Keiro(listOf("BB000017")), + KishuInu(listOf("AF52")), + Kango(listOf("BB000006")), + Konan(listOf("AF93")), + Kroak(listOf("BB000011")), + Neiro(listOf("AF98")), + NewWorldElite(listOf("AF26")), + PassimPay(listOf("BB000007")), + Pastel(listOf("AF43", "AF44", "AF45", "AF78", "AF79", "AF80")), + Pepecoin(listOf("BB000015")), + RamenCat(listOf("AF990006", "AF990007", "AF990008")), + RedPanda(listOf("AF34")), + Rizo(listOf("BB000012")), + Sakura(listOf("AF990029", "AF990030", "AF990031", "AF990071", "AF990072", "AF990073")), + SatoshiFriends(listOf("AF19")), + SinCity(listOf("BB000010")), + SpringBloom(listOf("AF990001", "AF990002", "AF990004")), + StealthCard(listOf("AF60", "AF74", "AF88")), + SunDrop(listOf("AF990005", "AF990003")), + Trillant(listOf("AF16")), + Tron(listOf("AF07")), + Upbit(listOf("BB000019")), + USA(listOf("AF91", "AF990017", "AF990056")), + VeChain(listOf("AF29")), + Vivid(listOf("AF40", "AF41", "AF42", "AF75", "AF76", "AF77")), + Vnish(listOf("BB000005")), + VoltInu(listOf("AF35")), + WhiteTangem(listOf("AF15")), + WildGoat(listOf("BB000001")), + Winter(listOf("AF85", "AF86", "AF87", "AF990013", "AF990012", "AF990011")), + WinterSakura(listOf("AF990053", "AF990054", "AF990055")), + LockedMoney(listOf("AF63")), + Ghoad(listOf("AF89")), + BlushSky(listOf("AF990020", "AF990021", "AF990022")), + ElectraSea(listOf("AF990023", "AF990024", "AF990025")), + HyperBlue(listOf("AF990026", "AF990027", "AF990028", "AF990050", "AF990051", "AF990052")), + Lunar(listOf("AF990057", "AF990058", "AF990059")), +} + +private enum class OtherCardType(val mainColor: String) { + NoteXRP("#726799"), + NoteDoge("#BFB565"), + NoteEthereum("#989C9F"), + NoteBinance("#C9B87C"), + NoteCardano("#5979AD"), + NoteBitcoin("#EABE8B"), + Starts2com("#356F99"), + Wallet1("#2E3944"), + Twins("#B8B7B6"), + Devkit("#938C92"), + WhiteWallet("#DDDDDD"), + Shiba("#D5963A"), +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt index 9adf3437d5..46a932bf55 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt @@ -27,6 +27,7 @@ import com.tangem.domain.pay.usecase.TangemPayMainScreenCustomerInfoUseCase import com.tangem.domain.settings.* import com.tangem.domain.tokens.RefreshMultiCurrencyWalletQuotesUseCase import com.tangem.domain.wallets.usecase.* +import com.tangem.domain.wallets.usecase.GetWalletIconUseCase import com.tangem.domain.yield.supply.usecase.YieldSupplyApyUpdateUseCase import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.presentation.router.InnerWalletRouter @@ -100,6 +101,7 @@ internal class WalletModel @Inject constructor( private val bindRefcodeWithWalletUseCase: BindRefcodeWithWalletUseCase, private val appsFlyerStore: AppsFlyerStore, private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, + private val getWalletIconUseCase: GetWalletIconUseCase, val screenLifecycleProvider: ScreenLifecycleProvider, val innerWalletRouter: InnerWalletRouter, ) : Model() { @@ -520,6 +522,7 @@ internal class WalletModel @Inject constructor( wallets = action.wallets, clickIntents = clickIntents, walletImageResolver = walletImageResolver, + getWalletIconUseCase = getWalletIconUseCase, ), ) @@ -565,6 +568,7 @@ internal class WalletModel @Inject constructor( newUserWallet = action.selectedWallet, clickIntents = clickIntents, walletImageResolver = walletImageResolver, + getWalletIconUseCase = getWalletIconUseCase, ), ) } @@ -585,6 +589,7 @@ internal class WalletModel @Inject constructor( userWallet = userWallet, clickIntents = clickIntents, walletImageResolver = walletImageResolver, + getWalletIconUseCase = getWalletIconUseCase, ), ) } @@ -598,6 +603,7 @@ internal class WalletModel @Inject constructor( userWallet = action.selectedWallet, clickIntents = clickIntents, walletImageResolver = walletImageResolver, + getWalletIconUseCase = getWalletIconUseCase, ), ) @@ -658,6 +664,7 @@ internal class WalletModel @Inject constructor( unlockedWallets = action.unlockedWallets, clickIntents = clickIntents, walletImageResolver = walletImageResolver, + getWalletIconUseCase = getWalletIconUseCase, ), ) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/preview/WalletBalancePreview.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/preview/WalletBalancePreview.kt index f71de661de..dc1d34c847 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/preview/WalletBalancePreview.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/preview/WalletBalancePreview.kt @@ -1,6 +1,7 @@ package com.tangem.feature.wallet.presentation.preview import androidx.compose.ui.text.SpanStyle +import com.tangem.core.ui.ds.image.DeviceIconUM import com.tangem.core.ui.extensions.combinedReference import com.tangem.core.ui.extensions.stringReference import com.tangem.core.ui.extensions.styledStringReference @@ -31,6 +32,7 @@ internal object WalletBalancePreview { ), stringReference(" $"), ), + deviceIcon = DeviceIconUM.Stub(cardsCount = 3), isBalanceFlickering = false, isZeroBalance = false, ) @@ -38,10 +40,12 @@ internal object WalletBalancePreview { val loading: WalletBalanceUM.Loading = WalletBalanceUM.Loading( id = UserWalletId("1"), name = "My Wallet", + deviceIcon = DeviceIconUM.Mobile, ) val error: WalletBalanceUM.Error = WalletBalanceUM.Error( id = UserWalletId("2"), name = "My Wallet", + deviceIcon = DeviceIconUM.Stub(cardsCount = 3), ) } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletImageResolver.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletImageResolver.kt index eb3e310843..1d84273c15 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletImageResolver.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletImageResolver.kt @@ -17,6 +17,7 @@ import javax.inject.Inject * [REDACTED_AUTHOR] */ +@Deprecated("Will be removed in favor of getWalletIconUseCase") internal class WalletImageResolver @Inject constructor( private val walletsRepository: WalletsRepository, ) { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletBalanceUM.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletBalanceUM.kt index a081ffe922..b3a4710b3a 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletBalanceUM.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletBalanceUM.kt @@ -1,6 +1,7 @@ package com.tangem.feature.wallet.presentation.wallet.state.model import androidx.compose.runtime.Immutable +import com.tangem.core.ui.ds.image.DeviceIconUM import com.tangem.core.ui.extensions.TextReference import com.tangem.domain.models.wallet.UserWalletId @@ -24,6 +25,9 @@ internal sealed interface WalletBalanceUM { /** Wallet Name */ val name: String + /** Wallet Icon */ + val deviceIcon: DeviceIconUM + /** * Wallet card content state * @@ -34,6 +38,7 @@ internal sealed interface WalletBalanceUM { data class Content( override val id: UserWalletId, override val name: String, + override val deviceIcon: DeviceIconUM, val balance: TextReference, val balanceInAppBar: TextReference, val isBalanceFlickering: Boolean, @@ -49,6 +54,7 @@ internal sealed interface WalletBalanceUM { data class Error( override val id: UserWalletId, override val name: String, + override val deviceIcon: DeviceIconUM, ) : WalletBalanceUM /** @@ -60,6 +66,7 @@ internal sealed interface WalletBalanceUM { data class Loading( override val id: UserWalletId, override val name: String, + override val deviceIcon: DeviceIconUM, ) : WalletBalanceUM fun copySealed(name: String): WalletBalanceUM { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/AddWalletTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/AddWalletTransformer.kt index 69574485b2..ec3d6943be 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/AddWalletTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/AddWalletTransformer.kt @@ -1,6 +1,7 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.wallets.usecase.GetWalletIconUseCase import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.presentation.wallet.domain.WalletImageResolver import com.tangem.feature.wallet.presentation.wallet.state.model.WalletScreenState @@ -11,12 +12,14 @@ internal class AddWalletTransformer( private val userWallet: UserWallet, private val clickIntents: WalletClickIntents, private val walletImageResolver: WalletImageResolver, + private val getWalletIconUseCase: GetWalletIconUseCase, ) : WalletScreenStateTransformer { private val walletLoadingStateFactory by lazy { WalletLoadingStateFactory( clickIntents = clickIntents, walletImageResolver = walletImageResolver, + getWalletIconUseCase = getWalletIconUseCase, ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt index 8fe34bed8e..eb010c9a39 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt @@ -1,9 +1,11 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers +import com.tangem.common.ui.userwallet.converter.WalletIconUMConverter import com.tangem.core.ui.ds.button.TangemButtonUM import com.tangem.domain.card.common.util.cardTypesResolver import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.isLocked +import com.tangem.domain.wallets.usecase.GetWalletIconUseCase import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory import com.tangem.feature.wallet.presentation.wallet.domain.WalletImageResolver @@ -22,12 +24,14 @@ internal class InitializeWalletsTransformer( private val wallets: List, private val clickIntents: WalletClickIntents, private val walletImageResolver: WalletImageResolver, + private val getWalletIconUseCase: GetWalletIconUseCase, ) : WalletScreenStateTransformer { private val walletLoadingStateFactory by lazy { WalletLoadingStateFactory( clickIntents = clickIntents, walletImageResolver = walletImageResolver, + getWalletIconUseCase = getWalletIconUseCase, ) } @@ -111,6 +115,8 @@ internal class InitializeWalletsTransformer( walletsBalanceUM = WalletBalanceUM.Loading( id = walletId, name = name, + deviceIcon = getWalletIconUseCase.invoke(userWallet = this) + .let { WalletIconUMConverter().convert(it) }, ), buttons = createWalletActions(userWallet = this), type = when (this) { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ReinitializeNewWalletTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ReinitializeNewWalletTransformer.kt index 59a5358db8..0c1b198d0c 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ReinitializeNewWalletTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ReinitializeNewWalletTransformer.kt @@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.wallets.usecase.GetWalletIconUseCase import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.presentation.wallet.domain.WalletImageResolver import com.tangem.feature.wallet.presentation.wallet.state.model.WalletScreenState @@ -22,12 +23,14 @@ internal class ReinitializeNewWalletTransformer( private val newUserWallet: UserWallet, private val clickIntents: WalletClickIntents, private val walletImageResolver: WalletImageResolver, + private val getWalletIconUseCase: GetWalletIconUseCase, ) : WalletScreenStateTransformer { private val walletLoadingStateFactory by lazy { WalletLoadingStateFactory( clickIntents = clickIntents, walletImageResolver = walletImageResolver, + getWalletIconUseCase = getWalletIconUseCase, ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ReinitializeWalletTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ReinitializeWalletTransformer.kt index fc2ade623b..6dab085776 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ReinitializeWalletTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ReinitializeWalletTransformer.kt @@ -1,6 +1,7 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.wallets.usecase.GetWalletIconUseCase import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.presentation.wallet.domain.WalletImageResolver import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState @@ -18,12 +19,14 @@ internal class ReinitializeWalletTransformer( private val userWallet: UserWallet, private val clickIntents: WalletClickIntents, private val walletImageResolver: WalletImageResolver, + private val getWalletIconUseCase: GetWalletIconUseCase, ) : WalletStateTransformer(userWalletId = userWallet.walletId) { private val walletLoadingStateFactory by lazy { WalletLoadingStateFactory( clickIntents = clickIntents, walletImageResolver = walletImageResolver, + getWalletIconUseCase = getWalletIconUseCase, ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListErrorTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListErrorTransformer.kt index aacaf7a5d2..0d7dc02991 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListErrorTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListErrorTransformer.kt @@ -91,6 +91,7 @@ internal class SetTokenListErrorTransformer( return WalletBalanceUM.Content( id = id, name = name, + deviceIcon = deviceIcon, balanceInAppBar = BigDecimal.ZERO.formatStyled { fiat( fiatCurrencyCode = appCurrency.code, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UnlockWalletTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UnlockWalletTransformer.kt index 126d447ac9..fcef9841df 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UnlockWalletTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UnlockWalletTransformer.kt @@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.wallets.usecase.GetWalletIconUseCase import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.presentation.wallet.domain.WalletImageResolver import com.tangem.feature.wallet.presentation.wallet.state.model.WalletScreenState @@ -16,12 +17,14 @@ internal class UnlockWalletTransformer( private val unlockedWallets: List, private val clickIntents: WalletClickIntents, private val walletImageResolver: WalletImageResolver, + private val getWalletIconUseCase: GetWalletIconUseCase, ) : WalletScreenStateTransformer { private val walletLoadingStateFactory by lazy { WalletLoadingStateFactory( clickIntents = clickIntents, walletImageResolver = walletImageResolver, + getWalletIconUseCase = getWalletIconUseCase, ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletBalanceUMTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletBalanceUMTransformer.kt index 8369a81071..d3a37dbb31 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletBalanceUMTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletBalanceUMTransformer.kt @@ -28,6 +28,7 @@ internal class MultiWalletBalanceUMTransformer( return WalletBalanceUM.Loading( id = id, name = name, + deviceIcon = deviceIcon, ) } @@ -35,6 +36,7 @@ internal class MultiWalletBalanceUMTransformer( return WalletBalanceUM.Error( id = id, name = name, + deviceIcon = deviceIcon, ) } @@ -42,6 +44,7 @@ internal class MultiWalletBalanceUMTransformer( return WalletBalanceUM.Content( id = id, name = name, + deviceIcon = deviceIcon, balanceInAppBar = fiatBalance.amount.formatStyled { fiat( fiatCurrencyCode = appCurrency.code, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt index 673b914f18..06d9f69510 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt @@ -1,5 +1,6 @@ package com.tangem.feature.wallet.presentation.wallet.state.utils +import com.tangem.common.ui.userwallet.converter.WalletIconUMConverter import com.tangem.core.analytics.models.event.MainScreenAnalyticsEvent.Companion.WALLET_TYPE import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig import com.tangem.core.ui.components.marketprice.MarketPriceBlockState @@ -10,6 +11,7 @@ import com.tangem.domain.card.common.util.cardTypesResolver import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.models.wallet.isMultiCurrency +import com.tangem.domain.wallets.usecase.GetWalletIconUseCase import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.impl.R import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory @@ -30,6 +32,7 @@ import kotlinx.coroutines.flow.MutableStateFlow internal class WalletLoadingStateFactory( private val clickIntents: WalletClickIntents, private val walletImageResolver: WalletImageResolver, + private val getWalletIconUseCase: GetWalletIconUseCase, ) { fun create(userWallet: UserWallet): WalletState { @@ -52,6 +55,8 @@ internal class WalletLoadingStateFactory( walletsBalanceUM = WalletBalanceUM.Loading( id = userWallet.walletId, name = userWallet.name, + deviceIcon = getWalletIconUseCase.invoke(userWallet = userWallet) + .let { WalletIconUMConverter().convert(it) }, ), buttons = createWalletActions(userWallet), notifications = persistentListOf(), diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletBalance.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletBalance.kt index d5e4a5649a..0d4a5903ce 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletBalance.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletBalance.kt @@ -8,7 +8,6 @@ import androidx.compose.animation.fadeOut import androidx.compose.animation.togetherWith import androidx.compose.foundation.layout.* import androidx.compose.foundation.text.TextAutoSize -import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.key @@ -16,21 +15,19 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.scale -import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.testTag -import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp -import com.tangem.core.ui.R import com.tangem.core.ui.components.SpacerH import com.tangem.core.ui.components.TextShimmer import com.tangem.core.ui.components.text.applyBladeBrush import com.tangem.core.ui.ds.button.SecondaryTangemButton import com.tangem.core.ui.ds.button.TangemButtonShape import com.tangem.core.ui.ds.button.TangemButtonUM +import com.tangem.core.ui.ds.image.TangemDeviceIcon import com.tangem.core.ui.ds.topbar.collapsing.TangemCollapsingAppBarBehavior import com.tangem.core.ui.ds.topbar.collapsing.rememberTangemExitUntilCollapsedScrollBehavior import com.tangem.core.ui.ds.topbar.collapsing.snapToExitUntilCollapsed @@ -87,19 +84,14 @@ internal fun WalletBalance( SpacerH(TangemTheme.dimens2.x3) Row( verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2), + horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1), ) { Text( text = walletBalanceUM.name, style = TangemTheme.typography2.bodyRegular14, color = TangemTheme.colors2.text.neutral.tertiary, ) - Icon( - imageVector = ImageVector.vectorResource(R.drawable.ic_tangem_24), - contentDescription = null, - tint = TangemTheme.colors2.graphic.neutral.tertiaryConstant, - modifier = Modifier.size(TangemTheme.dimens2.x6), - ) + TangemDeviceIcon(state = walletBalanceUM.deviceIcon) } } SpacerH(TangemTheme.dimens2.x2)