diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/ActionConfig.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/ActionButtonConfig.kt
similarity index 93%
rename from core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/ActionConfig.kt
rename to core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/ActionButtonConfig.kt
index dbfc71c767..3e69942c7f 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/ActionConfig.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/ActionButtonConfig.kt
@@ -12,7 +12,7 @@ import androidx.annotation.DrawableRes
*
[REDACTED_AUTHOR]
*/
-data class ActionConfig(
+data class ActionButtonConfig(
val text: String,
@DrawableRes val iconResId: Int,
val onClick: () -> Unit,
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt
index e755e7c8b9..027bad2d0c 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt
@@ -1,96 +1,150 @@
package com.tangem.core.ui.components.buttons.actions
-import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Icon
+import androidx.compose.material.Text
import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+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.datasource.CollectionPreviewParameterProvider
import com.tangem.core.ui.R
-import com.tangem.core.ui.components.buttons.common.TangemButton
-import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
-import com.tangem.core.ui.components.buttons.common.TangemButtonSize
-import com.tangem.core.ui.components.buttons.common.TangemButtonsDefaults
+import com.tangem.core.ui.components.SpacerW8
+import com.tangem.core.ui.components.buttons.common.*
import com.tangem.core.ui.res.TangemTheme
/**
- * [Show in Figma](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=290-305&t=3z98eFnTeyIx5TH5-4)
+ * Rounded action button
+ *
+ * @param config component config
+ * @param modifier modifier
+ * @param color background color
+ *
+ * @see Show in Figma
*/
@Composable
-fun RoundedActionButton(config: ActionConfig, modifier: Modifier = Modifier) {
- TangemButton(
+fun RoundedActionButton(
+ config: ActionButtonConfig,
+ modifier: Modifier = Modifier,
+ color: Color = TangemTheme.colors.button.secondary,
+) {
+ Button(
+ config = config,
+ shape = RoundedCornerShape(size = TangemTheme.dimens.radius24),
modifier = modifier,
- text = config.text,
- icon = TangemButtonIconPosition.Start(config.iconResId),
- onClick = config.onClick,
- enabled = config.enabled,
- showProgress = false,
- colors = TangemButtonsDefaults.secondaryButtonColors,
- size = TangemButtonSize.RoundedAction,
+ color = color,
)
}
/**
- * [Show in Figma](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=1208-1395&t=3z98eFnTeyIx5TH5-4)
+ * Action button
+ *
+ * @param config component config
+ * @param modifier modifier
+ * @param color background color
+ *
+ * @see Show in Figma
*/
@Composable
-fun ActionButton(config: ActionConfig, modifier: Modifier = Modifier) {
- TangemButton(
+fun ActionButton(
+ config: ActionButtonConfig,
+ modifier: Modifier = Modifier,
+ color: Color = TangemTheme.colors.button.secondary,
+) {
+ Button(
+ config = config,
+ shape = RoundedCornerShape(size = TangemTheme.dimens.radius12),
modifier = modifier,
- text = config.text,
- icon = TangemButtonIconPosition.Start(config.iconResId),
- onClick = config.onClick,
- enabled = config.enabled,
- showProgress = false,
- colors = TangemButtonsDefaults.secondaryButtonColors,
- size = TangemButtonSize.Action,
+ color = color,
)
}
-/**
- * Same as [RoundedActionButton] but colored in primary background color
- */
@Composable
-fun BackgroundActionButton(config: ActionConfig, modifier: Modifier = Modifier) {
- TangemButton(
- modifier = modifier,
- text = config.text,
- icon = TangemButtonIconPosition.Start(config.iconResId),
- onClick = config.onClick,
- enabled = config.enabled,
- showProgress = false,
- colors = TangemButtonsDefaults.backgroundButtonColors,
- size = TangemButtonSize.RoundedAction,
- )
+private fun Button(
+ config: ActionButtonConfig,
+ shape: RoundedCornerShape,
+ modifier: Modifier = Modifier,
+ color: Color = TangemTheme.colors.button.secondary,
+) {
+ Row(
+ modifier = modifier
+ .clickable(enabled = config.enabled, onClick = config.onClick)
+ .heightIn(min = TangemTheme.dimens.size36)
+ .background(
+ color = if (config.enabled) color else TangemTheme.colors.button.disabled,
+ shape = shape,
+ )
+ .padding(
+ start = TangemTheme.dimens.spacing16,
+ end = TangemTheme.dimens.spacing24,
+ )
+ .padding(vertical = TangemTheme.dimens.spacing8),
+ horizontalArrangement = Arrangement.Center,
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Icon(
+ painter = painterResource(id = config.iconResId),
+ contentDescription = null,
+ modifier = Modifier.size(size = TangemTheme.dimens.size20),
+ tint = if (config.enabled) TangemTheme.colors.icon.primary1 else TangemTheme.colors.icon.informative,
+ )
+
+ SpacerW8()
+
+ Text(
+ text = config.text,
+ color = if (config.enabled) TangemTheme.colors.text.primary1 else TangemTheme.colors.text.disabled,
+ overflow = TextOverflow.Ellipsis,
+ maxLines = 1,
+ style = TangemTheme.typography.button,
+ )
+ }
}
-@Preview(showBackground = true)
+@Preview(group = "RoundedActionButton", showBackground = true)
@Composable
-private fun Preview_ActionButton_Light(@PreviewParameter(ActionStateProvider::class) state: ActionConfig) {
+private fun Preview_RoundedActionButton_Light(@PreviewParameter(ActionStateProvider::class) state: ActionButtonConfig) {
TangemTheme(isDark = false) {
- Column {
- RoundedActionButton(state)
- ActionButton(state)
- BackgroundActionButton(state)
- }
+ RoundedActionButton(state)
}
}
-@Preview(showBackground = true)
+@Preview(group = "RoundedActionButton", showBackground = true)
@Composable
-private fun Preview_ActionButton_Dark(@PreviewParameter(ActionStateProvider::class) state: ActionConfig) {
- TangemTheme {
- Column {
- RoundedActionButton(state)
- ActionButton(state)
- BackgroundActionButton(state)
- }
+private fun Preview_RoundedActionButton_Dark(@PreviewParameter(ActionStateProvider::class) state: ActionButtonConfig) {
+ TangemTheme(isDark = true) {
+ RoundedActionButton(state)
}
}
-private class ActionStateProvider : CollectionPreviewParameterProvider(
+@Preview(group = "ActionButton", showBackground = true)
+@Composable
+private fun Preview_ActionButton_Light(@PreviewParameter(ActionStateProvider::class) state: ActionButtonConfig) {
+ TangemTheme(isDark = false) {
+ ActionButton(state)
+ }
+}
+
+@Preview(group = "ActionButton", showBackground = true)
+@Composable
+private fun Preview_ActionButton_Dark(@PreviewParameter(ActionStateProvider::class) state: ActionButtonConfig) {
+ TangemTheme(isDark = true) {
+ ActionButton(state)
+ }
+}
+
+private class ActionStateProvider : CollectionPreviewParameterProvider(
collection = listOf(
- ActionConfig(text = "Send", iconResId = R.drawable.ic_arrow_up_24, onClick = {}),
- ActionConfig(text = "Receive", iconResId = R.drawable.ic_arrow_down_24, enabled = false, onClick = {}),
+ ActionButtonConfig(text = "Enabled", iconResId = R.drawable.ic_arrow_up_24, enabled = true, onClick = {}),
+ ActionButtonConfig(text = "Disabled", iconResId = R.drawable.ic_arrow_down_24, enabled = false, onClick = {}),
),
)
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/notifications/Notification.kt b/core/ui/src/main/java/com/tangem/core/ui/components/notifications/Notification.kt
index db338c9721..5bc16b167a 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/notifications/Notification.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/notifications/Notification.kt
@@ -2,10 +2,11 @@ package com.tangem.core.ui.components.notifications
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
-import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@@ -32,19 +33,23 @@ import com.tangem.core.ui.res.TangemTheme
*/
@Composable
fun Notification(state: NotificationState, modifier: Modifier = Modifier) {
- Surface(
- onClick = if (state is NotificationState.Action) {
- state.onClick
- } else {
- {}
- },
- modifier = modifier,
- enabled = when (state) {
- is NotificationState.Simple -> false
- is NotificationState.Action -> true
- },
- shape = RoundedCornerShape(TangemTheme.dimens.radius18),
- color = TangemTheme.colors.button.secondary,
+ Box(
+ modifier = modifier
+ .clickable(
+ enabled = when (state) {
+ is NotificationState.Simple -> false
+ is NotificationState.Action -> true
+ },
+ onClick = if (state is NotificationState.Action) {
+ state.onClick
+ } else {
+ {}
+ },
+ )
+ .background(
+ color = TangemTheme.colors.button.secondary,
+ RoundedCornerShape(size = TangemTheme.dimens.radius18),
+ ),
) {
Box(
modifier = Modifier
diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt b/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt
index 14449b2c45..27a26b7c76 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt
@@ -30,6 +30,7 @@ data class TangemDimens internal constructor(
val radius12: Dp = 12.dp,
val radius16: Dp = 16.dp,
val radius18: Dp = 18.dp,
+ val radius24: Dp = 24.dp,
val radius28: Dp = 28.dp,
// endregion Radius
// region Size
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt
index 42f47eeb7f..883b5c626d 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt
@@ -49,6 +49,17 @@ internal object WalletPreviewData {
onClick = {},
)
+ val walletListConfig = WalletsListConfig(
+ selectedWalletIndex = 0,
+ wallets = persistentListOf(
+ walletCardContentState,
+ walletCardLoadingState,
+ walletCardHiddenContentState,
+ walletCardErrorState,
+ ),
+ onWalletChange = {},
+ )
+
val tokenItemVisibleState = TokenItemState.Content(
id = UUID.randomUUID().toString(),
tokenIconUrl = null,
@@ -195,13 +206,7 @@ internal object WalletPreviewData {
val multicurrencyWalletScreenState = WalletStateHolder.MultiCurrencyContent(
onBackClick = {},
topBarConfig = walletTopBarConfig,
- selectedWallet = walletCardContentState,
- wallets = persistentListOf(
- walletCardContentState,
- walletCardLoadingState,
- walletCardHiddenContentState,
- walletCardErrorState,
- ),
+ walletsListConfig = walletListConfig,
contentItems = persistentListOf(
WalletContentItemState.MultiCurrencyItem.NetworkGroupTitle("Bitcoin"),
WalletContentItemState.MultiCurrencyItem.Token(
@@ -263,13 +268,7 @@ internal object WalletPreviewData {
val singleWalletScreenState = WalletStateHolder.SingleCurrencyContent(
onBackClick = {},
topBarConfig = walletTopBarConfig,
- selectedWallet = walletCardContentState,
- wallets = persistentListOf(
- walletCardContentState,
- walletCardLoadingState,
- walletCardHiddenContentState,
- walletCardErrorState,
- ),
+ walletsListConfig = walletListConfig,
contentItems = persistentListOf(
WalletContentItemState.SingleCurrencyItem.Title(onExploreClick = {}),
WalletContentItemState.SingleCurrencyItem.TransactionGroupTitle("Today"),
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensScreen.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensScreen.kt
index 8aacb95163..d0967c3046 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensScreen.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensScreen.kt
@@ -23,8 +23,8 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import com.tangem.core.ui.components.PrimaryButton
import com.tangem.core.ui.components.SecondaryButton
-import com.tangem.core.ui.components.buttons.actions.ActionConfig
-import com.tangem.core.ui.components.buttons.actions.BackgroundActionButton
+import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig
+import com.tangem.core.ui.components.buttons.actions.RoundedActionButton
import com.tangem.core.ui.res.TangemTheme
import com.tangem.feature.wallet.impl.R
import com.tangem.feature.wallet.presentation.common.WalletPreviewData
@@ -206,21 +206,23 @@ private fun TopBar(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
) {
- BackgroundActionButton(
- config = ActionConfig(
+ RoundedActionButton(
+ config = ActionButtonConfig(
text = stringResource(id = R.string.organize_tokens_sort_by_balance),
iconResId = R.drawable.ic_sort_24,
onClick = config.onSortByBalanceClick,
),
modifier = Modifier.weight(1f),
+ color = TangemTheme.colors.background.primary,
)
- BackgroundActionButton(
- config = ActionConfig(
+ RoundedActionButton(
+ config = ActionButtonConfig(
text = stringResource(id = R.string.organize_tokens_group),
iconResId = R.drawable.ic_group_24,
onClick = config.onGroupByNetworkClick,
),
modifier = Modifier.weight(1f),
+ color = TangemTheme.colors.background.primary,
)
}
}
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt
index b963f8f7b7..0e1c8436b3 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt
@@ -34,10 +34,7 @@ internal class DefaultWalletRouter : InnerWalletRouter {
) {
composable(WalletScreens.WALLET.name) {
val viewModel = hiltViewModel().apply { router = this@DefaultWalletRouter }
- WalletScreen(
- modifier = Modifier.systemBarsPadding(),
- state = viewModel.uiState,
- )
+ WalletScreen(state = viewModel.uiState)
}
composable(WalletScreens.ORGANIZE_TOKENS.name) {
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletManageButton.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletManageButton.kt
index c4e41ed1b6..e5f6115aaa 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletManageButton.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletManageButton.kt
@@ -1,6 +1,6 @@
package com.tangem.feature.wallet.presentation.wallet.state
-import com.tangem.core.ui.components.buttons.actions.ActionConfig
+import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig
import com.tangem.feature.wallet.impl.R
/**
@@ -10,7 +10,7 @@ import com.tangem.feature.wallet.impl.R
*
[REDACTED_AUTHOR]
*/
-sealed class WalletManageButton(val config: ActionConfig) {
+sealed class WalletManageButton(val config: ActionButtonConfig) {
/**
* Buy
@@ -18,7 +18,7 @@ sealed class WalletManageButton(val config: ActionConfig) {
* @param onClick lambda be invoked when manage button is clicked
*/
data class Buy(val onClick: () -> Unit) : WalletManageButton(
- config = ActionConfig(
+ config = ActionButtonConfig(
text = "Buy",
iconResId = R.drawable.ic_plus_24,
onClick = onClick,
@@ -31,7 +31,7 @@ sealed class WalletManageButton(val config: ActionConfig) {
* @param onClick lambda be invoked when manage button is clicked
*/
data class Send(val onClick: () -> Unit) : WalletManageButton(
- config = ActionConfig(
+ config = ActionButtonConfig(
text = "Send",
iconResId = R.drawable.ic_arrow_up_24,
onClick = onClick,
@@ -44,7 +44,7 @@ sealed class WalletManageButton(val config: ActionConfig) {
* @param onClick lambda be invoked when manage button is clicked
*/
data class Receive(val onClick: () -> Unit) : WalletManageButton(
- config = ActionConfig(
+ config = ActionButtonConfig(
text = "Receive",
iconResId = R.drawable.ic_arrow_down_24,
onClick = onClick,
@@ -57,7 +57,7 @@ sealed class WalletManageButton(val config: ActionConfig) {
* @param onClick lambda be invoked when manage button is clicked
*/
data class Exchange(val onClick: () -> Unit) : WalletManageButton(
- config = ActionConfig(
+ config = ActionButtonConfig(
text = "Exchange",
iconResId = R.drawable.ic_exchange_vertical_24,
onClick = onClick,
@@ -70,7 +70,7 @@ sealed class WalletManageButton(val config: ActionConfig) {
* @param onClick lambda be invoked when manage button is clicked
*/
data class CopyAddress(val onClick: () -> Unit) : WalletManageButton(
- config = ActionConfig(
+ config = ActionButtonConfig(
text = "Copy address",
iconResId = R.drawable.ic_copy_24,
onClick = onClick,
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletManageButtons.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletManageButtons.kt
index 966ff09e16..1fd2c49db9 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletManageButtons.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletManageButtons.kt
@@ -1,5 +1,6 @@
package com.tangem.feature.wallet.presentation.wallet.state
+import androidx.compose.foundation.background
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
@@ -20,14 +21,16 @@ import kotlinx.collections.immutable.ImmutableList
* Wallet manage buttons
*
* @param buttons manage buttons
+ * @param modifier modifier
*
[REDACTED_AUTHOR]
*/
@Composable
-internal fun WalletManageButtons(buttons: ImmutableList) {
+internal fun WalletManageButtons(buttons: ImmutableList, modifier: Modifier = Modifier) {
Row(
- modifier = Modifier
+ modifier = modifier
.horizontalScroll(state = rememberScrollState())
+ .background(color = TangemTheme.colors.background.secondary)
.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing8),
) {
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletStateHolder.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletStateHolder.kt
index a1bcc27c31..0e9c80a61a 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletStateHolder.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletStateHolder.kt
@@ -5,20 +5,18 @@ import kotlinx.collections.immutable.ImmutableList
/**
* Wallet screen state holder
*
- * @property onBackClick lambda be invoked when back button is clicked
- * @property topBarConfig top bar config
- * @property selectedWallet selected wallet
- * @property wallets list of wallets states
- * @property contentItems content items
- * @property notifications notifications
+ * @property onBackClick lambda be invoked when back button is clicked
+ * @property topBarConfig top bar config
+ * @property walletsListConfig wallets list config
+ * @property contentItems content items
+ * @property notifications notifications
*
[REDACTED_AUTHOR]
*/
internal sealed class WalletStateHolder(
open val onBackClick: () -> Unit,
open val topBarConfig: WalletTopBarConfig,
- open val selectedWallet: WalletCardState,
- open val wallets: ImmutableList,
+ open val walletsListConfig: WalletsListConfig,
open val contentItems: ImmutableList,
open val notifications: ImmutableList,
) {
@@ -28,8 +26,7 @@ internal sealed class WalletStateHolder(
*
* @property onBackClick lambda be invoked when back button is clicked
* @property topBarConfig top bar config
- * @property selectedWallet selected wallet
- * @property wallets list of wallets states
+ * @property walletsListConfig wallets list config
* @property contentItems content items
* @property notifications notifications
* @property onOrganizeTokensClick lambda be invoked when organize tokens button is clicked
@@ -37,31 +34,28 @@ internal sealed class WalletStateHolder(
data class MultiCurrencyContent(
override val onBackClick: () -> Unit,
override val topBarConfig: WalletTopBarConfig,
- override val selectedWallet: WalletCardState,
- override val wallets: ImmutableList,
+ override val walletsListConfig: WalletsListConfig,
override val contentItems: ImmutableList,
override val notifications: ImmutableList,
val onOrganizeTokensClick: () -> Unit,
- ) : WalletStateHolder(onBackClick, topBarConfig, selectedWallet, wallets, contentItems, notifications)
+ ) : WalletStateHolder(onBackClick, topBarConfig, walletsListConfig, contentItems, notifications)
/**
* Single currency wallet content state
*
- * @property onBackClick lambda be invoked when back button is clicked
- * @property topBarConfig top bar config
- * @property selectedWallet selected wallet
- * @property wallets list of wallets states
- * @property contentItems content items
- * @property notifications notifications
- * @property buttons manage buttons
+ * @property onBackClick lambda be invoked when back button is clicked
+ * @property topBarConfig top bar config
+ * @property walletsListConfig wallets list config
+ * @property contentItems content items
+ * @property notifications notifications
+ * @property buttons manage buttons
*/
data class SingleCurrencyContent(
override val onBackClick: () -> Unit,
override val topBarConfig: WalletTopBarConfig,
- override val selectedWallet: WalletCardState,
- override val wallets: ImmutableList,
+ override val walletsListConfig: WalletsListConfig,
override val contentItems: ImmutableList,
override val notifications: ImmutableList,
val buttons: ImmutableList,
- ) : WalletStateHolder(onBackClick, topBarConfig, selectedWallet, wallets, contentItems, notifications)
+ ) : WalletStateHolder(onBackClick, topBarConfig, walletsListConfig, contentItems, notifications)
}
\ No newline at end of file
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletsListConfig.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletsListConfig.kt
new file mode 100644
index 0000000000..0349eb57bd
--- /dev/null
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletsListConfig.kt
@@ -0,0 +1,18 @@
+package com.tangem.feature.wallet.presentation.wallet.state
+
+import kotlinx.collections.immutable.ImmutableList
+
+/**
+ * Wallets list config
+ *
+ * @property selectedWalletIndex selected wallet index
+ * @property wallets wallets list
+ * @property onWalletChange lambda be invoked when wallet is swiped
+ *
+[REDACTED_AUTHOR]
+ */
+internal data class WalletsListConfig(
+ val selectedWalletIndex: Int,
+ val wallets: ImmutableList,
+ val onWalletChange: (Int) -> Unit,
+)
\ No newline at end of file
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt
index 7378c104e0..2246159c2f 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt
@@ -4,11 +4,8 @@ import androidx.activity.compose.BackHandler
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.itemsIndexed
-import androidx.compose.material3.Icon
-import androidx.compose.material3.Scaffold
-import androidx.compose.material3.Text
+import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -18,7 +15,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
-import com.tangem.core.ui.components.buttons.actions.ActionConfig
+import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig
import com.tangem.core.ui.components.buttons.actions.RoundedActionButton
import com.tangem.core.ui.components.notifications.Notification
import com.tangem.core.ui.components.transactions.Transaction
@@ -30,9 +27,10 @@ import com.tangem.feature.wallet.presentation.common.component.TokenItem
import com.tangem.feature.wallet.presentation.wallet.state.WalletContentItemState
import com.tangem.feature.wallet.presentation.wallet.state.WalletManageButtons
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateHolder
-import com.tangem.feature.wallet.presentation.wallet.ui.components.WalletCardsList
import com.tangem.feature.wallet.presentation.wallet.ui.components.WalletTopBar
+import com.tangem.feature.wallet.presentation.wallet.ui.components.WalletsList
import com.tangem.feature.wallet.presentation.wallet.ui.decorations.walletContentItemDecoration
+import com.tangem.feature.wallet.presentation.wallet.ui.decorations.walletNotificationDecoration
/**
* Wallet screen
@@ -42,7 +40,7 @@ import com.tangem.feature.wallet.presentation.wallet.ui.decorations.walletConten
[REDACTED_AUTHOR]
*/
@Composable
-internal fun WalletScreen(state: WalletStateHolder, modifier: Modifier = Modifier) {
+internal fun WalletScreen(state: WalletStateHolder) {
BackHandler(onBack = state.onBackClick)
Scaffold(
@@ -51,27 +49,42 @@ internal fun WalletScreen(state: WalletStateHolder, modifier: Modifier = Modifie
) { scaffoldPaddings ->
LazyColumn(
- modifier = modifier
+ modifier = Modifier
.padding(paddingValues = scaffoldPaddings)
.fillMaxSize(),
- contentPadding = PaddingValues(
- horizontal = TangemTheme.dimens.spacing16,
- vertical = TangemTheme.dimens.spacing8,
- ),
+ contentPadding = PaddingValues(vertical = TangemTheme.dimens.spacing8),
horizontalAlignment = Alignment.CenterHorizontally,
) {
item {
- WalletCardsList(
- wallets = state.wallets,
- modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12),
+ WalletsList(
+ config = state.walletsListConfig,
+ modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing14),
)
}
if (state is WalletStateHolder.SingleCurrencyContent) {
- item { WalletManageButtons(buttons = state.buttons) }
+ item {
+ WalletManageButtons(
+ buttons = state.buttons,
+ modifier = Modifier
+ .padding(horizontal = TangemTheme.dimens.spacing16)
+ .padding(bottom = TangemTheme.dimens.spacing14),
+ )
+ }
}
- items(items = state.notifications, itemContent = { Notification(state = it.state) })
+ itemsIndexed(
+ items = state.notifications,
+ itemContent = { index, item ->
+ Notification(
+ state = item.state,
+ modifier = Modifier.walletNotificationDecoration(
+ currentIndex = index,
+ lastIndex = state.notifications.lastIndex,
+ ),
+ )
+ },
+ )
itemsIndexed(
items = state.contentItems,
@@ -85,45 +98,40 @@ internal fun WalletScreen(state: WalletStateHolder, modifier: Modifier = Modifie
}
},
itemContent = { index, item ->
- ContentItem(currentIndex = index, lastIndex = state.contentItems.lastIndex, item = item)
+ ContentItem(
+ item = item,
+ modifier = Modifier.walletContentItemDecoration(
+ currentIndex = index,
+ lastIndex = state.contentItems.lastIndex,
+ ),
+ )
},
)
if (state is WalletStateHolder.MultiCurrencyContent) {
- item {
- RoundedActionButton(
- config = ActionConfig(
- text = stringResource(id = R.string.organize_tokens_title),
- iconResId = R.drawable.ic_filter_24,
- onClick = state.onOrganizeTokensClick,
- ),
- modifier = Modifier.padding(top = TangemTheme.dimens.spacing14),
- )
- }
+ item { OrganizeTokensButton(onClick = state.onOrganizeTokensClick) }
}
}
}
}
@Composable
-private fun ContentItem(currentIndex: Int, lastIndex: Int, item: WalletContentItemState) {
- val itemModifier = Modifier.walletContentItemDecoration(currentIndex, lastIndex)
-
+private fun ContentItem(item: WalletContentItemState, modifier: Modifier = Modifier) {
when (item) {
is WalletContentItemState.MultiCurrencyItem.NetworkGroupTitle -> {
- NetworkGroupItem(networkName = item.networkName, modifier = itemModifier)
+ NetworkGroupItem(networkName = item.networkName, modifier = modifier)
}
is WalletContentItemState.MultiCurrencyItem.Token -> {
- TokenItem(state = item.state, modifier = itemModifier)
+ TokenItem(state = item.state, modifier = modifier)
}
is WalletContentItemState.SingleCurrencyItem.Title -> {
- SingleCurrencyTitle(config = item, modifier = itemModifier)
+ SingleCurrencyTitle(config = item, modifier = modifier)
}
is WalletContentItemState.SingleCurrencyItem.TransactionGroupTitle -> {
- TransactionGroupTitle(config = item, modifier = itemModifier)
+ TransactionGroupTitle(config = item, modifier = modifier)
}
is WalletContentItemState.SingleCurrencyItem.Transaction -> {
- Transaction(state = item.state, modifier = itemModifier)
+ Transaction(state = item.state, modifier = modifier)
}
}
}
@@ -186,8 +194,22 @@ private fun TransactionGroupTitle(
)
}
+@Composable
+private fun OrganizeTokensButton(onClick: () -> Unit) {
+ RoundedActionButton(
+ config = ActionButtonConfig(
+ text = stringResource(id = R.string.organize_tokens_title),
+ iconResId = R.drawable.ic_filter_24,
+ onClick = onClick,
+ ),
+ modifier = Modifier
+ .padding(top = TangemTheme.dimens.spacing8)
+ .padding(horizontal = TangemTheme.dimens.spacing16),
+ )
+}
+
// region Preview
-@Preview(showBackground = true, widthDp = 360)
+@Preview
@Composable
private fun WalletScreenPreview_Light(
@PreviewParameter(WalletScreenParameterProvider::class) state: WalletStateHolder,
@@ -197,7 +219,7 @@ private fun WalletScreenPreview_Light(
}
}
-@Preview(showBackground = true, widthDp = 360)
+@Preview
@Composable
private fun WalletScreenPreview_Dark(
@PreviewParameter(WalletScreenParameterProvider::class) state: WalletStateHolder,
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/WalletCardsList.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/WalletsList.kt
similarity index 50%
rename from features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/WalletCardsList.kt
rename to features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/WalletsList.kt
index bbb62e7aa9..bba70f8c1a 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/WalletCardsList.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/WalletsList.kt
@@ -1,15 +1,17 @@
package com.tangem.feature.wallet.presentation.wallet.ui.components
-import androidx.compose.animation.core.*
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
-import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
-import androidx.compose.material3.*
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.tooling.preview.Preview
@@ -17,20 +19,24 @@ import androidx.compose.ui.unit.dp
import com.tangem.core.ui.res.TangemTheme
import com.tangem.feature.wallet.presentation.common.WalletPreviewData
import com.tangem.feature.wallet.presentation.wallet.state.WalletCardState
-import kotlinx.collections.immutable.ImmutableList
-import kotlinx.collections.immutable.persistentListOf
+import com.tangem.feature.wallet.presentation.wallet.state.WalletsListConfig
+import kotlinx.coroutines.InternalCoroutinesApi
+import kotlinx.coroutines.flow.FlowCollector
+
+private const val MIN_OFFSET = -2
+private const val MAX_OFFSET = 2
/**
- * Wallets list
+ * Wallets list component
*
- * @param wallets list of wallet state
+ * @param config config
* @param modifier modifier
*
[REDACTED_AUTHOR]
*/
-@OptIn(ExperimentalFoundationApi::class)
+@OptIn(ExperimentalFoundationApi::class, InternalCoroutinesApi::class)
@Composable
-internal fun WalletCardsList(wallets: ImmutableList, modifier: Modifier = Modifier) {
+internal fun WalletsList(config: WalletsListConfig, modifier: Modifier = Modifier) {
val horizontalCardPadding = TangemTheme.dimens.spacing16
val itemWidth = LocalConfiguration.current.screenWidthDp.dp - horizontalCardPadding * 2
@@ -38,27 +44,35 @@ internal fun WalletCardsList(wallets: ImmutableList, modifier:
LazyRow(
modifier = modifier.background(color = TangemTheme.colors.background.secondary),
state = lazyListState,
+ contentPadding = PaddingValues(horizontal = TangemTheme.dimens.spacing16),
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
flingBehavior = rememberSnapFlingBehavior(lazyListState = lazyListState),
) {
- items(items = wallets, key = WalletCardState::id) { state ->
+ items(items = config.wallets, key = WalletCardState::id) { state ->
WalletCard(state = state, modifier = Modifier.width(itemWidth))
}
}
+
+ LaunchedEffect(lazyListState) {
+ snapshotFlow(lazyListState::firstVisibleItemScrollOffset)
+ .collect(
+ collector = FlowCollector { firstVisibleItemScrollOffset ->
+ val itemSize = lazyListState.layoutInfo.visibleItemsInfo.firstOrNull()?.size ?: 1
+ val offset = lazyListState.firstVisibleItemIndex * itemSize + firstVisibleItemScrollOffset
+ val currentIndex = offset / itemSize
+ if (offset - currentIndex * itemSize in MIN_OFFSET..MAX_OFFSET) {
+ config.onWalletChange(currentIndex)
+ }
+ },
+ )
+ }
}
@Preview
@Composable
private fun Preview_WalletHeader_LightTheme() {
TangemTheme(isDark = false) {
- WalletCardsList(
- wallets = persistentListOf(
- WalletPreviewData.walletCardContentState,
- WalletPreviewData.walletCardLoadingState,
- WalletPreviewData.walletCardHiddenContentState,
- WalletPreviewData.walletCardErrorState,
- ),
- )
+ WalletsList(config = WalletPreviewData.walletListConfig)
}
}
@@ -66,13 +80,6 @@ private fun Preview_WalletHeader_LightTheme() {
@Composable
private fun Preview_WalletHeader_DarkTheme() {
TangemTheme(isDark = true) {
- WalletCardsList(
- wallets = persistentListOf(
- WalletPreviewData.walletCardContentState,
- WalletPreviewData.walletCardLoadingState,
- WalletPreviewData.walletCardHiddenContentState,
- WalletPreviewData.walletCardErrorState,
- ),
- )
+ WalletsList(config = WalletPreviewData.walletListConfig)
}
}
\ No newline at end of file
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/decorations/WalletContentItemDecoration.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/decorations/WalletContentItemDecoration.kt
index 9ec810b323..ea04e144c4 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/decorations/WalletContentItemDecoration.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/decorations/WalletContentItemDecoration.kt
@@ -10,10 +10,11 @@ import com.tangem.core.ui.res.TangemTheme
/**
[REDACTED_AUTHOR]
*/
-internal fun Modifier.walletContentItemDecoration(currentIndex: Int, lastItemIndex: Int): Modifier = composed {
+internal fun Modifier.walletContentItemDecoration(currentIndex: Int, lastIndex: Int): Modifier = composed {
+ val modifierWithHorizontalPadding = this.padding(horizontal = TangemTheme.dimens.spacing16)
when (currentIndex) {
0 -> {
- this
+ modifierWithHorizontalPadding
.padding(top = TangemTheme.dimens.spacing14)
.clip(
RoundedCornerShape(
@@ -22,8 +23,8 @@ internal fun Modifier.walletContentItemDecoration(currentIndex: Int, lastItemInd
),
)
}
- lastItemIndex -> {
- this
+ lastIndex -> {
+ modifierWithHorizontalPadding
.clip(
RoundedCornerShape(
bottomStart = TangemTheme.dimens.radius16,
@@ -31,6 +32,6 @@ internal fun Modifier.walletContentItemDecoration(currentIndex: Int, lastItemInd
),
)
}
- else -> this
+ else -> modifierWithHorizontalPadding
}
}
\ No newline at end of file
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/decorations/WalletNotificationDecoration.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/decorations/WalletNotificationDecoration.kt
new file mode 100644
index 0000000000..cd2cc0a5f1
--- /dev/null
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/decorations/WalletNotificationDecoration.kt
@@ -0,0 +1,24 @@
+package com.tangem.feature.wallet.presentation.wallet.ui.decorations
+
+import androidx.compose.foundation.layout.padding
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.composed
+import com.tangem.core.ui.res.TangemTheme
+
+/**
+ * Wallet notification decoration
+ *
+ * @param currentIndex current index
+ * @param lastIndex last index
+ *
+[REDACTED_AUTHOR]
+ */
+internal fun Modifier.walletNotificationDecoration(currentIndex: Int, lastIndex: Int): Modifier = composed {
+ val modifierWithHorizontalPadding = this.padding(horizontal = TangemTheme.dimens.spacing16)
+
+ if (currentIndex != lastIndex) {
+ modifierWithHorizontalPadding.padding(bottom = TangemTheme.dimens.spacing14)
+ } else {
+ modifierWithHorizontalPadding
+ }
+}
\ No newline at end of file