diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/TokenListUM.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/TokenListUM.kt new file mode 100644 index 0000000000..83d5fc1640 --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/TokenListUM.kt @@ -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, + val isBalanceHidden: Boolean, +) { + + /** Get search bar if it exists */ + fun getSearchBar(): TokensListItemState.SearchBar? { + return items.firstOrNull() as? TokensListItemState.SearchBar + } + + /** Get tokens */ + fun getTokens(): ImmutableList { + if (getSearchBar() == null) return items + + return if (items.size > 1) { + items.subList(fromIndex = 1, toIndex = items.size) + } else { + persistentListOf() + } + } +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/TokenListUMController.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/TokenListUMController.kt new file mode 100644 index 0000000000..6e3f7a5c6a --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/TokenListUMController.kt @@ -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 get() = _state + + private val _state: MutableStateFlow = 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 = {}, + ), + ) + } +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/TokenListUMTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/TokenListUMTransformer.kt new file mode 100644 index 0000000000..49678c022f --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/TokenListUMTransformer.kt @@ -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 \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/transformer/SearchBarUMTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/transformer/SearchBarUMTransformer.kt new file mode 100644 index 0000000000..a177307b2c --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/transformer/SearchBarUMTransformer.kt @@ -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 + } + } +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/transformer/UpdateSearchBarActiveStateTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/transformer/UpdateSearchBarActiveStateTransformer.kt new file mode 100644 index 0000000000..f33d3ea4ee --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/transformer/UpdateSearchBarActiveStateTransformer.kt @@ -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) + } +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/transformer/UpdateSearchBarIntentsTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/transformer/UpdateSearchBarIntentsTransformer.kt new file mode 100644 index 0000000000..de58815cd1 --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/transformer/UpdateSearchBarIntentsTransformer.kt @@ -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) + } +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/transformer/UpdateSearchQueryTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/transformer/UpdateSearchQueryTransformer.kt new file mode 100644 index 0000000000..93a6a20675 --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/transformer/UpdateSearchQueryTransformer.kt @@ -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) + } +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/transformer/UpdateTokenItemsTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/transformer/UpdateTokenItemsTransformer.kt new file mode 100644 index 0000000000..89d171d3f9 --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/tokenlist/entity/transformer/UpdateTokenItemsTransformer.kt @@ -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, + 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, + ) + } +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletTokensListState.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletTokensListState.kt index c582f8d8d8..29daa446b4 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletTokensListState.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletTokensListState.kt @@ -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() { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/multicurrency/MultiCurrencyContentItem.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/multicurrency/MultiCurrencyContentItem.kt index 6c3ca94c12..0b8e4ea13b 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/multicurrency/MultiCurrencyContentItem.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/multicurrency/MultiCurrencyContentItem.kt @@ -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), + ) + } } } \ No newline at end of file