Updated on 2026-08-14

This commit is contained in:
Tangem 2023-10-09 12:47:32 +05:00
parent f74f4e7083
commit a51012484f
4 changed files with 69 additions and 30 deletions

View file

@ -8,6 +8,7 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.chooseaddress.ChooseAddressBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.tokenreceive.AddressModel
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheetConfig
import com.tangem.core.ui.components.transactions.state.TxHistoryState
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.tokens.error.CurrencyStatusError
import com.tangem.domain.tokens.model.CryptoCurrency
@ -23,6 +24,7 @@ import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.t
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.txhistory.TokenDetailsLoadingTxHistoryConverter
import com.tangem.feature.tokendetails.presentation.tokendetails.viewmodels.TokenDetailsClickIntents
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
internal class TokenDetailsStateFactory(
private val currentStateProvider: Provider<TokenDetailsState>,
@ -89,6 +91,16 @@ 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>): TokenDetailsState {
return loadingTransactionsStateConverter.convert(value = itemsCountEither)
}

View file

@ -9,6 +9,7 @@ import com.tangem.domain.txhistory.models.TxHistoryStateError
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
import com.tangem.feature.tokendetails.presentation.tokendetails.viewmodels.TokenDetailsClickIntents
import com.tangem.utils.converter.Converter
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
internal class TokenDetailsLoadingTxHistoryConverter(
@ -34,22 +35,28 @@ internal class TokenDetailsLoadingTxHistoryConverter(
private fun convert(value: Int): TokenDetailsState {
val state = currentStateProvider()
val txHistoryContent = state.txHistoryState as TxHistoryState.Content
txHistoryContent.contentItems.update {
PagingData.from(
data = listOf(TxHistoryState.TxHistoryItemState.Title(onExploreClick = clickIntents::onExploreClick)) +
MutableList(
size = value,
init = {
TxHistoryState.TxHistoryItemState.Transaction(
state = TransactionState.Loading(it.toString()),
)
},
),
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)
}
}
return state
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())))
}
}
}
}

View file

@ -15,10 +15,7 @@ import com.tangem.utils.extensions.isToday
import com.tangem.utils.extensions.isYesterday
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.flow.*
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
@ -37,8 +34,12 @@ internal class TokenDetailsTxHistoryItemFlowConverter(
}
override fun convert(value: Flow<PagingData<TxHistoryItem>>): TxHistoryState {
val txHistoryContent = currentStateProvider().txHistoryState as TxHistoryState.Content
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

View file

@ -9,6 +9,7 @@ import arrow.core.getOrElse
import com.tangem.blockchain.common.address.AddressType
import com.tangem.common.Provider
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.ui.components.transactions.state.TxHistoryState
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.balancehiding.IsBalanceHiddenUseCase
@ -35,6 +36,8 @@ import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.JobHolder
import com.tangem.utils.coroutines.saveIn
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import timber.log.Timber
@ -103,7 +106,7 @@ internal class TokenDetailsViewModel @Inject constructor(
private fun updateContent(selectedWallet: UserWallet) {
updateMarketPrice(selectedWallet = selectedWallet)
updateTxHistory()
updateTxHistory(refresh = false, showItemsLoading = true)
updateWarnings(selectedWallet = selectedWallet)
}
@ -162,13 +165,19 @@ internal class TokenDetailsViewModel @Inject constructor(
.saveIn(marketPriceJobHolder)
}
private fun updateTxHistory(refresh: Boolean = false) {
/**
* @param refresh - invalidate cache and get data from remote
* @param showItemsLoading - show loading items placeholder.
*/
@Suppress("UnusedPrivateMember") // will be removed after implement caching
private fun updateTxHistory(refresh: Boolean, showItemsLoading: Boolean) {
viewModelScope.launch(dispatchers.io) {
val txHistoryItemsCountEither = txHistoryItemsCountUseCase(
network = cryptoCurrency.network,
)
if (!refresh) {
// if countEither is left, handling error state run inside getLoadingTxHistoryState
if (showItemsLoading || txHistoryItemsCountEither.isLeft()) {
uiState = stateFactory.getLoadingTxHistoryState(itemsCountEither = txHistoryItemsCountEither)
}
@ -211,7 +220,8 @@ internal class TokenDetailsViewModel @Inject constructor(
override fun onReloadClick() {
analyticsEventsHandler.send(TokenScreenEvent.ButtonReload(cryptoCurrency.symbol))
updateTxHistory()
uiState = stateFactory.getLoadingTxHistoryState()
updateTxHistory(refresh = true, showItemsLoading = true)
}
override fun onSendClick() {
@ -358,13 +368,22 @@ internal class TokenDetailsViewModel @Inject constructor(
uiState = stateFactory.getRefreshingState()
viewModelScope.launch(dispatchers.io) {
fetchCurrencyStatusUseCase.invoke(
userWalletId = wallet.walletId,
id = cryptoCurrency.id,
refresh = true,
)
updateTxHistory(refresh = true)
updateWarnings(wallet)
listOf(
async {
fetchCurrencyStatusUseCase.invoke(
userWalletId = wallet.walletId,
id = cryptoCurrency.id,
refresh = true,
)
},
async {
updateTxHistory(
refresh = true,
showItemsLoading = uiState.txHistoryState !is TxHistoryState.Content,
)
},
async { updateWarnings(wallet) },
).awaitAll()
uiState = stateFactory.getRefreshedState()
}.saveIn(refreshStateJobHolder)
}