Updated on 2026-08-14
This commit is contained in:
parent
6c40b47578
commit
06342d8509
15 changed files with 324 additions and 197 deletions
|
|
@ -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"),
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,10 +34,7 @@ internal class DefaultWalletRouter : InnerWalletRouter {
|
|||
) {
|
||||
composable(WalletScreens.WALLET.name) {
|
||||
val viewModel = hiltViewModel<WalletViewModel>().apply { router = this@DefaultWalletRouter }
|
||||
WalletScreen(
|
||||
modifier = Modifier.systemBarsPadding(),
|
||||
state = viewModel.uiState,
|
||||
)
|
||||
WalletScreen(state = viewModel.uiState)
|
||||
}
|
||||
|
||||
composable(WalletScreens.ORGANIZE_TOKENS.name) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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<WalletManageButton>) {
|
||||
internal fun WalletManageButtons(buttons: ImmutableList<WalletManageButton>, 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),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -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<WalletCardState>,
|
||||
open val walletsListConfig: WalletsListConfig,
|
||||
open val contentItems: ImmutableList<WalletContentItemState>,
|
||||
open val notifications: ImmutableList<WalletNotification>,
|
||||
) {
|
||||
|
|
@ -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<WalletCardState>,
|
||||
override val walletsListConfig: WalletsListConfig,
|
||||
override val contentItems: ImmutableList<WalletContentItemState.MultiCurrencyItem>,
|
||||
override val notifications: ImmutableList<WalletNotification>,
|
||||
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<WalletCardState>,
|
||||
override val walletsListConfig: WalletsListConfig,
|
||||
override val contentItems: ImmutableList<WalletContentItemState.SingleCurrencyItem>,
|
||||
override val notifications: ImmutableList<WalletNotification>,
|
||||
val buttons: ImmutableList<WalletManageButton>,
|
||||
) : WalletStateHolder(onBackClick, topBarConfig, selectedWallet, wallets, contentItems, notifications)
|
||||
) : WalletStateHolder(onBackClick, topBarConfig, walletsListConfig, contentItems, notifications)
|
||||
}
|
||||
|
|
@ -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<WalletCardState>,
|
||||
val onWalletChange: (Int) -> Unit,
|
||||
)
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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<WalletCardState>, 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<WalletCardState>, 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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue