Updated on 2026-08-14
This commit is contained in:
parent
62ddda3e69
commit
7868e94865
20 changed files with 254 additions and 169 deletions
|
|
@ -7,7 +7,7 @@ import androidx.compose.foundation.layout.*
|
|||
import androidx.compose.material3.CardColors
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
|
|
@ -93,7 +93,7 @@ fun UserWalletItem(
|
|||
@Composable
|
||||
private fun NameAndInfo(
|
||||
name: TextReference,
|
||||
information: TextReference,
|
||||
information: UserWalletItemUM.Information,
|
||||
balance: UserWalletItemUM.Balance,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
|
|
@ -113,8 +113,28 @@ private fun NameAndInfo(
|
|||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
AnimatedContent(
|
||||
targetState = information,
|
||||
label = "Information content",
|
||||
) { information ->
|
||||
val informationValue = getInformationValue(information)
|
||||
|
||||
if (informationValue == null) {
|
||||
TextShimmer(
|
||||
style = TangemTheme.typography.caption2,
|
||||
text = "aaaaa",
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
text = informationValue,
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
||||
}
|
||||
Text(
|
||||
text = information.resolveReference() + " $DOT ",
|
||||
text = " $DOT ",
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
maxLines = 1,
|
||||
|
|
@ -203,6 +223,15 @@ fun getBalanceValueAndFlickerState(balance: UserWalletItemUM.Balance): Pair<Stri
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun getInformationValue(information: UserWalletItemUM.Information): String? {
|
||||
return when (information) {
|
||||
UserWalletItemUM.Information.Failed -> DASH_SIGN
|
||||
UserWalletItemUM.Information.Loading -> null
|
||||
is UserWalletItemUM.Information.Loaded -> information.value.resolveReference()
|
||||
}
|
||||
}
|
||||
|
||||
// region Preview
|
||||
@Composable
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
|
|
@ -255,6 +284,15 @@ private class UserWalletItemUMPreviewProvider : PreviewParameterProvider<UserWal
|
|||
endIcon = UserWalletItemUM.EndIcon.Checkmark,
|
||||
onClick = {},
|
||||
),
|
||||
UserWalletItemUM(
|
||||
id = UserWalletId("user_wallet_3".encodeToByteArray()),
|
||||
name = stringReference("Multi Card"),
|
||||
information = UserWalletItemUM.Information.Loading,
|
||||
balance = UserWalletItemUM.Balance.Loading,
|
||||
isEnabled = false,
|
||||
endIcon = UserWalletItemUM.EndIcon.Checkmark,
|
||||
onClick = {},
|
||||
),
|
||||
UserWalletItemUM(
|
||||
id = UserWalletId("user_wallet_3".encodeToByteArray()),
|
||||
name = stringReference("Multi Card"),
|
||||
|
|
@ -279,14 +317,37 @@ private class UserWalletItemUMPreviewProvider : PreviewParameterProvider<UserWal
|
|||
endIcon = UserWalletItemUM.EndIcon.Checkmark,
|
||||
onClick = {},
|
||||
),
|
||||
UserWalletItemUM(
|
||||
id = UserWalletId("user_wallet_3".encodeToByteArray()),
|
||||
name = stringReference("Multi Card"),
|
||||
information = UserWalletItemUM.Information.Loading,
|
||||
balance = UserWalletItemUM.Balance.Loaded(
|
||||
value = "1.2345 BTC",
|
||||
isFlickering = false,
|
||||
),
|
||||
isEnabled = true,
|
||||
onClick = {},
|
||||
),
|
||||
UserWalletItemUM(
|
||||
id = UserWalletId("user_wallet_3".encodeToByteArray()),
|
||||
name = stringReference("Multi Card"),
|
||||
information = UserWalletItemUM.Information.Failed,
|
||||
balance = UserWalletItemUM.Balance.Loaded(
|
||||
value = "1.2345 BTC",
|
||||
isFlickering = false,
|
||||
),
|
||||
isEnabled = true,
|
||||
onClick = {},
|
||||
),
|
||||
)
|
||||
|
||||
private fun getInformation(cardCount: Int): TextReference {
|
||||
return TextReference.PluralRes(
|
||||
private fun getInformation(cardCount: Int): UserWalletItemUM.Information.Loaded {
|
||||
val text = TextReference.PluralRes(
|
||||
id = R.plurals.card_label_card_count,
|
||||
count = cardCount,
|
||||
formatArgs = wrappedList(cardCount),
|
||||
)
|
||||
return UserWalletItemUM.Information.Loaded(text)
|
||||
}
|
||||
}
|
||||
// endregion Preview
|
||||
|
|
@ -53,13 +53,14 @@ class UserWalletItemUMConverter(
|
|||
}
|
||||
}
|
||||
|
||||
private fun getInfo(userWallet: UserWallet): TextReference {
|
||||
private fun getInfo(userWallet: UserWallet): UserWalletItemUM.Information.Loaded {
|
||||
val cardCount = userWallet.getCardsCount() ?: 1
|
||||
return TextReference.PluralRes(
|
||||
val text = TextReference.PluralRes(
|
||||
id = R.plurals.card_label_card_count,
|
||||
count = cardCount,
|
||||
formatArgs = wrappedList(cardCount),
|
||||
)
|
||||
return UserWalletItemUM.Information.Loaded(text)
|
||||
}
|
||||
|
||||
private fun getBalanceInfo(userWallet: UserWallet): UserWalletItemUM.Balance {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import javax.annotation.concurrent.Immutable
|
|||
data class UserWalletItemUM(
|
||||
val id: UserWalletId,
|
||||
val name: TextReference,
|
||||
val information: TextReference,
|
||||
val information: Information,
|
||||
val balance: Balance,
|
||||
val imageState: ImageState = ImageState.Loading,
|
||||
val isEnabled: Boolean,
|
||||
|
|
@ -38,6 +38,17 @@ data class UserWalletItemUM(
|
|||
) : Balance()
|
||||
}
|
||||
|
||||
sealed class Information {
|
||||
|
||||
data object Failed : Information()
|
||||
|
||||
data object Loading : Information()
|
||||
|
||||
data class Loaded(
|
||||
val value: TextReference,
|
||||
) : Information()
|
||||
}
|
||||
|
||||
@Immutable
|
||||
sealed class ImageState {
|
||||
|
||||
|
|
|
|||
|
|
@ -561,6 +561,10 @@
|
|||
<string name="nft_send">NFT senden</string>
|
||||
<string name="nft_traits_title">Eigenschaften</string>
|
||||
<string name="nft_untitled_collection">Unbetitelte Sammlung</string>
|
||||
<plurals name="nft_wallet_count">
|
||||
<item quantity="one"></item>
|
||||
<item quantity="other">%1$d NFTs in der %2$d Sammlung</item>
|
||||
</plurals>
|
||||
<string name="nft_wallet_receive_nft">Tippe hier, um das erste NFT zu erhalten</string>
|
||||
<string name="nft_wallet_title">NFT-Sammlungen</string>
|
||||
<string name="nft_wallet_unable_to_load">Die Daten konnten nicht geladen werden</string>
|
||||
|
|
|
|||
|
|
@ -443,6 +443,8 @@
|
|||
<string name="markets_sort_by_top_gainers_title">Top Ganadores</string>
|
||||
<string name="markets_sort_by_top_losers_title">Top Perdedores</string>
|
||||
<string name="markets_sort_by_trending_title">Tendencias</string>
|
||||
<string name="markets_staking_banner_description_placeholder">Staking es la forma más fácil de recibir recompensas por tus criptomonedas. %s</string>
|
||||
<string name="markets_staking_banner_title">Gana hasta %s APY</string>
|
||||
<string name="markets_token_details_about_token_title">Acerca de %s</string>
|
||||
<plurals name="markets_token_details_amount_exchanges">
|
||||
<item quantity="one">%d intercambio</item>
|
||||
|
|
@ -864,6 +866,11 @@
|
|||
<string name="staking_notification_restake_text">La opción de volver a staking le permite mover sus fondos de un validador a otro sin necesidad de retirarlos.</string>
|
||||
<string name="staking_notification_stake_entire_balance_text">Está a punto de hacer staking con todo su saldo. Recomendamos dejar una cantidad para cubrir las tarifas de la red por unstaking o reclamo de recompensas.</string>
|
||||
<string name="staking_notification_ton_activate_account">Para empezar a hacer staking en TON, realice primero una transacción de salida de cualquier importe - esto activará su billetera.</string>
|
||||
<string name="staking_notification_ton_extra_reserve_info">Es posible que se requieran hasta 0.2 TON además de la tarifa de red para completar la transacción. Cualquier cantidad no utilizada será reembolsada.</string>
|
||||
<string name="staking_notification_ton_extra_reserve_is_required">Se requieren 0.2 TON para realizar esta operación, además de la tarifa de red. Por favor, recargue su saldo.</string>
|
||||
<string name="staking_notification_ton_extra_reserve_title">0.2 Ton Reservado</string>
|
||||
<string name="staking_notification_ton_have_to_unstake_all_text">Esta acción cerrará otras posiciones o las cambiará al estado de retiro, de acuerdo con las reglas de la red.</string>
|
||||
<string name="staking_notification_ton_have_to_unstake_all_title">Estado de las posiciones</string>
|
||||
<string name="staking_notification_unlock_text">Desbloquee su dinero para retirarlo del proceso de staking. El desbloqueo demora %s minuto.</string>
|
||||
<string name="staking_notification_unstake_cosmos_text">Sus fondos estarán disponibles para su uso después del período de desvinculación de 21 días. La recompensa se retirará junto con los fondos de desvinculación.</string>
|
||||
<string name="staking_notification_unstake_text">Sus fondos estarán disponibles para su uso después del período de desvinculación de %s.</string>
|
||||
|
|
|
|||
|
|
@ -443,6 +443,8 @@
|
|||
<string name="markets_sort_by_top_gainers_title">Meilleurs Gagnants</string>
|
||||
<string name="markets_sort_by_top_losers_title">Top Perdants</string>
|
||||
<string name="markets_sort_by_trending_title">Tendances</string>
|
||||
<string name="markets_staking_banner_description_placeholder">Le staking est le moyen le plus simple de recevoir des récompenses sur votre crypto. %s</string>
|
||||
<string name="markets_staking_banner_title">Gagnez jusqu\'à %s APY</string>
|
||||
<string name="markets_token_details_about_token_title">À propos de %s</string>
|
||||
<plurals name="markets_token_details_amount_exchanges">
|
||||
<item quantity="one">%d échange</item>
|
||||
|
|
@ -516,6 +518,10 @@
|
|||
<string name="nft_collections_title">Collections NFT</string>
|
||||
<string name="nft_collections_warning_subtitle">Certaines données peuvent ne pas se charger</string>
|
||||
<string name="nft_collections_warning_title">Problèmes de chargement temporaires</string>
|
||||
<plurals name="nft_wallet_count">
|
||||
<item quantity="one"></item>
|
||||
<item quantity="other">%1$d NFT dans la collection %2$d</item>
|
||||
</plurals>
|
||||
<string name="nft_wallet_receive_nft">Appuyez ici pour recevoir le premier NFT</string>
|
||||
<string name="nft_wallet_title">Collections NFT</string>
|
||||
<string name="nft_wallet_unable_to_load">Impossible de charger les données</string>
|
||||
|
|
@ -873,6 +879,11 @@
|
|||
<string name="staking_notification_restake_text">L\'option de restaker vous permet de déplacer vos fonds d\'un validateur à un autre sans avoir besoin de les déstaker.</string>
|
||||
<string name="staking_notification_stake_entire_balance_text">Vous êtes sur le point de staker l\'intégralité de votre solde. Nous vous recommandons de laisser un petit montant pour couvrir les frais de réseau pour unstaking ou la réclamation des récompenses.</string>
|
||||
<string name="staking_notification_ton_activate_account">Pour commencer à staker TON, effectuez d\'abord une transaction sortante de n\'importe quel montant — cela activera votre portefeuille.</string>
|
||||
<string name="staking_notification_ton_extra_reserve_info">Jusqu\'à 0,2 TON peuvent être requis en plus des frais de réseau pour terminer la transaction. Tout montant non utilisé sera remboursé.</string>
|
||||
<string name="staking_notification_ton_extra_reserve_is_required">0,2 TON requis pour effectuer cette opération, en plus des frais de réseau. Veuillez recharger votre solde.</string>
|
||||
<string name="staking_notification_ton_extra_reserve_title">0,2 Ton réservés</string>
|
||||
<string name="staking_notification_ton_have_to_unstake_all_text">Cette action fermera d\'autres positions ou les fera passer au statut de retrait, conformément aux règles du réseau.</string>
|
||||
<string name="staking_notification_ton_have_to_unstake_all_title">Statut des positions</string>
|
||||
<string name="staking_notification_unlock_text">Débloquez votre argent pour le retirer du processus de staking. Le déverrouillage prend %s.</string>
|
||||
<string name="staking_notification_unstake_cosmos_text">Vos fonds seront disponibles à l\'utilisation après la période de déblocage de 21 jours. La récompense sera retirée en même temps que vos fonds de déblocage.</string>
|
||||
<string name="staking_notification_unstake_text">Vos fonds seront disponibles pour utilisation après la période de désengagement %s.</string>
|
||||
|
|
|
|||
|
|
@ -554,6 +554,9 @@
|
|||
<string name="nft_send">NFTを送信する</string>
|
||||
<string name="nft_traits_title">特徴</string>
|
||||
<string name="nft_untitled_collection">無題のコレクション</string>
|
||||
<plurals name="nft_wallet_count">
|
||||
<item quantity="other">%1$dコレクションの%2$dNFT</item>
|
||||
</plurals>
|
||||
<string name="nft_wallet_receive_nft">ここをタップして最初のNFTを受け取ります</string>
|
||||
<string name="nft_wallet_title">NFTコレクション</string>
|
||||
<string name="nft_wallet_unable_to_load">データを読み込めません</string>
|
||||
|
|
@ -687,6 +690,7 @@
|
|||
<string name="organize_tokens_sort_by_balance">残高順</string>
|
||||
<string name="organize_tokens_title">トークンを整理する</string>
|
||||
<string name="organize_tokens_ungroup">グループ解除</string>
|
||||
<string name="push_notifications_more_info">詳細はこちら</string>
|
||||
<string name="push_notifications_permission_alert_description">Tangemの通知は設定で有効にできます。</string>
|
||||
<string name="push_notifications_permission_alert_negative_button">後で有効にする</string>
|
||||
<string name="push_notifications_permission_alert_positive_button">設定</string>
|
||||
|
|
@ -912,7 +916,7 @@
|
|||
<string name="staking_notification_restake_text">再ステーキングを使うと、ステーキングを解除することなく、あるバリデータから別のバリデータに資金を移動できます。</string>
|
||||
<string name="staking_notification_stake_entire_balance_text">残高のすべてをステーキングしようとしています。ステーキング解除や報酬請求にかかるネットワーク手数料をカバーするために、少額を残しておくことをお勧めします。</string>
|
||||
<string name="staking_notification_ton_activate_account">TONでステーキングを開始するには、まず任意の金額の送金を行ってください。これにより、ウォレットがアクティブになります。</string>
|
||||
<string name="staking_notification_ton_extra_reserve_info">ネットワーク手数料に加え、取引の全ステップを完了するには最大0.2 TONが必要です。未使用分は取引完了後に返金されます。</string>
|
||||
<string name="staking_notification_ton_extra_reserve_info">取引を完了するには、ネットワーク手数料に加えて最大0.2TONが必要になる場合があります。未使用分は返金されます。</string>
|
||||
<string name="staking_notification_ton_extra_reserve_is_required">この操作を続行するには、ネットワーク手数料に加えて0.2 TONが必要です。残高を補充してください。</string>
|
||||
<string name="staking_notification_ton_extra_reserve_title">0.2 TON保留済み</string>
|
||||
<string name="staking_notification_ton_have_to_unstake_all_text">このアクションは、ネットワークのルールに従って、他のポジションをクローズするか、引き出しステータスに切り替えます。</string>
|
||||
|
|
|
|||
|
|
@ -713,6 +713,8 @@
|
|||
<string name="organize_tokens_sort_by_balance">По балансу</string>
|
||||
<string name="organize_tokens_title">Упорядочить токены</string>
|
||||
<string name="organize_tokens_ungroup">Список</string>
|
||||
<string name="push_notifications_more_info">Подробнее</string>
|
||||
<string name="push_notifications_permission_alert_title">Подключить нотификации</string>
|
||||
<string name="qr_scanner_camera_denied_gallery_button">Выбрать из галереи</string>
|
||||
<string name="qr_scanner_camera_denied_settings_button">Настройки</string>
|
||||
<string name="qr_scanner_camera_denied_text">Вы не предоставили доступ к вашей камере</string>
|
||||
|
|
@ -937,9 +939,11 @@
|
|||
<string name="staking_notification_restake_text">Рестейк позволяет вам переместить средства из одного валидатора в другого без необходимости выхода из стейкинга.</string>
|
||||
<string name="staking_notification_stake_entire_balance_text">Вы собираетесь застейкать весь баланс, рекомендуем оставить небольшую сумму для оплаты комиссии сети при выходе из стейкинга или получении награды.</string>
|
||||
<string name="staking_notification_ton_activate_account">Чтобы начать стейкинг в TON, сначала осуществите исходящую транзакцию на любую сумму — это активирует ваш кошелек.</string>
|
||||
<string name="staking_notification_ton_extra_reserve_info">В дополнение к сетевой комиссии может потребоваться до 0.2 TON для завершения всех этапов транзакции. Неиспользованная часть будет возвращена после выполнения.</string>
|
||||
<string name="staking_notification_ton_extra_reserve_info">До 0.2 TON может потребоваться сверх сетевой комиссии для завершения транзакции. Неиспользованная часть будет возвращена.</string>
|
||||
<string name="staking_notification_ton_extra_reserve_is_required">Для выполнения операции требуется дополнительно 0.2 TON, помимо сетевой комиссии. Пожалуйста, пополните баланс.</string>
|
||||
<string name="staking_notification_ton_extra_reserve_title">Зарезервировано 0.2 TON</string>
|
||||
<string name="staking_notification_ton_have_to_unstake_all_text">Это действие закроет другие позиции или переведёт их в статус вывода средств в соответствии с правилами сети.</string>
|
||||
<string name="staking_notification_ton_have_to_unstake_all_title">Статус позиций</string>
|
||||
<string name="staking_notification_unlock_text">Разблокируйте свои средства, чтобы вывести их из стейкинга. Разблокировка займёт %s.</string>
|
||||
<string name="staking_notification_unstake_cosmos_text">Ваши средства будут доступны для использования после 21-дневного периода отзыва. Награда будет выведена вместе с вашими выводими средствами.</string>
|
||||
<string name="staking_notification_unstake_text">Ваши средства будут доступны после %s периода отзыва.</string>
|
||||
|
|
@ -1153,6 +1157,7 @@
|
|||
<string name="wallet_promo_banner_button_title">Получить с 10% скидкой</string>
|
||||
<string name="wallet_promo_banner_description">Получите доступ к более чем 13 000 криптовалют. Покупайте, продавайте, обменивайте и стейкайте в один клик. Свяжите до трех карт для резервного копирования. </string>
|
||||
<string name="wallet_promo_banner_title">Откройте Tangem Wallet</string>
|
||||
<string name="wallet_settings_push_notifications_title">Уведомления о транзакциях</string>
|
||||
<string name="wallet_settings_title">Настройки кошелька</string>
|
||||
<string name="wallet_title">Tangem</string>
|
||||
<string name="warning_access_denied_message">Используйте %s или отсканируйте карту/кольцо, чтобы разблокировать доступ к вашему кошельку</string>
|
||||
|
|
|
|||
|
|
@ -65,6 +65,10 @@
|
|||
<item quantity="one">%d device</item>
|
||||
<item quantity="other">%d devices</item>
|
||||
</plurals>
|
||||
<plurals name="card_label_token_count">
|
||||
<item quantity="one">%d token</item>
|
||||
<item quantity="other">%d tokens</item>
|
||||
</plurals>
|
||||
<string name="card_settings_access_code_recovery_disabled_description">Disable this option if you don\'t want this card to be used to reset access codes on other cards or rings in this wallet. Please note that this will also prevent you from resetting the access code on this card.</string>
|
||||
<string name="card_settings_access_code_recovery_enabled_description">Allows you to use this card to reset access code on other cards in this wallet</string>
|
||||
<string name="card_settings_access_code_recovery_title">Access code recovery</string>
|
||||
|
|
@ -929,7 +933,7 @@
|
|||
<string name="staking_notification_restake_text">Restake lets you move your funds from one validator to another without the need to unstake</string>
|
||||
<string name="staking_notification_stake_entire_balance_text">You’re about to stake your entire balance. We recommend leaving a small amount to cover network fees for unstaking or claiming rewards.</string>
|
||||
<string name="staking_notification_ton_activate_account">To start staking in TON, first make an outgoing transaction of any amount — this will activate your wallet.</string>
|
||||
<string name="staking_notification_ton_extra_reserve_info">In addition to the network fee, up to 0.2 TON is needed to complete all steps of the transaction. Unused amount will be returned after it\'s finished.</string>
|
||||
<string name="staking_notification_ton_extra_reserve_info">Up to 0.2 TON may be required in addition to the network fee to complete the transaction. Any unused amount will be refunded.</string>
|
||||
<string name="staking_notification_ton_extra_reserve_is_required">0.2 TON is required to proceed with this operation, in addition to the network fee. Please top up your balance.</string>
|
||||
<string name="staking_notification_ton_extra_reserve_title">0.2 Ton Reserved</string>
|
||||
<string name="staking_notification_ton_have_to_unstake_all_text">This action will close other positions or switch them to withdrawal status, according to network rules.</string>
|
||||
|
|
@ -1215,7 +1219,7 @@
|
|||
<string name="wallet_promo_banner_description">Access 13,000+ cryptocurrencies. Buy, sell, swap, and stake with a single tap.\nLink up to three cards for a backup.</string>
|
||||
<string name="wallet_promo_banner_title">Discover Tangem Wallet</string>
|
||||
<string name="wallet_settings_push_notifications_description">Stay notified on wallet incoming transactions and Tangem updates.</string>
|
||||
<string name="wallet_settings_push_notifications_title">Push Notifications</string>
|
||||
<string name="wallet_settings_push_notifications_title">Transaction Notifications</string>
|
||||
<string name="wallet_settings_title">Wallet settings</string>
|
||||
<string name="wallet_title">Tangem</string>
|
||||
<string name="warning_access_denied_message">Use %s or scan a card/ring to unlock access to your wallet</string>
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ dependencies {
|
|||
|
||||
/* Project - API */
|
||||
implementation(projects.features.details.api)
|
||||
implementation(projects.features.wallet.api)
|
||||
implementation(projects.features.disclaimer.api)
|
||||
implementation(projects.features.tester.api)
|
||||
|
||||
|
|
|
|||
|
|
@ -77,11 +77,12 @@ internal class PreviewUserWalletListComponent : UserWalletListComponent {
|
|||
}
|
||||
}
|
||||
|
||||
private fun getInformation(cardCount: Int): TextReference {
|
||||
return TextReference.PluralRes(
|
||||
private fun getInformation(cardCount: Int): UserWalletItemUM.Information.Loaded {
|
||||
val text = TextReference.PluralRes(
|
||||
id = R.plurals.card_label_card_count,
|
||||
count = cardCount,
|
||||
formatArgs = wrappedList(cardCount),
|
||||
)
|
||||
return UserWalletItemUM.Information.Loaded(text)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,18 @@
|
|||
package com.tangem.features.details.model
|
||||
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.features.details.entity.UserWalletListUM
|
||||
import com.tangem.features.details.impl.R
|
||||
import com.tangem.features.details.utils.UserWalletSaver
|
||||
import com.tangem.features.details.utils.UserWalletsFetcher
|
||||
import com.tangem.features.wallet.utils.UserWalletsFetcher
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
|
@ -21,13 +24,17 @@ import javax.inject.Inject
|
|||
|
||||
@ModelScoped
|
||||
internal class UserWalletListModel @Inject constructor(
|
||||
userWalletsFetcher: UserWalletsFetcher,
|
||||
userWalletsFetcherFactory: UserWalletsFetcher.Factory,
|
||||
shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
|
||||
private val router: Router,
|
||||
private val messageSender: UiMessageSender,
|
||||
private val userWalletSaver: UserWalletSaver,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
) : Model() {
|
||||
|
||||
private val isWalletSavingInProgress: MutableStateFlow<Boolean> = MutableStateFlow(value = false)
|
||||
private val userWalletsFetcher = userWalletsFetcherFactory
|
||||
.create(messageSender) { userWalletId -> router.push(AppRoute.WalletSettings(userWalletId)) }
|
||||
|
||||
val state: MutableStateFlow<UserWalletListUM> = MutableStateFlow(
|
||||
value = UserWalletListUM(
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
|||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.rows.model.BlockchainRowUM
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.features.markets.impl.R
|
||||
|
|
@ -25,7 +26,7 @@ internal class PreviewAddToPortfolioBSContentProvider : PreviewParameterProvider
|
|||
val userWallet = UserWalletItemUM(
|
||||
id = UserWalletId("1"),
|
||||
name = stringReference("Wallet 1"),
|
||||
information = stringReference("3 cards"),
|
||||
information = UserWalletItemUM.Information.Loaded(TextReference.Str("3 cards")),
|
||||
balance = UserWalletItemUM.Balance.Loading,
|
||||
isEnabled = true,
|
||||
endIcon = UserWalletItemUM.EndIcon.Arrow,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,14 @@ dependencies {
|
|||
/** AndroidX */
|
||||
implementation(deps.androidx.fragment.ktx)
|
||||
|
||||
/** Project - Domain */
|
||||
implementation(projects.domain.wallets.models)
|
||||
|
||||
/** Core */
|
||||
implementation(projects.core.ui)
|
||||
implementation(projects.core.decompose)
|
||||
implementation(projects.common.ui)
|
||||
|
||||
/** Other */
|
||||
implementation(deps.kotlin.immutable.collections)
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.tangem.features.wallet.utils
|
||||
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface UserWalletsFetcher {
|
||||
|
||||
val userWallets: Flow<ImmutableList<UserWalletItemUM>>
|
||||
|
||||
interface Factory {
|
||||
fun create(messageSender: UiMessageSender, onWalletClick: (UserWalletId) -> Unit): UserWalletsFetcher
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,9 @@ 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.DefaultUserWalletsFetcher
|
||||
import com.tangem.features.wallet.WalletEntryComponent
|
||||
import com.tangem.features.wallet.utils.UserWalletsFetcher
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -19,6 +21,9 @@ internal interface WalletFeatureModule {
|
|||
@Binds
|
||||
fun bindComponentFactory(impl: DefaultWalletEntryComponent.Factory): WalletEntryComponent.Factory
|
||||
|
||||
@Binds
|
||||
fun bindUserWalletsFetcher(impl: DefaultUserWalletsFetcher.Factory): UserWalletsFetcher.Factory
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(WalletModel::class)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
package com.tangem.features.details.utils
|
||||
package com.tangem.feature.wallet.utils
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.ui.userwallet.converter.UserWalletItemUMConverter
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
|
|
@ -15,6 +12,7 @@ import com.tangem.domain.appcurrency.model.AppCurrency
|
|||
import com.tangem.domain.balancehiding.BalanceHidingSettings
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.core.lce.Lce
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.domain.core.lce.lce
|
||||
import com.tangem.domain.core.utils.getOrElse
|
||||
import com.tangem.domain.core.utils.toLce
|
||||
|
|
@ -26,31 +24,32 @@ import com.tangem.domain.wallets.models.UserWallet
|
|||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.GetCardImageUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.features.details.impl.R
|
||||
import com.tangem.features.wallet.utils.UserWalletsFetcher
|
||||
import com.tangem.operations.attestation.ArtworkSize
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.*
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@ModelScoped
|
||||
internal class UserWalletsFetcher @Inject constructor(
|
||||
internal class DefaultUserWalletsFetcher @AssistedInject constructor(
|
||||
getWalletsUseCase: GetWalletsUseCase,
|
||||
private val getWalletTotalBalanceUseCase: GetWalletTotalBalanceUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
private val router: Router,
|
||||
private val messageSender: UiMessageSender,
|
||||
@Assisted private val onWalletClick: (UserWalletId) -> Unit,
|
||||
@Assisted private val messageSender: UiMessageSender,
|
||||
private val getCardImageUseCase: GetCardImageUseCase,
|
||||
) {
|
||||
) : UserWalletsFetcher {
|
||||
|
||||
private var loadedArtworks: HashMap<UserWalletId, ArtworkModel> = hashMapOf()
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
val userWallets: Flow<ImmutableList<UserWalletItemUM>> = getWalletsUseCase().transformLatest { wallets ->
|
||||
val uiModels = UserWalletItemUMConverter(onClick = ::navigateToWalletSettings).convertList(wallets)
|
||||
override val userWallets: Flow<ImmutableList<UserWalletItemUM>> = getWalletsUseCase().transformLatest { wallets ->
|
||||
val uiModels = UserWalletItemUMConverter(onClick = { onWalletClick(it) }).convertList(wallets)
|
||||
.toImmutableList()
|
||||
|
||||
emit(uiModels)
|
||||
|
|
@ -122,7 +121,7 @@ internal class UserWalletsFetcher @Inject constructor(
|
|||
balances
|
||||
.map { (userWallet, balance) ->
|
||||
UserWalletItemUMConverter(
|
||||
onClick = ::navigateToWalletSettings,
|
||||
onClick = { onWalletClick(it) },
|
||||
appCurrency = appCurrency,
|
||||
balance = balance,
|
||||
isBalanceHidden = balanceHidingSettings.isBalanceHidden,
|
||||
|
|
@ -133,14 +132,18 @@ internal class UserWalletsFetcher @Inject constructor(
|
|||
.toImmutableList()
|
||||
}
|
||||
|
||||
private fun navigateToWalletSettings(userWalletId: UserWalletId) {
|
||||
router.push(AppRoute.WalletSettings(userWalletId))
|
||||
}
|
||||
|
||||
sealed class Error {
|
||||
|
||||
data object UnableToGetAppCurrency : Error()
|
||||
|
||||
data object UnableToGetBalances : Error()
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : UserWalletsFetcher.Factory {
|
||||
override fun create(
|
||||
messageSender: UiMessageSender,
|
||||
onWalletClick: (UserWalletId) -> Unit,
|
||||
): DefaultUserWalletsFetcher
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,9 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
|||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
|
@ -138,6 +140,7 @@ private fun WcSelectWalletContent(
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO)
|
||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
|
|
@ -165,7 +168,7 @@ private fun WcSelectWalletContent_Preview() {
|
|||
UserWalletItemUM(
|
||||
id = UserWalletId("user_wallet_1".encodeToByteArray()),
|
||||
name = stringReference("Tangem 2.0"),
|
||||
information = stringReference("42 tokens"),
|
||||
information = getInformation(42),
|
||||
balance = UserWalletItemUM.Balance.Loaded("1 496,34 \$", isFlickering = false),
|
||||
isEnabled = true,
|
||||
onClick = {},
|
||||
|
|
@ -173,7 +176,7 @@ private fun WcSelectWalletContent_Preview() {
|
|||
UserWalletItemUM(
|
||||
id = UserWalletId("user_wallet_2".encodeToByteArray()),
|
||||
name = stringReference("Tangem White"),
|
||||
information = stringReference("24 tokens"),
|
||||
information = getInformation(24),
|
||||
balance = UserWalletItemUM.Balance.Loaded("1 496,34 \$", isFlickering = false),
|
||||
isEnabled = true,
|
||||
onClick = {},
|
||||
|
|
@ -181,7 +184,7 @@ private fun WcSelectWalletContent_Preview() {
|
|||
UserWalletItemUM(
|
||||
id = UserWalletId("user_wallet_3".encodeToByteArray()),
|
||||
name = stringReference("Bitcoin"),
|
||||
information = stringReference("1 token"),
|
||||
information = getInformation(1),
|
||||
balance = UserWalletItemUM.Balance.Loaded("1 496,34 \$", isFlickering = false),
|
||||
isEnabled = true,
|
||||
onClick = {},
|
||||
|
|
@ -189,7 +192,23 @@ private fun WcSelectWalletContent_Preview() {
|
|||
UserWalletItemUM(
|
||||
id = UserWalletId("user_wallet_4".encodeToByteArray()),
|
||||
name = stringReference("Tangem 1.0"),
|
||||
information = stringReference("21 tokens"),
|
||||
information = getInformation(21),
|
||||
balance = UserWalletItemUM.Balance.Loaded("1 496,34 \$", isFlickering = false),
|
||||
isEnabled = true,
|
||||
onClick = {},
|
||||
),
|
||||
UserWalletItemUM(
|
||||
id = UserWalletId("user_wallet_4".encodeToByteArray()),
|
||||
name = stringReference("Tangem 1.0"),
|
||||
information = UserWalletItemUM.Information.Loading,
|
||||
balance = UserWalletItemUM.Balance.Loaded("1 496,34 \$", isFlickering = false),
|
||||
isEnabled = true,
|
||||
onClick = {},
|
||||
),
|
||||
UserWalletItemUM(
|
||||
id = UserWalletId("user_wallet_4".encodeToByteArray()),
|
||||
name = stringReference("Tangem 1.0"),
|
||||
information = UserWalletItemUM.Information.Failed,
|
||||
balance = UserWalletItemUM.Balance.Loaded("1 496,34 \$", isFlickering = false),
|
||||
isEnabled = true,
|
||||
onClick = {},
|
||||
|
|
@ -199,4 +218,13 @@ private fun WcSelectWalletContent_Preview() {
|
|||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getInformation(tokenCount: Int): UserWalletItemUM.Information.Loaded {
|
||||
val text = TextReference.PluralRes(
|
||||
id = R.plurals.card_label_token_count,
|
||||
count = tokenCount,
|
||||
formatArgs = wrappedList(tokenCount),
|
||||
)
|
||||
return UserWalletItemUM.Information.Loaded(text)
|
||||
}
|
||||
|
|
@ -6,12 +6,9 @@ import com.tangem.core.decompose.model.Model
|
|||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.tokens.GetWalletTotalBalanceUseCase
|
||||
import com.tangem.domain.tokens.GetTokenListUseCase
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.GetCardImageUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.features.wallet.utils.UserWalletsFetcher
|
||||
import com.tangem.features.walletconnect.connections.components.WcSelectWalletComponent.WcSelectWalletParams
|
||||
import com.tangem.features.walletconnect.connections.entity.WcAppInfoWalletUM
|
||||
import com.tangem.features.walletconnect.connections.utils.WcUserWalletsFetcher
|
||||
|
|
@ -25,12 +22,9 @@ import javax.inject.Inject
|
|||
@ModelScoped
|
||||
internal class WcSelectWalletModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
getWalletsUseCase: GetWalletsUseCase,
|
||||
getWalletTotalBalanceUseCase: GetWalletTotalBalanceUseCase,
|
||||
getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
messageSender: UiMessageSender,
|
||||
getCardImageUseCase: GetCardImageUseCase,
|
||||
userWalletsFetcherFactory: UserWalletsFetcher.Factory,
|
||||
getTokenListUseCase: GetTokenListUseCase,
|
||||
private val router: Router,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
) : Model() {
|
||||
|
|
@ -46,12 +40,9 @@ internal class WcSelectWalletModel @Inject constructor(
|
|||
)
|
||||
|
||||
private val userWalletsFetcher = WcUserWalletsFetcher(
|
||||
getWalletsUseCase = getWalletsUseCase,
|
||||
getWalletTotalBalanceUseCase = getWalletTotalBalanceUseCase,
|
||||
getSelectedAppCurrencyUseCase = getSelectedAppCurrencyUseCase,
|
||||
getBalanceHidingSettingsUseCase = getBalanceHidingSettingsUseCase,
|
||||
userWalletsFetcherFactory = userWalletsFetcherFactory,
|
||||
getTokenListUseCase = getTokenListUseCase,
|
||||
messageSender = messageSender,
|
||||
getCardImageUseCase = getCardImageUseCase,
|
||||
onWalletSelected = ::onWalletSelected,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,140 +1,57 @@
|
|||
package com.tangem.features.walletconnect.connections.utils
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.common.ui.userwallet.converter.UserWalletItemUMConverter
|
||||
import com.tangem.common.ui.R
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.error.SelectedAppCurrencyError
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.balancehiding.BalanceHidingSettings
|
||||
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.getOrElse
|
||||
import com.tangem.domain.core.utils.toLce
|
||||
import com.tangem.domain.models.ArtworkModel
|
||||
import com.tangem.domain.tokens.GetWalletTotalBalanceUseCase
|
||||
import com.tangem.domain.tokens.error.TokenListError
|
||||
import com.tangem.domain.tokens.model.TotalFiatBalance
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.domain.tokens.GetTokenListUseCase
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.GetCardImageUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
import com.tangem.operations.attestation.ArtworkSize
|
||||
import com.tangem.features.wallet.utils.UserWalletsFetcher
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@ModelScoped
|
||||
internal class WcUserWalletsFetcher(
|
||||
getWalletsUseCase: GetWalletsUseCase,
|
||||
private val getWalletTotalBalanceUseCase: GetWalletTotalBalanceUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
private val messageSender: UiMessageSender,
|
||||
private val getCardImageUseCase: GetCardImageUseCase,
|
||||
userWalletsFetcherFactory: UserWalletsFetcher.Factory,
|
||||
messageSender: UiMessageSender,
|
||||
private val getTokenListUseCase: GetTokenListUseCase,
|
||||
private val onWalletSelected: (UserWalletId) -> Unit,
|
||||
) {
|
||||
|
||||
private var loadedArtworks: HashMap<UserWalletId, ArtworkModel> = hashMapOf()
|
||||
private val userWalletsFetcher = userWalletsFetcherFactory.create(messageSender) { onWalletSelected(it) }
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
val userWallets: Flow<ImmutableList<UserWalletItemUM>> = getWalletsUseCase().transformLatest { wallets ->
|
||||
val uiModels = UserWalletItemUMConverter(onClick = onWalletSelected)
|
||||
.convertList(wallets)
|
||||
.toImmutableList()
|
||||
val userWallets: Flow<ImmutableList<UserWalletItemUM>> = userWalletsFetcher.userWallets
|
||||
.flatMapLatest { listOfWalletItem ->
|
||||
val flows = listOfWalletItem.map(::getTokenListFlow)
|
||||
combine(flows) { it.toList().toImmutableList() }
|
||||
}
|
||||
|
||||
emit(uiModels)
|
||||
combine(
|
||||
flow = getSelectedAppCurrencyUseCase().distinctUntilChanged(),
|
||||
flow2 = getBalanceHidingSettingsUseCase().distinctUntilChanged(),
|
||||
flow3 = getWalletTotalBalanceUseCase(wallets.map(UserWallet::walletId)).distinctUntilChanged(),
|
||||
flow4 = loadArtworks(wallets),
|
||||
) { maybeAppCurrency, balanceHidingSettings, maybeBalances, artworks ->
|
||||
val models = createUiModels(
|
||||
wallets = wallets,
|
||||
maybeAppCurrency = maybeAppCurrency,
|
||||
maybeBalances = maybeBalances,
|
||||
balanceHidingSettings = balanceHidingSettings,
|
||||
artworks = artworks,
|
||||
).getOrElse(
|
||||
ifLoading = { return@combine },
|
||||
ifError = {
|
||||
val message = resourceReference(R.string.common_unknown_error)
|
||||
messageSender.send(SnackbarMessage(message))
|
||||
|
||||
return@combine
|
||||
},
|
||||
private fun getTokenListFlow(walletItem: UserWalletItemUM): Flow<UserWalletItemUM> {
|
||||
return getTokenListUseCase.launch(walletItem.id).map { lce ->
|
||||
val information = lce.fold(
|
||||
ifLoading = { UserWalletItemUM.Information.Loading },
|
||||
ifError = { UserWalletItemUM.Information.Failed },
|
||||
ifContent = { tokenList -> tokenCountInfo(tokenList.flattenCurrencies().size) },
|
||||
)
|
||||
|
||||
emit(models)
|
||||
}.collect()
|
||||
}
|
||||
|
||||
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.forEach { wallet ->
|
||||
val card = wallet.scanResponse.card
|
||||
val artwork = getCardImageUseCase(
|
||||
cardId = wallet.cardId,
|
||||
cardPublicKey = card.cardPublicKey,
|
||||
size = ArtworkSize.SMALL,
|
||||
manufacturerName = card.manufacturer.name,
|
||||
firmwareVersion = card.firmwareVersion.toSdkFirmwareVersion(),
|
||||
)
|
||||
loadedArtworks[wallet.walletId] = artwork
|
||||
emit(loadedArtworks)
|
||||
}
|
||||
walletItem.copy(information = information)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createUiModels(
|
||||
wallets: List<UserWallet>,
|
||||
maybeAppCurrency: Either<SelectedAppCurrencyError, AppCurrency>,
|
||||
maybeBalances: Lce<TokenListError, Map<UserWalletId, TotalFiatBalance>>,
|
||||
balanceHidingSettings: BalanceHidingSettings,
|
||||
artworks: HashMap<UserWalletId, ArtworkModel>,
|
||||
): Lce<Error, ImmutableList<UserWalletItemUM>> = lce {
|
||||
val balances = withError(
|
||||
transform = { Error.UnableToGetBalances },
|
||||
block = {
|
||||
maybeBalances.bindOrNull().orEmpty()
|
||||
.filterKeys { userWalletId -> wallets.any { it.walletId == userWalletId } }
|
||||
.mapKeys { entry -> wallets.first { it.walletId == entry.key } }
|
||||
},
|
||||
private fun tokenCountInfo(count: Int): UserWalletItemUM.Information.Loaded {
|
||||
val text = TextReference.PluralRes(
|
||||
id = R.plurals.card_label_token_count,
|
||||
count = count,
|
||||
formatArgs = wrappedList(count),
|
||||
)
|
||||
|
||||
val appCurrency = withError(
|
||||
transform = { Error.UnableToGetAppCurrency },
|
||||
block = { maybeAppCurrency.toLce().bind() },
|
||||
)
|
||||
|
||||
balances
|
||||
.map { (userWallet, balance) ->
|
||||
UserWalletItemUMConverter(
|
||||
onClick = onWalletSelected,
|
||||
appCurrency = appCurrency,
|
||||
balance = balance,
|
||||
isBalanceHidden = balanceHidingSettings.isBalanceHidden,
|
||||
artwork = artworks[userWallet.walletId],
|
||||
)
|
||||
.convert(userWallet)
|
||||
}
|
||||
.toImmutableList()
|
||||
}
|
||||
|
||||
sealed class Error {
|
||||
|
||||
data object UnableToGetAppCurrency : Error()
|
||||
|
||||
data object UnableToGetBalances : Error()
|
||||
return UserWalletItemUM.Information.Loaded(text)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue