Updated on 2026-08-14
This commit is contained in:
parent
ed8419b45b
commit
b97ddcb3f2
17 changed files with 379 additions and 147 deletions
|
|
@ -1,10 +1,15 @@
|
|||
package com.tangem.feature.tokendetails.presentation.tokendetails
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.paging.PagingData
|
||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||
import com.tangem.core.ui.components.marketprice.PriceChangeState
|
||||
import com.tangem.core.ui.components.marketprice.PriceChangeType
|
||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
||||
import com.tangem.core.ui.event.consumedEvent
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.*
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsActionButton
|
||||
|
|
@ -76,8 +81,8 @@ internal object TokenDetailsPreviewData {
|
|||
val balanceLoading = TokenDetailsBalanceBlockState.Loading(actionButtons = actionButtons)
|
||||
val balanceContent = TokenDetailsBalanceBlockState.Content(
|
||||
actionButtons = actionButtons,
|
||||
fiatBalance = "123,00$",
|
||||
cryptoBalance = "866,96 USDT",
|
||||
fiatBalance = "91,50$",
|
||||
cryptoBalance = "966,96 XLM",
|
||||
)
|
||||
val balanceError = TokenDetailsBalanceBlockState.Error(actionButtons = actionButtons)
|
||||
|
||||
|
|
@ -88,7 +93,131 @@ internal object TokenDetailsPreviewData {
|
|||
onRefresh = {},
|
||||
)
|
||||
|
||||
val tokenDetailsState = TokenDetailsState(
|
||||
private val txHistoryItems = listOf(
|
||||
TxHistoryState.TxHistoryItemState.Title(onExploreClick = {}),
|
||||
TxHistoryState.TxHistoryItemState.GroupTitle(
|
||||
title = "Today",
|
||||
itemKey = "Today",
|
||||
),
|
||||
TxHistoryState.TxHistoryItemState.Transaction(
|
||||
state = TransactionState.Content(
|
||||
txHash = "1",
|
||||
amount = "-0.500913 XLM",
|
||||
time = "8:41",
|
||||
status = TransactionState.Content.Status.Confirmed,
|
||||
direction = TransactionState.Content.Direction.OUTGOING,
|
||||
onClick = {},
|
||||
iconRes = R.drawable.ic_arrow_up_24,
|
||||
title = stringReference(value = "Sending"),
|
||||
subtitle = stringReference(value = "to: 33BddS...ga2B"),
|
||||
timestamp = 0,
|
||||
),
|
||||
),
|
||||
TxHistoryState.TxHistoryItemState.Transaction(
|
||||
state = TransactionState.Content(
|
||||
txHash = "2",
|
||||
amount = "+0.500913 XLM",
|
||||
time = "8:41",
|
||||
status = TransactionState.Content.Status.Confirmed,
|
||||
direction = TransactionState.Content.Direction.INCOMING,
|
||||
onClick = {},
|
||||
iconRes = R.drawable.ic_arrow_down_24,
|
||||
title = stringReference(value = "Receiving"),
|
||||
subtitle = stringReference(value = "from: 33BddS...ga2B"),
|
||||
timestamp = 0,
|
||||
),
|
||||
),
|
||||
TxHistoryState.TxHistoryItemState.Transaction(
|
||||
state = TransactionState.Content(
|
||||
txHash = "3",
|
||||
amount = "+0.500913 XLM",
|
||||
time = "8:41",
|
||||
status = TransactionState.Content.Status.Confirmed,
|
||||
direction = TransactionState.Content.Direction.INCOMING,
|
||||
onClick = {},
|
||||
iconRes = R.drawable.ic_doc_24,
|
||||
title = stringReference(value = "Approving"),
|
||||
subtitle = stringReference(value = "from: 33BddS...ga2B"),
|
||||
timestamp = 0,
|
||||
),
|
||||
),
|
||||
TxHistoryState.TxHistoryItemState.Transaction(
|
||||
state = TransactionState.Content(
|
||||
txHash = "4",
|
||||
amount = "+0.500913 XLM",
|
||||
time = "8:41",
|
||||
status = TransactionState.Content.Status.Confirmed,
|
||||
direction = TransactionState.Content.Direction.INCOMING,
|
||||
onClick = {},
|
||||
iconRes = R.drawable.ic_exchange_vertical_24,
|
||||
title = stringReference(value = "Swapping"),
|
||||
subtitle = stringReference(value = "contract: 33BddS...ga2B"),
|
||||
timestamp = 0,
|
||||
),
|
||||
),
|
||||
TxHistoryState.TxHistoryItemState.GroupTitle(
|
||||
title = "Yesterday",
|
||||
itemKey = "Yesterday",
|
||||
),
|
||||
TxHistoryState.TxHistoryItemState.Transaction(
|
||||
state = TransactionState.Content(
|
||||
txHash = "5",
|
||||
amount = "-0.500913 XLM",
|
||||
time = "8:41",
|
||||
status = TransactionState.Content.Status.Confirmed,
|
||||
direction = TransactionState.Content.Direction.OUTGOING,
|
||||
onClick = {},
|
||||
iconRes = R.drawable.ic_arrow_up_24,
|
||||
title = stringReference(value = "Sending"),
|
||||
subtitle = stringReference(value = "to: 33BddS...ga2B"),
|
||||
timestamp = 0,
|
||||
),
|
||||
),
|
||||
TxHistoryState.TxHistoryItemState.Transaction(
|
||||
state = TransactionState.Content(
|
||||
txHash = "6",
|
||||
amount = "+0.500913 XLM",
|
||||
time = "8:41",
|
||||
status = TransactionState.Content.Status.Confirmed,
|
||||
direction = TransactionState.Content.Direction.INCOMING,
|
||||
onClick = {},
|
||||
iconRes = R.drawable.ic_arrow_down_24,
|
||||
title = stringReference(value = "Receiving"),
|
||||
subtitle = stringReference(value = "from: 33BddS...ga2B"),
|
||||
timestamp = 0,
|
||||
),
|
||||
),
|
||||
TxHistoryState.TxHistoryItemState.Transaction(
|
||||
state = TransactionState.Content(
|
||||
txHash = "7",
|
||||
amount = "+0.500913 XLM",
|
||||
time = "8:41",
|
||||
status = TransactionState.Content.Status.Confirmed,
|
||||
direction = TransactionState.Content.Direction.INCOMING,
|
||||
onClick = {},
|
||||
iconRes = R.drawable.ic_doc_24,
|
||||
title = stringReference(value = "Approving"),
|
||||
subtitle = stringReference(value = "from: 33BddS...ga2B"),
|
||||
timestamp = 0,
|
||||
),
|
||||
),
|
||||
TxHistoryState.TxHistoryItemState.Transaction(
|
||||
state = TransactionState.Content(
|
||||
txHash = "8",
|
||||
amount = "+0.500913 XLM",
|
||||
time = "8:41",
|
||||
status = TransactionState.Content.Status.Confirmed,
|
||||
direction = TransactionState.Content.Direction.INCOMING,
|
||||
onClick = {},
|
||||
iconRes = R.drawable.ic_exchange_vertical_24,
|
||||
title = stringReference(value = "Swapping"),
|
||||
subtitle = stringReference(value = "contract: 33BddS...ga2B"),
|
||||
timestamp = 0,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
val tokenDetailsState_1 = TokenDetailsState(
|
||||
topAppBarConfig = tokenDetailsTopAppBarConfig,
|
||||
tokenInfoBlockState = tokenInfoBlockState,
|
||||
tokenBalanceBlockState = balanceLoading,
|
||||
|
|
@ -108,4 +237,41 @@ internal object TokenDetailsPreviewData {
|
|||
isMarketPriceAvailable = false,
|
||||
event = consumedEvent(),
|
||||
)
|
||||
|
||||
val tokenDetailsState_2 = TokenDetailsState(
|
||||
topAppBarConfig = tokenDetailsTopAppBarConfig,
|
||||
tokenInfoBlockState = tokenInfoBlockState.copy(
|
||||
name = "Stellar",
|
||||
),
|
||||
tokenBalanceBlockState = balanceContent,
|
||||
marketPriceBlockState = MarketPriceBlockState.Content(
|
||||
currencySymbol = "XLM",
|
||||
price = "0.11$",
|
||||
priceChangeConfig = PriceChangeState.Content(
|
||||
valueInPercent = "5,16%",
|
||||
type = PriceChangeType.UP,
|
||||
),
|
||||
),
|
||||
notifications = persistentListOf(),
|
||||
txHistoryState = TxHistoryState.NotSupported(
|
||||
onExploreClick = {},
|
||||
pendingTransactions = persistentListOf(),
|
||||
),
|
||||
dialogConfig = null,
|
||||
pendingTxs = persistentListOf(),
|
||||
swapTxs = persistentListOf(),
|
||||
pullToRefreshConfig = pullToRefreshConfig,
|
||||
bottomSheetConfig = null,
|
||||
isBalanceHidden = false,
|
||||
isMarketPriceAvailable = true,
|
||||
event = consumedEvent(),
|
||||
)
|
||||
|
||||
val tokenDetailsState_3 = tokenDetailsState_2.copy(
|
||||
txHistoryState = TxHistoryState.Content(
|
||||
contentItems = MutableStateFlow(
|
||||
value = PagingData.from(txHistoryItems),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.ui
|
|||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
|
|
@ -20,6 +21,8 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import com.tangem.core.ui.components.bottomsheets.chooseaddress.ChooseAddressBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.chooseaddress.ChooseAddressBottomSheetConfig
|
||||
|
|
@ -82,14 +85,12 @@ internal fun TokenDetailsScreen(state: TokenDetailsState) {
|
|||
.pullRefresh(pullRefreshState),
|
||||
) {
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxSize(),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentPadding = PaddingValues(bottom = TangemTheme.dimens.spacing16),
|
||||
) {
|
||||
item {
|
||||
TokenInfoBlock(
|
||||
modifier = Modifier
|
||||
.padding(top = TangemTheme.dimens.spacing4)
|
||||
.padding(horizontal = horizontalPadding),
|
||||
modifier = Modifier.padding(horizontal = horizontalPadding),
|
||||
state = state.tokenInfoBlockState,
|
||||
)
|
||||
}
|
||||
|
|
@ -181,18 +182,32 @@ internal fun TokenDetailsEventEffect(snackbarHostState: SnackbarHostState, event
|
|||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
// region Preview
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Composable
|
||||
private fun Preview_TokenDetailsScreen_LightTheme() {
|
||||
TangemTheme(isDark = false) {
|
||||
TokenDetailsScreen(state = TokenDetailsPreviewData.tokenDetailsState)
|
||||
private fun TokenDetailsScreenPreview_Light(
|
||||
@PreviewParameter(TokenDetailsScreenParameterProvider::class) state: TokenDetailsState,
|
||||
) {
|
||||
TangemTheme {
|
||||
TokenDetailsScreen(state)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Composable
|
||||
private fun Preview_TokenDetailsScreen_DarkTheme() {
|
||||
private fun TokenDetailsScreenPreview_Dark(
|
||||
@PreviewParameter(TokenDetailsScreenParameterProvider::class) state: TokenDetailsState,
|
||||
) {
|
||||
TangemTheme(isDark = true) {
|
||||
TokenDetailsScreen(state = TokenDetailsPreviewData.tokenDetailsState)
|
||||
TokenDetailsScreen(state)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TokenDetailsScreenParameterProvider : CollectionPreviewParameterProvider<TokenDetailsState>(
|
||||
collection = listOf(
|
||||
TokenDetailsPreviewData.tokenDetailsState_1,
|
||||
TokenDetailsPreviewData.tokenDetailsState_2,
|
||||
TokenDetailsPreviewData.tokenDetailsState_3,
|
||||
),
|
||||
)
|
||||
// endregion Preview
|
||||
|
|
@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.*
|
|||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -32,18 +33,21 @@ internal fun TokenDetailsBalanceBlock(
|
|||
color = TangemTheme.colors.background.primary,
|
||||
) {
|
||||
Column {
|
||||
Text(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
top = TangemTheme.dimens.spacing12,
|
||||
start = TangemTheme.dimens.spacing12,
|
||||
end = TangemTheme.dimens.spacing12,
|
||||
),
|
||||
text = stringResource(id = R.string.common_balance_title),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
maxLines = 1,
|
||||
)
|
||||
.padding(top = TangemTheme.dimens.spacing12)
|
||||
.padding(horizontal = TangemTheme.dimens.spacing12)
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = TangemTheme.dimens.spacing24),
|
||||
contentAlignment = Alignment.CenterStart,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.common_balance_title),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
||||
FiatBalance(
|
||||
state = state,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
|
|
@ -124,7 +128,7 @@ private fun CryptoBalance(
|
|||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Preview(widthDp = 328, heightDp = 152)
|
||||
@Composable
|
||||
private fun Preview_TokenDetailsBalanceBlock_LightTheme(
|
||||
@PreviewParameter(TokenDetailsBalanceBlockStateProvider::class) state: TokenDetailsBalanceBlockState,
|
||||
|
|
@ -134,7 +138,7 @@ private fun Preview_TokenDetailsBalanceBlock_LightTheme(
|
|||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Preview(widthDp = 328, heightDp = 152)
|
||||
@Composable
|
||||
private fun Preview_TokenDetailsBalanceBlock_DarkTheme(
|
||||
@PreviewParameter(TokenDetailsBalanceBlockStateProvider::class) state: TokenDetailsBalanceBlockState,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import androidx.compose.ui.graphics.ColorFilter
|
|||
import androidx.compose.ui.graphics.ColorMatrix
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
|
|
@ -29,9 +28,15 @@ private const val NORMAL_ALPHA = 1f
|
|||
|
||||
@Composable
|
||||
internal fun TokenInfoBlock(state: TokenInfoBlockState, modifier: Modifier = Modifier) {
|
||||
Row(modifier = modifier.fillMaxWidth()) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = TangemTheme.dimens.size60),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.weight(1F),
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterVertically)
|
||||
.weight(1F),
|
||||
) {
|
||||
Text(
|
||||
text = state.name,
|
||||
|
|
@ -88,7 +93,7 @@ private fun NetworkInfoText(currency: TokenInfoBlockState.Currency) {
|
|||
)
|
||||
Text(
|
||||
text = state.boldText,
|
||||
style = TangemTheme.typography.caption2.copy(fontWeight = FontWeight.Medium),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ private fun CustomContainer(state: TokenItemState, modifier: Modifier = Modifier
|
|||
Layout(content = content, modifier = modifier) { measurables, constraints ->
|
||||
|
||||
val layoutWidth = constraints.maxWidth
|
||||
val horizontalPadding = with(density) { dimens.size14.roundToPx() }
|
||||
val horizontalPadding = with(density) { dimens.size12.roundToPx() }
|
||||
val verticalPadding = with(density) { dimens.size16.roundToPx() }
|
||||
val layoutWidthWithoutPaddings = layoutWidth - 2 * horizontalPadding
|
||||
|
||||
|
|
@ -137,7 +137,7 @@ private fun CustomContainer(state: TokenItemState, modifier: Modifier = Modifier
|
|||
|
||||
/*
|
||||
* Title width take the whole REMAINING space.
|
||||
* If FiatAmount took the whole free space, then Title will has min width.
|
||||
* If FiatAmount took the whole free space, then Title will have min width.
|
||||
*/
|
||||
val title: Placeable
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ private fun CustomContainer(state: TokenItemState, modifier: Modifier = Modifier
|
|||
|
||||
/*
|
||||
* PriceChange width take the whole REMAINING space.
|
||||
* If CryptoAmount took the whole free space, then PriceChange will has min width.
|
||||
* If CryptoAmount took the whole free space, then PriceChange will have min width.
|
||||
*/
|
||||
val priceChange: Placeable?
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ private fun TokenList(
|
|||
)
|
||||
|
||||
val listContentPadding = PaddingValues(
|
||||
top = TangemTheme.dimens.spacing12,
|
||||
top = TangemTheme.dimens.spacing4,
|
||||
bottom = TangemTheme.dimens.spacing92,
|
||||
start = TangemTheme.dimens.spacing16,
|
||||
end = TangemTheme.dimens.spacing16,
|
||||
|
|
@ -245,7 +245,7 @@ private fun TopBar(
|
|||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = TangemTheme.dimens.size56),
|
||||
.padding(bottom = TangemTheme.dimens.spacing8),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
|
||||
) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue