Updated on 2026-08-14
This commit is contained in:
parent
b97ea5faf8
commit
6145f3c5db
16 changed files with 716 additions and 478 deletions
|
|
@ -170,6 +170,14 @@ internal object WalletPreviewData {
|
|||
),
|
||||
)
|
||||
|
||||
val manageButtons = persistentListOf(
|
||||
WalletManageButton.Buy(onClick = {}),
|
||||
WalletManageButton.Send(onClick = {}),
|
||||
WalletManageButton.Receive(onClick = {}),
|
||||
WalletManageButton.Exchange(onClick = {}),
|
||||
WalletManageButton.CopyAddress(onClick = {}),
|
||||
)
|
||||
|
||||
val multicurrencyWalletScreenState = WalletStateHolder.MultiCurrencyContent(
|
||||
onBackClick = {},
|
||||
topBarConfig = walletTopBarConfig,
|
||||
|
|
@ -273,5 +281,6 @@ internal object WalletPreviewData {
|
|||
WalletNotification.NeedToBackup(onClick = {}),
|
||||
WalletNotification.ScanCard(onClick = {}),
|
||||
),
|
||||
buttons = manageButtons,
|
||||
)
|
||||
}
|
||||
|
|
@ -21,9 +21,10 @@ import androidx.compose.ui.res.stringResource
|
|||
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.BackgroundActionButton
|
||||
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.res.TangemTheme
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.common.WalletPreviewData
|
||||
|
|
@ -214,16 +215,20 @@ private fun TopBar(
|
|||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
|
||||
) {
|
||||
BackgroundActionButton(
|
||||
config = ActionConfig(
|
||||
text = stringResource(id = R.string.organize_tokens_sort_by_balance),
|
||||
iconResId = R.drawable.ic_sort_24,
|
||||
onClick = config.onSortByBalanceClick,
|
||||
),
|
||||
modifier = Modifier.weight(1f),
|
||||
text = stringResource(id = R.string.organize_tokens_sort_by_balance),
|
||||
iconResId = R.drawable.ic_sort_24,
|
||||
onClick = config.onSortByBalanceClick,
|
||||
)
|
||||
BackgroundActionButton(
|
||||
config = ActionConfig(
|
||||
text = stringResource(id = R.string.organize_tokens_group),
|
||||
iconResId = R.drawable.ic_group_24,
|
||||
onClick = config.onGroupByNetworkClick,
|
||||
),
|
||||
modifier = Modifier.weight(1f),
|
||||
text = stringResource(id = R.string.organize_tokens_group),
|
||||
iconResId = R.drawable.ic_group_24,
|
||||
onClick = config.onGroupByNetworkClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state
|
||||
|
||||
import com.tangem.core.ui.components.buttons.actions.ActionConfig
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
|
||||
/**
|
||||
* Wallet manage button state
|
||||
*
|
||||
* @param config action config
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
sealed class WalletManageButton(val config: ActionConfig) {
|
||||
|
||||
/**
|
||||
* Buy
|
||||
*
|
||||
* @param onClick lambda be invoked when manage button is clicked
|
||||
*/
|
||||
data class Buy(val onClick: () -> Unit) : WalletManageButton(
|
||||
config = ActionConfig(
|
||||
text = "Buy",
|
||||
iconResId = R.drawable.ic_plus_24,
|
||||
onClick = onClick,
|
||||
),
|
||||
)
|
||||
|
||||
/**
|
||||
* Send
|
||||
*
|
||||
* @param onClick lambda be invoked when manage button is clicked
|
||||
*/
|
||||
data class Send(val onClick: () -> Unit) : WalletManageButton(
|
||||
config = ActionConfig(
|
||||
text = "Send",
|
||||
iconResId = R.drawable.ic_arrow_up_24,
|
||||
onClick = onClick,
|
||||
),
|
||||
)
|
||||
|
||||
/**
|
||||
* Receive
|
||||
*
|
||||
* @param onClick lambda be invoked when manage button is clicked
|
||||
*/
|
||||
data class Receive(val onClick: () -> Unit) : WalletManageButton(
|
||||
config = ActionConfig(
|
||||
text = "Receive",
|
||||
iconResId = R.drawable.ic_arrow_down_24,
|
||||
onClick = onClick,
|
||||
),
|
||||
)
|
||||
|
||||
/**
|
||||
* Exchange
|
||||
*
|
||||
* @param onClick lambda be invoked when manage button is clicked
|
||||
*/
|
||||
data class Exchange(val onClick: () -> Unit) : WalletManageButton(
|
||||
config = ActionConfig(
|
||||
text = "Exchange",
|
||||
iconResId = R.drawable.ic_exchange_vertical_24,
|
||||
onClick = onClick,
|
||||
),
|
||||
)
|
||||
|
||||
/**
|
||||
* Copy address
|
||||
*
|
||||
* @param onClick lambda be invoked when manage button is clicked
|
||||
*/
|
||||
data class CopyAddress(val onClick: () -> Unit) : WalletManageButton(
|
||||
config = ActionConfig(
|
||||
text = "Copy address",
|
||||
iconResId = R.drawable.ic_copy_24,
|
||||
onClick = onClick,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state
|
||||
|
||||
import androidx.compose.foundation.horizontalScroll
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.key
|
||||
import androidx.compose.ui.Modifier
|
||||
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.ActionButton
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.feature.wallet.presentation.common.WalletPreviewData
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
/**
|
||||
* Wallet manage buttons
|
||||
*
|
||||
* @param buttons manage buttons
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Composable
|
||||
internal fun WalletManageButtons(buttons: ImmutableList<WalletManageButton>) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.horizontalScroll(state = rememberScrollState())
|
||||
.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing8),
|
||||
) {
|
||||
buttons.forEach { button ->
|
||||
key(button.config.text) {
|
||||
ActionButton(config = button.config)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_WalletManageButtons_Light(
|
||||
@PreviewParameter(WalletManageButtonProvider::class) buttons: ImmutableList<WalletManageButton>,
|
||||
) {
|
||||
TangemTheme(isDark = false) {
|
||||
WalletManageButtons(buttons = buttons)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_WalletManageButtons_Dark(
|
||||
@PreviewParameter(WalletManageButtonProvider::class) buttons: ImmutableList<WalletManageButton>,
|
||||
) {
|
||||
TangemTheme(isDark = true) {
|
||||
WalletManageButtons(buttons = buttons)
|
||||
}
|
||||
}
|
||||
|
||||
private class WalletManageButtonProvider : CollectionPreviewParameterProvider<ImmutableList<WalletManageButton>>(
|
||||
collection = listOf(WalletPreviewData.manageButtons),
|
||||
)
|
||||
|
|
@ -53,6 +53,7 @@ internal sealed class WalletStateHolder(
|
|||
* @property wallets list of wallets states
|
||||
* @property contentItems content items
|
||||
* @property notifications notifications
|
||||
* @property buttons manage buttons
|
||||
*/
|
||||
data class SingleCurrencyContent(
|
||||
override val onBackClick: () -> Unit,
|
||||
|
|
@ -61,5 +62,6 @@ internal sealed class WalletStateHolder(
|
|||
override val wallets: ImmutableList<WalletCardState>,
|
||||
override val contentItems: ImmutableList<WalletContentItemState.SingleCurrencyItem>,
|
||||
override val notifications: ImmutableList<WalletNotification>,
|
||||
val buttons: ImmutableList<WalletManageButton>,
|
||||
) : WalletStateHolder(onBackClick, topBarConfig, selectedWallet, wallets, contentItems, notifications)
|
||||
}
|
||||
|
|
@ -1,28 +1,26 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.ui
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
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.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Scaffold
|
||||
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.composed
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
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.RoundedActionButton
|
||||
import com.tangem.core.ui.components.buttons.actions.ActionConfig
|
||||
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
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
|
|
@ -30,9 +28,11 @@ import com.tangem.feature.wallet.presentation.common.WalletPreviewData
|
|||
import com.tangem.feature.wallet.presentation.common.component.NetworkGroupItem
|
||||
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.decorations.walletContentItemDecoration
|
||||
|
||||
/**
|
||||
* Wallet screen
|
||||
|
|
@ -49,15 +49,29 @@ internal fun WalletScreen(state: WalletStateHolder, modifier: Modifier = Modifie
|
|||
topBar = { WalletTopBar(config = state.topBarConfig) },
|
||||
containerColor = TangemTheme.colors.background.secondary,
|
||||
) { scaffoldPaddings ->
|
||||
val lastContentItemIndex = remember(state.contentItems) { state.contentItems.lastIndex }
|
||||
|
||||
LazyColumn(
|
||||
modifier = modifier
|
||||
.padding(scaffoldPaddings)
|
||||
.padding(paddingValues = scaffoldPaddings)
|
||||
.fillMaxSize(),
|
||||
contentPadding = PaddingValues(
|
||||
horizontal = TangemTheme.dimens.spacing16,
|
||||
vertical = TangemTheme.dimens.spacing8,
|
||||
),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
item { WalletCardsList(wallets = state.wallets) }
|
||||
item {
|
||||
WalletCardsList(
|
||||
wallets = state.wallets,
|
||||
modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12),
|
||||
)
|
||||
}
|
||||
|
||||
if (state is WalletStateHolder.SingleCurrencyContent) {
|
||||
item { WalletManageButtons(buttons = state.buttons) }
|
||||
}
|
||||
|
||||
items(items = state.notifications, itemContent = { Notification(state = it.state) })
|
||||
|
||||
itemsIndexed(
|
||||
items = state.contentItems,
|
||||
|
|
@ -70,36 +84,19 @@ internal fun WalletScreen(state: WalletStateHolder, modifier: Modifier = Modifie
|
|||
is WalletContentItemState.SingleCurrencyItem.Transaction -> index
|
||||
}
|
||||
},
|
||||
) { index, item ->
|
||||
val itemModifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.clipFirstAndLastItems(index, lastContentItemIndex)
|
||||
|
||||
when (item) {
|
||||
is WalletContentItemState.MultiCurrencyItem.NetworkGroupTitle -> {
|
||||
NetworkGroupItem(networkName = item.networkName, modifier = itemModifier)
|
||||
}
|
||||
is WalletContentItemState.MultiCurrencyItem.Token -> {
|
||||
TokenItem(state = item.state, modifier = itemModifier)
|
||||
}
|
||||
is WalletContentItemState.SingleCurrencyItem.Title -> {
|
||||
SingleCurrencyTitle(config = item, modifier = itemModifier)
|
||||
}
|
||||
is WalletContentItemState.SingleCurrencyItem.TransactionGroupTitle -> {
|
||||
TransactionGroupTitle(config = item, modifier = itemModifier)
|
||||
}
|
||||
is WalletContentItemState.SingleCurrencyItem.Transaction -> {
|
||||
Transaction(state = item.state, modifier = itemModifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
itemContent = { index, item ->
|
||||
ContentItem(currentIndex = index, lastIndex = state.contentItems.lastIndex, item = item)
|
||||
},
|
||||
)
|
||||
|
||||
if (state is WalletStateHolder.MultiCurrencyContent) {
|
||||
item {
|
||||
RoundedActionButton(
|
||||
text = stringResource(id = R.string.organize_tokens_title),
|
||||
iconResId = R.drawable.ic_filter_24,
|
||||
onClick = state.onOrganizeTokensClick,
|
||||
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),
|
||||
)
|
||||
}
|
||||
|
|
@ -108,6 +105,29 @@ internal fun WalletScreen(state: WalletStateHolder, modifier: Modifier = Modifie
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ContentItem(currentIndex: Int, lastIndex: Int, item: WalletContentItemState) {
|
||||
val itemModifier = Modifier.walletContentItemDecoration(currentIndex, lastIndex)
|
||||
|
||||
when (item) {
|
||||
is WalletContentItemState.MultiCurrencyItem.NetworkGroupTitle -> {
|
||||
NetworkGroupItem(networkName = item.networkName, modifier = itemModifier)
|
||||
}
|
||||
is WalletContentItemState.MultiCurrencyItem.Token -> {
|
||||
TokenItem(state = item.state, modifier = itemModifier)
|
||||
}
|
||||
is WalletContentItemState.SingleCurrencyItem.Title -> {
|
||||
SingleCurrencyTitle(config = item, modifier = itemModifier)
|
||||
}
|
||||
is WalletContentItemState.SingleCurrencyItem.TransactionGroupTitle -> {
|
||||
TransactionGroupTitle(config = item, modifier = itemModifier)
|
||||
}
|
||||
is WalletContentItemState.SingleCurrencyItem.Transaction -> {
|
||||
Transaction(state = item.state, modifier = itemModifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SingleCurrencyTitle(
|
||||
config: WalletContentItemState.SingleCurrencyItem.Title,
|
||||
|
|
@ -166,31 +186,6 @@ private fun TransactionGroupTitle(
|
|||
)
|
||||
}
|
||||
|
||||
private fun Modifier.clipFirstAndLastItems(index: Int, lastItemIndex: Int): Modifier = composed {
|
||||
when (index) {
|
||||
0 -> {
|
||||
this
|
||||
.padding(top = TangemTheme.dimens.spacing14)
|
||||
.clip(
|
||||
RoundedCornerShape(
|
||||
topStart = TangemTheme.dimens.radius16,
|
||||
topEnd = TangemTheme.dimens.radius16,
|
||||
),
|
||||
)
|
||||
}
|
||||
lastItemIndex -> {
|
||||
this
|
||||
.clip(
|
||||
RoundedCornerShape(
|
||||
bottomStart = TangemTheme.dimens.radius16,
|
||||
bottomEnd = TangemTheme.dimens.radius16,
|
||||
),
|
||||
)
|
||||
}
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
||||
// region Preview
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -23,21 +23,21 @@ import kotlinx.collections.immutable.persistentListOf
|
|||
/**
|
||||
* Wallets list
|
||||
*
|
||||
* @param wallets list of wallet state
|
||||
* @param wallets list of wallet state
|
||||
* @param modifier modifier
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
internal fun WalletCardsList(wallets: ImmutableList<WalletCardState>) {
|
||||
internal fun WalletCardsList(wallets: ImmutableList<WalletCardState>, modifier: Modifier = Modifier) {
|
||||
val horizontalCardPadding = TangemTheme.dimens.spacing16
|
||||
val itemWidth = LocalConfiguration.current.screenWidthDp.dp - horizontalCardPadding * 2
|
||||
|
||||
val lazyListState = rememberLazyListState()
|
||||
LazyRow(
|
||||
modifier = Modifier.background(color = TangemTheme.colors.background.secondary),
|
||||
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),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.ui.decorations
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.composed
|
||||
import androidx.compose.ui.draw.clip
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal fun Modifier.walletContentItemDecoration(currentIndex: Int, lastItemIndex: Int): Modifier = composed {
|
||||
when (currentIndex) {
|
||||
0 -> {
|
||||
this
|
||||
.padding(top = TangemTheme.dimens.spacing14)
|
||||
.clip(
|
||||
RoundedCornerShape(
|
||||
topStart = TangemTheme.dimens.radius16,
|
||||
topEnd = TangemTheme.dimens.radius16,
|
||||
),
|
||||
)
|
||||
}
|
||||
lastItemIndex -> {
|
||||
this
|
||||
.clip(
|
||||
RoundedCornerShape(
|
||||
bottomStart = TangemTheme.dimens.radius16,
|
||||
bottomEnd = TangemTheme.dimens.radius16,
|
||||
),
|
||||
)
|
||||
}
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue