Updated on 2026-08-14

This commit is contained in:
Tangem 2024-11-29 11:57:20 +04:00
parent b606e249d4
commit 164e0718e6
9 changed files with 138 additions and 37 deletions

View file

@ -891,6 +891,7 @@
<string name="tokens_list_unavailable_to_purchase_header">Nicht verfügbar zum Kauf</string>
<string name="tokens_list_unavailable_to_sell_header">Nicht zum Verkauf verfügbar</string>
<string name="tokens_list_unavailable_to_swap_header">Nicht verfügbar für Tausch von %s</string>
<string name="tokens_list_unavailable_to_swap_source_header">Nicht zum Tausch verfügbar</string>
<string name="transaction_history_contract_address">Vertrag: %s</string>
<string name="transaction_history_empty_transactions">Du hast noch keine Transaktionen</string>
<string name="transaction_history_error_failed_to_load">Der Transaktionsverlauf konnte nicht geladen werden.\nKlicke auf die Schaltfläche Neu laden, um die Informationen zu aktualisieren.</string>

View file

@ -882,6 +882,7 @@
<string name="tokens_list_unavailable_to_purchase_header">買付できません</string>
<string name="tokens_list_unavailable_to_sell_header">売却できません</string>
<string name="tokens_list_unavailable_to_swap_header">%sからのスワップは利用できません</string>
<string name="tokens_list_unavailable_to_swap_source_header">スワップはできません</string>
<string name="transaction_history_contract_address">コントラクト: %s</string>
<string name="transaction_history_empty_transactions">まだ取引はありません</string>
<string name="transaction_history_error_failed_to_load">取引履歴の読み込みに失敗しました。\n情報を更新するには、リロードボタンをクリックしてください。</string>

View file

@ -914,6 +914,7 @@
<string name="tokens_list_unavailable_to_purchase_header">Недоступно для покупки</string>
<string name="tokens_list_unavailable_to_sell_header">Недоступно для продажи</string>
<string name="tokens_list_unavailable_to_swap_header">Недоступно для обмена с %s</string>
<string name="tokens_list_unavailable_to_swap_source_header">Недоступно для обмена</string>
<string name="transaction_history_contract_address">контракт: %s</string>
<string name="transaction_history_empty_transactions">У вас еще нет транзакций</string>
<string name="transaction_history_error_failed_to_load">Не удалось загрузить историю транзакций.\nНажмите на кнопку перезагрузки, чтобы обновить информацию.</string>

View file

@ -898,6 +898,7 @@
<string name="tokens_list_unavailable_to_purchase_header">Unavailable to purchase</string>
<string name="tokens_list_unavailable_to_sell_header">Unavailable to sell</string>
<string name="tokens_list_unavailable_to_swap_header">Unavailable for swap from %s</string>
<string name="tokens_list_unavailable_to_swap_source_header">Unavailable for swap</string>
<string name="transaction_history_contract_address">contract: %s</string>
<string name="transaction_history_empty_transactions">You don\'t have any transactions yet</string>
<string name="transaction_history_error_failed_to_load">Failed to load transaction history.\nClick on reload button to update the information.</string>

View file

@ -1,6 +1,7 @@
package com.tangem.core.ui.components.tokenlist
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@ -10,6 +11,7 @@ import com.tangem.core.ui.components.tokenlist.internal.GroupTitleItem
import com.tangem.core.ui.components.tokenlist.internal.NetworkTitleItem
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
/**
* Multi-currency content item
@ -39,5 +41,13 @@ fun TokenListItem(state: TokensListItemUM, isBalanceHidden: Boolean, modifier: M
is TokensListItemUM.SearchBar -> {
SearchBar(state = state.searchBarUM, modifier = modifier.padding(all = 12.dp))
}
is TokensListItemUM.Text -> {
Text(
text = state.text.resolveReference(),
modifier = modifier.padding(all = 12.dp),
color = TangemTheme.colors.text.tertiary,
style = TangemTheme.typography.body2,
)
}
}
}

View file

@ -48,4 +48,6 @@ sealed interface TokensListItemUM {
data class Token(val state: TokenItemState) : TokensListItemUM {
override val id: String = state.id
}
data class Text(override val id: Any, val text: TextReference) : TokensListItemUM
}

View file

@ -22,6 +22,7 @@ import com.tangem.features.onramp.swap.availablepairs.AvailableSwapPairsComponen
import com.tangem.features.onramp.swap.availablepairs.entity.transformers.SetLoadingTokenItemsTransformer
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
import com.tangem.features.onramp.tokenlist.entity.TokenListUMController
import com.tangem.features.onramp.tokenlist.entity.transformer.SetNothingToFoundStateTransformer
import com.tangem.features.onramp.tokenlist.entity.transformer.UpdateTokenItemsTransformer
import com.tangem.features.onramp.utils.InputManager
import com.tangem.features.onramp.utils.UpdateSearchBarActiveStateTransformer
@ -80,24 +81,35 @@ internal class AvailableSwapPairsModel @Inject constructor(
} else {
val (appCurrency, isBalanceHidden) = appCurrencyAndBalanceHiding
val filterTokenList = currencies
val filterByQueryTokenList = currencies
.filter { it.currency != selectedStatus?.currency }
.filterByQuery(query = query)
.filterByAvailability(availablePairs = availablePairs)
UpdateTokenItemsTransformer(
appCurrency = appCurrency,
onItemClick = params.onTokenClick,
statuses = filterTokenList,
isBalanceHidden = isBalanceHidden,
hasSearchBar = currencies.isNotEmpty(),
unavailableTokensHeaderReference = resourceReference(
id = R.string.tokens_list_unavailable_to_swap_header,
wrappedList(selectedStatus?.currency?.name?.capitalize() ?: ""),
),
onQueryChange = ::onSearchQueryChange,
onActiveChange = ::onSearchBarActiveChange,
)
if (query.isNotEmpty() && filterByQueryTokenList.isEmpty()) {
SetNothingToFoundStateTransformer(
isBalanceHidden = isBalanceHidden,
hasSearchBar = currencies.isNotEmpty(),
emptySearchMessageReference = resourceReference(
id = R.string.action_buttons_swap_empty_search_message,
),
onQueryChange = ::onSearchQueryChange,
onActiveChange = ::onSearchBarActiveChange,
)
} else {
UpdateTokenItemsTransformer(
appCurrency = appCurrency,
onItemClick = params.onTokenClick,
statuses = filterByQueryTokenList.filterByAvailability(availablePairs = availablePairs),
isBalanceHidden = isBalanceHidden,
hasSearchBar = currencies.isNotEmpty(),
unavailableTokensHeaderReference = resourceReference(
id = R.string.tokens_list_unavailable_to_swap_header,
wrappedList(selectedStatus?.currency?.name?.capitalize() ?: ""),
),
onQueryChange = ::onSearchQueryChange,
onActiveChange = ::onSearchBarActiveChange,
)
}
}
}
.onEach(tokenListUMController::update)

View file

@ -0,0 +1,65 @@
package com.tangem.features.onramp.tokenlist.entity.transformer
import com.tangem.core.ui.components.fields.entity.SearchBarUM
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
internal class SetNothingToFoundStateTransformer(
private val isBalanceHidden: Boolean,
private val hasSearchBar: Boolean,
private val emptySearchMessageReference: TextReference,
private val onQueryChange: (String) -> Unit,
private val onActiveChange: (Boolean) -> Unit,
) : TokenListUMTransformer {
override fun transform(prevState: TokenListUM): TokenListUM {
val searchBarItem = if (hasSearchBar) {
prevState.getSearchBar() ?: createSearchBarItem()
} else {
null
}
return prevState.copy(
availableItems = buildList {
if (searchBarItem != null) {
add(searchBarItem)
}
createGroupTitle(
textReference = resourceReference(id = R.string.exchange_tokens_available_tokens_header),
)
.let(::add)
TokensListItemUM.Text(
id = emptySearchMessageReference.hashCode(),
text = emptySearchMessageReference,
).let(::add)
}
.toImmutableList(),
unavailableItems = persistentListOf(),
isBalanceHidden = isBalanceHidden,
)
}
private fun createSearchBarItem(): TokensListItemUM.SearchBar {
return TokensListItemUM.SearchBar(
searchBarUM = SearchBarUM(
placeholderText = resourceReference(id = R.string.common_search),
query = "",
onQueryChange = onQueryChange,
isActive = false,
onActiveChange = onActiveChange,
),
)
}
private fun createGroupTitle(textReference: TextReference): TokensListItemUM.GroupTitle {
return TokensListItemUM.GroupTitle(id = textReference.hashCode(), text = textReference)
}
}

View file

@ -4,7 +4,6 @@ import arrow.core.getOrElse
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
@ -19,6 +18,7 @@ import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
import com.tangem.features.onramp.tokenlist.entity.OnrampOperation
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
import com.tangem.features.onramp.tokenlist.entity.TokenListUMController
import com.tangem.features.onramp.tokenlist.entity.transformer.SetNothingToFoundStateTransformer
import com.tangem.features.onramp.tokenlist.entity.transformer.UpdateTokenItemsTransformer
import com.tangem.features.onramp.utils.InputManager
import com.tangem.features.onramp.utils.UpdateSearchBarActiveStateTransformer
@ -65,30 +65,38 @@ internal class OnrampTokenListModel @Inject constructor(
)
.flattenCurrencies()
val filterTokenList = currencies
val filterByQueryTokenList = currencies
.filterByQuery(query = query)
.filterByAvailability()
UpdateTokenItemsTransformer(
appCurrency = appCurrency,
onItemClick = params.onTokenClick,
statuses = filterTokenList,
isBalanceHidden = isBalanceHidden,
hasSearchBar = params.hasSearchBar && currencies.isNotEmpty(),
unavailableTokensHeaderReference = when (params.filterOperation) {
OnrampOperation.BUY -> resourceReference(id = R.string.tokens_list_unavailable_to_purchase_header)
OnrampOperation.SELL -> resourceReference(id = R.string.tokens_list_unavailable_to_sell_header)
OnrampOperation.SWAP -> {
// TODO: [REDACTED_JIRA]
resourceReference(
id = R.string.tokens_list_unavailable_to_swap_header,
wrappedList(""),
)
if (query.isNotEmpty() && filterByQueryTokenList.isEmpty()) {
SetNothingToFoundStateTransformer(
isBalanceHidden = isBalanceHidden,
hasSearchBar = params.hasSearchBar && currencies.isNotEmpty(),
emptySearchMessageReference = when (params.filterOperation) {
OnrampOperation.BUY -> R.string.action_buttons_buy_empty_search_message
OnrampOperation.SELL -> R.string.action_buttons_sell_empty_search_message
OnrampOperation.SWAP -> R.string.action_buttons_swap_empty_search_message
}
},
onQueryChange = ::onSearchQueryChange,
onActiveChange = ::onSearchBarActiveChange,
)
.let(::resourceReference),
onQueryChange = ::onSearchQueryChange,
onActiveChange = ::onSearchBarActiveChange,
)
} else {
UpdateTokenItemsTransformer(
appCurrency = appCurrency,
onItemClick = params.onTokenClick,
statuses = filterByQueryTokenList.filterByAvailability(),
isBalanceHidden = isBalanceHidden,
hasSearchBar = params.hasSearchBar && currencies.isNotEmpty(),
unavailableTokensHeaderReference = when (params.filterOperation) {
OnrampOperation.BUY -> R.string.tokens_list_unavailable_to_purchase_header
OnrampOperation.SELL -> R.string.tokens_list_unavailable_to_sell_header
OnrampOperation.SWAP -> R.string.tokens_list_unavailable_to_swap_source_header
}.let(::resourceReference),
onQueryChange = ::onSearchQueryChange,
onActiveChange = ::onSearchBarActiveChange,
)
}
}
.onEach(tokenListUMController::update)
.flowOn(dispatchers.main)