Updated on 2026-08-14

This commit is contained in:
Tangem 2024-10-23 14:32:20 +04:00
parent d487f796be
commit ff5d3cb8b7
10 changed files with 217 additions and 0 deletions

View file

@ -0,0 +1,35 @@
package com.tangem.feature.wallet.presentation.tokenlist.entity
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletTokensListState.TokensListItemState
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
/**
* Token list UM
*
* @property items items (search bar, tokens, headers)
* @property isBalanceHidden flag that indicates if balance should be hidden
*
[REDACTED_AUTHOR]
*/
internal data class TokenListUM(
val items: ImmutableList<TokensListItemState>,
val isBalanceHidden: Boolean,
) {
/** Get search bar if it exists */
fun getSearchBar(): TokensListItemState.SearchBar? {
return items.firstOrNull() as? TokensListItemState.SearchBar
}
/** Get tokens */
fun getTokens(): ImmutableList<TokensListItemState> {
if (getSearchBar() == null) return items
return if (items.size > 1) {
items.subList(fromIndex = 1, toIndex = items.size)
} else {
persistentListOf()
}
}
}

View file

@ -0,0 +1,54 @@
package com.tangem.feature.wallet.presentation.tokenlist.entity
import com.tangem.core.ui.components.fields.entity.SearchBarUM
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.feature.wallet.impl.R
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletTokensListState.TokensListItemState
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import timber.log.Timber
import javax.inject.Inject
/**
* [TokenListUM] controller
*
[REDACTED_AUTHOR]
*/
internal class TokenListUMController @Inject constructor() {
val state: StateFlow<TokenListUM> get() = _state
private val _state: MutableStateFlow<TokenListUM> = MutableStateFlow(
value = TokenListUM(
items = persistentListOf(createInitialSearchBar()),
isBalanceHidden = false,
),
)
fun update(transform: (TokenListUM) -> TokenListUM) {
Timber.d("Applying non-name transformation")
_state.update(transform)
}
fun update(transformer: TokenListUMTransformer) {
Timber.d("Applying ${transformer::class.simpleName}")
_state.update(transformer::transform)
}
/** Get search bar if it exists */
fun getSearchBar(): TokensListItemState.SearchBar? = _state.value.getSearchBar()
private fun createInitialSearchBar(): TokensListItemState.SearchBar {
return TokensListItemState.SearchBar(
searchBarUM = SearchBarUM(
placeholderText = resourceReference(id = R.string.common_search),
query = "",
onQueryChange = {},
isActive = false,
onActiveChange = {},
),
)
}
}

View file

@ -0,0 +1,10 @@
package com.tangem.feature.wallet.presentation.tokenlist.entity
import com.tangem.utils.transformer.Transformer
/**
* Base [TokenListUM] transformer
*
[REDACTED_AUTHOR]
*/
internal interface TokenListUMTransformer : Transformer<TokenListUM>

View file

@ -0,0 +1,33 @@
package com.tangem.feature.wallet.presentation.tokenlist.entity.transformer
import com.tangem.core.ui.components.fields.entity.SearchBarUM
import com.tangem.feature.wallet.presentation.tokenlist.entity.TokenListUM
import com.tangem.feature.wallet.presentation.tokenlist.entity.TokenListUMTransformer
import kotlinx.collections.immutable.persistentListOf
/**
* Base [SearchBarUM] transformer
*
[REDACTED_AUTHOR]
*/
internal abstract class SearchBarUMTransformer : TokenListUMTransformer {
abstract fun transform(prevState: SearchBarUM): SearchBarUM
override fun transform(prevState: TokenListUM): TokenListUM {
val searchBarItem = prevState.getSearchBar()
return if (searchBarItem != null) {
val updatedSearchBar = searchBarItem.copy(searchBarUM = transform(searchBarItem.searchBarUM))
prevState.copy(
items = persistentListOf(
updatedSearchBar,
*prevState.getTokens().toTypedArray(),
),
)
} else {
prevState
}
}
}

View file

@ -0,0 +1,19 @@
package com.tangem.feature.wallet.presentation.tokenlist.entity.transformer
import com.tangem.core.ui.components.fields.entity.SearchBarUM
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.feature.wallet.impl.R
internal class UpdateSearchBarActiveStateTransformer(private val isActive: Boolean) : SearchBarUMTransformer() {
override fun transform(prevState: SearchBarUM): SearchBarUM {
val placeholderText = if (isActive) {
TextReference.EMPTY
} else {
resourceReference(id = R.string.common_search)
}
return prevState.copy(placeholderText = placeholderText, isActive = isActive)
}
}

View file

@ -0,0 +1,13 @@
package com.tangem.feature.wallet.presentation.tokenlist.entity.transformer
import com.tangem.core.ui.components.fields.entity.SearchBarUM
internal class UpdateSearchBarIntentsTransformer(
private val onQueryChange: (String) -> Unit,
private val onActiveChange: (Boolean) -> Unit,
) : SearchBarUMTransformer() {
override fun transform(prevState: SearchBarUM): SearchBarUM {
return prevState.copy(onQueryChange = onQueryChange, onActiveChange = onActiveChange)
}
}

View file

@ -0,0 +1,10 @@
package com.tangem.feature.wallet.presentation.tokenlist.entity.transformer
import com.tangem.core.ui.components.fields.entity.SearchBarUM
internal class UpdateSearchQueryTransformer(private val newQuery: String) : SearchBarUMTransformer() {
override fun transform(prevState: SearchBarUM): SearchBarUM {
return prevState.copy(query = newQuery)
}
}

View file

@ -0,0 +1,28 @@
package com.tangem.feature.wallet.presentation.tokenlist.entity.transformer
import com.tangem.common.ui.tokens.TokenItemStateConverter
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.feature.wallet.presentation.tokenlist.entity.TokenListUM
import com.tangem.feature.wallet.presentation.tokenlist.entity.TokenListUMTransformer
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletTokensListState.TokensListItemState
import kotlinx.collections.immutable.toImmutableList
internal class UpdateTokenItemsTransformer(
appCurrency: AppCurrency,
onItemClick: (CryptoCurrencyStatus) -> Unit,
private val statuses: List<CryptoCurrencyStatus>,
private val isBalanceHidden: Boolean,
) : TokenListUMTransformer {
private val converter = TokenItemStateConverter(appCurrency = appCurrency, onItemClick = onItemClick)
override fun transform(prevState: TokenListUM): TokenListUM {
val items = converter.convertList(input = statuses).map(TokensListItemState::Token)
return prevState.copy(
items = (listOfNotNull(prevState.getSearchBar()) + items).toImmutableList(),
isBalanceHidden = isBalanceHidden,
)
}
}

View file

@ -1,6 +1,7 @@
package com.tangem.feature.wallet.presentation.wallet.state.model
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.components.fields.entity.SearchBarUM
import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.core.ui.extensions.TextReference
import com.tangem.feature.wallet.impl.R
@ -43,6 +44,11 @@ internal sealed class WalletTokensListState {
abstract val id: Any
data class SearchBar(
override val id: Any = "search_bar",
val searchBarUM: SearchBarUM,
) : TokensListItemState()
data class NetworkGroupTitle(override val id: Int, val name: TextReference) : TokensListItemState()
data class Token(val state: TokenItemState) : TokensListItemState() {

View file

@ -1,8 +1,11 @@
package com.tangem.feature.wallet.presentation.wallet.ui.components.multicurrency
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.fields.SearchBar
import com.tangem.core.ui.components.token.TokenItem
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
@ -36,5 +39,11 @@ internal fun MultiCurrencyContentItem(
modifier = modifierWithBackground,
)
}
is TokensListItemState.SearchBar -> {
SearchBar(
state = state.searchBarUM,
modifier = modifierWithBackground.padding(all = 12.dp),
)
}
}
}