Updated on 2026-08-14
This commit is contained in:
parent
1858d5453a
commit
90abe449d6
23 changed files with 1741 additions and 11 deletions
202
core/ui/src/main/java/com/tangem/core/ui/ds/image/DeviceIcon.kt
Normal file
202
core/ui/src/main/java/com/tangem/core/ui/ds/image/DeviceIcon.kt
Normal file
|
|
@ -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<Pair<String, DeviceIconUM>>
|
||||
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
|
||||
|
|
@ -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
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
5
core/ui/src/main/res/drawable/ic_shield_24.xml
Normal file
5
core/ui/src/main/res/drawable/ic_shield_24.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||
|
||||
<path android:fillColor="#000000" android:pathData="M12,21C11.922,21 11.824,20.984 11.707,20.952C11.596,20.927 11.478,20.882 11.354,20.818C9.992,20.06 8.838,19.391 7.892,18.811C6.954,18.232 6.197,17.671 5.623,17.129C5.056,16.581 4.642,15.992 4.381,15.361C4.127,14.724 4,13.975 4,13.115V5.909C4,5.418 4.108,5.065 4.323,4.848C4.538,4.625 4.848,4.434 5.252,4.275C5.48,4.185 5.793,4.068 6.191,3.921C6.588,3.768 7.025,3.606 7.501,3.434C7.984,3.255 8.463,3.083 8.939,2.918C9.421,2.745 9.861,2.593 10.259,2.459C10.657,2.319 10.97,2.21 11.198,2.134C11.328,2.096 11.459,2.064 11.589,2.038C11.726,2.013 11.863,2 12,2C12.137,2 12.274,2.013 12.411,2.038C12.548,2.064 12.681,2.096 12.812,2.134C13.04,2.21 13.35,2.319 13.741,2.459C14.139,2.593 14.575,2.745 15.051,2.918C15.534,3.09 16.013,3.262 16.489,3.434C16.972,3.606 17.412,3.765 17.809,3.911C18.207,4.058 18.52,4.179 18.748,4.275C19.159,4.44 19.469,4.631 19.677,4.848C19.892,5.065 20,5.418 20,5.909V13.115C20,13.975 19.876,14.73 19.628,15.38C19.381,16.024 18.973,16.626 18.406,17.187C17.845,17.747 17.092,18.314 16.147,18.888C15.208,19.461 14.041,20.105 12.646,20.818C12.522,20.882 12.401,20.927 12.284,20.952C12.173,20.984 12.078,21 12,21ZM7.599,11.815C7.599,11.943 7.641,12.048 7.726,12.131C7.817,12.207 7.928,12.245 8.059,12.245H11.482L9.653,17.034C9.568,17.244 9.571,17.416 9.663,17.55C9.76,17.684 9.894,17.754 10.064,17.76C10.233,17.76 10.386,17.674 10.523,17.502L16.049,10.726C16.16,10.598 16.215,10.471 16.215,10.344C16.215,10.216 16.17,10.111 16.078,10.028C15.993,9.945 15.886,9.904 15.755,9.904H12.333L14.161,5.116C14.246,4.905 14.24,4.737 14.142,4.609C14.05,4.475 13.92,4.408 13.751,4.408C13.588,4.402 13.434,4.485 13.291,4.657L7.765,11.433C7.654,11.554 7.599,11.682 7.599,11.815Z"/>
|
||||
|
||||
</vector>
|
||||
Loading…
Add table
Add a link
Reference in a new issue