Updated on 2026-08-14

This commit is contained in:
Tangem 2026-04-29 18:02:22 +04:00
parent 7095ceec0f
commit 82506a1c9c
29 changed files with 239 additions and 997 deletions

View file

@ -0,0 +1,98 @@
package com.tangem.features.commonfeatures.api.choosetoken
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.features.commonfeatures.api.choosetoken.model.ChooseTokenPortfolioFullBlockUM
import com.tangem.features.commonfeatures.api.R
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
interface ChooseTokenBridge : ChooseTokenBridgeInternal {
val onCurrencyChosen: Channel<ChooseTokenResult>
val onClose: Channel<Unit>
/**
* for some Feature specific tokens filtering
*/
val tokenFilter: MutableStateFlow<(AccountStatus, CryptoCurrencyStatus) -> Boolean>
fun selectWalletTab(walletId: UserWalletId)
data class Settings(
val title: TextReference,
val isShowMarketBlock: Boolean,
val isShowPaymentAccount: Boolean,
) {
companion object {
val SwapFrom = Settings(
title = resourceReference(R.string.swapping_from_title),
isShowMarketBlock = true,
isShowPaymentAccount = true,
)
val SwapTo = Settings(
title = resourceReference(R.string.swapping_to_title),
isShowMarketBlock = true,
isShowPaymentAccount = true,
)
}
}
interface Factory {
fun create(
modelScope: CoroutineScope,
settings: Settings,
analyticsPayload: Set<ChooseTokenAnalyticsPayload> = emptySet(),
): ChooseTokenBridge
}
}
/**
* primary for internal impl usage, but you can also use it externally
*/
interface ChooseTokenBridgeInternal {
val settings: ChooseTokenBridge.Settings
val analyticsPayload: Set<ChooseTokenAnalyticsPayload>
val searchQueryState: StateFlow<SearchQuery>
val fullPortfolioBlock: StateFlow<ChooseTokenPortfolioFullBlockUM?>
fun onSearchQuery(query: SearchQuery)
fun onSearchQuery(query: String) = onSearchQuery(SearchQuery(query))
fun onClose()
fun onCurrencyChosen(result: ChooseTokenResult)
@JvmInline
value class SearchQuery(val value: String) {
companion object {
val Empty = SearchQuery("")
val SearchQuery.isSearchingState: Boolean get() = this.value.isNotBlank()
val StateFlow<SearchQuery>.isSearchingState: Boolean get() = this.value.isSearchingState
}
}
}
data class ChooseTokenResult(
val currency: CryptoCurrencyStatus,
val account: AccountStatus,
val wallet: UserWallet,
val analyticsPayload: Set<ChooseTokenAnalyticsPayload> = emptySet(),
) {
val walletId get() = wallet.walletId
}
sealed interface ChooseTokenAnalyticsPayload {
@Suppress("BooleanPropertyNaming")
@JvmInline
value class IsSearched(val value: Boolean) : ChooseTokenAnalyticsPayload
@JvmInline
value class ScreensSources(val value: String) : ChooseTokenAnalyticsPayload
}

View file

@ -0,0 +1,13 @@
package com.tangem.features.commonfeatures.api.choosetoken
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableContentComponent
interface ChooseTokenComponent : ComposableContentComponent {
data class Params(
val bridge: ChooseTokenBridge,
)
interface Factory : ComponentFactory<Params, ChooseTokenComponent>
}

View file

@ -0,0 +1,51 @@
package com.tangem.features.commonfeatures.api.choosetoken.model
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
import com.tangem.core.ui.extensions.TextReference
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
data class ChooseTokenPortfolioFullBlockUM(
val walletList: WalletListUM,
val isBalanceHidden: Boolean,
val isSearching: Boolean,
val tokensListData: TokenListUMData,
)
data class WalletListUM(
val items: ImmutableList<WalletTabUM>,
)
data class WalletTabUM(
val text: TextReference,
val count: TextReference?,
val isSelected: Boolean,
val onClick: () -> Unit,
)
@Immutable
sealed interface TokenListUMData {
val tokensList: ImmutableList<TokensListItemUM>
val totalTokensCount: Int
data class AccountList(
override val tokensList: ImmutableList<TokensListItemUM.Portfolio>,
override val totalTokensCount: Int,
) : TokenListUMData
data class TokenList(
override val tokensList: ImmutableList<TokensListItemUM>,
override val totalTokensCount: Int,
) : TokenListUMData
data object EmptyList : TokenListUMData {
override val tokensList: ImmutableList<TokensListItemUM> = persistentListOf()
override val totalTokensCount: Int = EMPTY_TOKENS_COUNT
}
private companion object {
const val EMPTY_TOKENS_COUNT = 0
}
}