diff --git a/app/src/main/java/com/tangem/tap/common/DialogManager.kt b/app/src/main/java/com/tangem/tap/common/DialogManager.kt index 8af2818c0a..9af6c88b29 100644 --- a/app/src/main/java/com/tangem/tap/common/DialogManager.kt +++ b/app/src/main/java/com/tangem/tap/common/DialogManager.kt @@ -22,6 +22,7 @@ import com.tangem.tap.features.onboarding.products.wallet.ui.dialogs.UnfinishedB import com.tangem.tap.features.wallet.redux.WalletDialog import com.tangem.tap.features.wallet.ui.dialogs.AmountToSendBottomSheetDialog import com.tangem.tap.features.wallet.ui.dialogs.ChooseTradeActionBottomSheetDialog +import com.tangem.tap.features.wallet.ui.dialogs.RussianCardholdersWarningBottomSheetDialog import com.tangem.tap.features.wallet.ui.dialogs.ScanFailsDialog import com.tangem.tap.features.wallet.ui.dialogs.SignedHashesWarningDialog import com.tangem.tap.features.wallet.ui.dialogs.SimpleOkDialog @@ -115,6 +116,8 @@ class DialogManager : StoreSubscriber { AmountToSendBottomSheetDialog(context, state.dialog) is WalletDialog.SignedHashesMultiWalletDialog -> SignedHashesWarningDialog.create(context) + is WalletDialog.RussianCardholdersWarningDialog -> + RussianCardholdersWarningBottomSheetDialog(context) else -> null } dialog?.show() diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt index 48591606c1..54142bb9af 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt @@ -28,6 +28,7 @@ data class GlobalState( val exchangeManager: CurrencyExchangeManager? = null, val resources: AndroidResources = AndroidResources(), val analyticsHandlers: AnalyticsHandler? = null, + val userCountry: String? = null, ) : StateType diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt index 769d28a8cd..c90af2af53 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt @@ -145,6 +145,7 @@ sealed class WalletAction : Action { object SignedHashesMultiWalletDialog : DialogAction() object ChooseTradeActionDialog : DialogAction() data class ChooseCurrency(val amounts: List?) : DialogAction() + object RussianCardholdersWarningDialog : DialogAction() object Hide : DialogAction() } @@ -155,8 +156,10 @@ sealed class WalletAction : Action { object EmptyWallet : WalletAction() sealed class TradeCryptoAction : WalletAction() { - object Buy : TradeCryptoAction() object Sell : TradeCryptoAction() + data class Buy( + val checkUserLocation: Boolean = true, + ) : TradeCryptoAction() data class FinishSelling(val transactionId: String) : TradeCryptoAction() data class SendCrypto( val currencyId: String, diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt index 26224eb41e..1bbf3366a6 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt @@ -1,7 +1,12 @@ package com.tangem.tap.features.wallet.redux import android.graphics.Bitmap -import com.tangem.blockchain.common.* +import com.tangem.blockchain.common.Amount +import com.tangem.blockchain.common.Blockchain +import com.tangem.blockchain.common.DerivationStyle +import com.tangem.blockchain.common.Token +import com.tangem.blockchain.common.Wallet +import com.tangem.blockchain.common.WalletManager import com.tangem.blockchain.common.address.AddressType import com.tangem.common.extensions.isZero import com.tangem.domain.common.extensions.canHandleToken @@ -17,15 +22,21 @@ import com.tangem.tap.domain.configurable.warningMessage.WarningMessage import com.tangem.tap.domain.tokens.models.BlockchainNetwork import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsState import com.tangem.tap.features.tokens.redux.TokenWithBlockchain -import com.tangem.tap.features.wallet.models.* +import com.tangem.tap.features.wallet.models.PendingTransaction +import com.tangem.tap.features.wallet.models.TotalBalance +import com.tangem.tap.features.wallet.models.WalletRent +import com.tangem.tap.features.wallet.models.WalletWarning +import com.tangem.tap.features.wallet.models.hasPendingTransactions +import com.tangem.tap.features.wallet.models.hasSendableAmounts +import com.tangem.tap.features.wallet.models.isSendableAmount import com.tangem.tap.features.wallet.redux.reducers.calculateTotalFiatAmount import com.tangem.tap.features.wallet.redux.reducers.findProgressState import com.tangem.tap.features.wallet.ui.BalanceStatus import com.tangem.tap.features.wallet.ui.BalanceWidgetData import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager import com.tangem.tap.store -import org.rekotlin.StateType import java.math.BigDecimal +import org.rekotlin.StateType import kotlin.properties.ReadOnlyProperty data class WalletState( @@ -317,6 +328,7 @@ sealed interface WalletDialog : StateDialog { val currenciesList: List, val currentAppCurrency: FiatCurrency, ) : WalletDialog + object RussianCardholdersWarningDialog : WalletDialog } enum class ProgressState : WidgetState { Loading, Refreshing, Done, Error } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt index 3ff2589348..636baf5aaf 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/TradeCryptoMiddleware.kt @@ -24,33 +24,34 @@ class TradeCryptoMiddleware { if (DemoHelper.tryHandle(state, action)) return when (action) { - is WalletAction.TradeCryptoAction.Buy -> startExchange(action) - is WalletAction.TradeCryptoAction.Sell -> startExchange(action) + is WalletAction.TradeCryptoAction.Buy -> proceedBuyAction(state, action) + is WalletAction.TradeCryptoAction.Sell -> proceedSellAction() is WalletAction.TradeCryptoAction.SendCrypto -> preconfigureAndOpenSendScreen(action) is WalletAction.TradeCryptoAction.FinishSelling -> openReceiptUrl(action.transactionId) } } - private fun startExchange(action: WalletAction.TradeCryptoAction) { - val selectedWalletData = store.state.walletState.getSelectedWalletData() - val exchangeManager = store.state.globalState.exchangeManager ?: return - val addresses = selectedWalletData?.walletAddresses ?: return - if (addresses.list.isEmpty()) return - val appCurrency = store.state.globalState.appCurrency - - val defaultAddress = addresses.list[0].address - val currency = selectedWalletData.currency - val currencySymbol = selectedWalletData.currency.currencySymbol - - val exchangeAction = if (action is WalletAction.TradeCryptoAction.Buy) { - CurrencyExchangeManager.Action.Buy - } else { - CurrencyExchangeManager.Action.Sell + private fun proceedBuyAction( + state: () -> AppState?, + action: WalletAction.TradeCryptoAction.Buy, + ) { + if (action.checkUserLocation && state()?.globalState?.userCountry == "RU") { + store.dispatchOnMain( + WalletAction.DialogAction.RussianCardholdersWarningDialog + ) + return } - if (exchangeAction == CurrencyExchangeManager.Action.Buy && - currency is Currency.Token && currency.blockchain.isTestnet() - ) { + val selectedWalletData = store.state.walletState.getSelectedWalletData() ?: return + val exchangeManager = store.state.globalState.exchangeManager ?: return + val appCurrency = store.state.globalState.appCurrency + + val addresses = selectedWalletData.walletAddresses?.list.orEmpty() + if (addresses.isEmpty()) return + + val currency = selectedWalletData.currency + + if (currency is Currency.Token && currency.blockchain.isTestnet()) { val walletManager = store.state.walletState.getWalletManager(currency) if (walletManager !is EthereumWalletManager) { store.dispatchDebugErrorNotification("Testnet tokens available only for the Ethereum") @@ -62,13 +63,31 @@ class TradeCryptoMiddleware { } exchangeManager.getUrl( - action = exchangeAction, + action = CurrencyExchangeManager.Action.Buy, blockchain = currency.blockchain, - cryptoCurrencyName = currencySymbol, + cryptoCurrencyName = currency.currencySymbol, fiatCurrencyName = appCurrency.code, - walletAddress = defaultAddress + walletAddress = addresses[0].address )?.let { store.dispatchOnMain(NavigationAction.OpenUrl(it)) } + } + private fun proceedSellAction() { + val selectedWalletData = store.state.walletState.getSelectedWalletData() ?: return + val exchangeManager = store.state.globalState.exchangeManager ?: return + val appCurrency = store.state.globalState.appCurrency + + val addresses = selectedWalletData.walletAddresses?.list.orEmpty() + if (addresses.isEmpty()) return + + val currency = selectedWalletData.currency + + exchangeManager.getUrl( + action = CurrencyExchangeManager.Action.Sell, + blockchain = currency.blockchain, + cryptoCurrencyName = currency.currencySymbol, + fiatCurrencyName = appCurrency.code, + walletAddress = addresses[0].address + )?.let { store.dispatchOnMain(NavigationAction.OpenUrl(it)) } } private fun preconfigureAndOpenSendScreen(action: WalletAction.TradeCryptoAction.SendCrypto) { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletDialogsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletDialogsMiddleware.kt index e495c55c94..e760c446f2 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletDialogsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletDialogsMiddleware.kt @@ -27,10 +27,13 @@ class WalletDialogsMiddleware { is WalletAction.DialogAction.ChooseCurrency -> { store.dispatchDialogShow( WalletDialog.SelectAmountToSendDialog( - amounts = action.amounts + amounts = action.amounts ) ) } + is WalletAction.DialogAction.RussianCardholdersWarningDialog -> { + store.dispatchDialogShow(WalletDialog.RussianCardholdersWarningDialog) + } is WalletAction.DialogAction.Hide -> { store.dispatchDialogHide() } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt index d5bd095cbc..1cf3a038b2 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt @@ -91,7 +91,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), private fun setupButtons() = with(binding) { rowButtons.onBuyClick = { - store.dispatch(WalletAction.TradeCryptoAction.Buy) + store.dispatch(WalletAction.TradeCryptoAction.Buy()) } rowButtons.onSellClick = { store.dispatch(WalletAction.TradeCryptoAction.Sell) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/ChooseTradeActionBottomSheetDialog.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/ChooseTradeActionBottomSheetDialog.kt index 1c65315d3a..397231a58c 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/ChooseTradeActionBottomSheetDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/ChooseTradeActionBottomSheetDialog.kt @@ -27,7 +27,7 @@ class ChooseTradeActionBottomSheetDialog(context: Context) : BottomSheetDialog(c } binding!!.dialogBtnBuy.setOnClickListener { - store.dispatch(WalletAction.TradeCryptoAction.Buy) + store.dispatch(WalletAction.TradeCryptoAction.Buy()) dismiss() } binding!!.dialogBtnSell.setOnClickListener { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/RussianCardholdersWarningBottomSheetDialog.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/RussianCardholdersWarningBottomSheetDialog.kt new file mode 100644 index 0000000000..a3b84e3a48 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/RussianCardholdersWarningBottomSheetDialog.kt @@ -0,0 +1,39 @@ +package com.tangem.tap.features.wallet.ui.dialogs + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import com.google.android.material.bottomsheet.BottomSheetDialog +import com.tangem.tap.common.extensions.dispatchDialogHide +import com.tangem.tap.features.wallet.redux.WalletAction +import com.tangem.tap.store +import com.tangem.wallet.databinding.DialogRussiansCardholdersWarningBinding + +class RussianCardholdersWarningBottomSheetDialog(context: Context) : BottomSheetDialog(context) { + + private var binding: DialogRussiansCardholdersWarningBinding? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = DialogRussiansCardholdersWarningBinding + .inflate(LayoutInflater.from(context)) + .also { setContentView(it.root) } + } + + override fun show() { + super.show() + setOnDismissListener { + binding = null + store.dispatchDialogHide() + } + + binding?.btnYes?.setOnClickListener { + // TODO: Open instruction WebView + dismiss() + } + binding?.btnNo?.setOnClickListener { + store.dispatch(WalletAction.TradeCryptoAction.Buy(checkUserLocation = false)) + dismiss() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt index 19815ccfe7..7c431c33b7 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt @@ -149,7 +149,7 @@ class SingleWalletView : WalletView { val allowedToBuy = tradeCryptoState.isAvailableToBuy() val allowedToSell = tradeCryptoState.isAvailableToSell() val action = when { - allowedToBuy && !allowedToSell -> WalletAction.TradeCryptoAction.Buy + allowedToBuy && !allowedToSell -> WalletAction.TradeCryptoAction.Buy() !allowedToBuy && allowedToSell -> WalletAction.TradeCryptoAction.Sell allowedToBuy && allowedToSell -> WalletAction.DialogAction.ChooseTradeActionDialog else -> null diff --git a/app/src/main/res/drawable/ic_cross_rounded_24.xml b/app/src/main/res/drawable/ic_cross_rounded_24.xml new file mode 100644 index 0000000000..ad1cab5a84 --- /dev/null +++ b/app/src/main/res/drawable/ic_cross_rounded_24.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/img_flag_ru_24.xml b/app/src/main/res/drawable/img_flag_ru_24.xml new file mode 100644 index 0000000000..deff0dc4bb --- /dev/null +++ b/app/src/main/res/drawable/img_flag_ru_24.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/app/src/main/res/layout/dialog_russians_cardholders_warning.xml b/app/src/main/res/layout/dialog_russians_cardholders_warning.xml new file mode 100644 index 0000000000..8f2196c2d5 --- /dev/null +++ b/app/src/main/res/layout/dialog_russians_cardholders_warning.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values-ru/strings_final.xml b/app/src/main/res/values-ru/strings_final.xml index 201a1684ae..7b022e0aa3 100644 --- a/app/src/main/res/values-ru/strings_final.xml +++ b/app/src/main/res/values-ru/strings_final.xml @@ -50,4 +50,22 @@ В сумме учтены не все монеты Управление токенами Нет цены + + Скрыть токен + Скрыть %s + Скрыть + Вы скрываете токен с главного экрана, но в любой момент сможете добавить его обратно. + Невозможно скрыть %s + Токен %s является основной валютой в сети %s и не может быть скрыт, до тех пор пока у вас в списке есть другие токены этой сети. + + Сеть %s не найдена. Пожалуйста, добавьте её и попробуйте заново. + Сеть %s + + Бэкап кошелька не был произведен + Чтобы защитить свои активы, мы советуем вам выполнить эту процедуру + + Карты банков РФ в данный момент не принимаются + У вас есть карта банка другой страны или платежной системы UnionPay? + Да + Нет diff --git a/app/src/main/res/values/strings_final.xml b/app/src/main/res/values/strings_final.xml index d59d31ff0e..3a16ec6ea0 100644 --- a/app/src/main/res/values/strings_final.xml +++ b/app/src/main/res/values/strings_final.xml @@ -50,4 +50,23 @@ The amount does not include some of your funds Manage tokens No rate + + Hide token + Hide %s + Hide + You are about to hide this token from the main screen. You can add it back anytime. + Unable to hide %s + The %s token is the main currency on the %s network and cannot be hidden as long as you have other tokens on this network in the list. + + %s network not found. Please, add it first and try again. + %s network + + Your wallet has not been backed up + To protect your assets, we advise you to carry out this procedure + Remove token + + Russian bank cards are not accepted at the moment + Do you have a bank card of another country or a UnionPay card? + Yes + No