From 04d22aa0929c28a6671788658b2441f22dc66284 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 29 Dec 2022 19:41:26 +0400 Subject: [PATCH] Updated on 2026-08-14 --- app/build.gradle.kts | 3 ++ .../com/tangem/tap/common/DialogManager.kt | 2 +- .../tap/common/extensions/Navigation.kt | 5 +++ .../redux/navigation/NavigationAction.kt | 2 + .../redux/navigation/NavigationState.kt | 1 + .../tap/features/wallet/redux/WalletAction.kt | 9 ++++- .../tap/features/wallet/redux/WalletState.kt | 3 ++ .../middlewares/TradeCryptoMiddleware.kt | 37 +++++++++++++++++++ .../middlewares/WalletDialogsMiddleware.kt | 8 +++- .../wallet/redux/models/WalletDialog.kt | 11 ++++-- .../wallet/ui/WalletDetailsFragment.kt | 18 ++++----- .../ChooseTradeActionBottomSheetDialog.kt | 34 +++++++++++++---- .../wallet/ui/view/WalletDetailsButtonsRow.kt | 9 ++--- .../wallet/ui/wallet/SingleWalletView.kt | 12 ++++-- .../main/res/layout/dialog_wallet_trade.xml | 19 +++++++++- build.gradle.kts | 1 + buildSrc/src/main/java/Dependency.kt | 1 + buildSrc/src/main/java/Versions.kt | 1 + .../main/res/drawable/ic_arrow_down_24.xml | 10 +++++ .../src/main/res/drawable/ic_arrow_up_24.xml | 10 +++++ features/swap/domain/build.gradle.kts | 5 ++- .../swap/domain/models/data/Currency.kt | 22 ++++++----- features/swap/presentation/build.gradle.kts | 2 + .../feature/swap/presentation/SwapFragment.kt | 4 ++ .../ui/SwapPermissionBottomSheetContent.kt | 21 ++++++----- .../com/tangem/feature/swap/ui/SwapScreen.kt | 6 +-- 26 files changed, 201 insertions(+), 55 deletions(-) create mode 100644 core/ui/src/main/res/drawable/ic_arrow_down_24.xml create mode 100644 core/ui/src/main/res/drawable/ic_arrow_up_24.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1876b0038c..9cae959b25 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.application") kotlin("android") kotlin("kapt") + kotlin("plugin.serialization") id("com.google.gms.google-services") id("com.google.firebase.crashlytics") id("com.google.dagger.hilt.android") @@ -102,6 +103,7 @@ android { } repositories { + mavenCentral() maven(url = "https://jitpack.io") } @@ -199,6 +201,7 @@ dependencies { implementation(Library.googlePlayServicesWallet) implementation(Library.composeShimmer) implementation(Library.mviCoreWatcher) + implementation(Library.kotlinSerialization) /** Testing libraries */ testImplementation(Test.junit) 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 94dd3ff6c1..595d9b6fad 100644 --- a/app/src/main/java/com/tangem/tap/common/DialogManager.kt +++ b/app/src/main/java/com/tangem/tap/common/DialogManager.kt @@ -133,7 +133,7 @@ class DialogManager : StoreSubscriber { is SaltPayDialog.Activation.NoGas -> NoFundsForActivationDialog.create(context) is SaltPayDialog.Activation.OnError -> RegistrationErrorDialog.create(context, state.dialog) is WalletDialog.CurrencySelectionDialog -> CurrencySelectionDialog.create(state.dialog, context) - is WalletDialog.ChooseTradeActionDialog -> ChooseTradeActionBottomSheetDialog(context) + is WalletDialog.ChooseTradeActionDialog -> ChooseTradeActionBottomSheetDialog(context, state.dialog) is WalletDialog.SelectAmountToSendDialog -> AmountToSendBottomSheetDialog(context, state.dialog) is WalletDialog.SignedHashesMultiWalletDialog -> SignedHashesWarningDialog.create(context) is WalletDialog.TokensAreLinkedDialog -> SimpleAlertDialog.create( diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt index 0e167cdcca..eaae03f471 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt @@ -1,5 +1,6 @@ package com.tangem.tap.common.extensions +import android.os.Bundle import androidx.activity.OnBackPressedCallback import androidx.fragment.app.DialogFragment import androidx.fragment.app.Fragment @@ -7,6 +8,7 @@ import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentManager import com.tangem.common.extensions.VoidCallback import com.tangem.feature.referral.ReferralFragment +import com.tangem.feature.swap.presentation.SwapFragment import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.FragmentShareTransition import com.tangem.tap.features.details.ui.appsettings.AppSettingsFragment @@ -37,10 +39,12 @@ import timber.log.Timber fun FragmentActivity.openFragment( screen: AppScreen, addToBackstack: Boolean, + bundle: Bundle? = null, fgShareTransition: FragmentShareTransition? = null, ) { val transaction = this.supportFragmentManager.beginTransaction() val fragment = fragmentFactory(screen) + fragment.arguments = bundle fgShareTransition?.apply { fragment.sharedElementEnterTransition = enterTransitionSet fragment.sharedElementReturnTransition = exitTransitionSet @@ -117,6 +121,7 @@ private fun fragmentFactory(screen: AppScreen): Fragment { AppScreen.WalletConnectSessions -> WalletConnectFragment() AppScreen.QrScan -> QrScanFragment() AppScreen.ReferralProgram -> ReferralFragment() + AppScreen.Swap -> SwapFragment() AppScreen.Welcome -> WelcomeFragment() AppScreen.SaveWallet -> SaveWalletBottomSheetFragment() AppScreen.WalletSelector -> WalletSelectorBottomSheetFragment() diff --git a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationAction.kt b/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationAction.kt index 3e4f3a9702..71f3274e4c 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationAction.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationAction.kt @@ -1,6 +1,7 @@ package com.tangem.tap.common.redux.navigation import android.net.Uri +import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import org.rekotlin.Action import java.lang.ref.WeakReference @@ -10,6 +11,7 @@ sealed class NavigationAction : Action { val screen: AppScreen, val fragmentShareTransition: FragmentShareTransition? = null, val addToBackstack: Boolean = true, + val bundle: Bundle? = null, ) : NavigationAction() data class PopBackTo( diff --git a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationState.kt b/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationState.kt index cf60dc79f6..0b40b7bd8e 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/navigation/NavigationState.kt @@ -23,6 +23,7 @@ enum class AppScreen( WalletConnectSessions, QrScan, ReferralProgram, + Swap, Welcome, SaveWallet(isDialogFragment = true), WalletSelector(isDialogFragment = true), 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 0cc8039e96..44872ab399 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 @@ -161,7 +161,12 @@ sealed class WalletAction : Action { ) : DialogAction() object SignedHashesMultiWalletDialog : DialogAction() - object ChooseTradeActionDialog : DialogAction() + data class ChooseTradeActionDialog( + val buyAllowed: Boolean, + val sellAllowed: Boolean, + val swapAllowed: Boolean, + ) : DialogAction() + data class ChooseCurrency(val amounts: List?) : DialogAction() data class RussianCardholdersWarningDialog( val dialogData: WalletDialog.RussianCardholdersWarningDialog.Data? = null, @@ -190,6 +195,8 @@ sealed class WalletAction : Action { val destinationAddress: String, val transactionId: String, ) : TradeCryptoAction() + + object Swap : TradeCryptoAction() } data class ChangeSelectedAddress(val type: AddressType) : WalletAction() 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 49773a9854..b803175cf8 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 @@ -329,6 +329,9 @@ data class WalletData( val isAvailableToSell: Boolean get() = store.state.globalState.exchangeManager.availableForSell(currency) + val isAvailableToSwap: Boolean + get() = currency.blockchain.isEvm() && currency.coinId != null + fun shouldShowMultipleAddress(): Boolean { val listOfAddresses = walletAddresses?.list ?: return false return listOfAddresses.size > 1 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 df69426a2c..0cb3293ea0 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 @@ -1,7 +1,10 @@ package com.tangem.tap.features.wallet.redux.middlewares +import androidx.core.os.bundleOf import com.tangem.blockchain.blockchains.ethereum.EthereumWalletManager import com.tangem.blockchain.common.AmountType +import com.tangem.domain.common.extensions.toNetworkId +import com.tangem.feature.swap.presentation.SwapFragment import com.tangem.tap.common.analytics.Analytics import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.analytics.events.Token @@ -11,6 +14,7 @@ import com.tangem.tap.common.extensions.dispatchOpenUrl import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction +import com.tangem.tap.domain.tokens.getIconUrl import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE import com.tangem.tap.features.send.redux.PrepareSendScreen @@ -22,6 +26,9 @@ import com.tangem.tap.network.exchangeServices.buyErc20TestnetTokens import com.tangem.tap.scope import com.tangem.tap.store import kotlinx.coroutines.launch +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import com.tangem.feature.swap.domain.models.data.Currency as SwapCurrency class TradeCryptoMiddleware { fun handle(state: () -> AppState?, action: WalletAction.TradeCryptoAction) { @@ -32,6 +39,7 @@ class TradeCryptoMiddleware { is WalletAction.TradeCryptoAction.Sell -> proceedSellAction() is WalletAction.TradeCryptoAction.SendCrypto -> preconfigureAndOpenSendScreen(action) is WalletAction.TradeCryptoAction.FinishSelling -> openReceiptUrl(action.transactionId) + is WalletAction.TradeCryptoAction.Swap -> openSwap() } } @@ -136,4 +144,33 @@ class TradeCryptoMiddleware { transactionId = transactionId, )?.let { store.dispatchOpenUrl(it) } } + + private fun openSwap() { + val currency = store.state.walletState.selectedWalletData?.currency?.toSwapCurrency() + val bundle = bundleOf(SwapFragment.CURRENCY_BUNDLE_KEY to Json.encodeToString(currency)) + store.dispatchOnMain(NavigationAction.NavigateTo(screen = AppScreen.Swap, bundle = bundle)) + } + + private fun Currency.toSwapCurrency(): SwapCurrency { + return when (this) { + is Currency.Blockchain -> { + SwapCurrency.NativeToken( + id = blockchain.id, + name = this.currencyName, + symbol = this.currencySymbol, + networkId = this.blockchain.toNetworkId(), + logoUrl = getIconUrl(this.blockchain.toNetworkId()), + ) + } + is Currency.Token -> SwapCurrency.NonNativeToken( + id = this.token.id ?: "", + name = this.currencyName, + symbol = this.currencySymbol, + networkId = this.blockchain.toNetworkId(), + logoUrl = getIconUrl(this.token.id ?: ""), + contractAddress = this.token.contractAddress, + decimalCount = decimals, + ) + } + } } \ No newline at end of file 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 fb6ff1dd3f..5f8e7c5ae2 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 @@ -20,7 +20,13 @@ class WalletDialogsMiddleware { store.state.walletState.selectedWalletData?.let { Analytics.send(Token.ButtonExchange(AnalyticsParam.CurrencyType.Currency(it.currency))) } - store.dispatchDialogShow(WalletDialog.ChooseTradeActionDialog) + store.dispatchDialogShow( + WalletDialog.ChooseTradeActionDialog( + buyAllowed = action.buyAllowed, + sellAllowed = action.sellAllowed, + swapAllowed = action.swapAllowed, + ), + ) } is WalletAction.DialogAction.QrCode -> { store.dispatchDialogShow( diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/models/WalletDialog.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/models/WalletDialog.kt index fc182e2c4f..d8ffb0df63 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/models/WalletDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/models/WalletDialog.kt @@ -9,7 +9,12 @@ import com.tangem.wallet.R sealed interface WalletDialog : StateDialog { data class SelectAmountToSendDialog(val amounts: List?) : WalletDialog object SignedHashesMultiWalletDialog : WalletDialog - object ChooseTradeActionDialog : WalletDialog + data class ChooseTradeActionDialog( + val buyAllowed: Boolean, + val sellAllowed: Boolean, + val swapAllowed: Boolean, + ) : WalletDialog + data class CurrencySelectionDialog( val currenciesList: List, val currentAppCurrency: FiatCurrency, @@ -17,7 +22,7 @@ sealed interface WalletDialog : StateDialog { data class RemoveWalletDialog( val currencyTitle: String, - val onOk: () -> Unit + val onOk: () -> Unit, ) : WalletDialog { val messageRes: Int = R.string.token_details_hide_alert_message val titleRes: Int = R.string.token_details_hide_alert_title @@ -26,7 +31,7 @@ sealed interface WalletDialog : StateDialog { data class TokensAreLinkedDialog( val currencyTitle: String, - val currencySymbol: String + val currencySymbol: String, ) : WalletDialog { val messageRes: Int = R.string.token_details_unable_hide_alert_message val titleRes: Int = R.string.token_details_unable_hide_alert_title 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 8083e9ba2b..0795efcea9 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 @@ -165,15 +165,6 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), } private fun setupButtons() = with(binding) { - rowButtons.onBuyClick = { - store.dispatch(WalletAction.TradeCryptoAction.Buy()) - } - rowButtons.onSellClick = { - store.dispatch(WalletAction.TradeCryptoAction.Sell) - } - rowButtons.onTradeClick = { - store.dispatch(WalletAction.DialogAction.ChooseTradeActionDialog) - } rowButtons.onSendClick = { store.dispatch(WalletAction.Send()) } @@ -273,6 +264,15 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), sellAllowed = selectedWallet.isAvailableToSell, sendAllowed = selectedWallet.mainButton.enabled, ) + rowButtons.onTradeClick = { + store.dispatch( + WalletAction.DialogAction.ChooseTradeActionDialog( + buyAllowed = selectedWallet.isAvailableToBuy, + sellAllowed = selectedWallet.isAvailableToSell, + swapAllowed = selectedWallet.isAvailableToSwap, + ), + ) + } } private fun handleWarnings(selectedWallet: WalletData) = with(binding) { 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 3fc5905990..cb940267b1 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 @@ -4,11 +4,16 @@ 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.show import com.tangem.tap.features.wallet.redux.WalletAction +import com.tangem.tap.features.wallet.redux.models.WalletDialog import com.tangem.tap.store import com.tangem.wallet.databinding.DialogWalletTradeBinding -class ChooseTradeActionBottomSheetDialog(context: Context) : BottomSheetDialog(context) { +class ChooseTradeActionBottomSheetDialog( + context: Context, + private val dialogData: WalletDialog.ChooseTradeActionDialog, +) : BottomSheetDialog(context) { var binding: DialogWalletTradeBinding? = null @@ -26,13 +31,26 @@ class ChooseTradeActionBottomSheetDialog(context: Context) : BottomSheetDialog(c store.dispatch(WalletAction.DialogAction.Hide) } - binding!!.dialogBtnBuy.setOnClickListener { - dismiss() - store.dispatch(WalletAction.TradeCryptoAction.Buy()) - } - binding!!.dialogBtnSell.setOnClickListener { - dismiss() - store.dispatch(WalletAction.TradeCryptoAction.Sell) + binding?.let { + with(it) + { + dialogBtnBuy.show(dialogData.buyAllowed) + dialogBtnSell.show(dialogData.sellAllowed) + dialogBtnSwap.show(dialogData.swapAllowed) + + dialogBtnBuy.setOnClickListener { + dismiss() + store.dispatch(WalletAction.TradeCryptoAction.Buy()) + } + dialogBtnSell.setOnClickListener { + dismiss() + store.dispatch(WalletAction.TradeCryptoAction.Sell) + } + dialogBtnSwap.setOnClickListener { + dismiss() + store.dispatch(WalletAction.TradeCryptoAction.Swap) + } + } } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/view/WalletDetailsButtonsRow.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/view/WalletDetailsButtonsRow.kt index 582b5f178c..5c73fa7531 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/view/WalletDetailsButtonsRow.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/view/WalletDetailsButtonsRow.kt @@ -5,6 +5,7 @@ import android.util.AttributeSet import android.view.LayoutInflater import android.widget.LinearLayout import androidx.core.view.isVisible +import com.tangem.tap.common.extensions.hide import com.tangem.wallet.databinding.ViewWalletDetailsButtonsRowBinding internal class WalletDetailsButtonsRow @JvmOverloads constructor( @@ -39,11 +40,9 @@ internal class WalletDetailsButtonsRow @JvmOverloads constructor( sendAllowed: Boolean, ) = with(binding) { containerExchangeButtons.isVisible = exchangeServiceFeatureOn - - btnBuy.isVisible = (buyAllowed && !sellAllowed) || (!buyAllowed && !sellAllowed) - btnBuy.isEnabled = buyAllowed - btnSell.isVisible = !buyAllowed && sellAllowed - btnTrade.isVisible = buyAllowed && sellAllowed + btnBuy.hide() + btnSell.hide() + btnTrade.isVisible = exchangeServiceFeatureOn btnSend.isEnabled = sendAllowed } } \ 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 e8fc90a242..ed9576d384 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 @@ -134,9 +134,15 @@ class SingleWalletView : WalletView() { sendAllowed = walletData.mainButton.enabled, ) - rowButtons.onBuyClick = { store.dispatch(WalletAction.TradeCryptoAction.Buy()) } - rowButtons.onSendClick = { store.dispatch(WalletAction.TradeCryptoAction.Sell) } - rowButtons.onTradeClick = { store.dispatch(WalletAction.DialogAction.ChooseTradeActionDialog) } + rowButtons.onTradeClick = { + store.dispatch( + WalletAction.DialogAction.ChooseTradeActionDialog( + buyAllowed = walletData.isAvailableToBuy, + sellAllowed = walletData.isAvailableToSell, + swapAllowed = walletData.isAvailableToSwap, + ), + ) + } rowButtons.onSendClick = { when (walletData.mainButton) { diff --git a/app/src/main/res/layout/dialog_wallet_trade.xml b/app/src/main/res/layout/dialog_wallet_trade.xml index cb4e47fecd..cc9299027f 100644 --- a/app/src/main/res/layout/dialog_wallet_trade.xml +++ b/app/src/main/res/layout/dialog_wallet_trade.xml @@ -27,7 +27,7 @@ android:textColor="@color/darkGray3" android:textSize="14sp" android:textStyle="bold" - app:drawableStartCompat="@drawable/ic_arrow_up" /> + app:drawableStartCompat="@drawable/ic_arrow_up_24" /> + app:drawableStartCompat="@drawable/ic_arrow_down_24" /> + + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 75b1a4e453..f772f94772 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,6 +16,7 @@ buildscript { plugins { id("com.google.dagger.hilt.android") version "2.44" apply false + kotlin("plugin.serialization") version Versions.kotlin apply false } allprojects { diff --git a/buildSrc/src/main/java/Dependency.kt b/buildSrc/src/main/java/Dependency.kt index 54ee97cd6d..3f2a1883da 100644 --- a/buildSrc/src/main/java/Dependency.kt +++ b/buildSrc/src/main/java/Dependency.kt @@ -67,6 +67,7 @@ object Library { const val zxingQrBarcodeScanner = "me.dm7.barcodescanner:zxing:" + Versions.zxingQrBarcodeScanner const val zxingQrCore = "com.google.zxing:core:" + Versions.zxingQrCode const val mviCoreWatcher = "com.github.badoo.mvicore:mvicore-diff:" + Versions.mviCore + const val kotlinSerialization = "org.jetbrains.kotlinx:kotlinx-serialization-json:" + Versions.kotlinSerialization } object Tangem { diff --git a/buildSrc/src/main/java/Versions.kt b/buildSrc/src/main/java/Versions.kt index 1ad00eea91..524e5e5277 100644 --- a/buildSrc/src/main/java/Versions.kt +++ b/buildSrc/src/main/java/Versions.kt @@ -56,6 +56,7 @@ object Versions { const val zxingQrBarcodeScanner = "1.9.8" const val zxingQrCode = "3.3.3" const val mviCore = "1.3.1" + const val kotlinSerialization = "1.4.1" // endregion Other libraries // region Tangem diff --git a/core/ui/src/main/res/drawable/ic_arrow_down_24.xml b/core/ui/src/main/res/drawable/ic_arrow_down_24.xml new file mode 100644 index 0000000000..90afd396ed --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_arrow_down_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/core/ui/src/main/res/drawable/ic_arrow_up_24.xml b/core/ui/src/main/res/drawable/ic_arrow_up_24.xml new file mode 100644 index 0000000000..57f3613ff6 --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_arrow_up_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/features/swap/domain/build.gradle.kts b/features/swap/domain/build.gradle.kts index 0d5065fe21..87fa664521 100644 --- a/features/swap/domain/build.gradle.kts +++ b/features/swap/domain/build.gradle.kts @@ -2,10 +2,10 @@ plugins { id("java-library") id("org.jetbrains.kotlin.jvm") kotlin("kapt") + kotlin("plugin.serialization") } dependencies { - /** Libs */ implementation(project(":libs:crypto")) implementation(project(":core:utils")) @@ -13,6 +13,9 @@ dependencies { /** DI */ implementation(Library.hiltCore) kapt(Library.hiltKapt) + + /** Other Libraries **/ + implementation(Library.kotlinSerialization) } java { diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/data/Currency.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/data/Currency.kt index cc69440af7..947c62e7bc 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/data/Currency.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/data/Currency.kt @@ -1,21 +1,25 @@ package com.tangem.feature.swap.domain.models.data -sealed class Currency( - open val id: String, - open val name: String, - open val symbol: String, - open val networkId: String, - open val logoUrl: String, -) { +import kotlinx.serialization.Serializable +@Serializable +sealed class Currency { + abstract val id: String + abstract val name: String + abstract val symbol: String + abstract val networkId: String + abstract val logoUrl: String + + @Serializable data class NativeToken( override val id: String, override val name: String, override val symbol: String, override val networkId: String, override val logoUrl: String, - ) : Currency(id, name, symbol, networkId, logoUrl) + ) : Currency() + @Serializable data class NonNativeToken( override val id: String, override val name: String, @@ -24,5 +28,5 @@ sealed class Currency( override val logoUrl: String, val contractAddress: String, val decimalCount: Int, - ) : Currency(id, name, symbol, networkId, logoUrl) + ) : Currency() } \ No newline at end of file diff --git a/features/swap/presentation/build.gradle.kts b/features/swap/presentation/build.gradle.kts index be71e61c6d..747a8690a8 100644 --- a/features/swap/presentation/build.gradle.kts +++ b/features/swap/presentation/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("com.android.library") kotlin("android") kotlin("kapt") + kotlin("plugin.serialization") id("com.google.dagger.hilt.android") } @@ -68,6 +69,7 @@ dependencies { /** Other libraries */ implementation(Library.composeShimmer) + implementation(Library.kotlinSerialization) /** DI */ implementation(Library.hilt) diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/presentation/SwapFragment.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/presentation/SwapFragment.kt index 118e2b6e34..71f56935ef 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/presentation/SwapFragment.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/presentation/SwapFragment.kt @@ -57,4 +57,8 @@ class SwapFragment : Fragment() { } } } + + companion object { + const val CURRENCY_BUNDLE_KEY = "swap_currency" + } } \ No newline at end of file diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapPermissionBottomSheetContent.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapPermissionBottomSheetContent.kt index 90082105f4..0d8f96198f 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapPermissionBottomSheetContent.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapPermissionBottomSheetContent.kt @@ -31,7 +31,7 @@ import com.tangem.feature.swap.presentation.R @Composable fun SwapPermissionBottomSheetContent( - data: SwapPermissionStateHolder, + data: SwapPermissionStateHolder?, onCancel: () -> Unit, ) { Column( @@ -54,7 +54,10 @@ fun SwapPermissionBottomSheetContent( SpacerH10() Text( - text = stringResource(id = R.string.swapping_permission_subheader, data.currency), + text = stringResource( + id = R.string.swapping_permission_subheader, + data?.currency ?: "", + ), color = TangemTheme.colors.text.secondary, style = TangemTheme.typography.body2, textAlign = TextAlign.Center, @@ -64,11 +67,11 @@ fun SwapPermissionBottomSheetContent( SpacerH16() ApprovalBottomSheetInfo( - currency = data.currency, - amount = data.amount, - walletAddress = data.walletAddress, - spenderAddress = data.spenderAddress, - fee = data.fee, + currency = data?.currency ?: "", + amount = data?.amount ?: "", + walletAddress = data?.walletAddress ?: "", + spenderAddress = data?.spenderAddress ?: "", + fee = data?.fee ?: "", ) SpacerH28() @@ -77,7 +80,7 @@ fun SwapPermissionBottomSheetContent( text = stringResource(id = R.string.swapping_permission_buttons_approve), icon = painterResource(id = R.drawable.ic_tangem_24), modifier = Modifier.fillMaxWidth(), - onClick = data.approveButton.onClick, + onClick = { data?.approveButton?.onClick?.invoke() }, ) SpacerH12() @@ -86,7 +89,7 @@ fun SwapPermissionBottomSheetContent( text = stringResource(id = R.string.common_cancel), modifier = Modifier.fillMaxWidth(), ) { - data.cancelButton.onClick() + data?.cancelButton?.onClick?.invoke() onCancel() } diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreen.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreen.kt index 5011b9ec33..e49409bd4e 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreen.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/SwapScreen.kt @@ -33,12 +33,10 @@ internal fun SwapScreen(stateHolder: SwapStateHolder) { ) }, sheetContent = { - if (stateHolder.permissionState != null) { SwapPermissionBottomSheetContent( data = stateHolder.permissionState, onCancel = { coroutineScope.launch { bottomSheetScaffoldState.bottomSheetState.collapse() } }, ) - } }, scaffoldState = bottomSheetScaffoldState, sheetShape = RoundedCornerShape( @@ -52,7 +50,9 @@ internal fun SwapScreen(stateHolder: SwapStateHolder) { state = stateHolder, onPermissionWarningClick = { coroutineScope.launch { - if (bottomSheetScaffoldState.bottomSheetState.isCollapsed) { + if (bottomSheetScaffoldState.bottomSheetState.isCollapsed + && stateHolder.permissionState != null + ) { bottomSheetScaffoldState.bottomSheetState.expand() } else { bottomSheetScaffoldState.bottomSheetState.collapse()