Updated on 2026-08-14
This commit is contained in:
parent
02f927fd48
commit
33f03e8653
11 changed files with 8 additions and 695 deletions
|
|
@ -1,14 +1,11 @@
|
||||||
package com.tangem.feature.tokendetails.presentation.tokendetails
|
package com.tangem.feature.tokendetails.presentation.tokendetails
|
||||||
|
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.paging.PagingData
|
|
||||||
import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig
|
import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig
|
||||||
import com.tangem.core.ui.components.dropdownmenu.TangemDropdownMenuItem
|
import com.tangem.core.ui.components.dropdownmenu.TangemDropdownMenuItem
|
||||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||||
import com.tangem.core.ui.components.marketprice.PriceChangeState
|
import com.tangem.core.ui.components.marketprice.PriceChangeState
|
||||||
import com.tangem.core.ui.components.marketprice.PriceChangeType
|
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.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.core.ui.extensions.stringReference
|
import com.tangem.core.ui.extensions.stringReference
|
||||||
|
|
@ -18,7 +15,6 @@ import com.tangem.feature.tokendetails.presentation.tokendetails.state.*
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsActionButton
|
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsActionButton
|
||||||
import com.tangem.features.tokendetails.impl.R
|
import com.tangem.features.tokendetails.impl.R
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
|
|
||||||
@Suppress("LargeClass")
|
@Suppress("LargeClass")
|
||||||
|
|
@ -168,130 +164,6 @@ internal object TokenDetailsPreviewData {
|
||||||
onRefresh = {},
|
onRefresh = {},
|
||||||
)
|
)
|
||||||
|
|
||||||
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(
|
val tokenDetailsState_1 = TokenDetailsState(
|
||||||
topAppBarConfig = tokenDetailsTopAppBarConfig,
|
topAppBarConfig = tokenDetailsTopAppBarConfig,
|
||||||
tokenInfoBlockState = tokenInfoBlockState,
|
tokenInfoBlockState = tokenInfoBlockState,
|
||||||
|
|
@ -299,13 +171,7 @@ internal object TokenDetailsPreviewData {
|
||||||
marketPriceBlockState = marketPriceLoading,
|
marketPriceBlockState = marketPriceLoading,
|
||||||
stakingBlocksState = stakingLoadingBlock,
|
stakingBlocksState = stakingLoadingBlock,
|
||||||
notifications = persistentListOf(),
|
notifications = persistentListOf(),
|
||||||
txHistoryState = TxHistoryState.Content(
|
|
||||||
contentItems = MutableStateFlow(
|
|
||||||
value = TxHistoryState.getDefaultLoadingTransactions {},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
dialogConfig = null,
|
dialogConfig = null,
|
||||||
pendingTxs = persistentListOf(),
|
|
||||||
expressTxs = persistentListOf(),
|
expressTxs = persistentListOf(),
|
||||||
expressTxsToDisplay = persistentListOf(),
|
expressTxsToDisplay = persistentListOf(),
|
||||||
pullToRefreshConfig = pullToRefreshConfig,
|
pullToRefreshConfig = pullToRefreshConfig,
|
||||||
|
|
@ -330,12 +196,7 @@ internal object TokenDetailsPreviewData {
|
||||||
),
|
),
|
||||||
stakingBlocksState = stakingAvailableBlock,
|
stakingBlocksState = stakingAvailableBlock,
|
||||||
notifications = persistentListOf(),
|
notifications = persistentListOf(),
|
||||||
txHistoryState = TxHistoryState.NotSupported(
|
|
||||||
onExploreClick = {},
|
|
||||||
pendingTransactions = persistentListOf(),
|
|
||||||
),
|
|
||||||
dialogConfig = null,
|
dialogConfig = null,
|
||||||
pendingTxs = persistentListOf(),
|
|
||||||
expressTxs = persistentListOf(),
|
expressTxs = persistentListOf(),
|
||||||
expressTxsToDisplay = persistentListOf(),
|
expressTxsToDisplay = persistentListOf(),
|
||||||
pullToRefreshConfig = pullToRefreshConfig,
|
pullToRefreshConfig = pullToRefreshConfig,
|
||||||
|
|
@ -344,12 +205,5 @@ internal object TokenDetailsPreviewData {
|
||||||
isMarketPriceAvailable = true,
|
isMarketPriceAvailable = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
val tokenDetailsState_3 = tokenDetailsState_2.copy(
|
val tokenDetailsState_3 = tokenDetailsState_2.copy(stakingBlocksState = stakingBalanceBlock)
|
||||||
txHistoryState = TxHistoryState.Content(
|
|
||||||
contentItems = MutableStateFlow(
|
|
||||||
value = PagingData.from(txHistoryItems),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
stakingBlocksState = stakingBalanceBlock,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package com.tangem.feature.tokendetails.presentation.tokendetails.model
|
package com.tangem.feature.tokendetails.presentation.tokendetails.model
|
||||||
|
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import androidx.paging.cachedIn
|
|
||||||
import arrow.core.getOrElse
|
import arrow.core.getOrElse
|
||||||
import arrow.core.merge
|
import arrow.core.merge
|
||||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||||
|
|
@ -24,7 +23,6 @@ import com.tangem.core.decompose.model.ParamsContainer
|
||||||
import com.tangem.core.decompose.ui.UiMessageSender
|
import com.tangem.core.decompose.ui.UiMessageSender
|
||||||
import com.tangem.core.navigation.share.ShareManager
|
import com.tangem.core.navigation.share.ShareManager
|
||||||
import com.tangem.core.ui.clipboard.ClipboardManager
|
import com.tangem.core.ui.clipboard.ClipboardManager
|
||||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.core.ui.extensions.stringReference
|
import com.tangem.core.ui.extensions.stringReference
|
||||||
|
|
@ -69,8 +67,6 @@ import com.tangem.domain.transaction.error.OpenTrustlineError
|
||||||
import com.tangem.domain.transaction.error.SendTransactionError
|
import com.tangem.domain.transaction.error.SendTransactionError
|
||||||
import com.tangem.domain.transaction.usecase.*
|
import com.tangem.domain.transaction.usecase.*
|
||||||
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
|
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
|
||||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
|
|
||||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
|
||||||
import com.tangem.domain.wallets.usecase.GetExploreUrlUseCase
|
import com.tangem.domain.wallets.usecase.GetExploreUrlUseCase
|
||||||
import com.tangem.domain.wallets.usecase.GetExtendedPublicKeyForCurrencyUseCase
|
import com.tangem.domain.wallets.usecase.GetExtendedPublicKeyForCurrencyUseCase
|
||||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||||
|
|
@ -107,8 +103,6 @@ internal class TokenDetailsModel @Inject constructor(
|
||||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||||
private val fetchCurrencyStatusUseCase: FetchCurrencyStatusUseCase,
|
private val fetchCurrencyStatusUseCase: FetchCurrencyStatusUseCase,
|
||||||
private val txHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase,
|
|
||||||
private val txHistoryItemsUseCase: GetTxHistoryItemsUseCase,
|
|
||||||
private val getExploreUrlUseCase: GetExploreUrlUseCase,
|
private val getExploreUrlUseCase: GetExploreUrlUseCase,
|
||||||
private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCase,
|
private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCase,
|
||||||
private val removeCurrencyUseCase: RemoveCurrencyUseCase,
|
private val removeCurrencyUseCase: RemoveCurrencyUseCase,
|
||||||
|
|
@ -177,8 +171,6 @@ internal class TokenDetailsModel @Inject constructor(
|
||||||
networkHasDerivationUseCase = networkHasDerivationUseCase,
|
networkHasDerivationUseCase = networkHasDerivationUseCase,
|
||||||
getUserWalletUseCase = getUserWalletUseCase,
|
getUserWalletUseCase = getUserWalletUseCase,
|
||||||
userWalletId = userWalletId,
|
userWalletId = userWalletId,
|
||||||
symbol = cryptoCurrency.symbol,
|
|
||||||
decimals = cryptoCurrency.decimals,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
private val expressStatusFactory by lazy(mode = LazyThreadSafetyMode.NONE) {
|
private val expressStatusFactory by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||||
|
|
@ -251,7 +243,6 @@ internal class TokenDetailsModel @Inject constructor(
|
||||||
private fun updateContent() {
|
private fun updateContent() {
|
||||||
subscribeOnCurrencyStatusUpdates()
|
subscribeOnCurrencyStatusUpdates()
|
||||||
subscribeOnExpressTransactionsUpdates()
|
subscribeOnExpressTransactionsUpdates()
|
||||||
updateTxHistory(refresh = false, showItemsLoading = true, initialUpdating = true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleBalanceHiding() {
|
private fun handleBalanceHiding() {
|
||||||
|
|
@ -382,39 +373,8 @@ internal class TokenDetailsModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private fun updateTxHistory() {
|
||||||
* @param refresh - invalidate cache and get data from remote
|
modelScope.launch { txHistoryContentUpdateEmitter.triggerUpdate() }
|
||||||
* @param showItemsLoading - show loading items placeholder.
|
|
||||||
*/
|
|
||||||
private fun updateTxHistory(refresh: Boolean, showItemsLoading: Boolean, initialUpdating: Boolean = false) {
|
|
||||||
modelScope.launch {
|
|
||||||
if (!initialUpdating) {
|
|
||||||
txHistoryContentUpdateEmitter.triggerUpdate()
|
|
||||||
} else {
|
|
||||||
val txHistoryItemsCountEither = txHistoryItemsCountUseCase(
|
|
||||||
userWalletId = userWalletId,
|
|
||||||
currency = cryptoCurrency,
|
|
||||||
)
|
|
||||||
|
|
||||||
// if countEither is left, handling error state run inside getLoadingTxHistoryState
|
|
||||||
if (showItemsLoading || txHistoryItemsCountEither.isLeft()) {
|
|
||||||
internalUiState.value = stateFactory.getLoadingTxHistoryState(
|
|
||||||
itemsCountEither = txHistoryItemsCountEither,
|
|
||||||
pendingTransactions = internalUiState.value.pendingTxs,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
txHistoryItemsCountEither.onRight {
|
|
||||||
val maybeTxHistory = txHistoryItemsUseCase(
|
|
||||||
userWalletId = userWalletId,
|
|
||||||
currency = cryptoCurrency,
|
|
||||||
refresh = refresh,
|
|
||||||
).map { it.cachedIn(modelScope) }
|
|
||||||
|
|
||||||
internalUiState.value = stateFactory.getLoadedTxHistoryState(maybeTxHistory)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun subscribeOnUpdateStakingInfo(cryptoCurrencyStatus: CryptoCurrencyStatus) {
|
private fun subscribeOnUpdateStakingInfo(cryptoCurrencyStatus: CryptoCurrencyStatus) {
|
||||||
|
|
@ -552,8 +512,7 @@ internal class TokenDetailsModel @Inject constructor(
|
||||||
|
|
||||||
override fun onReloadClick() {
|
override fun onReloadClick() {
|
||||||
analyticsEventsHandler.send(TokenScreenAnalyticsEvent.ButtonReload(cryptoCurrency.symbol))
|
analyticsEventsHandler.send(TokenScreenAnalyticsEvent.ButtonReload(cryptoCurrency.symbol))
|
||||||
internalUiState.value = stateFactory.getLoadingTxHistoryState()
|
updateTxHistory()
|
||||||
updateTxHistory(refresh = true, showItemsLoading = true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSendClick(unavailabilityReason: ScenarioUnavailabilityReason) {
|
override fun onSendClick(unavailabilityReason: ScenarioUnavailabilityReason) {
|
||||||
|
|
@ -800,10 +759,7 @@ internal class TokenDetailsModel @Inject constructor(
|
||||||
listOf(
|
listOf(
|
||||||
async { fetchCurrencyStatusUseCase(userWalletId = userWalletId, id = cryptoCurrency.id) },
|
async { fetchCurrencyStatusUseCase(userWalletId = userWalletId, id = cryptoCurrency.id) },
|
||||||
async {
|
async {
|
||||||
updateTxHistory(
|
updateTxHistory()
|
||||||
refresh = true,
|
|
||||||
showItemsLoading = internalUiState.value.txHistoryState !is TxHistoryState.Content,
|
|
||||||
)
|
|
||||||
subscribeOnExpressTransactionsUpdates()
|
subscribeOnExpressTransactionsUpdates()
|
||||||
},
|
},
|
||||||
).awaitAll()
|
).awaitAll()
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,8 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.state
|
||||||
|
|
||||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionStateUM
|
import com.tangem.common.ui.expressStatus.state.ExpressTransactionStateUM
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
|
||||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
|
||||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
|
||||||
import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig
|
import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig
|
||||||
|
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsDialogConfig
|
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsDialogConfig
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsNotification
|
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsNotification
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
|
@ -18,10 +16,8 @@ internal data class TokenDetailsState(
|
||||||
val marketPriceBlockState: MarketPriceBlockState,
|
val marketPriceBlockState: MarketPriceBlockState,
|
||||||
val stakingBlocksState: StakingBlockUM?,
|
val stakingBlocksState: StakingBlockUM?,
|
||||||
val notifications: ImmutableList<TokenDetailsNotification>,
|
val notifications: ImmutableList<TokenDetailsNotification>,
|
||||||
val pendingTxs: PersistentList<TransactionState>,
|
|
||||||
val expressTxsToDisplay: PersistentList<ExpressTransactionStateUM>,
|
val expressTxsToDisplay: PersistentList<ExpressTransactionStateUM>,
|
||||||
val expressTxs: PersistentList<ExpressTransactionStateUM>,
|
val expressTxs: PersistentList<ExpressTransactionStateUM>,
|
||||||
val txHistoryState: TxHistoryState,
|
|
||||||
val dialogConfig: TokenDetailsDialogConfig?,
|
val dialogConfig: TokenDetailsDialogConfig?,
|
||||||
val pullToRefreshConfig: PullToRefreshConfig,
|
val pullToRefreshConfig: PullToRefreshConfig,
|
||||||
val bottomSheetConfig: TangemBottomSheetConfig?,
|
val bottomSheetConfig: TangemBottomSheetConfig?,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||||
import com.tangem.core.ui.components.marketprice.PriceChangeState
|
import com.tangem.core.ui.components.marketprice.PriceChangeState
|
||||||
import com.tangem.core.ui.components.marketprice.PriceChangeType
|
import com.tangem.core.ui.components.marketprice.PriceChangeType
|
||||||
import com.tangem.core.ui.components.marketprice.utils.PriceChangeConverter
|
import com.tangem.core.ui.components.marketprice.utils.PriceChangeConverter
|
||||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
|
||||||
import com.tangem.core.ui.format.bigdecimal.*
|
import com.tangem.core.ui.format.bigdecimal.*
|
||||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||||
import com.tangem.domain.models.StatusSource
|
import com.tangem.domain.models.StatusSource
|
||||||
|
|
@ -18,29 +17,20 @@ import com.tangem.feature.tokendetails.presentation.tokendetails.state.BalanceTy
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsBalanceBlockState
|
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsBalanceBlockState
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsNotification
|
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsNotification
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.txhistory.TokenDetailsTxHistoryTransactionStateConverter
|
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.utils.getBalance
|
import com.tangem.feature.tokendetails.presentation.tokendetails.state.utils.getBalance
|
||||||
import com.tangem.utils.Provider
|
import com.tangem.utils.Provider
|
||||||
import com.tangem.utils.StringsSigns.DASH_SIGN
|
import com.tangem.utils.StringsSigns.DASH_SIGN
|
||||||
import com.tangem.utils.converter.Converter
|
import com.tangem.utils.converter.Converter
|
||||||
import com.tangem.utils.isNullOrZero
|
import com.tangem.utils.isNullOrZero
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.collections.immutable.toPersistentList
|
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
|
|
||||||
@Suppress("LongParameterList")
|
|
||||||
internal class TokenDetailsLoadedBalanceConverter(
|
internal class TokenDetailsLoadedBalanceConverter(
|
||||||
private val currentStateProvider: Provider<TokenDetailsState>,
|
private val currentStateProvider: Provider<TokenDetailsState>,
|
||||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||||
private val symbol: String,
|
|
||||||
private val decimals: Int,
|
|
||||||
private val clickIntents: TokenDetailsClickIntents,
|
private val clickIntents: TokenDetailsClickIntents,
|
||||||
) : Converter<Either<CurrencyStatusError, CryptoCurrencyStatus>, TokenDetailsState> {
|
) : Converter<Either<CurrencyStatusError, CryptoCurrencyStatus>, TokenDetailsState> {
|
||||||
|
|
||||||
private val txHistoryItemConverter by lazy {
|
|
||||||
TokenDetailsTxHistoryTransactionStateConverter(symbol, decimals, clickIntents)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun convert(value: Either<CurrencyStatusError, CryptoCurrencyStatus>): TokenDetailsState {
|
override fun convert(value: Either<CurrencyStatusError, CryptoCurrencyStatus>): TokenDetailsState {
|
||||||
return value.fold(
|
return value.fold(
|
||||||
ifLeft = { convertError() },
|
ifLeft = { convertError() },
|
||||||
|
|
@ -64,7 +54,6 @@ internal class TokenDetailsLoadedBalanceConverter(
|
||||||
private fun convert(status: CryptoCurrencyStatus): TokenDetailsState {
|
private fun convert(status: CryptoCurrencyStatus): TokenDetailsState {
|
||||||
val state = currentStateProvider()
|
val state = currentStateProvider()
|
||||||
val currencyName = state.marketPriceBlockState.currencySymbol
|
val currencyName = state.marketPriceBlockState.currencySymbol
|
||||||
val pendingTxs = status.value.pendingTransactions.map(txHistoryItemConverter::convert).toPersistentList()
|
|
||||||
|
|
||||||
return state.copy(
|
return state.copy(
|
||||||
tokenBalanceBlockState = getBalanceState(
|
tokenBalanceBlockState = getBalanceState(
|
||||||
|
|
@ -73,12 +62,6 @@ internal class TokenDetailsLoadedBalanceConverter(
|
||||||
),
|
),
|
||||||
stakingBlocksState = state.stakingBlocksState,
|
stakingBlocksState = state.stakingBlocksState,
|
||||||
marketPriceBlockState = getMarketPriceState(status = status.value, currencySymbol = currencyName),
|
marketPriceBlockState = getMarketPriceState(status = status.value, currencySymbol = currencyName),
|
||||||
pendingTxs = pendingTxs,
|
|
||||||
txHistoryState = if (state.txHistoryState is TxHistoryState.NotSupported) {
|
|
||||||
state.txHistoryState.copy(pendingTransactions = pendingTxs)
|
|
||||||
} else {
|
|
||||||
state.txHistoryState
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import arrow.core.getOrElse
|
||||||
import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig
|
import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig
|
||||||
import com.tangem.core.ui.components.dropdownmenu.TangemDropdownMenuItem
|
import com.tangem.core.ui.components.dropdownmenu.TangemDropdownMenuItem
|
||||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
import com.tangem.core.ui.extensions.networkIconResId
|
import com.tangem.core.ui.extensions.networkIconResId
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
|
|
@ -24,7 +23,6 @@ import com.tangem.utils.converter.Converter
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
|
|
||||||
internal class TokenDetailsSkeletonStateConverter(
|
internal class TokenDetailsSkeletonStateConverter(
|
||||||
private val clickIntents: TokenDetailsClickIntents,
|
private val clickIntents: TokenDetailsClickIntents,
|
||||||
|
|
@ -64,14 +62,8 @@ internal class TokenDetailsSkeletonStateConverter(
|
||||||
marketPriceBlockState = MarketPriceBlockState.Loading(value.symbol),
|
marketPriceBlockState = MarketPriceBlockState.Loading(value.symbol),
|
||||||
stakingBlocksState = StakingBlockUM.Loading(iconState).takeIf { isSupportedInMobileApp },
|
stakingBlocksState = StakingBlockUM.Loading(iconState).takeIf { isSupportedInMobileApp },
|
||||||
notifications = persistentListOf(),
|
notifications = persistentListOf(),
|
||||||
pendingTxs = persistentListOf(),
|
|
||||||
expressTxs = persistentListOf(),
|
expressTxs = persistentListOf(),
|
||||||
expressTxsToDisplay = persistentListOf(),
|
expressTxsToDisplay = persistentListOf(),
|
||||||
txHistoryState = TxHistoryState.Content(
|
|
||||||
contentItems = MutableStateFlow(
|
|
||||||
value = TxHistoryState.getDefaultLoadingTransactions(clickIntents::onExploreClick),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
dialogConfig = null,
|
dialogConfig = null,
|
||||||
pullToRefreshConfig = createPullToRefresh(),
|
pullToRefreshConfig = createPullToRefresh(),
|
||||||
bottomSheetConfig = null,
|
bottomSheetConfig = null,
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,11 @@
|
||||||
package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory
|
package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory
|
||||||
|
|
||||||
import androidx.paging.PagingData
|
|
||||||
import arrow.core.Either
|
import arrow.core.Either
|
||||||
import com.tangem.common.ui.bottomsheet.chooseaddress.ChooseAddressBottomSheetConfig
|
import com.tangem.common.ui.bottomsheet.chooseaddress.ChooseAddressBottomSheetConfig
|
||||||
import com.tangem.common.ui.bottomsheet.receive.TokenReceiveBottomSheetConfig
|
import com.tangem.common.ui.bottomsheet.receive.TokenReceiveBottomSheetConfig
|
||||||
import com.tangem.common.ui.tokens.getUnavailabilityReasonText
|
import com.tangem.common.ui.tokens.getUnavailabilityReasonText
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||||
import com.tangem.core.ui.components.dropdownmenu.TangemDropdownMenuItem
|
import com.tangem.core.ui.components.dropdownmenu.TangemDropdownMenuItem
|
||||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
|
||||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
|
|
@ -18,7 +15,6 @@ import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||||
import com.tangem.domain.models.network.Network
|
import com.tangem.domain.models.network.Network
|
||||||
import com.tangem.domain.models.network.NetworkAddress
|
import com.tangem.domain.models.network.NetworkAddress
|
||||||
import com.tangem.domain.models.network.TxInfo
|
|
||||||
import com.tangem.domain.models.wallet.UserWallet
|
import com.tangem.domain.models.wallet.UserWallet
|
||||||
import com.tangem.domain.models.wallet.UserWalletId
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
import com.tangem.domain.staking.model.StakingAvailability
|
import com.tangem.domain.staking.model.StakingAvailability
|
||||||
|
|
@ -27,8 +23,6 @@ import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||||
import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
|
import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
|
||||||
import com.tangem.domain.tokens.model.TokenActionsState
|
import com.tangem.domain.tokens.model.TokenActionsState
|
||||||
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
|
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
|
||||||
import com.tangem.domain.txhistory.models.TxHistoryListError
|
|
||||||
import com.tangem.domain.txhistory.models.TxHistoryStateError
|
|
||||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||||
import com.tangem.domain.wallets.usecase.NetworkHasDerivationUseCase
|
import com.tangem.domain.wallets.usecase.NetworkHasDerivationUseCase
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
|
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
|
||||||
|
|
@ -36,14 +30,9 @@ import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenBala
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsAppBarMenuConfig
|
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsAppBarMenuConfig
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsDialogConfig
|
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsDialogConfig
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.txhistory.TokenDetailsLoadedTxHistoryConverter
|
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.txhistory.TokenDetailsLoadingTxHistoryConverter
|
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.txhistory.TokenDetailsLoadingTxHistoryConverter.TokenDetailsLoadingTxHistoryModel
|
|
||||||
import com.tangem.features.tokendetails.impl.R
|
import com.tangem.features.tokendetails.impl.R
|
||||||
import com.tangem.utils.Provider
|
import com.tangem.utils.Provider
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
|
|
||||||
@Suppress("TooManyFunctions", "LargeClass", "LongParameterList")
|
@Suppress("TooManyFunctions", "LargeClass", "LongParameterList")
|
||||||
internal class TokenDetailsStateFactory(
|
internal class TokenDetailsStateFactory(
|
||||||
|
|
@ -54,8 +43,6 @@ internal class TokenDetailsStateFactory(
|
||||||
private val networkHasDerivationUseCase: NetworkHasDerivationUseCase,
|
private val networkHasDerivationUseCase: NetworkHasDerivationUseCase,
|
||||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||||
private val userWalletId: UserWalletId,
|
private val userWalletId: UserWalletId,
|
||||||
symbol: String,
|
|
||||||
decimals: Int,
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val skeletonStateConverter by lazy {
|
private val skeletonStateConverter by lazy {
|
||||||
|
|
@ -75,8 +62,6 @@ internal class TokenDetailsStateFactory(
|
||||||
TokenDetailsLoadedBalanceConverter(
|
TokenDetailsLoadedBalanceConverter(
|
||||||
currentStateProvider = currentStateProvider,
|
currentStateProvider = currentStateProvider,
|
||||||
appCurrencyProvider = appCurrencyProvider,
|
appCurrencyProvider = appCurrencyProvider,
|
||||||
symbol = symbol,
|
|
||||||
decimals = decimals,
|
|
||||||
clickIntents = clickIntents,
|
clickIntents = clickIntents,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -88,22 +73,6 @@ internal class TokenDetailsStateFactory(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val loadingTransactionsStateConverter by lazy {
|
|
||||||
TokenDetailsLoadingTxHistoryConverter(
|
|
||||||
currentStateProvider = currentStateProvider,
|
|
||||||
clickIntents = clickIntents,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val loadedTxHistoryConverter by lazy {
|
|
||||||
TokenDetailsLoadedTxHistoryConverter(
|
|
||||||
currentStateProvider = currentStateProvider,
|
|
||||||
clickIntents = clickIntents,
|
|
||||||
symbol = symbol,
|
|
||||||
decimals = decimals,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val refreshStateConverter by lazy {
|
private val refreshStateConverter by lazy {
|
||||||
TokenDetailsRefreshStateConverter(
|
TokenDetailsRefreshStateConverter(
|
||||||
currentStateProvider = currentStateProvider,
|
currentStateProvider = currentStateProvider,
|
||||||
|
|
@ -147,36 +116,6 @@ internal class TokenDetailsStateFactory(
|
||||||
return tokenDetailsButtonsConverter.convert(actions)
|
return tokenDetailsButtonsConverter.convert(actions)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLoadingTxHistoryState(): TokenDetailsState {
|
|
||||||
return currentStateProvider().copy(
|
|
||||||
txHistoryState = TxHistoryState.Content(
|
|
||||||
contentItems = MutableStateFlow(
|
|
||||||
value = TxHistoryState.getDefaultLoadingTransactions(clickIntents::onExploreClick),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getLoadingTxHistoryState(
|
|
||||||
itemsCountEither: Either<TxHistoryStateError, Int>,
|
|
||||||
pendingTransactions: List<TransactionState>,
|
|
||||||
): TokenDetailsState {
|
|
||||||
return loadingTransactionsStateConverter.convert(
|
|
||||||
value = TokenDetailsLoadingTxHistoryModel(
|
|
||||||
historyLoadingState = itemsCountEither,
|
|
||||||
pendingTransactions = pendingTransactions,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getLoadedTxHistoryState(
|
|
||||||
txHistoryEither: Either<TxHistoryListError, Flow<PagingData<TxInfo>>>,
|
|
||||||
): TokenDetailsState {
|
|
||||||
return currentStateProvider().copy(
|
|
||||||
txHistoryState = loadedTxHistoryConverter.convert(txHistoryEither),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getStateWithClosedDialog(): TokenDetailsState {
|
fun getStateWithClosedDialog(): TokenDetailsState {
|
||||||
val state = currentStateProvider()
|
val state = currentStateProvider()
|
||||||
return state.copy(dialogConfig = state.dialogConfig?.copy(isShow = false))
|
return state.copy(dialogConfig = state.dialogConfig?.copy(isShow = false))
|
||||||
|
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.txhistory
|
|
||||||
|
|
||||||
import androidx.paging.PagingData
|
|
||||||
import arrow.core.Either
|
|
||||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
|
||||||
import com.tangem.domain.models.network.TxInfo
|
|
||||||
import com.tangem.domain.txhistory.models.TxHistoryListError
|
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
|
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
|
||||||
import com.tangem.utils.Provider
|
|
||||||
import com.tangem.utils.converter.Converter
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
|
|
||||||
internal class TokenDetailsLoadedTxHistoryConverter(
|
|
||||||
private val currentStateProvider: Provider<TokenDetailsState>,
|
|
||||||
private val clickIntents: TokenDetailsClickIntents,
|
|
||||||
symbol: String,
|
|
||||||
decimals: Int,
|
|
||||||
) : Converter<Either<TxHistoryListError, Flow<PagingData<TxInfo>>>, TxHistoryState> {
|
|
||||||
|
|
||||||
private val txHistoryItemFlowConverter by lazy {
|
|
||||||
TokenDetailsTxHistoryItemFlowConverter(
|
|
||||||
currentStateProvider = currentStateProvider,
|
|
||||||
symbol = symbol,
|
|
||||||
decimals = decimals,
|
|
||||||
clickIntents = clickIntents,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun convert(value: Either<TxHistoryListError, Flow<PagingData<TxInfo>>>): TxHistoryState {
|
|
||||||
return value.fold(ifLeft = ::convertError, ifRight = ::convert)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun convertError(error: TxHistoryListError): TxHistoryState {
|
|
||||||
return when (error) {
|
|
||||||
is TxHistoryListError.DataError -> {
|
|
||||||
TxHistoryState.Error(
|
|
||||||
onReloadClick = clickIntents::onReloadClick,
|
|
||||||
onExploreClick = clickIntents::onExploreClick,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun convert(items: Flow<PagingData<TxInfo>>): TxHistoryState {
|
|
||||||
return txHistoryItemFlowConverter.convert(value = items)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.txhistory
|
|
||||||
|
|
||||||
import androidx.paging.PagingData
|
|
||||||
import arrow.core.Either
|
|
||||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
|
||||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
|
||||||
import com.tangem.domain.txhistory.models.TxHistoryStateError
|
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.txhistory.TokenDetailsLoadingTxHistoryConverter.TokenDetailsLoadingTxHistoryModel
|
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
|
|
||||||
import com.tangem.utils.Provider
|
|
||||||
import com.tangem.utils.converter.Converter
|
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
import kotlinx.coroutines.flow.update
|
|
||||||
|
|
||||||
internal class TokenDetailsLoadingTxHistoryConverter(
|
|
||||||
private val currentStateProvider: Provider<TokenDetailsState>,
|
|
||||||
private val clickIntents: TokenDetailsClickIntents,
|
|
||||||
) : Converter<TokenDetailsLoadingTxHistoryModel, TokenDetailsState> {
|
|
||||||
|
|
||||||
override fun convert(value: TokenDetailsLoadingTxHistoryModel): TokenDetailsState {
|
|
||||||
return value.historyLoadingState.fold(
|
|
||||||
ifLeft = { convertError(error = it, pendingTransactions = value.pendingTransactions) },
|
|
||||||
ifRight = ::convert,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun convertError(
|
|
||||||
error: TxHistoryStateError,
|
|
||||||
pendingTransactions: List<TransactionState>,
|
|
||||||
): TokenDetailsState {
|
|
||||||
return currentStateProvider().copy(
|
|
||||||
txHistoryState = when (error) {
|
|
||||||
is TxHistoryStateError.EmptyTxHistories -> TxHistoryState.Empty(clickIntents::onExploreClick)
|
|
||||||
is TxHistoryStateError.DataError -> TxHistoryState.Error(
|
|
||||||
onReloadClick = clickIntents::onReloadClick,
|
|
||||||
onExploreClick = clickIntents::onExploreClick,
|
|
||||||
)
|
|
||||||
is TxHistoryStateError.TxHistoryNotImplemented -> {
|
|
||||||
TxHistoryState.NotSupported(
|
|
||||||
pendingTransactions = pendingTransactions.toImmutableList(),
|
|
||||||
onExploreClick = clickIntents::onExploreClick,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun convert(value: Int): TokenDetailsState {
|
|
||||||
val state = currentStateProvider()
|
|
||||||
|
|
||||||
return if (state.txHistoryState is TxHistoryState.Content) {
|
|
||||||
state.txHistoryState.contentItems.update {
|
|
||||||
PagingData.from(data = createLoadingItems(value))
|
|
||||||
}
|
|
||||||
state
|
|
||||||
} else {
|
|
||||||
val txHistoryContent = TxHistoryState.Content(
|
|
||||||
contentItems = MutableStateFlow(
|
|
||||||
value = PagingData.from(data = createLoadingItems(value)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
state.copy(txHistoryState = txHistoryContent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createLoadingItems(size: Int): List<TxHistoryState.TxHistoryItemState> {
|
|
||||||
return buildList {
|
|
||||||
add(TxHistoryState.TxHistoryItemState.Title(onExploreClick = clickIntents::onExploreClick))
|
|
||||||
(1..size).forEach {
|
|
||||||
add(TxHistoryState.TxHistoryItemState.Transaction(state = TransactionState.Loading(it.toString())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class TokenDetailsLoadingTxHistoryModel(
|
|
||||||
val historyLoadingState: Either<TxHistoryStateError, Int>,
|
|
||||||
val pendingTransactions: List<TransactionState>,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -1,103 +0,0 @@
|
||||||
package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.txhistory
|
|
||||||
|
|
||||||
import androidx.paging.*
|
|
||||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
|
||||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
|
||||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState.TxHistoryItemState
|
|
||||||
import com.tangem.core.ui.utils.toDateFormatWithTodayYesterday
|
|
||||||
import com.tangem.domain.models.network.TxInfo
|
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
|
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
|
||||||
import com.tangem.utils.Provider
|
|
||||||
import com.tangem.utils.converter.Converter
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.flow.*
|
|
||||||
import java.util.UUID
|
|
||||||
|
|
||||||
internal class TokenDetailsTxHistoryItemFlowConverter(
|
|
||||||
private val currentStateProvider: Provider<TokenDetailsState>,
|
|
||||||
private val symbol: String,
|
|
||||||
private val decimals: Int,
|
|
||||||
private val clickIntents: TokenDetailsClickIntents,
|
|
||||||
) : Converter<Flow<PagingData<TxInfo>>, TxHistoryState> {
|
|
||||||
|
|
||||||
private val txHistoryItemConverter by lazy {
|
|
||||||
TokenDetailsTxHistoryTransactionStateConverter(
|
|
||||||
symbol = symbol,
|
|
||||||
decimals = decimals,
|
|
||||||
clickIntents = clickIntents,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun convert(value: Flow<PagingData<TxInfo>>): TxHistoryState {
|
|
||||||
val state = currentStateProvider()
|
|
||||||
val txHistoryContent = if (state.txHistoryState is TxHistoryState.Content) {
|
|
||||||
state.txHistoryState
|
|
||||||
} else {
|
|
||||||
TxHistoryState.Content(contentItems = MutableStateFlow(PagingData.empty()))
|
|
||||||
}
|
|
||||||
// FIXME: TxHistoryRepository should send loading transactions
|
|
||||||
// [REDACTED_JIRA]
|
|
||||||
value
|
|
||||||
.onEach { txHistoryStatePagingData ->
|
|
||||||
txHistoryContent.contentItems.update {
|
|
||||||
txHistoryStatePagingData
|
|
||||||
.map<TxInfo, TxHistoryItemState> { item ->
|
|
||||||
// [createTransactionState] returns timestamp without formatting
|
|
||||||
TxHistoryItemState.Transaction(state = createTransactionState(item))
|
|
||||||
}
|
|
||||||
.insertHeaderItem(
|
|
||||||
terminalSeparatorType = TerminalSeparatorType.SOURCE_COMPLETE,
|
|
||||||
item = TxHistoryItemState.Title(clickIntents::onExploreClick),
|
|
||||||
)
|
|
||||||
.insertGroupTitle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.launchIn(CoroutineScope(Dispatchers.IO))
|
|
||||||
|
|
||||||
return txHistoryContent
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createTransactionState(item: TxInfo): TransactionState {
|
|
||||||
return txHistoryItemConverter.convert(value = item)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun PagingData<TxHistoryItemState>.insertGroupTitle(): PagingData<TxHistoryItemState> {
|
|
||||||
return insertSeparators(terminalSeparatorType = TerminalSeparatorType.SOURCE_COMPLETE) { before, after ->
|
|
||||||
// Use raw timestamp to get date
|
|
||||||
|
|
||||||
// If [afterDate] is the first transaction in the flow, add the group title
|
|
||||||
val afterDate = after.getTimestamp()?.toDateFormatWithTodayYesterday() ?: return@insertSeparators null
|
|
||||||
if (before is TxHistoryItemState.Title) {
|
|
||||||
return@insertSeparators TxHistoryItemState.GroupTitle(
|
|
||||||
title = afterDate,
|
|
||||||
itemKey = UUID.randomUUID().toString(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If [beforeDate] is not equals to [afterDate], then [afterDate] is first transaction in
|
|
||||||
* the new group
|
|
||||||
*/
|
|
||||||
val beforeDate = before.getTimestamp()?.toDateFormatWithTodayYesterday() ?: return@insertSeparators null
|
|
||||||
return@insertSeparators if (beforeDate != afterDate) {
|
|
||||||
TxHistoryItemState.GroupTitle(
|
|
||||||
title = afterDate,
|
|
||||||
itemKey = UUID.randomUUID().toString(),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TxHistoryItemState?.getTimestamp(): Long? {
|
|
||||||
return if (this is TxHistoryItemState.Transaction && this.state is TransactionState.Content) {
|
|
||||||
val txContent = this.state as TransactionState.Content
|
|
||||||
txContent.timestamp
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,136 +0,0 @@
|
||||||
package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.txhistory
|
|
||||||
|
|
||||||
import com.tangem.common.extensions.isZero
|
|
||||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
|
||||||
import com.tangem.core.ui.components.transactions.state.TransactionState.Content.Direction
|
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
|
||||||
import com.tangem.core.ui.extensions.stringReference
|
|
||||||
import com.tangem.core.ui.extensions.wrappedList
|
|
||||||
import com.tangem.core.ui.format.bigdecimal.crypto
|
|
||||||
import com.tangem.core.ui.format.bigdecimal.format
|
|
||||||
import com.tangem.core.ui.utils.toTimeFormat
|
|
||||||
import com.tangem.domain.models.network.TxInfo
|
|
||||||
import com.tangem.domain.models.network.TxInfo.*
|
|
||||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
|
|
||||||
import com.tangem.features.tokendetails.impl.R
|
|
||||||
import com.tangem.utils.StringsSigns.MINUS
|
|
||||||
import com.tangem.utils.StringsSigns.PLUS
|
|
||||||
import com.tangem.utils.converter.Converter
|
|
||||||
import com.tangem.utils.toBriefAddressFormat
|
|
||||||
|
|
||||||
internal class TokenDetailsTxHistoryTransactionStateConverter(
|
|
||||||
private val symbol: String,
|
|
||||||
private val decimals: Int,
|
|
||||||
private val clickIntents: TokenDetailsClickIntents,
|
|
||||||
) : Converter<TxInfo, TransactionState> {
|
|
||||||
|
|
||||||
override fun convert(value: TxInfo): TransactionState {
|
|
||||||
return createTransactionStateItem(item = value)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("LongMethod")
|
|
||||||
private fun createTransactionStateItem(item: TxInfo): TransactionState {
|
|
||||||
return TransactionState.Content(
|
|
||||||
txHash = item.txHash,
|
|
||||||
amount = item.getAmount(),
|
|
||||||
time = item.timestampInMillis.toTimeFormat(),
|
|
||||||
status = item.status.tiUiStatus(),
|
|
||||||
direction = item.extractDirection(),
|
|
||||||
iconRes = item.extractIcon(),
|
|
||||||
title = item.extractTitle(),
|
|
||||||
subtitle = item.extractSubtitle(),
|
|
||||||
timestamp = item.timestampInMillis,
|
|
||||||
onClick = { clickIntents.onTransactionClick(item.txHash) },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TxInfo.extractIcon(): Int = if (status == TransactionStatus.Failed) {
|
|
||||||
R.drawable.ic_close_24
|
|
||||||
} else {
|
|
||||||
when (type) {
|
|
||||||
is TransactionType.Approve -> R.drawable.ic_doc_24
|
|
||||||
is TransactionType.Staking.Stake,
|
|
||||||
is TransactionType.Staking.Vote,
|
|
||||||
is TransactionType.Staking.Restake,
|
|
||||||
-> R.drawable.ic_transaction_history_staking_24
|
|
||||||
is TransactionType.Staking.ClaimRewards,
|
|
||||||
-> R.drawable.ic_transaction_history_claim_rewards_24
|
|
||||||
is TransactionType.Staking.Unstake,
|
|
||||||
is TransactionType.Staking.Withdraw,
|
|
||||||
-> R.drawable.ic_transaction_history_unstaking_24
|
|
||||||
is TransactionType.Operation,
|
|
||||||
is TransactionType.Swap,
|
|
||||||
is TransactionType.Transfer,
|
|
||||||
is TransactionType.UnknownOperation,
|
|
||||||
-> if (isOutgoing) R.drawable.ic_arrow_up_24 else R.drawable.ic_arrow_down_24
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TxInfo.extractTitle(): TextReference = when (val type = type) {
|
|
||||||
is TransactionType.Approve -> resourceReference(R.string.common_approval)
|
|
||||||
is TransactionType.Operation -> stringReference(type.name)
|
|
||||||
is TransactionType.Swap -> resourceReference(R.string.common_swap)
|
|
||||||
is TransactionType.Transfer -> resourceReference(R.string.common_transfer)
|
|
||||||
is TransactionType.UnknownOperation -> resourceReference(R.string.transaction_history_operation)
|
|
||||||
is TransactionType.Staking.Stake -> resourceReference(R.string.common_stake)
|
|
||||||
is TransactionType.Staking.Unstake -> resourceReference(R.string.common_unstake)
|
|
||||||
is TransactionType.Staking.Vote -> resourceReference(R.string.staking_vote)
|
|
||||||
is TransactionType.Staking.ClaimRewards -> resourceReference(R.string.common_claim_rewards)
|
|
||||||
is TransactionType.Staking.Withdraw -> resourceReference(R.string.staking_withdraw)
|
|
||||||
is TransactionType.Staking.Restake -> resourceReference(R.string.staking_restake)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TxInfo.extractSubtitle(): TextReference = when (val interactionAddress = interactionAddressType) {
|
|
||||||
is InteractionAddressType.Contract -> resourceReference(
|
|
||||||
id = R.string.transaction_history_contract_address,
|
|
||||||
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
|
|
||||||
)
|
|
||||||
is InteractionAddressType.Multiple -> resourceReference(
|
|
||||||
id = if (isOutgoing) {
|
|
||||||
R.string.transaction_history_transaction_to_address
|
|
||||||
} else {
|
|
||||||
R.string.transaction_history_transaction_from_address
|
|
||||||
},
|
|
||||||
formatArgs = wrappedList(resourceReference(R.string.transaction_history_multiple_addresses)),
|
|
||||||
)
|
|
||||||
is InteractionAddressType.User -> resourceReference(
|
|
||||||
id = if (isOutgoing) {
|
|
||||||
R.string.transaction_history_transaction_to_address
|
|
||||||
} else {
|
|
||||||
R.string.transaction_history_transaction_from_address
|
|
||||||
},
|
|
||||||
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
|
|
||||||
)
|
|
||||||
is InteractionAddressType.Validator -> resourceReference(
|
|
||||||
id = R.string.transaction_history_transaction_validator,
|
|
||||||
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
|
|
||||||
)
|
|
||||||
null -> {
|
|
||||||
TextReference.EMPTY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TxInfo.extractDirection() = if (isOutgoing) Direction.OUTGOING else Direction.INCOMING
|
|
||||||
|
|
||||||
private fun TransactionStatus.tiUiStatus() = when (this) {
|
|
||||||
TransactionStatus.Confirmed -> TransactionState.Content.Status.Confirmed
|
|
||||||
TransactionStatus.Failed -> TransactionState.Content.Status.Failed
|
|
||||||
TransactionStatus.Unconfirmed -> TransactionState.Content.Status.Unconfirmed
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TxInfo.getAmount(): String {
|
|
||||||
if (type is TransactionType.Staking.Vote ||
|
|
||||||
type == TransactionType.Staking.ClaimRewards ||
|
|
||||||
type == TransactionType.Staking.Withdraw
|
|
||||||
) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
val prefix = when {
|
|
||||||
status == TransactionStatus.Failed -> ""
|
|
||||||
this.amount.isZero() -> ""
|
|
||||||
else -> if (isOutgoing) MINUS else PLUS
|
|
||||||
}
|
|
||||||
return prefix + amount.format { crypto(symbol = symbol, decimals = decimals) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -6,7 +6,7 @@ import androidx.compose.foundation.lazy.*
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.ScaffoldDefaults
|
import androidx.compose.material3.ScaffoldDefaults
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.platform.testTag
|
import androidx.compose.ui.platform.testTag
|
||||||
|
|
@ -14,8 +14,6 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.paging.compose.LazyPagingItems
|
|
||||||
import androidx.paging.compose.collectAsLazyPagingItems
|
|
||||||
import com.tangem.common.ui.bottomsheet.chooseaddress.ChooseAddressBottomSheet
|
import com.tangem.common.ui.bottomsheet.chooseaddress.ChooseAddressBottomSheet
|
||||||
import com.tangem.common.ui.bottomsheet.chooseaddress.ChooseAddressBottomSheetConfig
|
import com.tangem.common.ui.bottomsheet.chooseaddress.ChooseAddressBottomSheetConfig
|
||||||
import com.tangem.common.ui.bottomsheet.receive.TokenReceiveBottomSheet
|
import com.tangem.common.ui.bottomsheet.receive.TokenReceiveBottomSheet
|
||||||
|
|
@ -26,8 +24,6 @@ import com.tangem.core.ui.components.containers.pullToRefresh.TangemPullToRefres
|
||||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlock
|
import com.tangem.core.ui.components.marketprice.MarketPriceBlock
|
||||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||||
import com.tangem.core.ui.components.notifications.Notification
|
import com.tangem.core.ui.components.notifications.Notification
|
||||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
|
||||||
import com.tangem.core.ui.components.transactions.txHistoryItems
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
import com.tangem.core.ui.res.TangemThemePreview
|
||||||
import com.tangem.core.ui.test.TokenDetailsScreenTestTags
|
import com.tangem.core.ui.test.TokenDetailsScreenTestTags
|
||||||
|
|
@ -46,7 +42,6 @@ import com.tangem.features.txhistory.component.TxHistoryComponent
|
||||||
import com.tangem.features.txhistory.entity.TxHistoryUM
|
import com.tangem.features.txhistory.entity.TxHistoryUM
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlin.reflect.KProperty
|
|
||||||
|
|
||||||
// TODO: Split to blocks [REDACTED_JIRA]
|
// TODO: Split to blocks [REDACTED_JIRA]
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod")
|
||||||
|
|
@ -63,11 +58,6 @@ internal fun TokenDetailsScreen(
|
||||||
contentWindowInsets = ScaffoldDefaults.contentWindowInsets.exclude(WindowInsets.navigationBars),
|
contentWindowInsets = ScaffoldDefaults.contentWindowInsets.exclude(WindowInsets.navigationBars),
|
||||||
containerColor = TangemTheme.colors.background.secondary,
|
containerColor = TangemTheme.colors.background.secondary,
|
||||||
) { scaffoldPaddings ->
|
) { scaffoldPaddings ->
|
||||||
val txHistoryItems = if (state.txHistoryState is TxHistoryState.Content) {
|
|
||||||
state.txHistoryState.contentItems.collectAsLazyPagingItems()
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
val listState = rememberLazyListState()
|
val listState = rememberLazyListState()
|
||||||
val txHistoryComponentState by txHistoryComponent.txHistoryState.collectAsStateWithLifecycle()
|
val txHistoryComponentState by txHistoryComponent.txHistoryState.collectAsStateWithLifecycle()
|
||||||
val betweenItemsPadding = TangemTheme.dimens.spacing12
|
val betweenItemsPadding = TangemTheme.dimens.spacing12
|
||||||
|
|
@ -160,14 +150,7 @@ internal fun TokenDetailsScreen(
|
||||||
modifier = itemModifier,
|
modifier = itemModifier,
|
||||||
)
|
)
|
||||||
|
|
||||||
txHistoryItems(
|
with(txHistoryComponent) { txHistoryContent(listState = listState, state = txHistoryComponentState) }
|
||||||
listState = listState,
|
|
||||||
txHistoryComponent = txHistoryComponent,
|
|
||||||
txHistoryComponentState = txHistoryComponentState,
|
|
||||||
txHistoryState = state.txHistoryState,
|
|
||||||
txHistoryItems = txHistoryItems,
|
|
||||||
isBalanceHidden = state.isBalanceHidden,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -189,28 +172,6 @@ internal fun TokenDetailsScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("LongParameterList")
|
|
||||||
private fun LazyListScope.txHistoryItems(
|
|
||||||
listState: LazyListState,
|
|
||||||
txHistoryComponent: TxHistoryComponent,
|
|
||||||
txHistoryComponentState: TxHistoryUM?,
|
|
||||||
txHistoryState: TxHistoryState,
|
|
||||||
txHistoryItems: LazyPagingItems<TxHistoryState.TxHistoryItemState>?,
|
|
||||||
isBalanceHidden: Boolean,
|
|
||||||
) {
|
|
||||||
if (txHistoryComponentState != null) {
|
|
||||||
with(txHistoryComponent) { txHistoryContent(listState = listState, state = txHistoryComponentState) }
|
|
||||||
} else {
|
|
||||||
txHistoryItems(
|
|
||||||
state = txHistoryState,
|
|
||||||
isBalanceHidden = isBalanceHidden,
|
|
||||||
txHistoryItems = txHistoryItems,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private inline operator fun <T> State<T>?.getValue(thisObj: Any?, property: KProperty<*>): T? = this?.value
|
|
||||||
|
|
||||||
// region Preview
|
// region Preview
|
||||||
@Preview(showBackground = true, widthDp = 360)
|
@Preview(showBackground = true, widthDp = 360)
|
||||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue