Updated on 2026-08-14

This commit is contained in:
Tangem 2025-10-15 15:59:43 +07:00
parent b92bb00c7f
commit 5e6bf6aaae
14 changed files with 172 additions and 109 deletions

View file

@ -2,15 +2,15 @@ package com.tangem.features.account
import com.tangem.domain.account.models.AccountStatusList
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.core.lce.Lce
import com.tangem.domain.models.TotalFiatBalance
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.tokens.error.TokenListError
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
/**
* How to use see [PortfolioSelectorComponent]
*/
interface PortfolioFetcher {
val data: Flow<Data>
@ -25,10 +25,11 @@ interface PortfolioFetcher {
)
data class PortfolioBalance(
val walletBalance: Lce<TokenListError, TotalFiatBalance>,
val userWallet: UserWallet,
val accountsBalance: AccountStatusList,
) {
val userWalletId: UserWalletId get() = accountsBalance.userWalletId
val walletBalance get() = accountsBalance.totalFiatBalance
val userWalletId: UserWalletId get() = userWallet.walletId
}
sealed interface Mode {
@ -36,6 +37,9 @@ interface PortfolioFetcher {
data class Wallet(val walletId: UserWalletId) : Mode
}
/**
* @param[mode] supports runtime change [PortfolioFetcher.updateMode]
*/
interface Factory {
fun create(mode: Mode, scope: CoroutineScope): PortfolioFetcher
}

View file

@ -8,27 +8,55 @@ import com.tangem.domain.models.account.AccountId
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.wallet.UserWallet
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
/**
* How to use
* 1) Create and keep instance of [PortfolioFetcher] and [PortfolioSelectorController] in your Feature Model
* 2) Provide them via [Params]
* 3) Now you have a bridge between your Feature and PortfolioSelector
* 4) Initial state is unselected. Select yourself [PortfolioSelectorController.selectAccount]
* or offer users to select
*
* 5) Listen [PortfolioSelectorController.selectedAccount] or [PortfolioSelectorController.selectedAccountWithData]
*
* Note:
* - Supports [PortfolioSelectorComponent.BottomSheet] and [PortfolioSelectorComponent.Content] modes
*/
interface PortfolioSelectorComponent : ComposableBottomSheetComponent, ComposableContentComponent {
val title: StateFlow<TextReference>
data class Params(
val onDismiss: () -> Unit,
val portfolioFetcher: PortfolioFetcher,
val controller: PortfolioSelectorController,
val bsCallback: BottomSheetCallback? = null,
)
interface BottomSheetCallback {
val onDismiss: () -> Unit
val onBack: () -> Unit
}
interface Factory : ComponentFactory<Params, PortfolioSelectorComponent>
}
/**
* How to use see [PortfolioSelectorComponent]
*
* if [isAccountMode] is false it's mean [selectedAccount] emit [AccountId] for Main account
*/
interface PortfolioSelectorController {
val isAccountMode: Flow<Boolean>
val selectedAccount: StateFlow<AccountId?>
val selectedAccount: Flow<AccountId?>
val selectedAccountSync: AccountId?
/**
* for some Feature specific filtering
* combine and update with your Feature data and [PortfolioFetcher.data]
*/
val isEnabled: MutableStateFlow<(UserWallet, AccountStatus) -> Boolean>
fun selectAccount(accountId: AccountId?)
fun selectedAccountWithData(portfolioFetcher: PortfolioFetcher): Flow<Pair<UserWallet, AccountStatus>?>