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
|
||||
|
||||
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.dropdownmenu.TangemDropdownMenuItem
|
||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||
import com.tangem.core.ui.components.marketprice.PriceChangeState
|
||||
import com.tangem.core.ui.components.marketprice.PriceChangeType
|
||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
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.features.tokendetails.impl.R
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import java.math.BigDecimal
|
||||
|
||||
@Suppress("LargeClass")
|
||||
|
|
@ -168,130 +164,6 @@ internal object TokenDetailsPreviewData {
|
|||
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(
|
||||
topAppBarConfig = tokenDetailsTopAppBarConfig,
|
||||
tokenInfoBlockState = tokenInfoBlockState,
|
||||
|
|
@ -299,13 +171,7 @@ internal object TokenDetailsPreviewData {
|
|||
marketPriceBlockState = marketPriceLoading,
|
||||
stakingBlocksState = stakingLoadingBlock,
|
||||
notifications = persistentListOf(),
|
||||
txHistoryState = TxHistoryState.Content(
|
||||
contentItems = MutableStateFlow(
|
||||
value = TxHistoryState.getDefaultLoadingTransactions {},
|
||||
),
|
||||
),
|
||||
dialogConfig = null,
|
||||
pendingTxs = persistentListOf(),
|
||||
expressTxs = persistentListOf(),
|
||||
expressTxsToDisplay = persistentListOf(),
|
||||
pullToRefreshConfig = pullToRefreshConfig,
|
||||
|
|
@ -330,12 +196,7 @@ internal object TokenDetailsPreviewData {
|
|||
),
|
||||
stakingBlocksState = stakingAvailableBlock,
|
||||
notifications = persistentListOf(),
|
||||
txHistoryState = TxHistoryState.NotSupported(
|
||||
onExploreClick = {},
|
||||
pendingTransactions = persistentListOf(),
|
||||
),
|
||||
dialogConfig = null,
|
||||
pendingTxs = persistentListOf(),
|
||||
expressTxs = persistentListOf(),
|
||||
expressTxsToDisplay = persistentListOf(),
|
||||
pullToRefreshConfig = pullToRefreshConfig,
|
||||
|
|
@ -344,12 +205,5 @@ internal object TokenDetailsPreviewData {
|
|||
isMarketPriceAvailable = true,
|
||||
)
|
||||
|
||||
val tokenDetailsState_3 = tokenDetailsState_2.copy(
|
||||
txHistoryState = TxHistoryState.Content(
|
||||
contentItems = MutableStateFlow(
|
||||
value = PagingData.from(txHistoryItems),
|
||||
),
|
||||
),
|
||||
stakingBlocksState = stakingBalanceBlock,
|
||||
)
|
||||
val tokenDetailsState_3 = tokenDetailsState_2.copy(stakingBlocksState = stakingBalanceBlock)
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.feature.tokendetails.presentation.tokendetails.model
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.paging.cachedIn
|
||||
import arrow.core.getOrElse
|
||||
import arrow.core.merge
|
||||
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.navigation.share.ShareManager
|
||||
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.resourceReference
|
||||
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.usecase.*
|
||||
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.GetExtendedPublicKeyForCurrencyUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
|
|
@ -107,8 +103,6 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val fetchCurrencyStatusUseCase: FetchCurrencyStatusUseCase,
|
||||
private val txHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase,
|
||||
private val txHistoryItemsUseCase: GetTxHistoryItemsUseCase,
|
||||
private val getExploreUrlUseCase: GetExploreUrlUseCase,
|
||||
private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCase,
|
||||
private val removeCurrencyUseCase: RemoveCurrencyUseCase,
|
||||
|
|
@ -177,8 +171,6 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
networkHasDerivationUseCase = networkHasDerivationUseCase,
|
||||
getUserWalletUseCase = getUserWalletUseCase,
|
||||
userWalletId = userWalletId,
|
||||
symbol = cryptoCurrency.symbol,
|
||||
decimals = cryptoCurrency.decimals,
|
||||
)
|
||||
|
||||
private val expressStatusFactory by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||
|
|
@ -251,7 +243,6 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
private fun updateContent() {
|
||||
subscribeOnCurrencyStatusUpdates()
|
||||
subscribeOnExpressTransactionsUpdates()
|
||||
updateTxHistory(refresh = false, showItemsLoading = true, initialUpdating = true)
|
||||
}
|
||||
|
||||
private fun handleBalanceHiding() {
|
||||
|
|
@ -382,39 +373,8 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param refresh - invalidate cache and get data from remote
|
||||
* @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 updateTxHistory() {
|
||||
modelScope.launch { txHistoryContentUpdateEmitter.triggerUpdate() }
|
||||
}
|
||||
|
||||
private fun subscribeOnUpdateStakingInfo(cryptoCurrencyStatus: CryptoCurrencyStatus) {
|
||||
|
|
@ -552,8 +512,7 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
|
||||
override fun onReloadClick() {
|
||||
analyticsEventsHandler.send(TokenScreenAnalyticsEvent.ButtonReload(cryptoCurrency.symbol))
|
||||
internalUiState.value = stateFactory.getLoadingTxHistoryState()
|
||||
updateTxHistory(refresh = true, showItemsLoading = true)
|
||||
updateTxHistory()
|
||||
}
|
||||
|
||||
override fun onSendClick(unavailabilityReason: ScenarioUnavailabilityReason) {
|
||||
|
|
@ -800,10 +759,7 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
listOf(
|
||||
async { fetchCurrencyStatusUseCase(userWalletId = userWalletId, id = cryptoCurrency.id) },
|
||||
async {
|
||||
updateTxHistory(
|
||||
refresh = true,
|
||||
showItemsLoading = internalUiState.value.txHistoryState !is TxHistoryState.Content,
|
||||
)
|
||||
updateTxHistory()
|
||||
subscribeOnExpressTransactionsUpdates()
|
||||
},
|
||||
).awaitAll()
|
||||
|
|
|
|||
|
|
@ -2,10 +2,8 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.state
|
|||
|
||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionStateUM
|
||||
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.marketprice.MarketPriceBlockState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsDialogConfig
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsNotification
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
|
@ -18,10 +16,8 @@ internal data class TokenDetailsState(
|
|||
val marketPriceBlockState: MarketPriceBlockState,
|
||||
val stakingBlocksState: StakingBlockUM?,
|
||||
val notifications: ImmutableList<TokenDetailsNotification>,
|
||||
val pendingTxs: PersistentList<TransactionState>,
|
||||
val expressTxsToDisplay: PersistentList<ExpressTransactionStateUM>,
|
||||
val expressTxs: PersistentList<ExpressTransactionStateUM>,
|
||||
val txHistoryState: TxHistoryState,
|
||||
val dialogConfig: TokenDetailsDialogConfig?,
|
||||
val pullToRefreshConfig: PullToRefreshConfig,
|
||||
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.PriceChangeType
|
||||
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.domain.appcurrency.model.AppCurrency
|
||||
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.TokenDetailsState
|
||||
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.utils.Provider
|
||||
import com.tangem.utils.StringsSigns.DASH_SIGN
|
||||
import com.tangem.utils.converter.Converter
|
||||
import com.tangem.utils.isNullOrZero
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import java.math.BigDecimal
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class TokenDetailsLoadedBalanceConverter(
|
||||
private val currentStateProvider: Provider<TokenDetailsState>,
|
||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
private val symbol: String,
|
||||
private val decimals: Int,
|
||||
private val clickIntents: TokenDetailsClickIntents,
|
||||
) : Converter<Either<CurrencyStatusError, CryptoCurrencyStatus>, TokenDetailsState> {
|
||||
|
||||
private val txHistoryItemConverter by lazy {
|
||||
TokenDetailsTxHistoryTransactionStateConverter(symbol, decimals, clickIntents)
|
||||
}
|
||||
|
||||
override fun convert(value: Either<CurrencyStatusError, CryptoCurrencyStatus>): TokenDetailsState {
|
||||
return value.fold(
|
||||
ifLeft = { convertError() },
|
||||
|
|
@ -64,7 +54,6 @@ internal class TokenDetailsLoadedBalanceConverter(
|
|||
private fun convert(status: CryptoCurrencyStatus): TokenDetailsState {
|
||||
val state = currentStateProvider()
|
||||
val currencyName = state.marketPriceBlockState.currencySymbol
|
||||
val pendingTxs = status.value.pendingTransactions.map(txHistoryItemConverter::convert).toPersistentList()
|
||||
|
||||
return state.copy(
|
||||
tokenBalanceBlockState = getBalanceState(
|
||||
|
|
@ -73,12 +62,6 @@ internal class TokenDetailsLoadedBalanceConverter(
|
|||
),
|
||||
stakingBlocksState = state.stakingBlocksState,
|
||||
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.dropdownmenu.TangemDropdownMenuItem
|
||||
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.networkIconResId
|
||||
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.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
internal class TokenDetailsSkeletonStateConverter(
|
||||
private val clickIntents: TokenDetailsClickIntents,
|
||||
|
|
@ -64,14 +62,8 @@ internal class TokenDetailsSkeletonStateConverter(
|
|||
marketPriceBlockState = MarketPriceBlockState.Loading(value.symbol),
|
||||
stakingBlocksState = StakingBlockUM.Loading(iconState).takeIf { isSupportedInMobileApp },
|
||||
notifications = persistentListOf(),
|
||||
pendingTxs = persistentListOf(),
|
||||
expressTxs = persistentListOf(),
|
||||
expressTxsToDisplay = persistentListOf(),
|
||||
txHistoryState = TxHistoryState.Content(
|
||||
contentItems = MutableStateFlow(
|
||||
value = TxHistoryState.getDefaultLoadingTransactions(clickIntents::onExploreClick),
|
||||
),
|
||||
),
|
||||
dialogConfig = null,
|
||||
pullToRefreshConfig = createPullToRefresh(),
|
||||
bottomSheetConfig = null,
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory
|
||||
|
||||
import androidx.paging.PagingData
|
||||
import arrow.core.Either
|
||||
import com.tangem.common.ui.bottomsheet.chooseaddress.ChooseAddressBottomSheetConfig
|
||||
import com.tangem.common.ui.bottomsheet.receive.TokenReceiveBottomSheetConfig
|
||||
import com.tangem.common.ui.tokens.getUnavailabilityReasonText
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
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.resourceReference
|
||||
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.network.Network
|
||||
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.UserWalletId
|
||||
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.TokenActionsState
|
||||
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.NetworkHasDerivationUseCase
|
||||
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.TokenDetailsState
|
||||
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.utils.Provider
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
@Suppress("TooManyFunctions", "LargeClass", "LongParameterList")
|
||||
internal class TokenDetailsStateFactory(
|
||||
|
|
@ -54,8 +43,6 @@ internal class TokenDetailsStateFactory(
|
|||
private val networkHasDerivationUseCase: NetworkHasDerivationUseCase,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val userWalletId: UserWalletId,
|
||||
symbol: String,
|
||||
decimals: Int,
|
||||
) {
|
||||
|
||||
private val skeletonStateConverter by lazy {
|
||||
|
|
@ -75,8 +62,6 @@ internal class TokenDetailsStateFactory(
|
|||
TokenDetailsLoadedBalanceConverter(
|
||||
currentStateProvider = currentStateProvider,
|
||||
appCurrencyProvider = appCurrencyProvider,
|
||||
symbol = symbol,
|
||||
decimals = decimals,
|
||||
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 {
|
||||
TokenDetailsRefreshStateConverter(
|
||||
currentStateProvider = currentStateProvider,
|
||||
|
|
@ -147,36 +116,6 @@ internal class TokenDetailsStateFactory(
|
|||
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 {
|
||||
val state = currentStateProvider()
|
||||
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.ScaffoldDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
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.datasource.CollectionPreviewParameterProvider
|
||||
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.ChooseAddressBottomSheetConfig
|
||||
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.MarketPriceBlockState
|
||||
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.TangemThemePreview
|
||||
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 kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
// TODO: Split to blocks [REDACTED_JIRA]
|
||||
@Suppress("LongMethod")
|
||||
|
|
@ -63,11 +58,6 @@ internal fun TokenDetailsScreen(
|
|||
contentWindowInsets = ScaffoldDefaults.contentWindowInsets.exclude(WindowInsets.navigationBars),
|
||||
containerColor = TangemTheme.colors.background.secondary,
|
||||
) { scaffoldPaddings ->
|
||||
val txHistoryItems = if (state.txHistoryState is TxHistoryState.Content) {
|
||||
state.txHistoryState.contentItems.collectAsLazyPagingItems()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
val listState = rememberLazyListState()
|
||||
val txHistoryComponentState by txHistoryComponent.txHistoryState.collectAsStateWithLifecycle()
|
||||
val betweenItemsPadding = TangemTheme.dimens.spacing12
|
||||
|
|
@ -160,14 +150,7 @@ internal fun TokenDetailsScreen(
|
|||
modifier = itemModifier,
|
||||
)
|
||||
|
||||
txHistoryItems(
|
||||
listState = listState,
|
||||
txHistoryComponent = txHistoryComponent,
|
||||
txHistoryComponentState = txHistoryComponentState,
|
||||
txHistoryState = state.txHistoryState,
|
||||
txHistoryItems = txHistoryItems,
|
||||
isBalanceHidden = state.isBalanceHidden,
|
||||
)
|
||||
with(txHistoryComponent) { txHistoryContent(listState = listState, state = txHistoryComponentState) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue