Updated on 2026-08-14

This commit is contained in:
Tangem 2023-10-20 13:51:11 +08:00
parent c9f84c9227
commit 6ec85eec82
2 changed files with 44 additions and 33 deletions

View file

@ -1,9 +1,7 @@
package com.tangem.tap.features.tokens.impl.presentation.ui
import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
@ -76,20 +74,20 @@ internal fun TokensListScreen(stateHolder: TokensListStateHolder, modifier: Modi
val tokens = stateHolder.tokens.collectAsLazyPagingItems()
TokensListContent(
isDifferentAddressesBlockVisible = stateHolder.isDifferentAddressesBlockVisible,
isDifferentAddressesBlockVisible = stateHolder.isDifferentAddressesBlockVisible && !stateHolder.isLoading,
tokens = tokens,
scaffoldPadding = scaffoldPadding,
bottomMarginDp = floatingButtonHeight,
)
stateHolder.onTokensLoadStateChanged(tokens.loadState.refresh)
Crossfade(targetState = stateHolder.isLoading, label = "Update progress bar visibility") {
if (it) {
LoadingContent()
}
}
AnimatedVisibility(
visible = stateHolder.isLoading,
enter = fadeIn(),
exit = fadeOut(),
) {
LoadingContent()
LaunchedEffect(key1 = tokens.loadState.refresh) {
stateHolder.onTokensLoadStateChanged(tokens.loadState.refresh)
}
}
}

View file

@ -1,15 +1,11 @@
package com.tangem.tap.features.tokens.impl.presentation.viewmodels
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.LoadState
import androidx.paging.PagingData
import androidx.paging.map
import androidx.lifecycle.*
import androidx.paging.*
import com.tangem.blockchain.common.Blockchain
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.ui.extensions.getActiveIconRes
@ -41,8 +37,7 @@ import com.tangem.utils.coroutines.Debouncer
import com.tangem.wallet.R
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import kotlinx.coroutines.plus
import timber.log.Timber
@ -102,6 +97,8 @@ internal class TokensListViewModel @Inject constructor(
changedBlockchainList = currentCoins.toMutableList()
changedTokensList = currentTokens.toMutableList()
uiState = uiState.copySealed(tokens = getTokensListBySearchText(text = ""))
}
}
@ -154,14 +151,13 @@ internal class TokensListViewModel @Inject constructor(
)
}
private fun getInitialTokensList(searchText: String = ""): Flow<PagingData<TokenItemState>> {
if (searchText.isNotEmpty()) analyticsSender.sendWhenTokenSearched()
return interactor.getTokensList(searchText = searchText).map {
it.map { token ->
if (isManageAccess) createManageTokenContent(token) else createReadTokenContent(token)
}
}
private fun getInitialTokensList(): Flow<PagingData<TokenItemState>> {
return flowOf(
value = PagingData.empty(
sourceLoadStates = LoadStates(LoadState.Loading, LoadState.Loading, LoadState.Loading),
mediatorLoadStates = LoadStates(LoadState.Loading, LoadState.Loading, LoadState.Loading),
),
)
}
private fun createManageTokenContent(token: Token): TokenItemState.ManageContent {
@ -181,9 +177,7 @@ internal class TokensListViewModel @Inject constructor(
return NetworkItemState.ManageContent(
name = network.blockchain.fullNameWithoutTestnet.uppercase(),
protocolName = getNetworkProtocolName(network),
iconResId = mutableStateOf(
getNetworkIconResId(network.address, network.blockchain),
),
iconResId = mutableIntStateOf(value = getNetworkIconResId(network.address, network.blockchain)),
isMainNetwork = isMainNetwork(network),
isAdded = mutableStateOf(
isAdded(address = network.address, blockchain = network.blockchain),
@ -212,7 +206,7 @@ internal class TokensListViewModel @Inject constructor(
return NetworkItemState.ReadContent(
name = network.blockchain.fullNameWithoutTestnet.uppercase(),
protocolName = getNetworkProtocolName(network),
iconResId = mutableStateOf(getNetworkIconResId(network.address, network.blockchain)),
iconResId = mutableIntStateOf(value = getNetworkIconResId(network.address, network.blockchain)),
isMainNetwork = isMainNetwork(network),
)
}
@ -247,6 +241,20 @@ internal class TokensListViewModel @Inject constructor(
}
}
private fun getTokensListBySearchText(text: String): Flow<PagingData<TokenItemState>> {
return interactor.getTokensList(searchText = text)
.mapToTokenItemState()
.cachedIn(viewModelScope)
}
private fun Flow<PagingData<Token>>.mapToTokenItemState(): Flow<PagingData<TokenItemState>> {
return map { pagingData ->
pagingData.map { token ->
if (isManageAccess) createManageTokenContent(token) else createReadTokenContent(token)
}
}
}
private inner class ActionsHandler(
private val router: TokensListRouter,
private val debouncer: Debouncer,
@ -306,10 +314,15 @@ internal class TokensListViewModel @Inject constructor(
uiState = uiState.copySealed(toolbarState = state.copy(value = newValue))
debouncer.debounce(waitMs = 800L, coroutineScope = viewModelScope + dispatchers.io) {
uiState = uiState.copySealed(tokens = getInitialTokensList(newValue))
uiState = uiState.copySealed(tokens = getSearchedTokensList(newValue))
}
}
private fun getSearchedTokensList(searchText: String): Flow<PagingData<TokenItemState>> {
analyticsSender.sendWhenTokenSearched()
return getTokensListBySearchText(text = searchText)
}
private fun onCleanButtonClick() {
val state = requireNotNull(uiState.toolbarState as? TokensListToolbarState.InputField)