Updated on 2026-08-14
This commit is contained in:
parent
229dc89bcb
commit
3398db66e2
13 changed files with 609 additions and 156 deletions
|
|
@ -14,7 +14,8 @@ import androidx.compose.ui.util.fastForEach
|
|||
import androidx.paging.compose.LazyPagingItems
|
||||
import androidx.paging.compose.itemContentType
|
||||
import androidx.paging.compose.itemKey
|
||||
import com.tangem.core.ui.components.transactions.empty.EmptyTransactionBlock
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.transactions.empty.EmptyTransactionBlockLegacy
|
||||
import com.tangem.core.ui.components.transactions.empty.EmptyTransactionsBlockState
|
||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
||||
|
|
@ -45,13 +46,21 @@ fun LazyListScope.txHistoryItems(
|
|||
)
|
||||
}
|
||||
is TxHistoryState.Empty -> {
|
||||
nonContentItem(state = EmptyTransactionsBlockState.Empty(state.onExploreClick), modifier = modifier)
|
||||
nonContentItem(
|
||||
state = EmptyTransactionsBlockState.Empty(
|
||||
onExplore = state.onExploreClick,
|
||||
exploreIconResId = R.drawable.ic_arrow_top_right_24,
|
||||
),
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
is TxHistoryState.Error -> {
|
||||
nonContentItem(
|
||||
state = EmptyTransactionsBlockState.FailedToLoad(
|
||||
onReload = state.onReloadClick,
|
||||
onExplore = state.onExploreClick,
|
||||
reloadIconResId = R.drawable.ic_refresh_24,
|
||||
exploreIconResId = R.drawable.ic_arrow_top_right_24,
|
||||
),
|
||||
modifier = modifier,
|
||||
)
|
||||
|
|
@ -64,7 +73,10 @@ fun LazyListScope.txHistoryItems(
|
|||
}
|
||||
|
||||
nonContentItem(
|
||||
state = EmptyTransactionsBlockState.NotImplemented(onExplore = state.onExploreClick),
|
||||
state = EmptyTransactionsBlockState.NotImplemented(
|
||||
onExplore = state.onExploreClick,
|
||||
exploreIconResId = R.drawable.ic_arrow_top_right_24,
|
||||
),
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
|
@ -121,7 +133,7 @@ fun PendingTxsBlock(pendingTxs: ImmutableList<TransactionState>, isBalanceHidden
|
|||
|
||||
private fun LazyListScope.nonContentItem(state: EmptyTransactionsBlockState, modifier: Modifier = Modifier) {
|
||||
item(key = state::class.java, contentType = state::class.java) {
|
||||
EmptyTransactionBlock(
|
||||
EmptyTransactionBlockLegacy(
|
||||
state = state,
|
||||
modifier = modifier
|
||||
.animateItem(fadeInSpec = null, fadeOutSpec = null)
|
||||
|
|
|
|||
|
|
@ -1,65 +1,74 @@
|
|||
package com.tangem.core.ui.components.transactions.empty
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
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.ActionButton
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig
|
||||
import com.tangem.core.ui.ds.button.TangemButton
|
||||
import com.tangem.core.ui.ds.button.TangemButtonIconPosition
|
||||
import com.tangem.core.ui.ds.button.TangemButtonShape
|
||||
import com.tangem.core.ui.ds.button.TangemButtonSize
|
||||
import com.tangem.core.ui.ds.button.TangemButtonType
|
||||
import com.tangem.core.ui.ds.button.TangemButtonUM
|
||||
import com.tangem.core.ui.ds.image.TangemIcon
|
||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import com.tangem.core.ui.test.EmptyTransactionBlockTestTags
|
||||
|
||||
/**
|
||||
* Placeholder for transaction's block without content
|
||||
*
|
||||
* @param state component state
|
||||
* @param modifier modifier
|
||||
*/
|
||||
@Composable
|
||||
fun EmptyTransactionBlock(state: EmptyTransactionsBlockState, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.clip(TangemTheme.shapes.roundedCornersXMedium)
|
||||
.background(color = TangemTheme.colors.background.primary)
|
||||
.padding(vertical = TangemTheme.dimens.spacing24)
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = TangemTheme.dimens2.x6)
|
||||
.testTag(EmptyTransactionBlockTestTags.BLOCK),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing24),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Icon(
|
||||
TangemIcon(
|
||||
tangemIconUM = TangemIconUM.Icon(
|
||||
iconRes = state.iconRes,
|
||||
tintReference = { TangemTheme.colors2.graphic.neutral.tertiary },
|
||||
),
|
||||
modifier = Modifier
|
||||
.size(TangemTheme.dimens.size64)
|
||||
.size(TangemTheme.dimens2.x16)
|
||||
.testTag(EmptyTransactionBlockTestTags.ICON),
|
||||
painter = painterResource(id = state.iconRes),
|
||||
tint = TangemTheme.colors.icon.inactive,
|
||||
contentDescription = null,
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(TangemTheme.dimens2.x4))
|
||||
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.spacing32)
|
||||
.padding(horizontal = TangemTheme.dimens2.x8)
|
||||
.testTag(EmptyTransactionBlockTestTags.TEXT),
|
||||
textAlign = TextAlign.Center,
|
||||
text = state.text.resolveReference(),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography2.calloutRegular15,
|
||||
color = TangemTheme.colors2.text.neutral.tertiary,
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(TangemTheme.dimens2.x8))
|
||||
|
||||
Buttons(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.spacing18)
|
||||
.padding(horizontal = TangemTheme.dimens2.x4)
|
||||
.testTag(EmptyTransactionBlockTestTags.EXPLORE_BUTTON),
|
||||
state = state.buttonsState,
|
||||
)
|
||||
|
|
@ -76,41 +85,70 @@ private fun Buttons(state: EmptyTransactionsBlockState.ButtonsState, modifier: M
|
|||
|
||||
@Composable
|
||||
private fun SingleButton(state: EmptyTransactionsBlockState.ButtonsState.SingleButton, modifier: Modifier = Modifier) {
|
||||
ActionButton(modifier = modifier, config = state.actionButtonConfig)
|
||||
Row(
|
||||
modifier = modifier,
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
TangemButton(buttonUM = state.actionButtonConfig.toButtonUM())
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PairButtons(state: EmptyTransactionsBlockState.ButtonsState.PairButtons, modifier: Modifier = Modifier) {
|
||||
Row(
|
||||
modifier = modifier,
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2),
|
||||
) {
|
||||
ActionButton(
|
||||
TangemButton(
|
||||
modifier = Modifier.weight(1F),
|
||||
config = state.firstButtonConfig,
|
||||
buttonUM = state.firstButtonConfig.toButtonUM(),
|
||||
)
|
||||
ActionButton(
|
||||
TangemButton(
|
||||
modifier = Modifier.weight(1F),
|
||||
config = state.secondButtonConfig,
|
||||
buttonUM = state.secondButtonConfig.toButtonUM(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ActionButtonConfig.toButtonUM(): TangemButtonUM = TangemButtonUM(
|
||||
text = text,
|
||||
tangemIconUM = TangemIconUM.Icon(iconRes = iconResId),
|
||||
type = TangemButtonType.Secondary,
|
||||
size = TangemButtonSize.X12,
|
||||
isEnabled = isEnabled,
|
||||
isLoading = isInProgress,
|
||||
onClick = onClick,
|
||||
shape = TangemButtonShape.Rounded,
|
||||
iconPosition = TangemButtonIconPosition.End,
|
||||
)
|
||||
|
||||
@Composable
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Preview(widthDp = 360, showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun EmptyTransactionBlockPreview(
|
||||
@PreviewParameter(EmptyTransactionBlockStateProvider::class) state: EmptyTransactionsBlockState,
|
||||
) {
|
||||
TangemThemePreview {
|
||||
TangemThemePreviewRedesign {
|
||||
EmptyTransactionBlock(state = state)
|
||||
}
|
||||
}
|
||||
|
||||
private class EmptyTransactionBlockStateProvider : CollectionPreviewParameterProvider<EmptyTransactionsBlockState>(
|
||||
collection = listOf(
|
||||
EmptyTransactionsBlockState.Empty {},
|
||||
EmptyTransactionsBlockState.FailedToLoad(onReload = {}, onExplore = {}),
|
||||
EmptyTransactionsBlockState.NotImplemented(onExplore = {}),
|
||||
),
|
||||
)
|
||||
private class EmptyTransactionBlockStateProvider :
|
||||
CollectionPreviewParameterProvider<EmptyTransactionsBlockState>(
|
||||
collection = listOf(
|
||||
EmptyTransactionsBlockState.Empty(
|
||||
onExplore = {},
|
||||
exploreIconResId = R.drawable.ic_compass_24,
|
||||
),
|
||||
EmptyTransactionsBlockState.FailedToLoad(
|
||||
onReload = {},
|
||||
onExplore = {},
|
||||
reloadIconResId = R.drawable.ic_refresh_24,
|
||||
exploreIconResId = R.drawable.ic_compass_24,
|
||||
),
|
||||
EmptyTransactionsBlockState.NotImplemented(
|
||||
onExplore = {},
|
||||
exploreIconResId = R.drawable.ic_compass_24,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
package com.tangem.core.ui.components.transactions.empty
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
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.R
|
||||
import com.tangem.core.ui.components.buttons.actions.ActionButton
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.test.EmptyTransactionBlockTestTags
|
||||
|
||||
/**
|
||||
* Placeholder for transaction's block without content
|
||||
*
|
||||
* @param state component state
|
||||
* @param modifier modifier
|
||||
*/
|
||||
@Composable
|
||||
fun EmptyTransactionBlockLegacy(state: EmptyTransactionsBlockState, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.clip(TangemTheme.shapes.roundedCornersXMedium)
|
||||
.background(color = TangemTheme.colors.background.primary)
|
||||
.padding(vertical = TangemTheme.dimens.spacing24)
|
||||
.testTag(EmptyTransactionBlockTestTags.BLOCK),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing24),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.size(TangemTheme.dimens.size64)
|
||||
.testTag(EmptyTransactionBlockTestTags.ICON),
|
||||
painter = painterResource(id = state.iconRes),
|
||||
tint = TangemTheme.colors.icon.inactive,
|
||||
contentDescription = null,
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.spacing32)
|
||||
.testTag(EmptyTransactionBlockTestTags.TEXT),
|
||||
textAlign = TextAlign.Center,
|
||||
text = state.text.resolveReference(),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
||||
Buttons(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.spacing18)
|
||||
.testTag(EmptyTransactionBlockTestTags.EXPLORE_BUTTON),
|
||||
state = state.buttonsState,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Buttons(state: EmptyTransactionsBlockState.ButtonsState, modifier: Modifier = Modifier) {
|
||||
when (state) {
|
||||
is EmptyTransactionsBlockState.ButtonsState.SingleButton -> SingleButton(state = state, modifier = modifier)
|
||||
is EmptyTransactionsBlockState.ButtonsState.PairButtons -> PairButtons(state = state, modifier = modifier)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SingleButton(state: EmptyTransactionsBlockState.ButtonsState.SingleButton, modifier: Modifier = Modifier) {
|
||||
ActionButton(modifier = modifier, config = state.actionButtonConfig)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PairButtons(state: EmptyTransactionsBlockState.ButtonsState.PairButtons, modifier: Modifier = Modifier) {
|
||||
Row(
|
||||
modifier = modifier,
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
|
||||
) {
|
||||
ActionButton(
|
||||
modifier = Modifier.weight(1F),
|
||||
config = state.firstButtonConfig,
|
||||
)
|
||||
ActionButton(
|
||||
modifier = Modifier.weight(1F),
|
||||
config = state.secondButtonConfig,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Preview(widthDp = 360, showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun EmptyTransactionBlockLegacyPreview(
|
||||
@PreviewParameter(EmptyTransactionBlockLegacyStateProvider::class) state: EmptyTransactionsBlockState,
|
||||
) {
|
||||
TangemThemePreview {
|
||||
EmptyTransactionBlockLegacy(state = state)
|
||||
}
|
||||
}
|
||||
|
||||
private class EmptyTransactionBlockLegacyStateProvider :
|
||||
CollectionPreviewParameterProvider<EmptyTransactionsBlockState>(
|
||||
collection = listOf(
|
||||
EmptyTransactionsBlockState.Empty(
|
||||
onExplore = {},
|
||||
exploreIconResId = R.drawable.ic_arrow_top_right_24,
|
||||
),
|
||||
EmptyTransactionsBlockState.FailedToLoad(
|
||||
onReload = {},
|
||||
onExplore = {},
|
||||
reloadIconResId = R.drawable.ic_refresh_24,
|
||||
exploreIconResId = R.drawable.ic_arrow_top_right_24,
|
||||
),
|
||||
EmptyTransactionsBlockState.NotImplemented(
|
||||
onExplore = {},
|
||||
exploreIconResId = R.drawable.ic_arrow_top_right_24,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.core.ui.components.transactions.empty
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
|
@ -21,17 +22,19 @@ sealed class EmptyTransactionsBlockState(
|
|||
data class FailedToLoad(
|
||||
val onReload: () -> Unit,
|
||||
val onExplore: () -> Unit,
|
||||
@DrawableRes val reloadIconResId: Int,
|
||||
@DrawableRes val exploreIconResId: Int,
|
||||
) : EmptyTransactionsBlockState(
|
||||
buttonsState = ButtonsState.PairButtons(
|
||||
firstButtonConfig = ActionButtonConfig(
|
||||
text = TextReference.Res(R.string.common_reload),
|
||||
iconResId = R.drawable.ic_refresh_24,
|
||||
iconResId = reloadIconResId,
|
||||
onClick = onReload,
|
||||
isEnabled = true,
|
||||
),
|
||||
secondButtonConfig = ActionButtonConfig(
|
||||
text = TextReference.Res(R.string.common_explore),
|
||||
iconResId = R.drawable.ic_arrow_top_right_24,
|
||||
iconResId = exploreIconResId,
|
||||
onClick = onExplore,
|
||||
isEnabled = true,
|
||||
),
|
||||
|
|
@ -40,11 +43,14 @@ sealed class EmptyTransactionsBlockState(
|
|||
text = TextReference.Res(R.string.transaction_history_error_failed_to_load),
|
||||
)
|
||||
|
||||
data class Empty(val onExplore: (() -> Unit)) : EmptyTransactionsBlockState(
|
||||
data class Empty(
|
||||
val onExplore: () -> Unit,
|
||||
@DrawableRes val exploreIconResId: Int,
|
||||
) : EmptyTransactionsBlockState(
|
||||
buttonsState = ButtonsState.SingleButton(
|
||||
actionButtonConfig = ActionButtonConfig(
|
||||
text = TextReference.Res(R.string.common_explore),
|
||||
iconResId = R.drawable.ic_arrow_top_right_24,
|
||||
iconResId = exploreIconResId,
|
||||
onClick = onExplore,
|
||||
isEnabled = true,
|
||||
),
|
||||
|
|
@ -53,11 +59,14 @@ sealed class EmptyTransactionsBlockState(
|
|||
text = TextReference.Res(R.string.transaction_history_empty_transactions),
|
||||
)
|
||||
|
||||
data class NotImplemented(val onExplore: () -> Unit) : EmptyTransactionsBlockState(
|
||||
data class NotImplemented(
|
||||
val onExplore: () -> Unit,
|
||||
@DrawableRes val exploreIconResId: Int,
|
||||
) : EmptyTransactionsBlockState(
|
||||
buttonsState = ButtonsState.SingleButton(
|
||||
actionButtonConfig = ActionButtonConfig(
|
||||
text = TextReference.Res(R.string.common_explore_transaction_history),
|
||||
iconResId = R.drawable.ic_arrow_top_right_24,
|
||||
iconResId = exploreIconResId,
|
||||
onClick = onExplore,
|
||||
isEnabled = true,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ internal class DefaultTokenDetailsComponent @AssistedInject constructor(
|
|||
tokenDetailsUM = tokenDetailsUM,
|
||||
tokenMarketBlockComponent = tokenMarketBlockComponent,
|
||||
yieldSupplyComponent = yieldSupplyComponent,
|
||||
txHistoryComponent = txHistoryComponent,
|
||||
modifier = modifier,
|
||||
)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.foundation.layout.statusBarsPadding
|
||||
import androidx.compose.foundation.layout.systemBars
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import com.tangem.common.ui.earn.EarnBlock
|
||||
import com.tangem.common.ui.notifications.notifications
|
||||
|
||||
|
|
@ -21,6 +24,7 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
|
|
@ -56,10 +60,14 @@ import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDeta
|
|||
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.TokenDetailsBalanceBlock
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.TokenDetailsBalanceBlockHeight
|
||||
import com.tangem.features.markets.token.block.TokenMarketBlockComponent
|
||||
import com.tangem.features.txhistory.component.TxHistoryComponent
|
||||
import com.tangem.features.txhistory.entity.TxHistoryUM
|
||||
import com.tangem.features.yield.supply.api.YieldSupplyComponent
|
||||
import dev.chrisbanes.haze.HazeProgressive
|
||||
import dev.chrisbanes.haze.HazeTint
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
private val TopBarHeight: Dp = 64.dp
|
||||
private val MarketBlockHorizontalPadding: Dp = 14.dp
|
||||
|
|
@ -69,6 +77,7 @@ internal fun TokenDetailsScreen(
|
|||
tokenDetailsUM: TokenDetailsUM,
|
||||
tokenMarketBlockComponent: TokenMarketBlockComponent?,
|
||||
yieldSupplyComponent: YieldSupplyComponent,
|
||||
txHistoryComponent: TxHistoryComponent,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val statusBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getTop(this).toDp() }
|
||||
|
|
@ -110,6 +119,7 @@ internal fun TokenDetailsScreen(
|
|||
TokenDetailsBody(
|
||||
tokenDetailsUM = tokenDetailsUM,
|
||||
yieldSupplyComponent = yieldSupplyComponent,
|
||||
txHistoryComponent = txHistoryComponent,
|
||||
rootBackground = rootBackground,
|
||||
bottomContentPadding = marketBlockHeight,
|
||||
modifier = Modifier
|
||||
|
|
@ -197,13 +207,18 @@ private fun BoxScope.TokenDetailsMarketBlockOverlay(
|
|||
private fun TokenDetailsBody(
|
||||
tokenDetailsUM: TokenDetailsUM,
|
||||
yieldSupplyComponent: YieldSupplyComponent,
|
||||
txHistoryComponent: TxHistoryComponent,
|
||||
rootBackground: Color,
|
||||
bottomContentPadding: Dp,
|
||||
modifier: Modifier = Modifier,
|
||||
itemModifier: Modifier = Modifier,
|
||||
) {
|
||||
val listState = rememberLazyListState()
|
||||
val txHistoryState by txHistoryComponent.txHistoryState.collectAsStateWithLifecycle()
|
||||
|
||||
LazyColumn(
|
||||
modifier = modifier,
|
||||
state = listState,
|
||||
contentPadding = PaddingValues(bottom = bottomContentPadding),
|
||||
) {
|
||||
notifications(
|
||||
|
|
@ -222,7 +237,9 @@ private fun TokenDetailsBody(
|
|||
item(key = "yield_supply_block") {
|
||||
yieldSupplyComponent.Content(modifier = itemModifier.padding(vertical = TangemTheme.dimens2.x2))
|
||||
}
|
||||
// TODO [REDACTED_TASK_KEY] Token Details Make Transaction History
|
||||
with(txHistoryComponent) {
|
||||
txHistoryContent(listState = listState, state = txHistoryState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -273,6 +290,15 @@ private fun TokenDetailsScreen_Preview() {
|
|||
@Composable
|
||||
override fun Content(modifier: Modifier) = Unit
|
||||
},
|
||||
txHistoryComponent = object : TxHistoryComponent {
|
||||
override val txHistoryState: StateFlow<TxHistoryUM> = MutableStateFlow(
|
||||
value = TxHistoryUM.Empty(isBalanceHidden = false, onExploreClick = {}),
|
||||
)
|
||||
|
||||
override fun LazyListScope.txHistoryContentLegacy(listState: LazyListState, state: TxHistoryUM) = Unit
|
||||
|
||||
override fun LazyListScope.txHistoryContent(listState: LazyListState, state: TxHistoryUM) = Unit
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,7 +151,9 @@ internal fun TokenDetailsScreenLegacy(
|
|||
modifier = itemModifier,
|
||||
)
|
||||
|
||||
with(txHistoryComponent) { txHistoryContent(listState = listState, state = txHistoryComponentState) }
|
||||
with(txHistoryComponent) {
|
||||
txHistoryContentLegacy(listState = listState, state = txHistoryComponentState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -179,6 +181,8 @@ private fun TokenDetailsScreenPreview(
|
|||
value = TxHistoryUM.Empty(isBalanceHidden = false, onExploreClick = {}),
|
||||
)
|
||||
|
||||
override fun LazyListScope.txHistoryContentLegacy(listState: LazyListState, state: TxHistoryUM) = Unit
|
||||
|
||||
override fun LazyListScope.txHistoryContent(listState: LazyListState, state: TxHistoryUM) = Unit
|
||||
},
|
||||
yieldSupplyComponent = object : YieldSupplyComponent {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ dependencies {
|
|||
/** Compose */
|
||||
implementation(deps.compose.runtime)
|
||||
implementation(deps.compose.foundation)
|
||||
implementation(deps.compose.ui.tooling)
|
||||
|
||||
/** Other */
|
||||
implementation(deps.kotlin.immutable.collections)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ interface TxHistoryComponent {
|
|||
|
||||
val txHistoryState: StateFlow<TxHistoryUM>
|
||||
|
||||
fun LazyListScope.txHistoryContentLegacy(listState: LazyListState, state: TxHistoryUM)
|
||||
|
||||
fun LazyListScope.txHistoryContent(listState: LazyListState, state: TxHistoryUM)
|
||||
|
||||
data class Params(
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ sealed interface TxHistoryUM {
|
|||
TxHistoryItemUM.Transaction(TransactionState.Loading("LOADING_TX_HASH_1")),
|
||||
TxHistoryItemUM.Transaction(TransactionState.Loading("LOADING_TX_HASH_2")),
|
||||
TxHistoryItemUM.Transaction(TransactionState.Loading("LOADING_TX_HASH_3")),
|
||||
TxHistoryItemUM.Transaction(TransactionState.Loading("LOADING_TX_HASH_4")),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,139 +1,214 @@
|
|||
package com.tangem.features.txhistory.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.core.ui.components.list.InfiniteListHandler
|
||||
import com.tangem.core.ui.components.transactions.PendingTxsBlock
|
||||
import com.tangem.core.ui.components.transactions.Transaction
|
||||
import com.tangem.core.ui.components.transactions.TxHistoryGroupTitle
|
||||
import com.tangem.core.ui.components.transactions.TxHistoryTitle
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.layout.layoutId
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.util.lerp
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.CircleShimmer
|
||||
import com.tangem.core.ui.components.RectangleShimmer
|
||||
import com.tangem.core.ui.components.transactions.empty.EmptyTransactionBlock
|
||||
import com.tangem.core.ui.components.transactions.empty.EmptyTransactionsBlockState
|
||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
||||
import com.tangem.core.ui.decorations.roundedShapeItemDecoration
|
||||
import com.tangem.core.ui.ds.row.TangemRowContainer
|
||||
import com.tangem.core.ui.ds.row.TangemRowLayoutId
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import com.tangem.features.txhistory.entity.TxHistoryUM
|
||||
|
||||
private const val LOAD_ITEMS_BUFFER = 20
|
||||
private val LoadingTitleShimmerWidth = 52.dp
|
||||
private val LoadingPrimaryShimmerWidth = 110.dp
|
||||
private val LoadingSecondaryShimmerWidth = 52.dp
|
||||
private val LoadingEndTopShimmerWidth = 107.dp
|
||||
private val LoadingEndBottomShimmerWidth = 52.dp
|
||||
|
||||
private const val LOADING_TRANSACTION_MIN_ALPHA = 0.1f
|
||||
|
||||
fun LazyListScope.txHistoryItems(listState: LazyListState, state: TxHistoryUM) {
|
||||
when (state) {
|
||||
is TxHistoryUM.Content -> contentItems(listState, state)
|
||||
is TxHistoryUM.Empty -> nonContentItem(state = EmptyTransactionsBlockState.Empty(state.onExploreClick))
|
||||
is TxHistoryUM.Error -> nonContentItem(
|
||||
state = EmptyTransactionsBlockState.FailedToLoad(
|
||||
onReload = state.onReloadClick,
|
||||
onExplore = state.onExploreClick,
|
||||
),
|
||||
)
|
||||
is TxHistoryUM.Empty -> emptyItem(state)
|
||||
is TxHistoryUM.Error -> errorItem(state)
|
||||
is TxHistoryUM.Loading -> loadingItems(state)
|
||||
is TxHistoryUM.NotSupported -> {
|
||||
if (state.pendingTransactions.isNotEmpty()) {
|
||||
item(key = "PendingTxsBlock", contentType = "PendingTxsBlock") {
|
||||
PendingTxsBlock(pendingTxs = state.pendingTransactions, isBalanceHidden = state.isBalanceHidden)
|
||||
}
|
||||
}
|
||||
|
||||
nonContentItem(
|
||||
state = EmptyTransactionsBlockState.NotImplemented(onExplore = state.onExploreClick),
|
||||
)
|
||||
}
|
||||
is TxHistoryUM.NotSupported -> notSupportedItem(state)
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyListScope.nonContentItem(state: EmptyTransactionsBlockState, modifier: Modifier = Modifier) {
|
||||
item(key = state::class.java, contentType = state::class.java) {
|
||||
EmptyTransactionBlock(
|
||||
state = state,
|
||||
modifier = modifier
|
||||
.animateItem(fadeInSpec = null, fadeOutSpec = null)
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16, vertical = TangemTheme.dimens.spacing12)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
private fun LazyListScope.contentItems(listState: LazyListState, state: TxHistoryUM.Content) {
|
||||
item(key = "tx_history_content", contentType = "tx_history_content") {
|
||||
TxHistoryContentBlock(state = state)
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyListScope.emptyItem(state: TxHistoryUM.Empty) {
|
||||
item(key = "tx_history_empty", contentType = "tx_history_empty") {
|
||||
TxHistoryEmptyBlock(state = state)
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyListScope.errorItem(state: TxHistoryUM.Error) {
|
||||
item(key = "tx_history_error", contentType = "tx_history_error") {
|
||||
TxHistoryErrorBlock(state = state)
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyListScope.loadingItems(state: TxHistoryUM.Loading) {
|
||||
itemsIndexed(
|
||||
items = state.items,
|
||||
key = { _, item ->
|
||||
when (item) {
|
||||
is TxHistoryUM.TxHistoryItemUM.GroupTitle -> item.itemKey
|
||||
is TxHistoryUM.TxHistoryItemUM.Title -> item.onExploreClick.hashCode()
|
||||
is TxHistoryUM.TxHistoryItemUM.Transaction ->
|
||||
item.state.txHash + (item.state as? TransactionState.Content)?.hashCode()
|
||||
}
|
||||
},
|
||||
contentType = { _, item -> item::class.java },
|
||||
itemContent = { index, item ->
|
||||
TxHistoryListItem(
|
||||
state = item,
|
||||
isBalanceHidden = true,
|
||||
modifier = Modifier.roundedShapeItemDecoration(
|
||||
currentIndex = index,
|
||||
lastIndex = state.items.lastIndex,
|
||||
),
|
||||
)
|
||||
},
|
||||
item(key = "tx_history_loading", contentType = "tx_history_loading") {
|
||||
TxHistoryLoadingBlock(state = state)
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyListScope.notSupportedItem(state: TxHistoryUM.NotSupported) {
|
||||
item(key = "tx_history_not_supported", contentType = "tx_history_not_supported") {
|
||||
TxHistoryNotSupportedBlock(state = state)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
@Composable
|
||||
private fun TxHistoryContentBlock(state: TxHistoryUM.Content, modifier: Modifier = Modifier) {
|
||||
// TODO [REDACTED_TASK_KEY] redesign Content state
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TxHistoryEmptyBlock(state: TxHistoryUM.Empty, modifier: Modifier = Modifier) {
|
||||
EmptyTransactionBlock(
|
||||
state = EmptyTransactionsBlockState.Empty(
|
||||
onExplore = state.onExploreClick,
|
||||
exploreIconResId = R.drawable.ic_compass_24,
|
||||
),
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
private fun LazyListScope.contentItems(listState: LazyListState, state: TxHistoryUM.Content) {
|
||||
itemsIndexed(
|
||||
items = state.items,
|
||||
key = { _, item ->
|
||||
when (item) {
|
||||
is TxHistoryUM.TxHistoryItemUM.GroupTitle -> item.itemKey
|
||||
is TxHistoryUM.TxHistoryItemUM.Title -> item.onExploreClick.hashCode()
|
||||
is TxHistoryUM.TxHistoryItemUM.Transaction ->
|
||||
item.state.txHash + (item.state as? TransactionState.Content)?.hashCode()
|
||||
}
|
||||
},
|
||||
contentType = { _, item -> item::class.java },
|
||||
itemContent = { index, item ->
|
||||
TxHistoryListItem(
|
||||
state = item,
|
||||
isBalanceHidden = state.isBalanceHidden,
|
||||
modifier = Modifier.roundedShapeItemDecoration(
|
||||
currentIndex = index,
|
||||
lastIndex = state.items.lastIndex,
|
||||
),
|
||||
)
|
||||
},
|
||||
@Composable
|
||||
private fun TxHistoryErrorBlock(state: TxHistoryUM.Error, modifier: Modifier = Modifier) {
|
||||
EmptyTransactionBlock(
|
||||
state = EmptyTransactionsBlockState.FailedToLoad(
|
||||
onReload = state.onReloadClick,
|
||||
onExplore = state.onExploreClick,
|
||||
reloadIconResId = R.drawable.ic_refresh_24,
|
||||
exploreIconResId = R.drawable.ic_compass_24,
|
||||
),
|
||||
modifier = modifier,
|
||||
)
|
||||
item {
|
||||
InfiniteListHandler(
|
||||
listState = listState,
|
||||
buffer = LOAD_ITEMS_BUFFER,
|
||||
onLoadMore = state.loadMore,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TxHistoryLoadingBlock(state: TxHistoryUM.Loading, modifier: Modifier = Modifier) {
|
||||
val transactionCount = state.items.count { it is TxHistoryUM.TxHistoryItemUM.Transaction }
|
||||
Column(modifier = modifier.fillMaxWidth()) {
|
||||
var transactionIndex = 0
|
||||
state.items.forEach { item ->
|
||||
when (item) {
|
||||
is TxHistoryUM.TxHistoryItemUM.Title -> TxHistoryLoadingTitle()
|
||||
is TxHistoryUM.TxHistoryItemUM.Transaction -> {
|
||||
val fraction = if (transactionCount <= 1) {
|
||||
0f
|
||||
} else {
|
||||
transactionIndex.toFloat() / (transactionCount - 1)
|
||||
}
|
||||
val alpha = lerp(start = 1f, stop = LOADING_TRANSACTION_MIN_ALPHA, fraction = fraction)
|
||||
TxHistoryLoadingTransaction(modifier = Modifier.alpha(alpha))
|
||||
transactionIndex++
|
||||
}
|
||||
is TxHistoryUM.TxHistoryItemUM.GroupTitle -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun TxHistoryListItem(
|
||||
state: TxHistoryUM.TxHistoryItemUM,
|
||||
isBalanceHidden: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
when (state) {
|
||||
is TxHistoryUM.TxHistoryItemUM.GroupTitle -> {
|
||||
TxHistoryGroupTitle(config = state.legacyGroupTitle, modifier = modifier)
|
||||
}
|
||||
is TxHistoryUM.TxHistoryItemUM.Title -> {
|
||||
TxHistoryTitle(onExploreClick = state.onExploreClick, modifier = modifier)
|
||||
}
|
||||
is TxHistoryUM.TxHistoryItemUM.Transaction -> {
|
||||
Transaction(
|
||||
state = state.state,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
modifier = modifier,
|
||||
private fun TxHistoryLoadingTitle(modifier: Modifier = Modifier) {
|
||||
RectangleShimmer(
|
||||
modifier = modifier
|
||||
.padding(
|
||||
top = TangemTheme.dimens2.x6,
|
||||
bottom = TangemTheme.dimens2.x3,
|
||||
start = TangemTheme.dimens2.x4,
|
||||
)
|
||||
}
|
||||
.size(width = LoadingTitleShimmerWidth, height = TangemTheme.dimens2.x4),
|
||||
radius = TangemTheme.dimens2.x2,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TxHistoryLoadingTransaction(modifier: Modifier = Modifier) {
|
||||
TangemRowContainer(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
contentPadding = PaddingValues(
|
||||
horizontal = TangemTheme.dimens2.x4,
|
||||
vertical = TangemTheme.dimens2.x3,
|
||||
),
|
||||
content = {
|
||||
CircleShimmer(
|
||||
modifier = Modifier
|
||||
.layoutId(TangemRowLayoutId.HEAD)
|
||||
.padding(end = TangemTheme.dimens2.x3)
|
||||
.size(TangemTheme.dimens2.x10),
|
||||
)
|
||||
RectangleShimmer(
|
||||
modifier = Modifier
|
||||
.layoutId(TangemRowLayoutId.START_TOP)
|
||||
.size(width = LoadingPrimaryShimmerWidth, height = TangemTheme.dimens2.x5),
|
||||
radius = TangemTheme.dimens2.x2,
|
||||
)
|
||||
RectangleShimmer(
|
||||
modifier = Modifier
|
||||
.layoutId(TangemRowLayoutId.START_BOTTOM)
|
||||
.size(width = LoadingSecondaryShimmerWidth, height = TangemTheme.dimens2.x4),
|
||||
radius = TangemTheme.dimens2.x2,
|
||||
)
|
||||
RectangleShimmer(
|
||||
modifier = Modifier
|
||||
.layoutId(TangemRowLayoutId.END_TOP)
|
||||
.size(width = LoadingEndTopShimmerWidth, height = TangemTheme.dimens2.x5),
|
||||
radius = TangemTheme.dimens2.x2,
|
||||
)
|
||||
RectangleShimmer(
|
||||
modifier = Modifier
|
||||
.layoutId(TangemRowLayoutId.END_BOTTOM)
|
||||
.size(width = LoadingEndBottomShimmerWidth, height = TangemTheme.dimens2.x4),
|
||||
radius = TangemTheme.dimens2.x2,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TxHistoryNotSupportedBlock(state: TxHistoryUM.NotSupported, modifier: Modifier = Modifier) {
|
||||
EmptyTransactionBlock(
|
||||
state = EmptyTransactionsBlockState.NotImplemented(
|
||||
onExplore = state.onExploreClick,
|
||||
exploreIconResId = R.drawable.ic_compass_24,
|
||||
),
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
// region Preview
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun TxHistoryLoadingBlock_Preview() {
|
||||
TangemThemePreviewRedesign {
|
||||
TxHistoryLoadingBlock(
|
||||
state = TxHistoryUM.Loading(
|
||||
isBalanceHidden = false,
|
||||
onExploreClick = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
// endregion Preview
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
package com.tangem.features.txhistory.ui
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.list.InfiniteListHandler
|
||||
import com.tangem.core.ui.components.transactions.PendingTxsBlock
|
||||
import com.tangem.core.ui.components.transactions.Transaction
|
||||
import com.tangem.core.ui.components.transactions.TxHistoryGroupTitle
|
||||
import com.tangem.core.ui.components.transactions.TxHistoryTitle
|
||||
import com.tangem.core.ui.components.transactions.empty.EmptyTransactionBlockLegacy
|
||||
import com.tangem.core.ui.components.transactions.empty.EmptyTransactionsBlockState
|
||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
||||
import com.tangem.core.ui.decorations.roundedShapeItemDecoration
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.txhistory.entity.TxHistoryUM
|
||||
|
||||
private const val LOAD_ITEMS_BUFFER = 20
|
||||
|
||||
fun LazyListScope.txHistoryItemsLegacy(listState: LazyListState, state: TxHistoryUM) {
|
||||
when (state) {
|
||||
is TxHistoryUM.Content -> contentItems(listState, state)
|
||||
is TxHistoryUM.Empty -> nonContentItem(
|
||||
state = EmptyTransactionsBlockState.Empty(
|
||||
onExplore = state.onExploreClick,
|
||||
exploreIconResId = R.drawable.ic_arrow_top_right_24,
|
||||
),
|
||||
)
|
||||
is TxHistoryUM.Error -> nonContentItem(
|
||||
state = EmptyTransactionsBlockState.FailedToLoad(
|
||||
onReload = state.onReloadClick,
|
||||
onExplore = state.onExploreClick,
|
||||
reloadIconResId = R.drawable.ic_refresh_24,
|
||||
exploreIconResId = R.drawable.ic_arrow_top_right_24,
|
||||
),
|
||||
)
|
||||
is TxHistoryUM.Loading -> loadingItems(state)
|
||||
is TxHistoryUM.NotSupported -> {
|
||||
if (state.pendingTransactions.isNotEmpty()) {
|
||||
item(key = "PendingTxsBlock", contentType = "PendingTxsBlock") {
|
||||
PendingTxsBlock(pendingTxs = state.pendingTransactions, isBalanceHidden = state.isBalanceHidden)
|
||||
}
|
||||
}
|
||||
|
||||
nonContentItem(
|
||||
state = EmptyTransactionsBlockState.NotImplemented(
|
||||
onExplore = state.onExploreClick,
|
||||
exploreIconResId = R.drawable.ic_arrow_top_right_24,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyListScope.nonContentItem(state: EmptyTransactionsBlockState, modifier: Modifier = Modifier) {
|
||||
item(key = state::class.java, contentType = state::class.java) {
|
||||
EmptyTransactionBlockLegacy(
|
||||
state = state,
|
||||
modifier = modifier
|
||||
.animateItem(fadeInSpec = null, fadeOutSpec = null)
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16, vertical = TangemTheme.dimens.spacing12)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyListScope.loadingItems(state: TxHistoryUM.Loading) {
|
||||
itemsIndexed(
|
||||
items = state.items,
|
||||
key = { _, item ->
|
||||
when (item) {
|
||||
is TxHistoryUM.TxHistoryItemUM.GroupTitle -> item.itemKey
|
||||
is TxHistoryUM.TxHistoryItemUM.Title -> item.onExploreClick.hashCode()
|
||||
is TxHistoryUM.TxHistoryItemUM.Transaction ->
|
||||
item.state.txHash + (item.state as? TransactionState.Content)?.hashCode()
|
||||
}
|
||||
},
|
||||
contentType = { _, item -> item::class.java },
|
||||
itemContent = { index, item ->
|
||||
TxHistoryListItemLegacy(
|
||||
state = item,
|
||||
isBalanceHidden = true,
|
||||
modifier = Modifier.roundedShapeItemDecoration(
|
||||
currentIndex = index,
|
||||
lastIndex = state.items.lastIndex,
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun LazyListScope.contentItems(listState: LazyListState, state: TxHistoryUM.Content) {
|
||||
itemsIndexed(
|
||||
items = state.items,
|
||||
key = { _, item ->
|
||||
when (item) {
|
||||
is TxHistoryUM.TxHistoryItemUM.GroupTitle -> item.itemKey
|
||||
is TxHistoryUM.TxHistoryItemUM.Title -> item.onExploreClick.hashCode()
|
||||
is TxHistoryUM.TxHistoryItemUM.Transaction ->
|
||||
item.state.txHash + (item.state as? TransactionState.Content)?.hashCode()
|
||||
}
|
||||
},
|
||||
contentType = { _, item -> item::class.java },
|
||||
itemContent = { index, item ->
|
||||
TxHistoryListItemLegacy(
|
||||
state = item,
|
||||
isBalanceHidden = state.isBalanceHidden,
|
||||
modifier = Modifier.roundedShapeItemDecoration(
|
||||
currentIndex = index,
|
||||
lastIndex = state.items.lastIndex,
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
item {
|
||||
InfiniteListHandler(
|
||||
listState = listState,
|
||||
buffer = LOAD_ITEMS_BUFFER,
|
||||
onLoadMore = state.loadMore,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun TxHistoryListItemLegacy(
|
||||
state: TxHistoryUM.TxHistoryItemUM,
|
||||
isBalanceHidden: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
when (state) {
|
||||
is TxHistoryUM.TxHistoryItemUM.GroupTitle -> {
|
||||
TxHistoryGroupTitle(config = state.legacyGroupTitle, modifier = modifier)
|
||||
}
|
||||
is TxHistoryUM.TxHistoryItemUM.Title -> {
|
||||
TxHistoryTitle(onExploreClick = state.onExploreClick, modifier = modifier)
|
||||
}
|
||||
is TxHistoryUM.TxHistoryItemUM.Transaction -> {
|
||||
Transaction(
|
||||
state = state.state,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import com.tangem.core.decompose.model.getOrCreateModel
|
|||
import com.tangem.features.txhistory.entity.TxHistoryUM
|
||||
import com.tangem.features.txhistory.model.TxHistoryModel
|
||||
import com.tangem.features.txhistory.ui.txHistoryItems
|
||||
import com.tangem.features.txhistory.ui.txHistoryItemsLegacy
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
|
@ -22,6 +23,10 @@ internal class DefaultTxHistoryComponent @AssistedInject constructor(
|
|||
override val txHistoryState: StateFlow<TxHistoryUM>
|
||||
get() = model.uiState
|
||||
|
||||
override fun LazyListScope.txHistoryContentLegacy(listState: LazyListState, state: TxHistoryUM) {
|
||||
txHistoryItemsLegacy(listState, state)
|
||||
}
|
||||
|
||||
override fun LazyListScope.txHistoryContent(listState: LazyListState, state: TxHistoryUM) {
|
||||
txHistoryItems(listState, state)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue