Updated on 2026-08-14
This commit is contained in:
commit
03bd081b97
15 changed files with 269 additions and 4 deletions
|
|
@ -3,7 +3,6 @@ package com.tangem.tap.features.customtoken.impl.presentation.ui.components
|
|||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
|
|
@ -30,7 +29,7 @@ import com.tangem.wallet.R
|
|||
internal fun AddCustomTokenWarning(description: TextReference, modifier: Modifier = Modifier) {
|
||||
Card(
|
||||
modifier = modifier,
|
||||
shape = RoundedCornerShape(TangemTheme.dimens.radius4),
|
||||
shape = TangemTheme.shapes.roundedCornersSmall2,
|
||||
backgroundColor = TangemColorPalette.Tangerine,
|
||||
contentColor = TangemColorPalette.White,
|
||||
elevation = TangemTheme.dimens.elevation4,
|
||||
|
|
|
|||
|
|
@ -65,7 +65,9 @@ data class TangemDimens internal constructor(
|
|||
val size93: Dp = 93.dp,
|
||||
val size96: Dp = 96.dp,
|
||||
val size102: Dp = 102.dp,
|
||||
val size108: Dp = 108.dp,
|
||||
val size116: Dp = 116.dp,
|
||||
val size120: Dp = 120.dp,
|
||||
val size142: Dp = 142.dp,
|
||||
val size164: Dp = 164.dp,
|
||||
val size200: Dp = 200.dp,
|
||||
|
|
@ -95,5 +97,6 @@ data class TangemDimens internal constructor(
|
|||
val spacing54: Dp = 54.dp,
|
||||
val spacing56: Dp = 56.dp,
|
||||
val spacing92: Dp = 92.dp,
|
||||
val spacing154: Dp = 154.dp,
|
||||
// endregion Spacing
|
||||
)
|
||||
|
|
@ -9,6 +9,7 @@ data class TangemShapes internal constructor(
|
|||
val roundedCornersSmall: Shape,
|
||||
val roundedCornersSmall2: Shape,
|
||||
val roundedCornersMedium: Shape,
|
||||
val roundedCornersXMedium: Shape,
|
||||
val roundedCornersLarge: Shape,
|
||||
val bottomSheet: Shape,
|
||||
) {
|
||||
|
|
@ -16,6 +17,7 @@ data class TangemShapes internal constructor(
|
|||
roundedCornersSmall = RoundedCornerShape(size = dimens.radius2),
|
||||
roundedCornersSmall2 = RoundedCornerShape(size = dimens.radius4),
|
||||
roundedCornersMedium = RoundedCornerShape(size = dimens.radius12),
|
||||
roundedCornersXMedium = RoundedCornerShape(size = dimens.radius16),
|
||||
roundedCornersLarge = RoundedCornerShape(size = dimens.radius28),
|
||||
bottomSheet = RoundedCornerShape(
|
||||
topStart = dimens.radius16,
|
||||
|
|
|
|||
9
core/ui/src/main/res/drawable/ic_eye_off_24.xml
Normal file
9
core/ui/src/main/res/drawable/ic_eye_off_24.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M2,5.27L3.28,4L20,20.72L18.73,22L15.65,18.92C14.5,19.3 13.28,19.5 12,19.5C7,19.5 2.73,16.39 1,12C1.69,10.24 2.79,8.69 4.19,7.46L2,5.27ZM12,9C12.796,9 13.559,9.316 14.121,9.879C14.684,10.441 15,11.204 15,12C15,12.35 14.94,12.69 14.83,13L11,9.17C11.31,9.06 11.65,9 12,9ZM12,4.5C17,4.5 21.27,7.61 23,12C22.18,14.08 20.79,15.88 19,17.19L17.58,15.76C18.94,14.82 20.06,13.54 20.82,12C19.17,8.64 15.76,6.5 12,6.5C10.91,6.5 9.84,6.68 8.84,7L7.3,5.47C8.74,4.85 10.33,4.5 12,4.5ZM3.18,12C4.83,15.36 8.24,17.5 12,17.5C12.69,17.5 13.37,17.43 14,17.29L11.72,15C10.29,14.85 9.15,13.71 9,12.28L5.6,8.87C4.61,9.72 3.78,10.78 3.18,12Z"
|
||||
android:fillColor="#000000"/>
|
||||
</vector>
|
||||
1
features/wallet/api/.gitignore
vendored
Normal file
1
features/wallet/api/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
5
features/wallet/api/build.gradle.kts
Normal file
5
features/wallet/api/build.gradle.kts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
plugins {
|
||||
alias(deps.plugins.android.library)
|
||||
alias(deps.plugins.kotlin.android)
|
||||
id("configuration")
|
||||
}
|
||||
2
features/wallet/api/src/main/AndroidManifest.xml
Normal file
2
features/wallet/api/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="com.tangem.features.wallet.api" />
|
||||
1
features/wallet/impl/.gitignore
vendored
Normal file
1
features/wallet/impl/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
34
features/wallet/impl/build.gradle.kts
Normal file
34
features/wallet/impl/build.gradle.kts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
plugins {
|
||||
alias(deps.plugins.android.library)
|
||||
alias(deps.plugins.kotlin.android)
|
||||
alias(deps.plugins.kotlin.kapt)
|
||||
alias(deps.plugins.hilt.android)
|
||||
id("configuration")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
/** AndroidX */
|
||||
implementation(deps.androidx.activity.compose)
|
||||
|
||||
/** Compose */
|
||||
implementation(deps.compose.material)
|
||||
implementation(deps.compose.foundation)
|
||||
implementation(deps.compose.navigation)
|
||||
implementation(deps.compose.navigation.hilt)
|
||||
implementation(deps.compose.ui)
|
||||
implementation(deps.compose.ui.tooling)
|
||||
implementation(deps.compose.shimmer)
|
||||
implementation(deps.compose.accompanist.systemUiController)
|
||||
|
||||
/** DI */
|
||||
implementation(deps.hilt.android)
|
||||
kapt(deps.hilt.kapt)
|
||||
|
||||
/** Core modules */
|
||||
implementation(project(":core:featuretoggles"))
|
||||
implementation(project(":core:ui"))
|
||||
|
||||
/** Feature Apis */
|
||||
implementation(project(":features:wallet:api"))
|
||||
|
||||
}
|
||||
4
features/wallet/impl/src/main/AndroidManifest.xml
Normal file
4
features/wallet/impl/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.tangem.feature.wallet.impl">
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package com.tangem.feature.main.presentation.ui
|
||||
|
||||
enum class BalanceUIState {
|
||||
VISIBLE, LOADING, HIDDEN, NONE
|
||||
}
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
package com.tangem.feature.main.presentation.ui
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.*
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.valentinilk.shimmer.shimmer
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun WalletHeaderCard(config: WalletHeaderConfig, modifier: Modifier = Modifier) {
|
||||
Surface(
|
||||
modifier = modifier.defaultMinSize(minHeight = TangemTheme.dimens.size108),
|
||||
shape = TangemTheme.shapes.roundedCornersXMedium,
|
||||
color = TangemTheme.colors.background.primary,
|
||||
onClick = config.onClick ?: {},
|
||||
enabled = config.onClick != null,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(intrinsicSize = IntrinsicSize.Max),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(all = TangemTheme.dimens.spacing12),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
|
||||
) {
|
||||
HeaderWalletName(
|
||||
walletName = config.walletName,
|
||||
balanceState = config.balanceState,
|
||||
)
|
||||
HeaderBalanceTitle(
|
||||
balance = config.balance,
|
||||
balanceState = config.balanceState,
|
||||
)
|
||||
Text(
|
||||
text = config.additionalInfo,
|
||||
color = TangemTheme.colors.text.disabled,
|
||||
style = TangemTheme.typography.caption,
|
||||
)
|
||||
}
|
||||
Image(
|
||||
modifier = Modifier
|
||||
.width(TangemTheme.dimens.size120)
|
||||
.padding(end = TangemTheme.dimens.spacing18)
|
||||
.fillMaxHeight(),
|
||||
painter = config.cardImage,
|
||||
contentDescription = null,
|
||||
contentScale = ContentScale.FillWidth,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HeaderWalletName(walletName: String, balanceState: BalanceUIState) {
|
||||
if (balanceState == BalanceUIState.HIDDEN) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing4)) {
|
||||
Text(
|
||||
text = walletName,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography.body2,
|
||||
maxLines = 1,
|
||||
)
|
||||
Icon(
|
||||
modifier = Modifier.size(size = TangemTheme.dimens.size20),
|
||||
painter = painterResource(id = R.drawable.ic_eye_off_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.informative,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Text(
|
||||
text = walletName,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography.body2,
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HeaderBalanceTitle(balance: String, balanceState: BalanceUIState) {
|
||||
when (balanceState) {
|
||||
BalanceUIState.VISIBLE -> {
|
||||
ResizableText(
|
||||
text = balance,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
style = TangemTheme.typography.h2,
|
||||
fontSizeRange = FontSizeRange(min = 16.sp, max = TangemTheme.typography.h2.fontSize),
|
||||
modifier = Modifier.defaultMinSize(minHeight = TangemTheme.dimens.size32),
|
||||
)
|
||||
}
|
||||
BalanceUIState.LOADING -> {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(vertical = TangemTheme.dimens.spacing4)
|
||||
.size(width = TangemTheme.dimens.size102, height = TangemTheme.dimens.size24)
|
||||
.shimmer()
|
||||
.background(
|
||||
color = TangemTheme.colors.button.secondary,
|
||||
shape = RoundedCornerShape(TangemTheme.dimens.radius6),
|
||||
),
|
||||
)
|
||||
}
|
||||
BalanceUIState.HIDDEN -> {
|
||||
Text(
|
||||
text = "•••",
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
style = TangemTheme.typography.h2,
|
||||
)
|
||||
}
|
||||
BalanceUIState.NONE -> {
|
||||
Text(
|
||||
text = "—",
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
style = TangemTheme.typography.h2,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// region Preview
|
||||
|
||||
@Composable
|
||||
private fun WarningsPreview() {
|
||||
val walletHeaderConfig = WalletHeaderConfig(
|
||||
walletName = "Wallet 1",
|
||||
balance = "8923,05 $",
|
||||
additionalInfo = "3 cards • Seed enabled",
|
||||
balanceState = BalanceUIState.VISIBLE,
|
||||
cardImage = painterResource(id = R.drawable.ill_businessman_3d),
|
||||
onClick = {},
|
||||
)
|
||||
Column(modifier = Modifier.fillMaxWidth()) {
|
||||
WalletHeaderCard(
|
||||
config = walletHeaderConfig,
|
||||
)
|
||||
SpacerH32()
|
||||
WalletHeaderCard(
|
||||
config = walletHeaderConfig.copy(balanceState = BalanceUIState.HIDDEN),
|
||||
)
|
||||
SpacerH32()
|
||||
WalletHeaderCard(
|
||||
config = walletHeaderConfig.copy(balanceState = BalanceUIState.LOADING),
|
||||
)
|
||||
SpacerH32()
|
||||
WalletHeaderCard(
|
||||
config = walletHeaderConfig.copy(balanceState = BalanceUIState.NONE),
|
||||
)
|
||||
SpacerH32()
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun Preview_Warning_InLightTheme() {
|
||||
TangemTheme(isDark = false) {
|
||||
WarningsPreview()
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun Preview_Warning_InDarkTheme() {
|
||||
TangemTheme(isDark = true) {
|
||||
WarningsPreview()
|
||||
}
|
||||
}
|
||||
|
||||
// endregion Preview
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.feature.main.presentation.ui
|
||||
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
|
||||
data class WalletHeaderConfig(
|
||||
val walletName: String,
|
||||
val balance: String,
|
||||
val additionalInfo: String,
|
||||
val balanceState: BalanceUIState,
|
||||
val cardImage: Painter,
|
||||
val onClick: (() -> Unit)?,
|
||||
)
|
||||
|
|
@ -20,10 +20,10 @@ internal fun BaseExtension.configureCompilerOptions() {
|
|||
internal fun BaseExtension.configureCompose(project: Project) {
|
||||
val useCompose = with(project.path) {
|
||||
contains(":ui") ||
|
||||
contains(":onboarding") ||
|
||||
contains(":onboarding") || // TODO: divide on api/impl after migrating all onboarding to module
|
||||
contains(":presentation") ||
|
||||
contains(":app") || // TODO: [REDACTED_JIRA]
|
||||
contains(":tester:impl") // TODO: Rename module
|
||||
contains(":impl")
|
||||
}
|
||||
buildFeatures.compose = useCompose
|
||||
if (useCompose) {
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@ include(":features:swap:presentation")
|
|||
|
||||
include(":features:tester:api")
|
||||
include(":features:tester:impl")
|
||||
|
||||
include(":features:wallet:api")
|
||||
include(":features:wallet:impl")
|
||||
// endregion Feature modules
|
||||
|
||||
// region Domain modules
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue