Updated on 2026-08-14
This commit is contained in:
parent
220a43c1b9
commit
3a96b203e0
18 changed files with 285 additions and 136 deletions
|
|
@ -9,6 +9,7 @@ import androidx.compose.material3.Text
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.common.ui.R
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
|
@ -73,6 +74,8 @@ private fun Title(title: TextReference) {
|
|||
text = title.resolveReference(),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -82,6 +85,8 @@ private fun Subtitle(subtitle: TextReference) {
|
|||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography.caption2,
|
||||
text = subtitle.resolveReference(),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ package com.tangem.common.ui.userwallet.converter
|
|||
|
||||
import com.tangem.common.ui.R
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
|
||||
import com.tangem.core.ui.components.label.entity.LabelUM
|
||||
import com.tangem.core.ui.components.label.entity.LabelStyle
|
||||
import com.tangem.core.ui.components.label.entity.LabelUM
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
|
|
@ -12,7 +12,6 @@ import com.tangem.core.ui.format.bigdecimal.fiat
|
|||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.card.common.util.getCardsCount
|
||||
import com.tangem.domain.models.ArtworkModel
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.TotalFiatBalance
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
|
|
@ -37,10 +36,10 @@ class UserWalletItemUMConverter(
|
|||
private val isBalanceHidden: Boolean = false,
|
||||
private val authMode: Boolean = false,
|
||||
private val endIcon: UserWalletItemUM.EndIcon = UserWalletItemUM.EndIcon.None,
|
||||
private val artwork: ArtworkModel? = null,
|
||||
artwork: UserWalletItemUM.ImageState? = null,
|
||||
) : Converter<UserWallet, UserWalletItemUM> {
|
||||
|
||||
private val artworkUMConverter = ArtworkUMConverter()
|
||||
private val artwork = artwork ?: UserWalletItemUM.ImageState.Loading
|
||||
|
||||
override fun convert(value: UserWallet): UserWalletItemUM {
|
||||
return with(value) {
|
||||
|
|
@ -52,7 +51,7 @@ class UserWalletItemUMConverter(
|
|||
isEnabled = isEnabled(userWallet = this),
|
||||
endIcon = endIcon,
|
||||
onClick = { onClick(value.walletId) },
|
||||
imageState = getImageState(userWallet = value),
|
||||
imageState = artwork,
|
||||
label = getLabelOrNull(userWallet = this),
|
||||
)
|
||||
}
|
||||
|
|
@ -73,14 +72,6 @@ class UserWalletItemUMConverter(
|
|||
}
|
||||
}
|
||||
|
||||
private fun getImageState(userWallet: UserWallet): UserWalletItemUM.ImageState {
|
||||
return when {
|
||||
userWallet is UserWallet.Hot -> UserWalletItemUM.ImageState.MobileWallet
|
||||
artwork != null -> UserWalletItemUM.ImageState.Image(artworkUMConverter.convert(artwork))
|
||||
else -> UserWalletItemUM.ImageState.Loading
|
||||
}
|
||||
}
|
||||
|
||||
private fun getInfo(userWallet: UserWallet): UserWalletItemUM.Information.Loaded {
|
||||
val text = when (userWallet) {
|
||||
is UserWallet.Cold -> {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ dependencies {
|
|||
api(projects.features.onramp.api)
|
||||
api(projects.features.sendV2.api)
|
||||
api(projects.features.tokenRecieve.api)
|
||||
api(projects.features.wallet.api)
|
||||
|
||||
/* Data */
|
||||
implementation(projects.data.common)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
|||
import com.tangem.core.ui.components.rows.model.BlockchainRowUM
|
||||
import com.tangem.domain.markets.TokenMarketInfo
|
||||
import com.tangem.domain.markets.TokenMarketParams
|
||||
import com.tangem.domain.models.ArtworkModel
|
||||
import com.tangem.domain.models.TotalFiatBalance
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
|
@ -56,7 +55,7 @@ internal class AddToPortfolioBSContentUMFactory(
|
|||
portfolioUIData: PortfolioUIData,
|
||||
selectedWallet: UserWallet?,
|
||||
alreadyAddedNetworks: Set<String>?,
|
||||
artworks: HashMap<UserWalletId, ArtworkModel>,
|
||||
artworks: Map<UserWalletId, UserWalletItemUM.ImageState>,
|
||||
): TangemBottomSheetConfig {
|
||||
return (currentState ?: TangemBottomSheetConfig.Empty).copy(
|
||||
isShown = portfolioUIData.portfolioBSVisibilityModel.addToPortfolioBSVisibility,
|
||||
|
|
@ -110,7 +109,7 @@ internal class AddToPortfolioBSContentUMFactory(
|
|||
}
|
||||
|
||||
private fun UserWallet.toSelectedUserWalletItemUM(
|
||||
artwork: ArtworkModel? = null,
|
||||
artwork: UserWalletItemUM.ImageState? = null,
|
||||
portfolioData: PortfolioData,
|
||||
balance: TotalFiatBalance?,
|
||||
): UserWalletItemUM {
|
||||
|
|
@ -128,7 +127,7 @@ internal class AddToPortfolioBSContentUMFactory(
|
|||
isShow: Boolean,
|
||||
portfolioData: PortfolioData,
|
||||
selectedWalletId: UserWalletId,
|
||||
artworks: HashMap<UserWalletId, ArtworkModel>,
|
||||
artworks: Map<UserWalletId, UserWalletItemUM.ImageState>,
|
||||
): TangemBottomSheetConfig {
|
||||
return TangemBottomSheetConfig(
|
||||
isShown = isShow,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.features.markets.portfolio.impl.model
|
|||
|
||||
import androidx.compose.runtime.Stable
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
|
||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||
import com.arkivanov.decompose.router.slot.activate
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
|
|
@ -21,7 +22,6 @@ import com.tangem.domain.managetokens.CheckCurrencyUnsupportedUseCase
|
|||
import com.tangem.domain.managetokens.model.CurrencyUnsupportedState
|
||||
import com.tangem.domain.markets.SaveMarketTokensUseCase
|
||||
import com.tangem.domain.markets.TokenMarketInfo
|
||||
import com.tangem.domain.models.ArtworkModel
|
||||
import com.tangem.domain.models.ReceiveAddressModel
|
||||
import com.tangem.domain.models.TokenReceiveConfig
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
|
|
@ -31,7 +31,6 @@ import com.tangem.domain.models.wallet.UserWalletId
|
|||
import com.tangem.domain.models.wallet.isMultiCurrency
|
||||
import com.tangem.domain.tokens.GetViewedTokenReceiveWarningUseCase
|
||||
import com.tangem.domain.transaction.usecase.GetEnsNameUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetCardImageUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase
|
||||
import com.tangem.domain.wallets.usecase.HasMissedDerivationsUseCase
|
||||
import com.tangem.features.markets.impl.R
|
||||
|
|
@ -42,13 +41,14 @@ import com.tangem.features.markets.portfolio.impl.loader.PortfolioDataLoader
|
|||
import com.tangem.features.markets.portfolio.impl.ui.state.MyPortfolioUM
|
||||
import com.tangem.features.markets.portfolio.impl.ui.state.TokenActionsBSContentUM
|
||||
import com.tangem.features.tokenreceive.TokenReceiveFeatureToggle
|
||||
import com.tangem.features.wallet.utils.UserWalletImageFetcher
|
||||
import com.tangem.lib.crypto.BlockchainUtils
|
||||
import com.tangem.operations.attestation.ArtworkSize
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -66,21 +66,17 @@ internal class MarketsPortfolioModel @Inject constructor(
|
|||
private val portfolioDataLoader: PortfolioDataLoader,
|
||||
private val hasMissedDerivationsUseCase: HasMissedDerivationsUseCase,
|
||||
private val saveMarketTokensUseCase: SaveMarketTokensUseCase,
|
||||
private val getCardImageUseCase: GetCardImageUseCase,
|
||||
private val addToPortfolioManager: AddToPortfolioManager,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val tokenReceiveFeatureToggle: TokenReceiveFeatureToggle,
|
||||
private val getViewedTokenReceiveWarningUseCase: GetViewedTokenReceiveWarningUseCase,
|
||||
private val getEnsNameUseCase: GetEnsNameUseCase,
|
||||
private val userWalletImageFetcher: UserWalletImageFetcher,
|
||||
) : Model() {
|
||||
|
||||
val state: StateFlow<MyPortfolioUM> get() = _state
|
||||
private val _state: MutableStateFlow<MyPortfolioUM> = MutableStateFlow(value = MyPortfolioUM.Loading)
|
||||
|
||||
private val loadedArtworks: HashMap<UserWalletId, ArtworkModel> = hashMapOf()
|
||||
private val artworksState: MutableStateFlow<HashMap<UserWalletId, ArtworkModel>> = MutableStateFlow(hashMapOf())
|
||||
private val loadArtworksMutex = Mutex()
|
||||
|
||||
private val params = paramsContainer.require<MarketsPortfolioComponent.Params>()
|
||||
private val analyticsEventBuilder = PortfolioAnalyticsEvent.EventBuilder(
|
||||
token = params.token,
|
||||
|
|
@ -196,38 +192,33 @@ internal class MarketsPortfolioModel @Inject constructor(
|
|||
|
||||
private fun subscribeOnStateUpdates() {
|
||||
combine(
|
||||
flow = loadPortfolioData(params.token.id),
|
||||
flow = loadPortfolioDataWithArtworks(params.token.id),
|
||||
flow2 = getPortfolioUIDataFlow(),
|
||||
flow3 = artworksState,
|
||||
transform = factory::create,
|
||||
transform = { pair, portfolioUIData ->
|
||||
val (portfolioData, artworks) = pair
|
||||
factory.create(portfolioData, portfolioUIData, artworks)
|
||||
},
|
||||
)
|
||||
.onEach { _state.value = it }
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun loadPortfolioData(currencyRawId: CryptoCurrency.RawID): Flow<PortfolioData> {
|
||||
portfolioDataLoader.load(currencyRawId).onEach {
|
||||
loadArtworks(it.walletsWithCurrencies.keys.toList())
|
||||
}.also { return it }
|
||||
}
|
||||
private fun loadPortfolioDataWithArtworks(
|
||||
currencyRawId: CryptoCurrency.RawID,
|
||||
): Flow<Pair<PortfolioData, Map<UserWalletId, UserWalletItemUM.ImageState>>> {
|
||||
val wallets = Channel<Set<UserWallet>>()
|
||||
val portfolioFlow = portfolioDataLoader
|
||||
.load(currencyRawId)
|
||||
.onEach { wallets.trySend(it.walletsWithCurrencies.keys) }
|
||||
|
||||
private fun loadArtworks(wallets: List<UserWallet>) {
|
||||
modelScope.launch {
|
||||
loadArtworksMutex.withLock {
|
||||
wallets.filterIsInstance<UserWallet.Cold>().forEach { wallet ->
|
||||
if (!loadedArtworks.containsKey(wallet.walletId)) {
|
||||
val artwork = getCardImageUseCase(
|
||||
cardId = wallet.cardId,
|
||||
manufacturerName = wallet.scanResponse.card.manufacturer.name,
|
||||
firmwareVersion = wallet.scanResponse.card.firmwareVersion.toSdkFirmwareVersion(),
|
||||
cardPublicKey = wallet.scanResponse.card.cardPublicKey,
|
||||
)
|
||||
loadedArtworks[wallet.walletId] = artwork
|
||||
artworksState.emit(loadedArtworks)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val artworksFlow = wallets.receiveAsFlow()
|
||||
.distinctUntilChanged()
|
||||
.flatMapLatest { userWalletImageFetcher.walletsImage(wallets = it, size = ArtworkSize.SMALL) }
|
||||
|
||||
return combine(
|
||||
flow = portfolioFlow,
|
||||
flow2 = artworksFlow,
|
||||
) { portfolioData, artworks -> portfolioData to artworks }
|
||||
}
|
||||
|
||||
private fun getPortfolioUIDataFlow(): Flow<PortfolioUIData> {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package com.tangem.features.markets.portfolio.impl.model
|
||||
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.domain.markets.TokenMarketInfo
|
||||
import com.tangem.domain.models.ArtworkModel
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
|
@ -36,7 +36,7 @@ internal class MyPortfolioUMFactory(
|
|||
fun create(
|
||||
portfolioData: PortfolioData,
|
||||
portfolioUIData: PortfolioUIData,
|
||||
artworks: HashMap<UserWalletId, ArtworkModel>,
|
||||
artworks: Map<UserWalletId, UserWalletItemUM.ImageState>,
|
||||
): MyPortfolioUM {
|
||||
val addToPortfolioData = portfolioUIData.addToPortfolioData
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ internal class MyPortfolioUMFactory(
|
|||
private fun createAddToPortfolioBSConfig(
|
||||
portfolioData: PortfolioData,
|
||||
portfolioUIData: PortfolioUIData,
|
||||
artworks: HashMap<UserWalletId, ArtworkModel>,
|
||||
artworks: Map<UserWalletId, UserWalletItemUM.ImageState>,
|
||||
): TangemBottomSheetConfig {
|
||||
val selectedWallet = portfolioData.walletsWithCurrencies.keys
|
||||
.firstOrNull { it.walletId == portfolioUIData.selectedWalletId }
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ dependencies {
|
|||
implementation(projects.features.onboardingV2.api)
|
||||
implementation(projects.features.pushNotifications.api)
|
||||
implementation(projects.features.hotWallet.api)
|
||||
implementation(projects.features.wallet.api)
|
||||
|
||||
/* Project - Core */
|
||||
implementation(projects.core.decompose)
|
||||
|
|
@ -69,4 +70,5 @@ dependencies {
|
|||
|
||||
/** Tangem libraries */
|
||||
implementation(tangemDeps.hot.core)
|
||||
implementation(tangemDeps.card.core)
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package com.tangem.feature.walletsettings.component.preview
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.common.ui.account.AccountIconPreviewData
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM.ImageState
|
||||
import com.tangem.core.analytics.DummyAnalyticsEventHandler
|
||||
import com.tangem.core.decompose.navigation.DummyRouter
|
||||
import com.tangem.core.ui.components.block.model.BlockUM
|
||||
|
|
@ -13,6 +14,7 @@ import com.tangem.domain.models.wallet.UserWalletId
|
|||
import com.tangem.feature.walletsettings.component.WalletSettingsComponent
|
||||
import com.tangem.feature.walletsettings.entity.WalletSettingsAccountsUM
|
||||
import com.tangem.feature.walletsettings.entity.WalletSettingsAccountsUM.Footer.AddAccountUM
|
||||
import com.tangem.feature.walletsettings.entity.WalletSettingsItemUM
|
||||
import com.tangem.feature.walletsettings.entity.WalletSettingsUM
|
||||
import com.tangem.feature.walletsettings.impl.R
|
||||
import com.tangem.feature.walletsettings.ui.WalletSettingsScreen
|
||||
|
|
@ -34,14 +36,11 @@ internal class PreviewWalletSettingsComponent : WalletSettingsComponent {
|
|||
wallets = null,
|
||||
backedUp = false,
|
||||
),
|
||||
userWalletName = "My Wallet",
|
||||
isReferralAvailable = true,
|
||||
isLinkMoreCardsAvailable = true,
|
||||
isRenameWalletAvailable = false,
|
||||
isNFTFeatureEnabled = true,
|
||||
isNFTEnabled = true,
|
||||
onCheckedNFTChange = {},
|
||||
renameWallet = {},
|
||||
forgetWallet = {},
|
||||
onLinkMoreCardsClick = {},
|
||||
onReferralClick = {},
|
||||
|
|
@ -56,6 +55,7 @@ internal class PreviewWalletSettingsComponent : WalletSettingsComponent {
|
|||
onUpgradeWalletClick = {},
|
||||
onDismissUpgradeWalletClick = {},
|
||||
accountsUM = previewAccounts(),
|
||||
cardItem = previewCardBlock(),
|
||||
),
|
||||
requestPushNotificationsPermission = false,
|
||||
onPushNotificationPermissionGranted = {},
|
||||
|
|
@ -90,6 +90,15 @@ internal class PreviewWalletSettingsComponent : WalletSettingsComponent {
|
|||
).let(::add)
|
||||
}
|
||||
|
||||
private fun previewCardBlock() = WalletSettingsItemUM.CardBlock(
|
||||
id = "wallet_name",
|
||||
title = resourceReference(id = R.string.user_wallet_list_rename_popup_placeholder),
|
||||
text = stringReference("Wallet Name"),
|
||||
isEnabled = true,
|
||||
onClick = { },
|
||||
imageState = ImageState.MobileWallet,
|
||||
)
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
WalletSettingsScreen(
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.feature.walletsettings.entity
|
|||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.common.ui.account.CryptoPortfolioIconUM
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM.ImageState
|
||||
import com.tangem.core.ui.components.block.model.BlockUM
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
|
@ -24,11 +25,12 @@ internal sealed class WalletSettingsItemUM {
|
|||
val onCheckedChange: (Boolean) -> Unit,
|
||||
) : WalletSettingsItemUM()
|
||||
|
||||
data class WithText(
|
||||
data class CardBlock(
|
||||
override val id: String,
|
||||
val title: TextReference,
|
||||
val text: TextReference,
|
||||
val isEnabled: Boolean,
|
||||
val imageState: ImageState,
|
||||
val onClick: () -> Unit,
|
||||
) : WalletSettingsItemUM()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.feature.walletsettings.model
|
||||
|
||||
import android.os.Build
|
||||
import arrow.core.Either
|
||||
import arrow.core.getOrElse
|
||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||
import com.arkivanov.decompose.router.slot.activate
|
||||
|
|
@ -44,6 +45,7 @@ import com.tangem.feature.walletsettings.entity.WalletSettingsUM
|
|||
import com.tangem.feature.walletsettings.impl.R
|
||||
import com.tangem.feature.walletsettings.utils.AccountItemsDelegate
|
||||
import com.tangem.feature.walletsettings.utils.ItemsBuilder
|
||||
import com.tangem.feature.walletsettings.utils.WalletCardItemDelegate
|
||||
import com.tangem.features.pushnotifications.api.analytics.PushNotificationAnalyticEvents
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
|
|
@ -66,7 +68,7 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val analyticsContextProxy: AnalyticsContextProxy,
|
||||
private val getShouldSaveUserWalletsSyncUseCase: ShouldSaveUserWalletsSyncUseCase,
|
||||
walletCardItemDelegateFactory: WalletCardItemDelegate.Factory,
|
||||
private val isDemoCardUseCase: IsDemoCardUseCase,
|
||||
getWalletNFTEnabledUseCase: GetWalletNFTEnabledUseCase,
|
||||
private val enableWalletNFTUseCase: EnableWalletNFTUseCase,
|
||||
|
|
@ -85,6 +87,7 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
val params: WalletSettingsComponent.Params = paramsContainer.require()
|
||||
val dialogNavigation = SlotNavigation<DialogConfig>()
|
||||
val bottomSheetNavigation: SlotNavigation<NetworksAvailableForNotificationBSConfig> = SlotNavigation()
|
||||
private val walletCardItemDelegate = walletCardItemDelegateFactory.create(dialogNavigation)
|
||||
|
||||
val state: MutableStateFlow<WalletSettingsUM> = MutableStateFlow(
|
||||
value = WalletSettingsUM(
|
||||
|
|
@ -117,14 +120,12 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
}
|
||||
|
||||
init {
|
||||
combine(
|
||||
getWalletUseCase.invokeFlow(params.userWalletId).distinctUntilChanged(),
|
||||
fun combineUI(wallet: UserWallet) = combine(
|
||||
getWalletNFTEnabledUseCase.invoke(params.userWalletId),
|
||||
getWalletNotificationsEnabledUseCase(params.userWalletId),
|
||||
isUpgradeWalletNotificationEnabledUseCase(params.userWalletId),
|
||||
) { maybeWallet, nftEnabled, notificationsEnabled, isUpgradeNotificationEnabled ->
|
||||
val wallet = maybeWallet.getOrNull() ?: return@combine
|
||||
val isRenameWalletAvailable = getShouldSaveUserWalletsSyncUseCase()
|
||||
walletCardItemDelegate.cardItemFlow(wallet),
|
||||
) { nftEnabled, notificationsEnabled, isUpgradeNotificationEnabled, cardItem ->
|
||||
val isWalletBackedUp = when (wallet) {
|
||||
is UserWallet.Hot -> wallet.backedUp
|
||||
is UserWallet.Cold -> true
|
||||
|
|
@ -135,8 +136,7 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
value.copy(
|
||||
items = buildItems(
|
||||
userWallet = wallet,
|
||||
dialogNavigation = dialogNavigation,
|
||||
isRenameWalletAvailable = isRenameWalletAvailable,
|
||||
cardItem = cardItem,
|
||||
isNFTEnabled = nftEnabled,
|
||||
isNotificationsEnabled = notificationsEnabled,
|
||||
isNotificationsFeatureEnabled = isNeedShowNotifications,
|
||||
|
|
@ -147,6 +147,10 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
getWalletUseCase.invokeFlow(params.userWalletId)
|
||||
.distinctUntilChanged()
|
||||
.filterIsInstance<Either.Right<UserWallet>>()
|
||||
.flatMapLatest { combineUI(it.value) }
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
|
|
@ -162,8 +166,7 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
|
||||
private fun buildItems(
|
||||
userWallet: UserWallet,
|
||||
dialogNavigation: SlotNavigation<DialogConfig>,
|
||||
isRenameWalletAvailable: Boolean,
|
||||
cardItem: WalletSettingsItemUM.CardBlock,
|
||||
isNFTEnabled: Boolean,
|
||||
isNotificationsFeatureEnabled: Boolean,
|
||||
isNotificationsEnabled: Boolean,
|
||||
|
|
@ -176,7 +179,7 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
}
|
||||
return itemsBuilder.buildItems(
|
||||
userWallet = userWallet,
|
||||
userWalletName = userWallet.name,
|
||||
cardItem = cardItem,
|
||||
isReferralAvailable = when (userWallet) {
|
||||
is UserWallet.Cold -> userWallet.cardTypesResolver.isTangemWallet()
|
||||
is UserWallet.Hot -> false
|
||||
|
|
@ -186,8 +189,6 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
is UserWallet.Hot -> false
|
||||
},
|
||||
isManageTokensAvailable = isMultiCurrency,
|
||||
isRenameWalletAvailable = isRenameWalletAvailable,
|
||||
renameWallet = { openRenameWalletDialog(userWallet, dialogNavigation) },
|
||||
isNFTFeatureEnabled = isMultiCurrency,
|
||||
isNFTEnabled = isNFTEnabled,
|
||||
onCheckedNFTChange = ::onCheckedNFTChange,
|
||||
|
|
@ -226,15 +227,6 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private fun openRenameWalletDialog(userWallet: UserWallet, dialogNavigation: SlotNavigation<DialogConfig>) {
|
||||
val config = DialogConfig.RenameWallet(
|
||||
userWalletId = userWallet.walletId,
|
||||
currentName = userWallet.name,
|
||||
)
|
||||
|
||||
dialogNavigation.activate(config)
|
||||
}
|
||||
|
||||
private fun forgetWallet() = modelScope.launch {
|
||||
val hasUserWallets = deleteWalletUseCase(params.userWalletId).getOrElse {
|
||||
Timber.e("Unable to delete wallet: $it")
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.common.ui.account.AccountRow
|
||||
import com.tangem.common.ui.userwallet.CardImage
|
||||
import com.tangem.core.ui.components.SpacerH
|
||||
import com.tangem.core.ui.components.SpacerH8
|
||||
import com.tangem.core.ui.components.TangemSwitch
|
||||
|
|
@ -30,10 +31,13 @@ import com.tangem.core.ui.components.appbar.TangemTopAppBar
|
|||
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
||||
import com.tangem.core.ui.components.block.BlockCard
|
||||
import com.tangem.core.ui.components.block.BlockItem
|
||||
import com.tangem.core.ui.components.buttons.SecondarySmallButton
|
||||
import com.tangem.core.ui.components.buttons.SmallButtonConfig
|
||||
import com.tangem.core.ui.components.items.DescriptionItem
|
||||
import com.tangem.core.ui.components.notifications.Notification
|
||||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
|
@ -115,7 +119,7 @@ private fun Content(state: WalletSettingsUM, modifier: Modifier = Modifier) {
|
|||
modifier = itemModifier,
|
||||
model = item,
|
||||
)
|
||||
is WalletSettingsItemUM.WithText -> TextBlock(
|
||||
is WalletSettingsItemUM.CardBlock -> CardBlock(
|
||||
modifier = itemModifier,
|
||||
model = item,
|
||||
)
|
||||
|
|
@ -180,30 +184,40 @@ private fun ItemsBlock(model: WalletSettingsItemUM.WithItems, modifier: Modifier
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun TextBlock(model: WalletSettingsItemUM.WithText, modifier: Modifier = Modifier) {
|
||||
private fun CardBlock(model: WalletSettingsItemUM.CardBlock, modifier: Modifier = Modifier) {
|
||||
BlockCard(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
enabled = model.isEnabled,
|
||||
onClick = model.onClick,
|
||||
) {
|
||||
Column(
|
||||
Row(
|
||||
modifier = Modifier.padding(all = TangemTheme.dimens.spacing12),
|
||||
horizontalAlignment = Alignment.Start,
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
text = model.title.resolveReference(),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
||||
Text(
|
||||
text = model.text.resolveReference(),
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
style = TangemTheme.typography.body1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
CardImage(model.imageState)
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(
|
||||
text = model.title.resolveReference(),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography.caption2,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
Text(
|
||||
text = model.text.resolveReference(),
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
||||
SecondarySmallButton(
|
||||
config = SmallButtonConfig(
|
||||
enabled = model.isEnabled,
|
||||
text = resourceReference(R.string.common_rename),
|
||||
onClick = model.onClick,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import com.tangem.core.ui.components.block.model.BlockUM
|
|||
import com.tangem.core.ui.components.label.entity.LabelStyle
|
||||
import com.tangem.core.ui.components.label.entity.LabelUM
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.feature.walletsettings.analytics.Settings
|
||||
import com.tangem.feature.walletsettings.entity.WalletSettingsAccountsUM
|
||||
|
|
@ -30,12 +29,11 @@ internal class ItemsBuilder @Inject constructor(
|
|||
@Suppress("LongParameterList")
|
||||
fun buildItems(
|
||||
userWallet: UserWallet,
|
||||
userWalletName: String,
|
||||
cardItem: WalletSettingsItemUM.CardBlock,
|
||||
accountsUM: List<WalletSettingsAccountsUM>,
|
||||
isLinkMoreCardsAvailable: Boolean,
|
||||
isReferralAvailable: Boolean,
|
||||
isManageTokensAvailable: Boolean,
|
||||
isRenameWalletAvailable: Boolean,
|
||||
isNFTFeatureEnabled: Boolean,
|
||||
isNFTEnabled: Boolean,
|
||||
onCheckedNFTChange: (Boolean) -> Unit,
|
||||
|
|
@ -45,7 +43,6 @@ internal class ItemsBuilder @Inject constructor(
|
|||
onCheckedNotificationsChanged: (Boolean) -> Unit,
|
||||
onNotificationsDescriptionClick: () -> Unit,
|
||||
forgetWallet: () -> Unit,
|
||||
renameWallet: () -> Unit,
|
||||
onLinkMoreCardsClick: () -> Unit,
|
||||
onReferralClick: () -> Unit,
|
||||
onAccessCodeClick: () -> Unit,
|
||||
|
|
@ -53,7 +50,7 @@ internal class ItemsBuilder @Inject constructor(
|
|||
onUpgradeWalletClick: () -> Unit,
|
||||
onDismissUpgradeWalletClick: () -> Unit,
|
||||
): PersistentList<WalletSettingsItemUM> = persistentListOf<WalletSettingsItemUM>()
|
||||
.add(buildNameItem(userWalletName, isRenameWalletAvailable, renameWallet))
|
||||
.add(cardItem)
|
||||
.addAll(
|
||||
buildUpgradeWalletItem(
|
||||
userWallet = userWallet,
|
||||
|
|
@ -62,8 +59,8 @@ internal class ItemsBuilder @Inject constructor(
|
|||
onDismissUpgradeWalletClick = onDismissUpgradeWalletClick,
|
||||
),
|
||||
)
|
||||
.addAll(accountsUM)
|
||||
.addAll(buildAccessCodeItem(userWallet, onAccessCodeClick))
|
||||
.addAll(accountsUM)
|
||||
.add(
|
||||
buildCardItem(
|
||||
userWallet = userWallet,
|
||||
|
|
@ -121,15 +118,6 @@ internal class ItemsBuilder @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun buildNameItem(walletName: String, isRenameWalletAvailable: Boolean, renameWallet: () -> Unit) =
|
||||
WalletSettingsItemUM.WithText(
|
||||
id = "wallet_name",
|
||||
title = resourceReference(id = R.string.settings_wallet_name_title),
|
||||
text = stringReference(walletName),
|
||||
isEnabled = isRenameWalletAvailable,
|
||||
onClick = renameWallet,
|
||||
)
|
||||
|
||||
private fun buildNFTItem(isNFTEnabled: Boolean, onCheckedNFTChange: (Boolean) -> Unit) =
|
||||
WalletSettingsItemUM.WithSwitch(
|
||||
id = "nft",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
package com.tangem.feature.walletsettings.utils
|
||||
|
||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||
import com.arkivanov.decompose.router.slot.activate
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsSyncUseCase
|
||||
import com.tangem.feature.walletsettings.entity.DialogConfig
|
||||
import com.tangem.feature.walletsettings.entity.WalletSettingsItemUM
|
||||
import com.tangem.feature.walletsettings.impl.R
|
||||
import com.tangem.features.wallet.utils.UserWalletImageFetcher
|
||||
import com.tangem.operations.attestation.ArtworkSize
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.flow
|
||||
|
||||
internal class WalletCardItemDelegate @AssistedInject constructor(
|
||||
private val getShouldSaveUserWalletsSyncUseCase: ShouldSaveUserWalletsSyncUseCase,
|
||||
private val walletImageFetcher: UserWalletImageFetcher,
|
||||
@Assisted private val dialogNavigation: SlotNavigation<DialogConfig>,
|
||||
) {
|
||||
|
||||
fun cardItemFlow(wallet: UserWallet): Flow<WalletSettingsItemUM.CardBlock> = combine(
|
||||
flow = walletImageFetcher.walletImage(wallet, ArtworkSize.SMALL),
|
||||
flow2 = flow { emit(getShouldSaveUserWalletsSyncUseCase()) },
|
||||
transform = { imageState, isRenameAvailable ->
|
||||
val walletName = wallet.name
|
||||
WalletSettingsItemUM.CardBlock(
|
||||
id = "wallet_name",
|
||||
title = resourceReference(id = R.string.user_wallet_list_rename_popup_placeholder),
|
||||
text = stringReference(walletName),
|
||||
isEnabled = isRenameAvailable,
|
||||
onClick = { openRenameWalletDialog(wallet) },
|
||||
imageState = imageState,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
private fun openRenameWalletDialog(userWallet: UserWallet) {
|
||||
val config = DialogConfig.RenameWallet(
|
||||
userWalletId = userWallet.walletId,
|
||||
currentName = userWallet.name,
|
||||
)
|
||||
dialogNavigation.activate(config)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(dialogNavigation: SlotNavigation<DialogConfig>): WalletCardItemDelegate
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,9 @@ dependencies {
|
|||
/** Project - Domain */
|
||||
implementation(projects.domain.models)
|
||||
|
||||
/** Tangem libraries */
|
||||
implementation(tangemDeps.card.core)
|
||||
|
||||
/** Core */
|
||||
implementation(projects.core.ui)
|
||||
implementation(projects.core.decompose)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.features.wallet.utils
|
||||
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.operations.attestation.ArtworkSize
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface UserWalletImageFetcher {
|
||||
|
||||
fun walletImage(walletId: UserWalletId, size: ArtworkSize): Flow<UserWalletItemUM.ImageState>
|
||||
fun walletImage(cardDTO: CardDTO, size: ArtworkSize): Flow<UserWalletItemUM.ImageState>
|
||||
fun walletImage(wallet: UserWallet, size: ArtworkSize): Flow<UserWalletItemUM.ImageState>
|
||||
|
||||
fun walletsImage(
|
||||
wallets: Collection<UserWallet>,
|
||||
size: ArtworkSize,
|
||||
): Flow<Map<UserWalletId, UserWalletItemUM.ImageState>>
|
||||
}
|
||||
|
|
@ -4,8 +4,10 @@ import com.tangem.core.decompose.model.Model
|
|||
import com.tangem.feature.wallet.DefaultWalletEntryComponent
|
||||
import com.tangem.feature.wallet.child.organizetokens.model.OrganizeTokensModel
|
||||
import com.tangem.feature.wallet.child.wallet.model.WalletModel
|
||||
import com.tangem.feature.wallet.utils.DefaultUserWalletImageFetcher
|
||||
import com.tangem.feature.wallet.utils.DefaultUserWalletsFetcher
|
||||
import com.tangem.features.wallet.WalletEntryComponent
|
||||
import com.tangem.features.wallet.utils.UserWalletImageFetcher
|
||||
import com.tangem.features.wallet.utils.UserWalletsFetcher
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
|
|
@ -13,6 +15,7 @@ import dagger.hilt.InstallIn
|
|||
import dagger.hilt.components.SingletonComponent
|
||||
import dagger.multibindings.ClassKey
|
||||
import dagger.multibindings.IntoMap
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
|
|
@ -24,6 +27,10 @@ internal interface WalletFeatureModule {
|
|||
@Binds
|
||||
fun bindUserWalletsFetcher(impl: DefaultUserWalletsFetcher.Factory): UserWalletsFetcher.Factory
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindUserWalletImageFetcher(impl: DefaultUserWalletImageFetcher): UserWalletImageFetcher
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(WalletModel::class)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
package com.tangem.feature.wallet.utils
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.common.ui.userwallet.converter.ArtworkUMConverter
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
|
||||
import com.tangem.core.ui.components.artwork.ArtworkUM
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.GetCardImageUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.features.wallet.utils.UserWalletImageFetcher
|
||||
import com.tangem.operations.attestation.ArtworkSize
|
||||
import kotlinx.coroutines.flow.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class DefaultUserWalletImageFetcher @Inject constructor(
|
||||
private val getCardImageUseCase: GetCardImageUseCase,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val artworkUMConverter: ArtworkUMConverter,
|
||||
) : UserWalletImageFetcher {
|
||||
|
||||
private val smallCache = MutableStateFlow(mapOf<String, ArtworkUM>())
|
||||
private val largeCache = MutableStateFlow(mapOf<String, ArtworkUM>())
|
||||
|
||||
override fun walletImage(wallet: UserWallet, size: ArtworkSize): Flow<UserWalletItemUM.ImageState> = when (wallet) {
|
||||
is UserWallet.Cold -> walletImage(wallet.scanResponse.card, size)
|
||||
is UserWallet.Hot -> flowOf(UserWalletItemUM.ImageState.MobileWallet)
|
||||
}
|
||||
|
||||
override fun walletsImage(
|
||||
wallets: Collection<UserWallet>,
|
||||
size: ArtworkSize,
|
||||
): Flow<Map<UserWalletId, UserWalletItemUM.ImageState>> = wallets
|
||||
.map { userWallet -> walletImage(userWallet, size).map { imageState -> userWallet.walletId to imageState } }
|
||||
.merge()
|
||||
.runningFold(mapOf<UserWalletId, UserWalletItemUM.ImageState>()) { map, newState -> map.plus(newState) }
|
||||
.filter { it.size >= wallets.size } // prevent spam, waiting full map
|
||||
.distinctUntilChanged()
|
||||
|
||||
override fun walletImage(walletId: UserWalletId, size: ArtworkSize): Flow<UserWalletItemUM.ImageState> = flow {
|
||||
val imagesFlow = getUserWalletUseCase.invokeFlow(walletId)
|
||||
// emit Loading and wait wallet
|
||||
.onEach { if (it.isLeft()) emit(UserWalletItemUM.ImageState.Loading) }
|
||||
.filterIsInstance<Either.Right<UserWallet>>()
|
||||
.map { it.value }
|
||||
.distinctUntilChanged()
|
||||
.flatMapLatest { wallet -> walletImage(wallet, size) }
|
||||
emitAll(imagesFlow)
|
||||
}.distinctUntilChanged()
|
||||
|
||||
override fun walletImage(cardDTO: CardDTO, size: ArtworkSize): Flow<UserWalletItemUM.ImageState> =
|
||||
internalGetCardImage(
|
||||
cardInfo = cardDTO,
|
||||
size = size,
|
||||
).distinctUntilChanged()
|
||||
|
||||
private fun internalGetCardImage(cardInfo: CardDTO, size: ArtworkSize): Flow<UserWalletItemUM.ImageState> = flow {
|
||||
emit(cacheOrLoading(cardInfo.cardId, size))
|
||||
|
||||
val artwork = getCardImageUseCase.invoke(
|
||||
cardId = cardInfo.cardId,
|
||||
cardPublicKey = cardInfo.cardPublicKey,
|
||||
size = size,
|
||||
manufacturerName = cardInfo.manufacturer.name,
|
||||
firmwareVersion = cardInfo.firmwareVersion.toSdkFirmwareVersion(),
|
||||
)
|
||||
.let { artworkUMConverter.convert(it) }
|
||||
.also { save(cardInfo.cardId, size, it) }
|
||||
emit(UserWalletItemUM.ImageState.Image(artwork))
|
||||
}
|
||||
|
||||
private fun cacheOrLoading(cardId: String, size: ArtworkSize): UserWalletItemUM.ImageState {
|
||||
val artwork = when (size) {
|
||||
ArtworkSize.LARGE -> largeCache.value[cardId]
|
||||
ArtworkSize.SMALL -> smallCache.value[cardId]
|
||||
}
|
||||
return artwork
|
||||
?.let { UserWalletItemUM.ImageState.Image(artwork) }
|
||||
?: UserWalletItemUM.ImageState.Loading
|
||||
}
|
||||
|
||||
private fun save(cardId: String, size: ArtworkSize, artwork: ArtworkUM) {
|
||||
when (size) {
|
||||
ArtworkSize.LARGE -> largeCache.update { it.plus(cardId to artwork) }
|
||||
ArtworkSize.SMALL -> smallCache.update { it.plus(cardId to artwork) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -14,16 +14,15 @@ import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
|||
import com.tangem.domain.core.lce.Lce
|
||||
import com.tangem.domain.core.lce.lce
|
||||
import com.tangem.domain.core.utils.toLce
|
||||
import com.tangem.domain.models.ArtworkModel
|
||||
import com.tangem.domain.models.TotalFiatBalance
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.models.wallet.isMultiCurrency
|
||||
import com.tangem.domain.tokens.GetWalletTotalBalanceUseCase
|
||||
import com.tangem.domain.tokens.error.TokenListError
|
||||
import com.tangem.domain.wallets.usecase.GetCardImageUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.features.wallet.utils.UserWalletImageFetcher
|
||||
import com.tangem.features.wallet.utils.UserWalletsFetcher
|
||||
import com.tangem.operations.attestation.ArtworkSize
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
@ -45,11 +44,10 @@ internal class DefaultUserWalletsFetcher @AssistedInject constructor(
|
|||
@Assisted private val messageSender: UiMessageSender,
|
||||
@Assisted("onlyMultiCurrency") private val onlyMultiCurrency: Boolean,
|
||||
@Assisted("authMode") private val authMode: Boolean,
|
||||
private val getCardImageUseCase: GetCardImageUseCase,
|
||||
private val userWalletImageFetcher: UserWalletImageFetcher,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
) : UserWalletsFetcher {
|
||||
|
||||
private var loadedArtworks: HashMap<UserWalletId, ArtworkModel> = hashMapOf()
|
||||
private val walletsFlow =
|
||||
if (onlyMultiCurrency) getWalletsUseCase().map { it.filter { it.isMultiCurrency } } else getWalletsUseCase()
|
||||
|
||||
|
|
@ -67,7 +65,7 @@ internal class DefaultUserWalletsFetcher @AssistedInject constructor(
|
|||
flow = getSelectedAppCurrencyUseCase().distinctUntilChanged(),
|
||||
flow2 = getBalanceHidingSettingsUseCase().distinctUntilChanged(),
|
||||
flow3 = getWalletTotalBalanceUseCase(wallets.map(UserWallet::walletId)).distinctUntilChanged(),
|
||||
flow4 = loadArtworks(wallets),
|
||||
flow4 = userWalletImageFetcher.walletsImage(wallets, ArtworkSize.SMALL),
|
||||
) { maybeAppCurrency, balanceHidingSettings, maybeBalances, artworks ->
|
||||
createUiModels(
|
||||
wallets = wallets,
|
||||
|
|
@ -90,29 +88,12 @@ internal class DefaultUserWalletsFetcher @AssistedInject constructor(
|
|||
}
|
||||
.flowOn(dispatchers.default)
|
||||
|
||||
private fun loadArtworks(wallets: List<UserWallet>): Flow<HashMap<UserWalletId, ArtworkModel>> {
|
||||
return flow {
|
||||
emit(hashMapOf()) // emits right away so the transform doesn't wait for the images' loading to finish
|
||||
wallets.filterIsInstance<UserWallet.Cold>().forEach { wallet ->
|
||||
val artwork = getCardImageUseCase(
|
||||
cardId = wallet.cardId,
|
||||
manufacturerName = wallet.scanResponse.card.manufacturer.name,
|
||||
firmwareVersion = wallet.scanResponse.card.firmwareVersion.toSdkFirmwareVersion(),
|
||||
cardPublicKey = wallet.scanResponse.card.cardPublicKey,
|
||||
size = ArtworkSize.SMALL,
|
||||
)
|
||||
loadedArtworks[wallet.walletId] = artwork
|
||||
emit(loadedArtworks)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createUiModels(
|
||||
wallets: List<UserWallet>,
|
||||
maybeAppCurrency: Either<SelectedAppCurrencyError, AppCurrency>,
|
||||
maybeBalances: Lce<TokenListError, Map<UserWalletId, TotalFiatBalance>>,
|
||||
balanceHidingSettings: BalanceHidingSettings,
|
||||
artworks: HashMap<UserWalletId, ArtworkModel>,
|
||||
artworks: Map<UserWalletId, UserWalletItemUM.ImageState>,
|
||||
): Lce<Error, ImmutableList<UserWalletItemUM>> = lce {
|
||||
val balances = withError(
|
||||
transform = { Error.UnableToGetBalances },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue