Updated on 2026-08-14
This commit is contained in:
parent
c9f84c9227
commit
6ec85eec82
2 changed files with 44 additions and 33 deletions
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue