diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index 0ce8ca7272..7469eea102 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -1,13 +1,13 @@ Token nicht in Deinem Portfolio gefunden? Überprüfe die Märkte, um es zu finden und zum Kauf hinzuzufügen - Token nicht in Deinem Portfolio gefunden? Überprüfe die Märkte, um es zu finden und zum Verkauf hinzuzufügen + Token nicht in Ihrem Portfolio gefunden? Überprüfe die Märkte, um es zu finden und zum Verkauf hinzuzufügen Wähle den Token Token nicht in Deinem Portfolio gefunden? Überprüfe die Märkte, um es für Swaps zu finden und hinzuzufügen Es gibt keine verfügbaren Token, die mit dem ausgewählten Token getauscht werden können. Bitte wähle einen anderen. Kein verfügbares Paar - Du möchtest erhalten - Du möchtest tauschen + Wähle den Token aus, das Du erhalten möchtest + Wähle den Token, den Du tauschen möchtest Netzwerk wählen Token anlegen Token verwalten diff --git a/core/res/src/main/res/values-es/strings.xml b/core/res/src/main/res/values-es/strings.xml index 38c53c5104..24e4fe0863 100644 --- a/core/res/src/main/res/values-es/strings.xml +++ b/core/res/src/main/res/values-es/strings.xml @@ -6,8 +6,6 @@ ¿No encuentras el token en tu billetera? Consulte los mercados para encontrarlo y agregarlo al intercambio No hay tokens disponibles para intercambiar con el token seleccionado. Por favor elige otro. No hay par disponible - Desea recibir - Quiere intercambiar Elige red Agregue un token personalizado Gestionar tokens diff --git a/core/res/src/main/res/values-fr/strings.xml b/core/res/src/main/res/values-fr/strings.xml index e6010bdeda..2b0fc6e1be 100644 --- a/core/res/src/main/res/values-fr/strings.xml +++ b/core/res/src/main/res/values-fr/strings.xml @@ -6,8 +6,6 @@ Jeton non trouvé dans votre portefeuille ? Consultez les marchés pour le trouver et l\'ajouter à l\'échange Il n\'y a pas de token disponible pour échanger avec le token sélectionné. Veuillez en choisir un autre. Aucune paire disponible - Vous souhaitez recevoir - Vous souhaitez échanger Choisissez le réseau Ajouter un jeton personnalisé Gérer les jetons diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index fa0b45908d..2436c1ed9f 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -2,12 +2,13 @@ ポートフォリオにトークンが見つかりませんか?マーケットから見つけ、買付のために追加してください ポートフォリオにトークンが見つかりませんか?マーケットから見つけ、売却のために追加してください + 暗号資産を売却 トークンを選択 ポートフォリオにトークンが見つかりませんか?マーケットから見つけ、スワップのために追加してください 選択したトークンと交換できるトークンがありません。別のトークンを選択してください。 利用可能なペアがありません - 受け取りたい - 交換したい + 受け取りたいトークンを選択します + スワップしたいトークンを選択します ネットワークを選択 カスタムトークンの追加 トークンの管理 diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index dfbc4e21cc..b39fdb0286 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -1,10 +1,14 @@ + Не нашли свой токен? Перейдите в раздел «Рынок» на главной странице и добавьте его в свой портфель для покупки. + Не нашли свой токен? Перейдите в раздел «Рынок» на главной странице и добавьте его в свой портфель для продажи. + Продать криптовалюту Выберите токен - Нет доступных токенов для обмена с выбранным токеном, пожалуйста, выберите другой. + Не нашли свой токен? Перейдите в раздел «Рынок» на главной странице и добавьте его в свой портфель для обмена. + Нет доступных вариантов для обмена с выбранным токеном, пожалуйста, выберите другой. Нет доступных пар - Вы хотите получить - Вы хотите обменять + Выберите токен для получения + Выберите токен для обмена Выберите сеть Добавить токен Валюты @@ -652,6 +656,10 @@ Сканировать Отсканируйте карту или кольцо, чтобы изменить ее настройки. Изменения затронут только ту карту или кольцо, которые вы отсканировали, и не повлияют на другие устройства, привязанные к вашему кошельку. Приготовьте свой Tangem! + На вашем балансе недостаточно средств для продажи этой криптовалюты. Пожалуйста, пополните нужный актив, чтобы продолжить. + Недостаточно средств + Продажа криптовалюты в вашем регионе временно недоступна. Мы активно работаем над тем, чтобы добавить эту возможность. Следите за нашими новостями! + Региональные ограничения Уже содержится во введенном адресе Сумма комиссии в %s раз превышает рекомендованную. Убедитесь, что указанная комиссия верна. Вы указали комиссию ниже рекомендуемой, это может привести к задержке исполнения вашей транзакции. Продолжить? diff --git a/core/res/src/main/res/values-uk-rUA/strings.xml b/core/res/src/main/res/values-uk-rUA/strings.xml index 25e1a4419d..0422f45055 100644 --- a/core/res/src/main/res/values-uk-rUA/strings.xml +++ b/core/res/src/main/res/values-uk-rUA/strings.xml @@ -6,8 +6,6 @@ Токен не знайдено у вашому портфелі? Перевірте ринки, щоб знайти та додати його для обміну Немає доступних токенів для обміну з обраним токеном. Будь ласка, оберіть інший. Немає вільної пари - Ви хочете отримати - Ви хочете обміняти Оберіть мережу Додати токен Токени diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 5ee169bd92..3b501160aa 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -1,13 +1,14 @@ - Token not found in your portfolio? Check the Markets to find and add it for purchase - Token not found in your portfolio? Check the Markets to find and add it for selling + Can’t find your token? Go to the Market section on the main page and add it to your portfolio for purchase + Can’t find your token? Go to the Market section on the main page and add it to your portfolio for selling. + Sell crypto Choose the Token - Token not found in your portfolio? Check the Markets to find and add it for swap + Can’t find your token? Go to the Market section on the main page and add it to your portfolio for swapping. There are no available tokens to swap with the selected token. Please choose another one. No available pair - You want to Receive - You want to Swap + Choose the token you want to receive + Choose the token you want to swap Choose network Add custom token Manage tokens @@ -647,6 +648,10 @@ Scan card or ring Scan the card or ring to change its settings. The changes will impact only the card or ring you\'ve scanned and will not affect other devices tied to your wallet. Get your Tangem ready! + You don’t have enough funds in your balance to sell this cryptocurrency. Please deposit the desired asset to proceed. + Insufficient Balance + Selling cryptocurrency is unavailable in your region at the moment. We’re actively working to bring this option to you soon—stay tuned! + Regional Restriction Already included in the entered address Your commission amount is %s times higher than the recommended amount. Please review and adjust your custom settings. You specified a commission below the recommended amount, which could cause a delay in your transaction. Continue? diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt index 99a762cea6..129a6ff281 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt @@ -35,6 +35,7 @@ internal object WalletPreviewData { onRenameClick = { _ -> }, onDeleteClick = {}, cardCount = 1, + isZeroBalance = false, ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/preview/WalletScreenPreviewData.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/preview/WalletScreenPreviewData.kt index 8082bd05e2..fcff8bb806 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/preview/WalletScreenPreviewData.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/preview/WalletScreenPreviewData.kt @@ -110,6 +110,7 @@ internal object WalletScreenPreviewData { balance = DASH_SIGN, onRenameClick = { _ -> }, onDeleteClick = {}, + isZeroBalance = false, ) } private val multiWalletState by lazy { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoader.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoader.kt index 9a11997960..6b1652a33a 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoader.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoader.kt @@ -1,7 +1,6 @@ package com.tangem.feature.wallet.presentation.wallet.loaders.implementors import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase -import com.tangem.domain.exchange.RampStateManager import com.tangem.domain.tokens.ApplyTokenListSortingUseCase import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase import com.tangem.domain.wallets.models.UserWallet @@ -11,12 +10,10 @@ import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarnin import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenListStore import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController -import com.tangem.feature.wallet.presentation.wallet.subscribers.MultiWalletActionsSubscriber import com.tangem.feature.wallet.presentation.wallet.subscribers.MultiWalletTokenListSubscriber import com.tangem.feature.wallet.presentation.wallet.subscribers.MultiWalletWarningsSubscriber import com.tangem.feature.wallet.presentation.wallet.subscribers.WalletSubscriber import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents -import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles @Suppress("LongParameterList") internal class MultiWalletContentLoader( @@ -31,8 +28,6 @@ internal class MultiWalletContentLoader( private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase, private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory, private val runPolkadotAccountHealthCheckUseCase: RunPolkadotAccountHealthCheckUseCase, - private val rampStateManager: RampStateManager, - private val walletFeatureToggles: WalletFeatureToggles, ) : WalletContentLoader(id = userWallet.walletId) { override fun create(): List { @@ -55,16 +50,6 @@ internal class MultiWalletContentLoader( getMultiWalletWarningsFactory = getMultiWalletWarningsFactory, walletWarningsAnalyticsSender = walletWarningsAnalyticsSender, ), - createMultiWalletButtonsSubscriber(), ) } - - private fun createMultiWalletButtonsSubscriber(): MultiWalletActionsSubscriber? { - return MultiWalletActionsSubscriber( - userWallet = userWallet, - rampStateManager = rampStateManager, - stateController = stateHolder, - ) - .takeIf { walletFeatureToggles.isMainActionButtonsEnabled } - } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoaderFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoaderFactory.kt index 5bc11a8b00..7a70b865b2 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoaderFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoaderFactory.kt @@ -1,7 +1,6 @@ package com.tangem.feature.wallet.presentation.wallet.loaders.implementors import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase -import com.tangem.domain.exchange.RampStateManager import com.tangem.domain.tokens.ApplyTokenListSortingUseCase import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase import com.tangem.domain.wallets.models.UserWallet @@ -12,7 +11,6 @@ import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenList import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents -import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles import dagger.hilt.android.scopes.ViewModelScoped import javax.inject.Inject @@ -28,8 +26,6 @@ internal class MultiWalletContentLoaderFactory @Inject constructor( private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase, private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender, private val runPolkadotAccountHealthCheckUseCase: RunPolkadotAccountHealthCheckUseCase, - private val rampStateManager: RampStateManager, - private val walletFeatureToggles: WalletFeatureToggles, ) { fun create(userWallet: UserWallet, clickIntents: WalletClickIntents): WalletContentLoader { @@ -45,8 +41,6 @@ internal class MultiWalletContentLoaderFactory @Inject constructor( walletWarningsAnalyticsSender = walletWarningsAnalyticsSender, applyTokenListSortingUseCase = applyTokenListSortingUseCase, runPolkadotAccountHealthCheckUseCase = runPolkadotAccountHealthCheckUseCase, - rampStateManager = rampStateManager, - walletFeatureToggles = walletFeatureToggles, ) } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletAlertState.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletAlertState.kt index 03fb7f7902..f43173acd0 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletAlertState.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletAlertState.kt @@ -83,4 +83,32 @@ internal sealed interface WalletAlertState { ) override val onConfirmClick: (() -> Unit)? = null } + + data object ProvidersStillLoading : Basic() { + override val title: TextReference = stringReference(value = "Providers are still loading") + override val message: TextReference = resourceReference(R.string.wallet_connect_toast_awaiting_session_proposal) + override val onConfirmClick: (() -> Unit)? = null + } + + data object UnavailableOperation : Basic() { + override val title: TextReference = stringReference(value = "This operation is currently unavailable") + override val message: TextReference = resourceReference(R.string.warning_some_networks_unreachable_message) + override val onConfirmClick: (() -> Unit)? = null + } + + data object SellingRegionalRestriction : Basic() { + override val title: TextReference = resourceReference(id = R.string.selling_regional_restriction_alert_title) + override val message: TextReference = + resourceReference(id = R.string.selling_regional_restriction_alert_message) + + override val onConfirmClick: (() -> Unit)? = null + } + + data object InsufficientBalanceForSelling : Basic() { + override val title: TextReference = resourceReference(id = R.string.selling_insufficient_balance_alert_title) + override val message: TextReference = + resourceReference(id = R.string.selling_insufficient_balance_alert_message) + + override val onConfirmClick: (() -> Unit)? = null + } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletCardState.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletCardState.kt index 69b9b48fb1..76fa712a77 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletCardState.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletCardState.kt @@ -50,6 +50,7 @@ internal sealed interface WalletCardState { override val onDeleteClick: (UserWalletId) -> Unit, val cardCount: Int?, val balance: String, + val isZeroBalance: Boolean?, ) : WalletCardState /** diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/DisableActionTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/DisableActionTransformer.kt new file mode 100644 index 0000000000..9c1a7178bc --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/DisableActionTransformer.kt @@ -0,0 +1,57 @@ +package com.tangem.feature.wallet.presentation.wallet.state.transformers + +import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.feature.wallet.presentation.wallet.state.model.WalletManageButton +import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.toPersistentList +import timber.log.Timber +import kotlin.reflect.KClass + +/** + * Transformer for disabling action of multi-currency wallet + * + * @param userWalletId user wallet id + * @property actionClass action class that must be disabled + */ +internal class DisableActionTransformer( + userWalletId: UserWalletId, + private val actionClass: KClass, +) : WalletStateTransformer(userWalletId = userWalletId) { + + override fun transform(prevState: WalletState): WalletState { + return when (prevState) { + is WalletState.MultiCurrency.Content -> { + prevState.copy(buttons = prevState.buttons.updateButtons()) + } + is WalletState.MultiCurrency.Locked -> { + Timber.w("Impossible to disable action for locked wallet") + prevState + } + is WalletState.SingleCurrency -> { + Timber.w("Impossible to disable action for single-currency wallet") + prevState + } + is WalletState.Visa -> { + Timber.w("Impossible to disable action for VISA wallet") + prevState + } + } + } + + private fun PersistentList.updateButtons(): PersistentList { + return map { action -> + if (action::class == actionClass) { + when (action) { + is WalletManageButton.Buy -> action.copy(enabled = false) + is WalletManageButton.Swap -> action.copy(enabled = false) + is WalletManageButton.Sell -> action.copy(enabled = false) + else -> action + } + } else { + action + } + } + .toPersistentList() + } +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt index 0c85aed9cd..7ff1da092b 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/InitializeWalletsTransformer.kt @@ -58,7 +58,7 @@ internal class InitializeWalletsTransformer( multiCurrencyCreator = { WalletState.MultiCurrency.Locked( walletCardState = userWallet.toLockedWalletCardState(), - buttons = createMultiWalletDisabledButtons(), + buttons = createMultiWalletEnabledButtons(), bottomSheetConfig = null, onUnlockNotificationClick = clickIntents::onOpenUnlockWalletsBottomSheetClick, ) @@ -67,7 +67,7 @@ internal class InitializeWalletsTransformer( WalletState.SingleCurrency.Locked( walletCardState = userWallet.toLockedWalletCardState(), bottomSheetConfig = null, - buttons = createDisabledButtons(), + buttons = createSingleWalletDisabledButtons(), onUnlockNotificationClick = clickIntents::onOpenUnlockWalletsBottomSheetClick, onExploreClick = clickIntents::onExploreClick, ) @@ -75,7 +75,7 @@ internal class InitializeWalletsTransformer( visaWalletCreator = { WalletState.Visa.Locked( walletCardState = userWallet.toLockedWalletCardState(), - buttons = createMultiWalletDisabledButtons(), + buttons = createMultiWalletEnabledButtons(), bottomSheetConfig = null, onUnlockNotificationClick = clickIntents::onOpenUnlockWalletsBottomSheetClick, onExploreClick = clickIntents::onExploreClick, @@ -95,18 +95,17 @@ internal class InitializeWalletsTransformer( ) } - private fun createMultiWalletDisabledButtons(): PersistentList { + private fun createMultiWalletEnabledButtons(): PersistentList { if (!walletFeatureToggles.isMainActionButtonsEnabled) return persistentListOf() return persistentListOf( - WalletManageButton.Receive(enabled = false, dimContent = false, onClick = {}, onLongClick = null), - WalletManageButton.Send(enabled = false, dimContent = false, onClick = {}), WalletManageButton.Buy(enabled = false, dimContent = false, onClick = {}), + WalletManageButton.Swap(enabled = false, dimContent = false, onClick = {}), WalletManageButton.Sell(enabled = false, dimContent = false, onClick = {}), ) } - private fun createDisabledButtons(): PersistentList { + private fun createSingleWalletDisabledButtons(): PersistentList { return persistentListOf( WalletManageButton.Receive(enabled = false, dimContent = false, onClick = {}, onLongClick = null), WalletManageButton.Send(enabled = false, dimContent = false, onClick = {}), diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetBalancesAndLimitsTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetBalancesAndLimitsTransformer.kt index af365a24d7..705ffefdc5 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetBalancesAndLimitsTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetBalancesAndLimitsTransformer.kt @@ -14,6 +14,7 @@ import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAdditiona import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents +import com.tangem.utils.extensions.isZero import org.joda.time.DateTime import org.joda.time.Days @@ -76,6 +77,7 @@ internal class SetBalancesAndLimitsTransformer( crypto(visaCurrency.symbol, visaCurrency.decimals) }, cardCount = userWallet.getCardsCount(), + isZeroBalance = visaCurrency.balances.available.isZero(), ) } } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListErrorTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListErrorTransformer.kt index a13bd46297..39b11b41e6 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListErrorTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListErrorTransformer.kt @@ -9,6 +9,7 @@ import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfo import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState import com.tangem.feature.wallet.presentation.wallet.state.model.WalletTokensListState +import com.tangem.feature.wallet.presentation.wallet.state.utils.disableButtons import timber.log.Timber import java.math.BigDecimal @@ -26,6 +27,11 @@ internal class SetTokenListErrorTransformer( prevState.copy( walletCardState = prevState.walletCardState.toLoadedState(), tokensListState = WalletTokensListState.Empty, + buttons = if (error == TokenListError.EmptyTokens) { + prevState.disableButtons() + } else { + prevState.buttons + }, ) } is WalletState.MultiCurrency.Locked -> { @@ -62,6 +68,7 @@ internal class SetTokenListErrorTransformer( fiatCurrencySymbol = appCurrency.symbol, ), cardCount = selectedWallet.getCardsCount(), + isZeroBalance = true, ) } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListTransformer.kt index 44698f71e3..86d40d6d13 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetTokenListTransformer.kt @@ -8,6 +8,7 @@ import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState import com.tangem.feature.wallet.presentation.wallet.state.model.WalletTokensListState import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.MultiWalletCardStateConverter import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.TokenListStateConverter +import com.tangem.feature.wallet.presentation.wallet.state.utils.enableButtons import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents import timber.log.Timber @@ -24,6 +25,7 @@ internal class SetTokenListTransformer( prevState.copy( walletCardState = prevState.walletCardState.toLoadedState(), tokensListState = prevState.tokensListState.toLoadedState(), + buttons = prevState.enableButtons(), ) } is WalletState.MultiCurrency.Locked -> { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCardStateConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCardStateConverter.kt index 0ff9942daf..d37d638432 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCardStateConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/MultiWalletCardStateConverter.kt @@ -8,6 +8,7 @@ import com.tangem.domain.wallets.models.UserWallet import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState import com.tangem.utils.converter.Converter +import com.tangem.utils.extensions.isZero internal class MultiWalletCardStateConverter( private val fiatBalance: TotalFiatBalance, @@ -58,6 +59,7 @@ internal class MultiWalletCardStateConverter( fiatCurrencyCode = appCurrency.code, fiatCurrencySymbol = appCurrency.symbol, ), + isZeroBalance = fiatBalance.amount.isZero(), cardCount = selectedWallet.getCardsCount(), ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletCardStateConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletCardStateConverter.kt index 8ea62cf3fe..c33ff28872 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletCardStateConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletCardStateConverter.kt @@ -8,6 +8,7 @@ import com.tangem.domain.wallets.models.UserWallet import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState import com.tangem.utils.converter.Converter +import com.tangem.utils.extensions.isZero internal class SingleWalletCardStateConverter( private val status: CryptoCurrencyStatus.Value, @@ -63,6 +64,7 @@ internal class SingleWalletCardStateConverter( onDeleteClick = onDeleteClick, balance = formatFiatAmount(status = status, appCurrency = appCurrency), cardCount = selectedWallet.getCardsCount(), + isZeroBalance = status.fiatAmount?.isZero(), ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/MultiWalletActionsExt.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/MultiWalletActionsExt.kt new file mode 100644 index 0000000000..e109933f15 --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/MultiWalletActionsExt.kt @@ -0,0 +1,27 @@ +package com.tangem.feature.wallet.presentation.wallet.state.utils + +import com.tangem.feature.wallet.presentation.wallet.state.model.WalletManageButton +import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.toPersistentList + +internal fun WalletState.MultiCurrency.Content.enableButtons(): PersistentList { + return changeAvailability(enabled = true) +} + +internal fun WalletState.MultiCurrency.Content.disableButtons(): PersistentList { + return changeAvailability(enabled = false) +} + +private fun WalletState.MultiCurrency.Content.changeAvailability(enabled: Boolean): PersistentList { + return buttons + .map { action -> + when (action) { + is WalletManageButton.Buy -> action.copy(enabled = enabled) + is WalletManageButton.Sell -> action.copy(enabled = enabled) + is WalletManageButton.Swap -> action.copy(enabled = enabled) + else -> action + } + } + .toPersistentList() +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt index 6b9dda9803..b9aa9f82fd 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt @@ -98,18 +98,18 @@ internal class WalletLoadingStateFactory( return persistentListOf( WalletManageButton.Buy( - enabled = false, - dimContent = true, + enabled = true, + dimContent = false, onClick = { clickIntents.onMultiWalletBuyClick(userWalletId = userWallet.walletId) }, ), WalletManageButton.Swap( - enabled = false, - dimContent = true, + enabled = true, + dimContent = false, onClick = { clickIntents.onMultiWalletSwapClick(userWalletId = userWallet.walletId) }, ), WalletManageButton.Sell( - enabled = false, - dimContent = true, + enabled = true, + dimContent = false, onClick = { clickIntents.onMultiWalletSellClick(userWalletId = userWallet.walletId) }, ), ) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletCurrencyActionsClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletCurrencyActionsClickIntents.kt index 3e0fac69ce..2eac6d5e37 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletCurrencyActionsClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletCurrencyActionsClickIntents.kt @@ -21,9 +21,14 @@ import com.tangem.core.ui.haptic.VibratorHapticManager import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.appcurrency.extenstions.unwrap import com.tangem.domain.common.util.cardTypesResolver +import com.tangem.domain.core.lce.Lce +import com.tangem.domain.core.utils.lceError import com.tangem.domain.demo.IsDemoCardUseCase +import com.tangem.domain.exchange.RampStateManager import com.tangem.domain.markets.TokenMarketParams import com.tangem.domain.redux.ReduxStateHolder +import com.tangem.domain.settings.usercountry.GetUserCountryUseCase +import com.tangem.domain.settings.usercountry.models.UserCountry import com.tangem.domain.staking.model.stakekit.Yield import com.tangem.domain.tokens.* import com.tangem.domain.tokens.legacy.TradeCryptoAction @@ -42,17 +47,23 @@ import com.tangem.feature.wallet.impl.R import com.tangem.feature.wallet.presentation.wallet.domain.unwrap import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAlertState +import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent +import com.tangem.feature.wallet.presentation.wallet.state.model.WalletManageButton import com.tangem.feature.wallet.presentation.wallet.state.transformers.CloseBottomSheetTransformer +import com.tangem.feature.wallet.presentation.wallet.state.transformers.DisableActionTransformer import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.hilt.android.scopes.ViewModelScoped import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.take import kotlinx.coroutines.launch import java.math.BigDecimal import javax.inject.Inject +import kotlin.reflect.KClass interface WalletCurrencyActionsClickIntents { @@ -112,6 +123,8 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor( private val vibratorHapticManager: VibratorHapticManager, private val clipboardManager: ClipboardManager, private val appRouter: AppRouter, + private val rampStateManager: RampStateManager, + private val getUserCountryUseCase: GetUserCountryUseCase, ) : BaseWalletClickIntents(), WalletCurrencyActionsClickIntents { override fun onSendClick( @@ -441,36 +454,59 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor( } override fun onMultiWalletSellClick(userWalletId: UserWalletId) { - analyticsEventHandler.send( - event = MainScreenAnalyticsEvent.ButtonSell( - status = AnalyticsParam.Status.Success, // TODO [REDACTED_JIRA] - ), - ) + viewModelScope.launch { + val userCountry = getUserCountryUseCase().getOrNull() + if (userCountry is UserCountry.Russia) { + handleError( + userWalletId = userWalletId, + actionKClass = WalletManageButton.Sell::class, + alertState = WalletAlertState.SellingRegionalRestriction, + eventCreator = MainScreenAnalyticsEvent::ButtonSell, + ) - // TODO [REDACTED_JIRA] - appRouter.push(route = AppRoute.SellCrypto(userWalletId = userWalletId)) + return@launch + } + + val selectedWallet = stateHolder.getSelectedWallet().walletCardState as? WalletCardState.Content + if (selectedWallet?.isZeroBalance == true) { + handleError( + userWalletId = userWalletId, + actionKClass = WalletManageButton.Sell::class, + alertState = WalletAlertState.InsufficientBalanceForSelling, + eventCreator = MainScreenAnalyticsEvent::ButtonSell, + ) + + return@launch + } + + onMultiWalletActionClick( + userWalletId = userWalletId, + statusFlow = rampStateManager.getSellInitializationStatus(), + route = AppRoute.SellCrypto(userWalletId = userWalletId), + actionKClass = WalletManageButton.Sell::class, + eventCreator = MainScreenAnalyticsEvent::ButtonSell, + ) + } } override fun onMultiWalletSwapClick(userWalletId: UserWalletId) { - analyticsEventHandler.send( - event = MainScreenAnalyticsEvent.ButtonSwap( - status = AnalyticsParam.Status.Success, // TODO [REDACTED_JIRA] - ), + onMultiWalletActionClick( + userWalletId = userWalletId, + statusFlow = rampStateManager.getSwapInitializationStatus(userWalletId), + route = AppRoute.SwapCrypto(userWalletId = userWalletId), + actionKClass = WalletManageButton.Swap::class, + eventCreator = MainScreenAnalyticsEvent::ButtonSwap, ) - - // TODO [REDACTED_JIRA] - appRouter.push(route = AppRoute.SwapCrypto(userWalletId = userWalletId)) } override fun onMultiWalletBuyClick(userWalletId: UserWalletId) { - analyticsEventHandler.send( - event = MainScreenAnalyticsEvent.ButtonBuy( - status = AnalyticsParam.Status.Success, // TODO [REDACTED_JIRA] - ), + onMultiWalletActionClick( + userWalletId = userWalletId, + statusFlow = rampStateManager.getBuyInitializationStatus(), + route = AppRoute.BuyCrypto(userWalletId = userWalletId), + actionKClass = WalletManageButton.Buy::class, + eventCreator = MainScreenAnalyticsEvent::ButtonBuy, ) - - // TODO [REDACTED_JIRA] - appRouter.push(route = AppRoute.BuyCrypto(userWalletId = userWalletId)) } private fun openExplorer() { @@ -570,4 +606,69 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor( return true } + + private fun onMultiWalletActionClick( + userWalletId: UserWalletId, + statusFlow: Flow>, + route: AppRoute, + actionKClass: KClass, + eventCreator: (AnalyticsParam.Status) -> MainScreenAnalyticsEvent, + ) { + viewModelScope.launch { + statusFlow.foldStatus( + onContent = { handleContent(route, eventCreator) }, + onError = { + handleError( + userWalletId = userWalletId, + actionKClass = actionKClass, + eventCreator = eventCreator, + ) + }, + onLoading = { handleLoading(eventCreator) }, + ) + } + } + + private suspend fun Flow>.foldStatus( + onContent: () -> Unit, + onError: () -> Unit, + onLoading: () -> Unit, + ) { + val status = firstOrNull() ?: IllegalStateException("Status is null").lceError() + + when (status) { + is Lce.Content -> onContent() + is Lce.Error -> onError() + is Lce.Loading -> onLoading() + } + } + + private fun handleContent(route: AppRoute, eventCreator: (AnalyticsParam.Status) -> MainScreenAnalyticsEvent) { + analyticsEventHandler.send(event = eventCreator(AnalyticsParam.Status.Success)) + + appRouter.push(route = route) + } + + private fun handleError( + userWalletId: UserWalletId, + actionKClass: KClass, + alertState: WalletAlertState = WalletAlertState.UnavailableOperation, + eventCreator: (AnalyticsParam.Status) -> MainScreenAnalyticsEvent, + ) { + analyticsEventHandler.send(event = eventCreator(AnalyticsParam.Status.Error)) + + stateHolder.update( + transformer = DisableActionTransformer(userWalletId = userWalletId, actionClass = actionKClass), + ) + + walletEventSender.send(event = WalletEvent.ShowAlert(state = alertState)) + } + + private fun handleLoading(eventCreator: (AnalyticsParam.Status) -> MainScreenAnalyticsEvent) { + analyticsEventHandler.send(event = eventCreator(AnalyticsParam.Status.Pending)) + + walletEventSender.send( + event = WalletEvent.ShowAlert(state = WalletAlertState.ProvidersStillLoading), + ) + } } \ No newline at end of file