From 2a86be0cd0b03e10afde9729dc509a17318833de Mon Sep 17 00:00:00 2001 From: arvifox Date: Mon, 28 Aug 2023 14:02:46 +0300 Subject: [PATCH 01/20] sn-2869 swap bug fixes --- .../presentation/screens/swap/SwapViewModel.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt index b463c1a93..7c0a3b402 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt @@ -350,11 +350,13 @@ class SwapViewModel @AssistedInject constructor( onError(it) } .collectLatest { - if (it.reloadMarkets) getMarkets() + if (it.reloadMarkets) { + getMarkets() + property.reset() + } recalcDetails() toggleSwapButtonStatus() resetLoading() - property.reset() } } viewModelScope.launch { From 4680fad53fc990b8708fb18ab34deef44e65e1e9 Mon Sep 17 00:00:00 2001 From: AmadeyKuspakov Date: Mon, 28 Aug 2023 15:08:58 +0400 Subject: [PATCH 02/20] Minor internal additions --- .../presentation/get/card/details/SoraCardIBANCard.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/details/SoraCardIBANCard.kt b/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/details/SoraCardIBANCard.kt index 69831350c..7a4fa512e 100644 --- a/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/details/SoraCardIBANCard.kt +++ b/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/details/SoraCardIBANCard.kt @@ -45,6 +45,7 @@ import androidx.compose.material.Icon import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign @@ -54,6 +55,7 @@ import jp.co.soramitsu.common.presentation.compose.uikit.tokens.Image import jp.co.soramitsu.common.presentation.compose.uikit.tokens.Text import jp.co.soramitsu.common.presentation.compose.uikit.tokens.retrievePainter import jp.co.soramitsu.common.presentation.compose.uikit.tokens.retrieveString +import jp.co.soramitsu.common.util.ext.testTagAsId import jp.co.soramitsu.ui_core.component.card.ContentCard import jp.co.soramitsu.ui_core.resources.Dimens import jp.co.soramitsu.ui_core.theme.customColors @@ -83,6 +85,9 @@ fun SoraCardIBANCard( onCardClick: () -> Unit, ) { ContentCard( + modifier = remember { + Modifier.testTagAsId("IbanCardClick") + }, cornerRadius = Dimens.x4, onClick = onCardClick, ) { @@ -110,6 +115,7 @@ fun SoraCardIBANCard( if (soraCardIBANCardState.iban.isNotEmpty()) Icon( modifier = Modifier + .testTagAsId("IbanCardShareClick") .clickable(onClick = onShareClick) .wrapContentSize(), painter = soraCardIBANCardState.actionIcon.retrievePainter(), From fec661bef7440f351c8e3a1e969fa817efc8ad20 Mon Sep 17 00:00:00 2001 From: arvifox Date: Mon, 28 Aug 2023 18:59:19 +0300 Subject: [PATCH 03/20] sn-2882 xor balance warning fixes --- .../soramitsu/common/view/WarningTextCard.kt | 9 --- common/src/main/res/values-ar/strings.xml | 2 +- common/src/main/res/values-az/strings.xml | 2 +- common/src/main/res/values-de/strings.xml | 2 +- common/src/main/res/values-es/strings.xml | 2 +- common/src/main/res/values-fa/strings.xml | 2 +- common/src/main/res/values-fi/strings.xml | 2 +- common/src/main/res/values-fr/strings.xml | 2 +- common/src/main/res/values-hi-rIN/strings.xml | 2 +- common/src/main/res/values-in/strings.xml | 2 +- common/src/main/res/values-iw/strings.xml | 2 +- common/src/main/res/values-ja/strings.xml | 2 +- common/src/main/res/values-ms-rMY/strings.xml | 2 +- common/src/main/res/values-nb/strings.xml | 2 +- common/src/main/res/values-nl/strings.xml | 2 +- common/src/main/res/values-pt/strings.xml | 2 +- common/src/main/res/values-ru/strings.xml | 2 +- common/src/main/res/values-sr/strings.xml | 2 +- common/src/main/res/values-tr/strings.xml | 2 +- common/src/main/res/values-vi/strings.xml | 4 +- common/src/main/res/values-zh-rCN/strings.xml | 4 +- common/src/main/res/values-zh-rTW/strings.xml | 2 +- common/src/main/res/values/strings.xml | 2 +- .../domain/interfaces/AssetsInteractor.kt | 6 +- .../domain/AssetsInteractorImpl.kt | 25 +------ .../components/compose/send/SendScreen.kt | 5 +- .../screens/send/TransferAmountFragment.kt | 1 - .../screens/send/TransferAmountViewModel.kt | 8 +- .../presentation/states/SendState.kt | 1 - .../domain/AssetsInteractorTest.kt | 17 +---- .../send/TransferAmountViewModelTest.kt | 26 +------ .../compose/LiquidityAddConfirmScreen.kt | 1 - .../components/compose/LiquidityAddScreen.kt | 4 +- .../compose/LiquidityRemoveConfirmScreen.kt | 1 - .../compose/LiquidityRemoveScreen.kt | 4 +- .../components/compose/SwapMainScreen.kt | 3 +- .../liquidityadd/LiquidityAddViewModel.kt | 9 +-- .../LiquidityRemoveViewModel.kt | 9 +-- .../screens/swap/SwapViewModel.kt | 36 +++------ .../presentation/states/LiquidityAddState.kt | 1 - .../states/LiquidityRemoveState.kt | 1 - .../presentation/states/SwapMainState.kt | 2 - .../polkaswap/SwapViewModelTest.kt | 53 +++---------- .../add/AddLiquidityViewModelTest.kt | 12 +-- .../remove/RemoveLiquidityViewModelTest.kt | 12 +-- feature_referral_impl/build.gradle | 1 + .../presentation/ReferralBondUnbondXor.kt | 6 +- .../presentation/ReferralFragment.kt | 24 +++--- .../presentation/ReferralScreenState.kt | 1 - .../presentation/ReferralViewModel.kt | 74 +++++++++---------- .../presentation/ReferralViewModelTest.kt | 24 ++---- .../cardshub/CardsHubViewModel.kt | 2 - 52 files changed, 125 insertions(+), 301 deletions(-) diff --git a/common/src/main/java/jp/co/soramitsu/common/view/WarningTextCard.kt b/common/src/main/java/jp/co/soramitsu/common/view/WarningTextCard.kt index ec35c0402..6c5825961 100644 --- a/common/src/main/java/jp/co/soramitsu/common/view/WarningTextCard.kt +++ b/common/src/main/java/jp/co/soramitsu/common/view/WarningTextCard.kt @@ -32,9 +32,7 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.common.view -import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.background -import androidx.compose.foundation.border import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -80,13 +78,6 @@ fun WarningTextCard( shape = shape, ) .clip(shape) - .border( - border = BorderStroke( - 1.dp, - main, - ), - shape = shape - ) .padding( vertical = Dimens.x2, horizontal = Dimens.x3, diff --git a/common/src/main/res/values-ar/strings.xml b/common/src/main/res/values-ar/strings.xml index 596901152..2bd410746 100644 --- a/common/src/main/res/values-ar/strings.xml +++ b/common/src/main/res/values-ar/strings.xml @@ -539,7 +539,7 @@ ناجح الحالة You have succesfully imported an account - Your %s balance will be less than %s after this transaction. You won’t be able to pay for the network fee for another transaction. + Ensure that you have %s left after this transaction. Otherwise, you won’t be able to do another transaction. Switch node مظهر النظام البرلمان diff --git a/common/src/main/res/values-az/strings.xml b/common/src/main/res/values-az/strings.xml index 2b268dd48..b1ac07115 100644 --- a/common/src/main/res/values-az/strings.xml +++ b/common/src/main/res/values-az/strings.xml @@ -515,7 +515,7 @@ Successful Status You have succesfully imported an account - Your %s balance will be less than %s after this transaction. You won’t be able to pay for the network fee for another transaction. + Bu əməliyyatdan sonra %s qaldığınıza əmin olun. Əks halda, başqa sövdələşmə edə bilməyəcəksiniz. Switch node System appearance Parlament diff --git a/common/src/main/res/values-de/strings.xml b/common/src/main/res/values-de/strings.xml index 6c930247f..b4ca69980 100644 --- a/common/src/main/res/values-de/strings.xml +++ b/common/src/main/res/values-de/strings.xml @@ -515,7 +515,7 @@ Successful Status You have succesfully imported an account - Your %s balance will be less than %s after this transaction. You won’t be able to pay for the network fee for another transaction. + Ensure that you have %s left after this transaction. Otherwise, you won’t be able to do another transaction. Switch node System appearance Parlament diff --git a/common/src/main/res/values-es/strings.xml b/common/src/main/res/values-es/strings.xml index 8dd8ee1b9..240783435 100644 --- a/common/src/main/res/values-es/strings.xml +++ b/common/src/main/res/values-es/strings.xml @@ -515,7 +515,7 @@ Successful Estado You have succesfully imported an account - Your %s balance will be less than %s after this transaction. You won’t be able to pay for the network fee for another transaction. + Ensure that you have %s left after this transaction. Otherwise, you won’t be able to do another transaction. Switch node System appearance Parlamento diff --git a/common/src/main/res/values-fa/strings.xml b/common/src/main/res/values-fa/strings.xml index 3aa726a47..8f88ca0fb 100644 --- a/common/src/main/res/values-fa/strings.xml +++ b/common/src/main/res/values-fa/strings.xml @@ -515,7 +515,7 @@ Successful وضعیت You have succesfully imported an account - Your %s balance will be less than %s after this transaction. You won’t be able to pay for the network fee for another transaction. + Ensure that you have %s left after this transaction. Otherwise, you won’t be able to do another transaction. Switch node System appearance مجلس diff --git a/common/src/main/res/values-fi/strings.xml b/common/src/main/res/values-fi/strings.xml index 48cc26291..db738371c 100644 --- a/common/src/main/res/values-fi/strings.xml +++ b/common/src/main/res/values-fi/strings.xml @@ -515,7 +515,7 @@ Successful Tila You have succesfully imported an account - Your %s balance will be less than %s after this transaction. You won’t be able to pay for the network fee for another transaction. + Ensure that you have %s left after this transaction. Otherwise, you won’t be able to do another transaction. Switch node System appearance Parlamentti diff --git a/common/src/main/res/values-fr/strings.xml b/common/src/main/res/values-fr/strings.xml index 84cccc1bc..01cb982e5 100644 --- a/common/src/main/res/values-fr/strings.xml +++ b/common/src/main/res/values-fr/strings.xml @@ -515,7 +515,7 @@ Confirmée Statut Vous avez importé votre compte avec succès - Votre solde sera en deçà de %s après cette transaction. Vous ne pourrez plus payer les frais de transaction du réseau pour une autre transaction. + Assurez-vous qu’il vous reste %s après cette transaction. Sinon, vous ne pourrez pas effectuer une autre transaction. Changer de nœud Apparence du système Parlement diff --git a/common/src/main/res/values-hi-rIN/strings.xml b/common/src/main/res/values-hi-rIN/strings.xml index 56bd4470d..3cd1d399b 100644 --- a/common/src/main/res/values-hi-rIN/strings.xml +++ b/common/src/main/res/values-hi-rIN/strings.xml @@ -515,7 +515,7 @@ सफल स्थिति You have succesfully imported an account - Your %s balance will be less than %s after this transaction. You won’t be able to pay for the network fee for another transaction. + Ensure that you have %s left after this transaction. Otherwise, you won’t be able to do another transaction. Switch node सिस्टम स्थिति संसद diff --git a/common/src/main/res/values-in/strings.xml b/common/src/main/res/values-in/strings.xml index 5aacc1cfe..4a18bdb8e 100644 --- a/common/src/main/res/values-in/strings.xml +++ b/common/src/main/res/values-in/strings.xml @@ -510,7 +510,7 @@ Successful Status You have succesfully imported an account - Your %s balance will be less than %s after this transaction. You won’t be able to pay for the network fee for another transaction. + Ensure that you have %s left after this transaction. Otherwise, you won’t be able to do another transaction. Switch node System appearance Parlemen diff --git a/common/src/main/res/values-iw/strings.xml b/common/src/main/res/values-iw/strings.xml index e8533777f..af19abba2 100644 --- a/common/src/main/res/values-iw/strings.xml +++ b/common/src/main/res/values-iw/strings.xml @@ -527,7 +527,7 @@ מוצלח סטטוס ייבאת חשבון בהצלחה - היתרה שלך ב %s תהיה פחות מ- %s לאחר הטרנזקציה הזו. לא תוכל לשלם עבור עמלת הרשת עבור טרנזקציה נוספת. + ודא שנותרו לך %s לאחר עסקה זו. אחרת, לא תוכל לבצע עסקה אחרת. החלף צומת מראה חיצוני של המערכת פרלמנט diff --git a/common/src/main/res/values-ja/strings.xml b/common/src/main/res/values-ja/strings.xml index f8fc30308..33dbc024c 100644 --- a/common/src/main/res/values-ja/strings.xml +++ b/common/src/main/res/values-ja/strings.xml @@ -509,7 +509,7 @@ 成功 ステータス You have succesfully imported an account - Your %s balance will be less than %s after this transaction. You won’t be able to pay for the network fee for another transaction. + Ensure that you have %s left after this transaction. Otherwise, you won’t be able to do another transaction. Switch node システム外観 議会 diff --git a/common/src/main/res/values-ms-rMY/strings.xml b/common/src/main/res/values-ms-rMY/strings.xml index 886c0b48f..8c705e741 100644 --- a/common/src/main/res/values-ms-rMY/strings.xml +++ b/common/src/main/res/values-ms-rMY/strings.xml @@ -509,7 +509,7 @@ Berjaya Status Anda telah berjaya mengimport akaun - Baki %s anda akan kurang daripada %s selepas transaksi ini. Anda tidak akan dapat membayar yuran rangkaian untuk transaksi lain. + Pastikan anda mempunyai %s yang tersisa selepas transaksi ini. Jika tidak, anda tidak akan dapat melakukan transaksi lain. Tukar nod Penampilan sistem Parlimen diff --git a/common/src/main/res/values-nb/strings.xml b/common/src/main/res/values-nb/strings.xml index 5257155a4..d74ddaced 100644 --- a/common/src/main/res/values-nb/strings.xml +++ b/common/src/main/res/values-nb/strings.xml @@ -515,7 +515,7 @@ Successful Status You have succesfully imported an account - Your %s balance will be less than %s after this transaction. You won’t be able to pay for the network fee for another transaction. + Ensure that you have %s left after this transaction. Otherwise, you won’t be able to do another transaction. Switch node System appearance Parlamentet diff --git a/common/src/main/res/values-nl/strings.xml b/common/src/main/res/values-nl/strings.xml index d4c0d6eae..d29fc1d66 100644 --- a/common/src/main/res/values-nl/strings.xml +++ b/common/src/main/res/values-nl/strings.xml @@ -515,7 +515,7 @@ Succesvol Status You have succesfully imported an account - Your %s balance will be less than %s after this transaction. You won’t be able to pay for the network fee for another transaction. + Ensure that you have %s left after this transaction. Otherwise, you won’t be able to do another transaction. Switch node Systeem verschijning Parlement diff --git a/common/src/main/res/values-pt/strings.xml b/common/src/main/res/values-pt/strings.xml index 04b2bdd73..35966f0e1 100644 --- a/common/src/main/res/values-pt/strings.xml +++ b/common/src/main/res/values-pt/strings.xml @@ -515,7 +515,7 @@ Successful Status You have succesfully imported an account - Your %s balance will be less than %s after this transaction. You won’t be able to pay for the network fee for another transaction. + Ensure that you have %s left after this transaction. Otherwise, you won’t be able to do another transaction. Switch node System appearance Parlamento diff --git a/common/src/main/res/values-ru/strings.xml b/common/src/main/res/values-ru/strings.xml index 4c598dc9d..52a355e04 100644 --- a/common/src/main/res/values-ru/strings.xml +++ b/common/src/main/res/values-ru/strings.xml @@ -533,7 +533,7 @@ Successful Статус Вы успешно импортировали учетную запись - После этой транзакции ваш баланс %s будет меньше, чем %s. Вы не сможете оплатить комиссию сети за другую транзакцию. + Убедитесь, что у вас останется %s после этой транзакции. Иначе вы не сможете оплатить комиссию сети за другую транзакцию. Переключить ноду Внешний вид системы Парламент diff --git a/common/src/main/res/values-sr/strings.xml b/common/src/main/res/values-sr/strings.xml index cb11a141d..eae64df61 100644 --- a/common/src/main/res/values-sr/strings.xml +++ b/common/src/main/res/values-sr/strings.xml @@ -520,7 +520,7 @@ Successful Статус You have succesfully imported an account - Your %s balance will be less than %s after this transaction. You won’t be able to pay for the network fee for another transaction. + Ensure that you have %s left after this transaction. Otherwise, you won’t be able to do another transaction. Switch node System appearance Парламент diff --git a/common/src/main/res/values-tr/strings.xml b/common/src/main/res/values-tr/strings.xml index 0ba2a4dc3..242e2c9c3 100644 --- a/common/src/main/res/values-tr/strings.xml +++ b/common/src/main/res/values-tr/strings.xml @@ -515,7 +515,7 @@ Successful Durum You have succesfully imported an account - Your %s balance will be less than %s after this transaction. You won’t be able to pay for the network fee for another transaction. + Ensure that you have %s left after this transaction. Otherwise, you won’t be able to do another transaction. Switch node System appearance Parlamento diff --git a/common/src/main/res/values-vi/strings.xml b/common/src/main/res/values-vi/strings.xml index 9ec72553e..01ee4c10e 100644 --- a/common/src/main/res/values-vi/strings.xml +++ b/common/src/main/res/values-vi/strings.xml @@ -475,7 +475,7 @@ Chuyển Tôi đã có thẻ Phí dịch vụ hàng năm € 0 - Card info + Thông tin thẻ Không bao gồm ứng dụng Cư dân từ một số quốc gia không thể đăng ký Thẻ SORA tại thời điểm này Mua XOR bằng EUR @@ -509,7 +509,7 @@ Thành công Trạng thái Bạn đã nhập thành công một tài khoản - Số dư %s của bạn sẽ ít hơn %s sau giao dịch này. Bạn sẽ không thể thanh toán phí mạng cho một giao dịch khác. + Đảm bảo rằng bạn còn %s sau giao dịch này. Nếu không, bạn sẽ không thể thực hiện một giao dịch khác. Chuyển node Hệ thống hiển thị Nghị viện diff --git a/common/src/main/res/values-zh-rCN/strings.xml b/common/src/main/res/values-zh-rCN/strings.xml index 200926889..ce3eb039a 100644 --- a/common/src/main/res/values-zh-rCN/strings.xml +++ b/common/src/main/res/values-zh-rCN/strings.xml @@ -475,7 +475,7 @@ 转账 我已经有一张卡了 年服务费€0 - Card info + 卡片信息 应用程序排除 来自某些国家的居民目前无法申请SORA卡。 用欧元购买XOR @@ -509,7 +509,7 @@ 成功的 状态 您已成功导入一个账户 - 此次交易后,您的%s余额将少于%s。您将无法支付另一笔交易的网络费用。 + 确保在此事务之后还剩下 %s。否则,您将无法进行其他交易。 切换节点 系统外观 议会 diff --git a/common/src/main/res/values-zh-rTW/strings.xml b/common/src/main/res/values-zh-rTW/strings.xml index 525351523..b0e8fb1f3 100644 --- a/common/src/main/res/values-zh-rTW/strings.xml +++ b/common/src/main/res/values-zh-rTW/strings.xml @@ -510,7 +510,7 @@ Successful 狀態 You have succesfully imported an account - Your %s balance will be less than %s after this transaction. You won’t be able to pay for the network fee for another transaction. + Ensure that you have %s left after this transaction. Otherwise, you won’t be able to do another transaction. Switch node System appearance 議會 diff --git a/common/src/main/res/values/strings.xml b/common/src/main/res/values/strings.xml index 22c5ee6e2..200ff564f 100644 --- a/common/src/main/res/values/strings.xml +++ b/common/src/main/res/values/strings.xml @@ -515,7 +515,7 @@ Successful Status You have succesfully imported an account - Your %s balance will be less than %s after this transaction. You won’t be able to pay for the network fee for another transaction. + Ensure that you have %s left after this transaction. Otherwise, you won’t be able to do another transaction. Switch node System appearance Parliament diff --git a/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/interfaces/AssetsInteractor.kt b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/interfaces/AssetsInteractor.kt index ce6a1d5e7..e7d971d69 100644 --- a/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/interfaces/AssetsInteractor.kt +++ b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/interfaces/AssetsInteractor.kt @@ -44,12 +44,8 @@ interface AssetsInteractor { suspend fun calcTransactionFee(to: String, token: Token, amount: BigDecimal): BigDecimal? suspend fun isNotEnoughXorLeftAfterTransaction( - primaryToken: Token, - primaryTokenAmount: BigDecimal, - secondaryToken: Token?, - secondaryTokenAmount: BigDecimal?, networkFeeInXor: BigDecimal, - isUnbonding: Boolean = false + xorChange: BigDecimal? = null, ): Boolean suspend fun getAccountName(): String diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorImpl.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorImpl.kt index 9db2bf3d1..4373e7370 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorImpl.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorImpl.kt @@ -79,34 +79,13 @@ class AssetsInteractorImpl constructor( } override suspend fun isNotEnoughXorLeftAfterTransaction( - primaryToken: Token, - primaryTokenAmount: BigDecimal, - secondaryToken: Token?, - secondaryTokenAmount: BigDecimal?, networkFeeInXor: BigDecimal, - isUnbonding: Boolean, + xorChange: BigDecimal?, ): Boolean { val xorAssetBalanceAmount = getAssetOrThrow(SubstrateOptionsProvider.feeAssetId).balance.transferable - if (primaryToken.id != SubstrateOptionsProvider.feeAssetId && - secondaryToken?.id != SubstrateOptionsProvider.feeAssetId - ) { - return xorAssetBalanceAmount.minus(networkFeeInXor) <= networkFeeInXor - } - - if (primaryToken.id == SubstrateOptionsProvider.feeAssetId) { - return if (isUnbonding) { - xorAssetBalanceAmount.plus(primaryTokenAmount) - .minus(networkFeeInXor) <= networkFeeInXor - } else { - xorAssetBalanceAmount.minus(primaryTokenAmount) - .minus(networkFeeInXor) <= networkFeeInXor - } - } - - return xorAssetBalanceAmount.plus(secondaryTokenAmount.orZero()) - .minus(networkFeeInXor) <= networkFeeInXor + return xorAssetBalanceAmount.minus(xorChange.orZero()).minus(networkFeeInXor) <= networkFeeInXor } override suspend fun getAccountName(): String = userRepository.getCurSoraAccount().accountName diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/send/SendScreen.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/send/SendScreen.kt index 8249bbef0..6db71105c 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/send/SendScreen.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/send/SendScreen.kt @@ -87,7 +87,6 @@ internal fun SendScreen( feeLoading: Boolean, reviewEnabled: Boolean, shouldTransactionReminderInsufficientWarningBeShown: Boolean, - transactionFeeToken: String ) { SendScreenAddress( address = address, @@ -119,10 +118,9 @@ internal fun SendScreen( color = Color.Transparent ) WarningTextCard( - title = stringResource(id = R.string.common_title_warning), text = stringResource( id = R.string.swap_confirmation_screen_warning_balance_afterwards_transaction_is_too_small, - formatArgs = arrayOf(transactionFeeToken, feeAmount) + formatArgs = arrayOf(feeAmount), ) ) } @@ -238,7 +236,6 @@ private fun PreviewSendScreen() { feeLoading = true, reviewEnabled = false, shouldTransactionReminderInsufficientWarningBeShown = true, - transactionFeeToken = "" ) } } diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountFragment.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountFragment.kt index cafd0a457..6eb1fca25 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountFragment.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountFragment.kt @@ -176,7 +176,6 @@ class TransferAmountFragment : SoraBaseFragment() { feeAmount = state.fee, reviewEnabled = state.reviewEnabled, shouldTransactionReminderInsufficientWarningBeShown = state.shouldTransactionReminderInsufficientWarningBeShown, - transactionFeeToken = state.transactionFeeToken ) } diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt index 356ffc465..728f76ad4 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt @@ -200,16 +200,12 @@ class TransferAmountViewModel @AssistedInject constructor( return@with val result = interactor.isNotEnoughXorLeftAfterTransaction( - primaryToken = token, - primaryTokenAmount = amount, - secondaryToken = null, - secondaryTokenAmount = null, - networkFeeInXor = fee.orZero() + networkFeeInXor = fee.orZero(), + xorChange = if (token.id == SubstrateOptionsProvider.feeAssetId) amount else null, ) sendState = sendState.copy( shouldTransactionReminderInsufficientWarningBeShown = result, - transactionFeeToken = feeAsset?.token?.symbol ?: "" ) } diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/states/SendState.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/states/SendState.kt index 30eef77cb..327156007 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/states/SendState.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/states/SendState.kt @@ -47,5 +47,4 @@ internal data class SendState( val feeLoading: Boolean = true, val selectSearchAssetState: SelectSearchAssetState = SelectSearchAssetState("", emptyList()), val shouldTransactionReminderInsufficientWarningBeShown: Boolean = false, - val transactionFeeToken: String = "" ) diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorTest.kt index 829a9ee9b..c1ec9e2e6 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorTest.kt @@ -228,12 +228,8 @@ class AssetsInteractorTest { ) val result = interactor.isNotEnoughXorLeftAfterTransaction( - primaryToken = oneToken(), - primaryTokenAmount = BigDecimal(1), - secondaryToken = oneToken(), - secondaryTokenAmount = BigDecimal(1), + xorChange = BigDecimal(1), networkFeeInXor = BigDecimal(1), - isUnbonding = false ) Assert.assertEquals( @@ -262,10 +258,7 @@ class AssetsInteractorTest { ) val result = interactor.isNotEnoughXorLeftAfterTransaction( - primaryToken = xorToken, - primaryTokenAmount = BigDecimal(1), - secondaryToken = oneToken(), - secondaryTokenAmount = BigDecimal(1), + xorChange = BigDecimal(1), networkFeeInXor = BigDecimal(1) ) @@ -295,12 +288,8 @@ class AssetsInteractorTest { ) val result = interactor.isNotEnoughXorLeftAfterTransaction( - primaryToken = oneToken(), - primaryTokenAmount = BigDecimal(1), - secondaryToken = xorToken, - secondaryTokenAmount = BigDecimal(1), + xorChange = BigDecimal(1), networkFeeInXor = BigDecimal(1), - isUnbonding = false ) Assert.assertEquals(true, result) diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt index 6dca92f19..6338abb78 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt @@ -125,10 +125,6 @@ class TransferAmountViewModelTest { assetsInteractor.isNotEnoughXorLeftAfterTransaction( any(), any(), - any(), - any(), - any(), - any() ) } returns false coEvery { @@ -209,12 +205,8 @@ class TransferAmountViewModelTest { advanceUntilIdle() coVerify(atMost = 1) { assetsInteractor.isNotEnoughXorLeftAfterTransaction( - primaryToken = PolkaswapTestData.XOR_ASSET.token, - primaryTokenAmount = BigDecimal.ONE, - secondaryToken = null, - secondaryTokenAmount = null, + xorChange = BigDecimal.ONE, networkFeeInXor = networkFee, - isUnbonding = false ) } transferAmountViewModel.onTokenChange(PolkaswapTestData.VAL_ASSET.token.id) @@ -223,12 +215,7 @@ class TransferAmountViewModelTest { advanceUntilIdle() coVerify(atMost = 1) { assetsInteractor.isNotEnoughXorLeftAfterTransaction( - primaryToken = PolkaswapTestData.VAL_ASSET.token, - primaryTokenAmount = BigDecimal.TEN, - secondaryToken = null, - secondaryTokenAmount = null, networkFeeInXor = networkFee, - isUnbonding = false ) } } @@ -245,12 +232,7 @@ class TransferAmountViewModelTest { advanceUntilIdle() coVerify(atMost = 1) { assetsInteractor.isNotEnoughXorLeftAfterTransaction( - primaryToken = any(), - primaryTokenAmount = any(), - secondaryToken = any(), - secondaryTokenAmount = any(), networkFeeInXor = any(), - isUnbonding = any() ) } transferAmountViewModel.onTokenChange(PolkaswapTestData.XOR_ASSET.token.id) @@ -259,12 +241,8 @@ class TransferAmountViewModelTest { advanceUntilIdle() coVerify(atMost = 1) { assetsInteractor.isNotEnoughXorLeftAfterTransaction( - primaryToken = PolkaswapTestData.XOR_ASSET.token, - primaryTokenAmount = BigDecimal.TEN, - secondaryToken = null, - secondaryTokenAmount = null, + xorChange = BigDecimal.TEN, networkFeeInXor = networkFee, - isUnbonding = false ) } } diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityAddConfirmScreen.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityAddConfirmScreen.kt index 3e230222f..3a6c93bac 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityAddConfirmScreen.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityAddConfirmScreen.kt @@ -288,7 +288,6 @@ private fun PreviewLiquidityRemoveConfirmScreen() { ), ), shouldTransactionReminderInsufficientWarningBeShown = true, - transactionFeeToken = "", poolInFarming = false, ), onConfirmClick = {}, diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityAddScreen.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityAddScreen.kt index aa08d72f7..a3f1e2812 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityAddScreen.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityAddScreen.kt @@ -153,10 +153,9 @@ internal fun LiquidityAddScreen( color = Color.Transparent ) WarningTextCard( - title = stringResource(id = R.string.common_title_warning), text = stringResource( id = R.string.swap_confirmation_screen_warning_balance_afterwards_transaction_is_too_small, - formatArgs = arrayOf(state.transactionFeeToken, state.prices.fee) + formatArgs = arrayOf(state.prices.fee), ) ) } @@ -293,7 +292,6 @@ private fun PreviewLiquidityRemoveScreen() { ), selectSearchAssetState = null, shouldTransactionReminderInsufficientWarningBeShown = true, - transactionFeeToken = "" ), onSelect1 = {}, onSelect2 = {}, diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityRemoveConfirmScreen.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityRemoveConfirmScreen.kt index 2d23a9733..8044b126f 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityRemoveConfirmScreen.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityRemoveConfirmScreen.kt @@ -285,7 +285,6 @@ private fun PreviewLiquidityRemoveConfirmScreen() { ), ), shouldTransactionReminderInsufficientWarningBeShown = true, - transactionFeeToken = "", poolInFarming = false, ), onConfirmClick = {}, diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityRemoveScreen.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityRemoveScreen.kt index 86acb10cb..ee0e1b5ed 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityRemoveScreen.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityRemoveScreen.kt @@ -152,10 +152,9 @@ internal fun LiquidityRemoveScreen( color = Color.Transparent ) WarningTextCard( - title = stringResource(id = R.string.common_title_warning), text = stringResource( id = R.string.swap_confirmation_screen_warning_balance_afterwards_transaction_is_too_small, - formatArgs = arrayOf(state.transactionFeeToken, state.prices.fee) + formatArgs = arrayOf(state.prices.fee) ) ) } @@ -269,7 +268,6 @@ private fun PreviewLiquidityRemoveScreen() { ), ), shouldTransactionReminderInsufficientWarningBeShown = true, - transactionFeeToken = "", poolInFarming = true, ), ) diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapMainScreen.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapMainScreen.kt index 96456d1dc..d7f1e8747 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapMainScreen.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapMainScreen.kt @@ -162,10 +162,9 @@ internal fun SwapMainScreen( if (state.details.shouldTransactionReminderInsufficientWarningBeShown) { Divider(color = Color.Transparent, modifier = Modifier.height(Dimens.x2)) WarningTextCard( - title = stringResource(id = R.string.common_title_warning), text = stringResource( id = R.string.swap_confirmation_screen_warning_balance_afterwards_transaction_is_too_small, - formatArgs = arrayOf(state.details.transactionFeeToken, state.details.transactionFee) + formatArgs = arrayOf(state.details.transactionFee), ) ) } diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt index e80f2cc96..3823f855c 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt @@ -193,7 +193,6 @@ class LiquidityAddViewModel @AssistedInject constructor( ), selectSearchAssetState = null, shouldTransactionReminderInsufficientWarningBeShown = false, - transactionFeeToken = "" ) ) @@ -488,16 +487,12 @@ class LiquidityAddViewModel @AssistedInject constructor( return@with val result = assetsInteractor.isNotEnoughXorLeftAfterTransaction( - primaryToken = assetState1.token, - primaryTokenAmount = assetState1.amount, - secondaryToken = null, - secondaryTokenAmount = null, - networkFeeInXor = networkFee + networkFeeInXor = networkFee, + xorChange = if (assetState1.token.id == SubstrateOptionsProvider.feeAssetId) assetState1.amount else null, ) addState = addState.copy( shouldTransactionReminderInsufficientWarningBeShown = result, - transactionFeeToken = feeToken().symbol ) } diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityremove/LiquidityRemoveViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityremove/LiquidityRemoveViewModel.kt index 60749c53a..645f69337 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityremove/LiquidityRemoveViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityremove/LiquidityRemoveViewModel.kt @@ -161,7 +161,6 @@ class LiquidityRemoveViewModel @AssistedInject constructor( ), ), shouldTransactionReminderInsufficientWarningBeShown = false, - transactionFeeToken = "", poolInFarming = poolInFarming, ) ) @@ -691,16 +690,12 @@ class LiquidityRemoveViewModel @AssistedInject constructor( return@with val result = assetsInteractor.isNotEnoughXorLeftAfterTransaction( - primaryToken = assetState1.token, - primaryTokenAmount = assetState1.amount, - secondaryToken = null, - secondaryTokenAmount = null, - networkFeeInXor = networkFee.orZero() + networkFeeInXor = networkFee.orZero(), + xorChange = if (assetState1.token.id == SubstrateOptionsProvider.feeAssetId) -assetState1.amount else null, ) removeState = removeState.copy( shouldTransactionReminderInsufficientWarningBeShown = result, - transactionFeeToken = feeToken().symbol ) } diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt index 7c0a3b402..9b13c36a0 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt @@ -90,9 +90,7 @@ import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -152,7 +150,6 @@ class SwapViewModel @AssistedInject constructor( private var desired: WithDesired = WithDesired.INPUT private var swapDetails: SwapDetails? = null private var networkFee: BigDecimal? = null - private var hasXorReminderWarningBeenChecked = false private val _swapMainState = MutableStateFlow( SwapMainState( @@ -356,6 +353,7 @@ class SwapViewModel @AssistedInject constructor( } recalcDetails() toggleSwapButtonStatus() + updateTransactionReminderWarningVisibility() resetLoading() } } @@ -385,18 +383,6 @@ class SwapViewModel @AssistedInject constructor( } } } - - merge(fromAmountFlow, toAmountFlow) - .filter { - _swapMainState.value.tokenFromState?.token?.id == SubstrateOptionsProvider.feeAssetId || - _swapMainState.value.tokenToState?.token?.id == SubstrateOptionsProvider.feeAssetId || - !hasXorReminderWarningBeenChecked - }.onEach { - updateTransactionReminderWarningVisibility() - hasXorReminderWarningBeenChecked = true - } - .flowOn(coroutineManager.io) - .launchIn(viewModelScope) } fun onDisclaimerClose() { @@ -472,18 +458,19 @@ class SwapViewModel @AssistedInject constructor( with(_swapMainState.value) { if (tokenFromState == null || tokenToState == null) return@with + val change = if (tokenFromState.token.id == SubstrateOptionsProvider.feeAssetId) { + tokenFromState.amount + } else if (tokenToState.token.id == SubstrateOptionsProvider.feeAssetId) { + -tokenToState.amount + } else { null } val result = assetsInteractor.isNotEnoughXorLeftAfterTransaction( - primaryToken = tokenFromState.token, - primaryTokenAmount = tokenFromState.amount, - secondaryToken = tokenToState.token, - secondaryTokenAmount = tokenToState.amount, - networkFeeInXor = networkFee.orZero() + networkFeeInXor = networkFee.orZero(), + xorChange = change, ) _swapMainState.value = _swapMainState.value.copy( details = details.copy( - shouldTransactionReminderInsufficientWarningBeShown = result, - transactionFeeToken = feeToken().symbol + shouldTransactionReminderInsufficientWarningBeShown = result && swapButtonState.enabled, ) ) } @@ -492,14 +479,12 @@ class SwapViewModel @AssistedInject constructor( assetsList.find { it.token.id == tokenId }?.let { toAndFromAssetsSelected(null, it.token) } - hasXorReminderWarningBeenChecked = false } fun toAssetSelected(tokenId: String) { assetsList.find { it.token.id == tokenId }?.let { toAndFromAssetsSelected(it.token, null) } - hasXorReminderWarningBeenChecked = false } fun onMarketSelected(market: Market) { @@ -521,9 +506,6 @@ class SwapViewModel @AssistedInject constructor( ) setSwapButtonLoading(true) onChangedProperty.set(property.newReloadMarkets(false)) - viewModelScope.launch { - updateTransactionReminderWarningVisibility() - } } private fun toAndFromAssetsSelected(to: Token?, from: Token?) { diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/LiquidityAddState.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/LiquidityAddState.kt index 0d49f51de..f6b4ce30f 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/LiquidityAddState.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/LiquidityAddState.kt @@ -48,7 +48,6 @@ data class LiquidityAddState( val selectSearchAssetState: SelectSearchAssetState?, val hintVisible: Boolean, val shouldTransactionReminderInsufficientWarningBeShown: Boolean, - val transactionFeeToken: String ) data class LiquidityAddConfirmState( diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/LiquidityRemoveState.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/LiquidityRemoveState.kt index 31fa82e2c..9f0542a0d 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/LiquidityRemoveState.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/LiquidityRemoveState.kt @@ -45,7 +45,6 @@ data class LiquidityRemoveState( val confirm: LiquidityRemoveConfirmState, val hintVisible: Boolean, val shouldTransactionReminderInsufficientWarningBeShown: Boolean, - val transactionFeeToken: String, val poolInFarming: Boolean, ) diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/SwapMainState.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/SwapMainState.kt index 821f15488..5c6ccd2ef 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/SwapMainState.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/SwapMainState.kt @@ -68,7 +68,6 @@ data class SwapDetailsState( val lpFee: String, val route: String, val shouldTransactionReminderInsufficientWarningBeShown: Boolean, - val transactionFeeToken: String ) fun defaultSwapDetailsState() = @@ -86,5 +85,4 @@ fun defaultSwapDetailsState() = lpFee = "", route = "", shouldTransactionReminderInsufficientWarningBeShown = false, - transactionFeeToken = "" ) diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt index 80d566306..224822860 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt @@ -60,7 +60,6 @@ import jp.co.soramitsu.test_data.TestTokens import jp.co.soramitsu.test_shared.MainCoroutineRule import jp.co.soramitsu.test_shared.anyNonNull import jp.co.soramitsu.test_shared.getOrAwaitValue -import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.flow @@ -80,15 +79,15 @@ import org.mockito.Mock import org.mockito.Mockito import org.mockito.junit.MockitoJUnitRunner import org.mockito.kotlin.any +import org.mockito.kotlin.anyOrNull +import org.mockito.kotlin.atLeast import org.mockito.kotlin.atLeastOnce -import org.mockito.kotlin.atMost import org.mockito.kotlin.times import java.math.BigDecimal import org.mockito.kotlin.verify as kVerify @FlowPreview @ExperimentalCoroutinesApi -@OptIn(ExperimentalStdlibApi::class) @RunWith(MockitoJUnitRunner::class) class SwapViewModelTest { @@ -155,19 +154,11 @@ class SwapViewModelTest { given(assetsInteractor.subscribeAssetsActiveOfCurAccount()).willReturn(flowOf(assets)) given( assetsInteractor.isNotEnoughXorLeftAfterTransaction( - primaryToken = any(), - primaryTokenAmount = any(), - secondaryToken = any(), - secondaryTokenAmount = any(), networkFeeInXor = any(), - isUnbonding = any() + xorChange = anyOrNull(), ) ).willReturn(false) - given( - coroutineManager.io - ).willReturn(this.coroutineContext[CoroutineDispatcher]!!) - setUpAfterViewModelInit() viewModel = SwapViewModel( assetsInteractor, @@ -415,12 +406,8 @@ class SwapViewModelTest { assetsInteractor, atLeastOnce() ).isNotEnoughXorLeftAfterTransaction( - primaryToken = PolkaswapTestData.XOR_ASSET.token, - primaryTokenAmount = BigDecimal.ONE, - secondaryToken = PolkaswapTestData.VAL_ASSET.token, - secondaryTokenAmount = BigDecimal.ZERO, + xorChange = BigDecimal.ONE, networkFeeInXor = networkFee, - isUnbonding = false ) viewModel.onToAmountChange(BigDecimal.ONE) @@ -429,14 +416,10 @@ class SwapViewModelTest { kVerify( mock = assetsInteractor, - times(1) + atLeast(1) ).isNotEnoughXorLeftAfterTransaction( - primaryToken = PolkaswapTestData.XOR_ASSET.token, - primaryTokenAmount = BigDecimal.ONE, - secondaryToken = PolkaswapTestData.VAL_ASSET.token, - secondaryTokenAmount = BigDecimal.ONE, + xorChange = BigDecimal.ONE, networkFeeInXor = networkFee, - isUnbonding = false ) viewModel.fromAssetSelected(TestAssets.pswapAsset().token.id) @@ -449,14 +432,10 @@ class SwapViewModelTest { kVerify( mock = assetsInteractor, - atMost(1) + atLeast(1) ).isNotEnoughXorLeftAfterTransaction( - primaryToken = TestAssets.pswapAsset().token, - primaryTokenAmount = BigDecimal.TEN, - secondaryToken = PolkaswapTestData.VAL_ASSET.token, - secondaryTokenAmount = BigDecimal.ONE, networkFeeInXor = networkFee, - isUnbonding = false + xorChange = null, ) } @@ -480,14 +459,10 @@ class SwapViewModelTest { kVerify( mock = assetsInteractor, - atMost(1) + atLeast(1) ).isNotEnoughXorLeftAfterTransaction( - primaryToken = any(), - primaryTokenAmount = any(), - secondaryToken = any(), - secondaryTokenAmount = any(), - networkFeeInXor = any(), - isUnbonding = any() + networkFeeInXor = networkFee, + xorChange = null, ) viewModel.fromAssetSelected(TestAssets.xorAsset().token.id) @@ -502,12 +477,8 @@ class SwapViewModelTest { mock = assetsInteractor, times(1) ).isNotEnoughXorLeftAfterTransaction( - primaryToken = TestAssets.xorAsset().token, - primaryTokenAmount = BigDecimal.TEN, - secondaryToken = PolkaswapTestData.VAL_ASSET.token, - secondaryTokenAmount = BigDecimal.ONE, + xorChange = BigDecimal.TEN, networkFeeInXor = networkFee, - isUnbonding = false ) } } diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt index e3c7ff293..458dde500 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt @@ -160,12 +160,8 @@ class AddLiquidityViewModelTest { every { TestTokens.xstToken.iconUri() } returns mockedUri given( assetsInteractor.isNotEnoughXorLeftAfterTransaction( - primaryToken = any(), - primaryTokenAmount = any(), - secondaryToken = anyOrNull(), - secondaryTokenAmount = anyOrNull(), networkFeeInXor = any(), - isUnbonding = any() + xorChange = any(), ) ).willReturn(false) given(poolsInteractor.subscribeReservesCache(XOR_ASSET.token.id, VAL_ASSET.token.id)) @@ -447,12 +443,8 @@ class AddLiquidityViewModelTest { assetsInteractor, times(1) ).isNotEnoughXorLeftAfterTransaction( - primaryToken = XOR_ASSET.token, - primaryTokenAmount = BigDecimal.TEN, - secondaryToken = null, - secondaryTokenAmount = null, + xorChange = BigDecimal.TEN, networkFeeInXor = LIQUIDITY_DETAILS.networkFee, - isUnbonding = false ) } } diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/remove/RemoveLiquidityViewModelTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/remove/RemoveLiquidityViewModelTest.kt index 1d0eb6656..bd0bab202 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/remove/RemoveLiquidityViewModelTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/remove/RemoveLiquidityViewModelTest.kt @@ -164,12 +164,8 @@ class RemoveLiquidityViewModelTest { given( assetsInteractor.isNotEnoughXorLeftAfterTransaction( - primaryToken = any(), - primaryTokenAmount = any(), - secondaryToken = anyOrNull(), - secondaryTokenAmount = anyOrNull(), networkFeeInXor = any(), - isUnbonding = any() + xorChange = any(), ) ).willReturn(false) } @@ -266,12 +262,8 @@ class RemoveLiquidityViewModelTest { mock = assetsInteractor, mode = times(1) ).isNotEnoughXorLeftAfterTransaction( - primaryToken = TestTokens.xorToken, - primaryTokenAmount = BigDecimal.ONE, // is not TEN due to basePooled in POOL_DATA - secondaryToken = null, - secondaryTokenAmount = null, + xorChange = -BigDecimal.ONE, // is not TEN due to basePooled in POOL_DATA networkFeeInXor = NETWORK_FEE, - isUnbonding = false ) } } diff --git a/feature_referral_impl/build.gradle b/feature_referral_impl/build.gradle index f2dba8419..b2972c337 100644 --- a/feature_referral_impl/build.gradle +++ b/feature_referral_impl/build.gradle @@ -93,6 +93,7 @@ dependencies { implementation composeMaterialDep implementation composeAnimationDep implementation composeActivityDep + implementation composeLifecycleDep implementation composeViewModelDep implementation composeToolingPreviewDep implementation composeLiveDataDep diff --git a/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralBondUnbondXor.kt b/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralBondUnbondXor.kt index 551c5c137..031ff3cac 100644 --- a/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralBondUnbondXor.kt +++ b/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralBondUnbondXor.kt @@ -132,10 +132,9 @@ fun ReferralBondXor( color = Color.Transparent ) WarningTextCard( - title = stringResource(id = R.string.common_title_warning), text = stringResource( id = R.string.swap_confirmation_screen_warning_balance_afterwards_transaction_is_too_small, - formatArgs = arrayOf(state.transactionFeeToken, common.extrinsicFee) + formatArgs = arrayOf(common.extrinsicFee) ) ) } @@ -220,10 +219,9 @@ fun ReferralUnbondXor( color = Color.Transparent ) WarningTextCard( - title = stringResource(id = R.string.common_title_warning), text = stringResource( id = R.string.swap_confirmation_screen_warning_balance_afterwards_transaction_is_too_small, - formatArgs = arrayOf(state.transactionFeeToken, common.extrinsicFee) + formatArgs = arrayOf(common.extrinsicFee) ) ) } diff --git a/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralFragment.kt b/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralFragment.kt index 57820747b..9c85f924c 100644 --- a/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralFragment.kt +++ b/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralFragment.kt @@ -46,6 +46,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.fragment.app.viewModels +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import dagger.hilt.android.AndroidEntryPoint @@ -90,7 +91,7 @@ class ReferralFragment : SoraBaseFragment() { ) { FooWrapper(scrollState) { ReferralWelcomePageScreen( - state = viewModel.referralScreenState, + state = viewModel.referralScreenState.collectAsStateWithLifecycle().value, onStartInviting = { viewModel.openBond() navController.navigate(ReferralFeatureRoutes.BOND_XOR) @@ -108,7 +109,7 @@ class ReferralFragment : SoraBaseFragment() { ) { FooWrapper(scrollState) { ReferralProgramPage( - state = viewModel.referralScreenState, + state = viewModel.referralScreenState.collectAsStateWithLifecycle().value, onGetMoreInvitations = { viewModel.openBond() navController.navigate(ReferralFeatureRoutes.BOND_XOR) @@ -133,9 +134,10 @@ class ReferralFragment : SoraBaseFragment() { route = ReferralFeatureRoutes.BOND_XOR ) { FooWrapper(scrollState) { + val state = viewModel.referralScreenState.collectAsStateWithLifecycle().value ReferralBondXor( - common = viewModel.referralScreenState.common, - state = viewModel.referralScreenState.bondState, + common = state.common, + state = state.bondState, onBondInvitationsCountChange = { viewModel.onBondValueChange(it) }, onBondMinus = { viewModel.onBondMinus() }, onBondPlus = { viewModel.onBondPlus() }, @@ -148,9 +150,10 @@ class ReferralFragment : SoraBaseFragment() { route = ReferralFeatureRoutes.UNBOND_XOR ) { FooWrapper(scrollState) { + val state = viewModel.referralScreenState.collectAsStateWithLifecycle().value ReferralUnbondXor( - common = viewModel.referralScreenState.common, - state = viewModel.referralScreenState.bondState, + common = state.common, + state = state.bondState, onUnbondInvitationsCountChange = { viewModel.onUnbondValueChange(it) }, onUnbondMinus = { viewModel.onUnbondMinus() }, onUnbondPlus = { viewModel.onUnbondPlus() }, @@ -164,8 +167,8 @@ class ReferralFragment : SoraBaseFragment() { ) { FooWrapper(scrollState) { ReferrerInput( - common = viewModel.referralScreenState.common, - state = viewModel.referralScreenState.referrerInputState, + common = viewModel.referralScreenState.collectAsStateWithLifecycle().value.common, + state = viewModel.referralScreenState.collectAsStateWithLifecycle().value.referrerInputState, onActivateReferrerClicked = { viewModel.onActivateLinkClick() }, @@ -178,10 +181,11 @@ class ReferralFragment : SoraBaseFragment() { route = ReferralFeatureRoutes.REFERRER_FILLED ) { FooWrapper(scrollState) { + val state = viewModel.referralScreenState.collectAsStateWithLifecycle().value ReferrerFilled( - state = viewModel.referralScreenState.common, + state = state.common, onCloseClicked = { - if (viewModel.referralScreenState.isInitialized()) { + if (state.isInitialized()) { navController.popBackStack( ReferralFeatureRoutes.REFERRAL_PROGRAM, false diff --git a/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralScreenState.kt b/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralScreenState.kt index 5f919a76e..59ee7ab7e 100644 --- a/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralScreenState.kt +++ b/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralScreenState.kt @@ -90,7 +90,6 @@ data class ReferralBondState( val invitationsAmount: String, val balance: String, val shouldTransactionReminderInsufficientWarningBeShown: Boolean = false, - val transactionFeeToken: String = "" ) data class ReferralsCardState( diff --git a/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModel.kt b/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModel.kt index 3835759d7..0884654ac 100644 --- a/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModel.kt +++ b/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModel.kt @@ -32,9 +32,6 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_referral_impl.presentation -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue import androidx.compose.ui.text.input.TextFieldValue import androidx.lifecycle.LiveData import androidx.lifecycle.viewModelScope @@ -69,6 +66,8 @@ import jp.co.soramitsu.ui_core.component.input.InputTextState import jp.co.soramitsu.ui_core.component.wrappedtext.WrappedTextState import kotlin.math.truncate import kotlinx.coroutines.FlowPreview +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.distinctUntilChanged @@ -101,8 +100,8 @@ class ReferralViewModel @Inject constructor( private var referralsState: ReferralsCardState = ReferralsCardState() set(value) { - referralScreenState = referralScreenState.copy( - referralInvitationsCardState = referralScreenState.referralInvitationsCardState.copy( + _referralScreenState.value = _referralScreenState.value.copy( + referralInvitationsCardState = _referralScreenState.value.referralInvitationsCardState.copy( referrals = value ) ) @@ -112,8 +111,8 @@ class ReferralViewModel @Inject constructor( private val _shareLinkEvent = SingleLiveEvent() val shareLinkEvent: LiveData = _shareLinkEvent - internal var referralScreenState by mutableStateOf(emptyState) - private set + private val _referralScreenState = MutableStateFlow(emptyState) + val referralScreenState = _referralScreenState.asStateFlow() private var referrer: String? = null @@ -140,7 +139,7 @@ class ReferralViewModel @Inject constructor( referrerBalance = it.orZero() val feeToken = feeToken() val invitationsCount = calcInvitationsCount() - referralScreenState = + _referralScreenState.value = if (currentDestination == ReferralFeatureRoutes.WELCOME_PROGRESS) { ReferralProgramState( common = ReferralCommonState( @@ -178,8 +177,8 @@ class ReferralViewModel @Inject constructor( ) ) } else { - referralScreenState.copy( - referralInvitationsCardState = referralScreenState.referralInvitationsCardState.copy( + _referralScreenState.value.copy( + referralInvitationsCardState = _referralScreenState.value.referralInvitationsCardState.copy( title = if (invitationsCount > 0) { resourceManager.getString(R.string.referral_invitaion_link_title) } else { @@ -192,7 +191,7 @@ class ReferralViewModel @Inject constructor( } if (currentDestination == ReferralFeatureRoutes.WELCOME_PROGRESS) { _navEvent.value = - if (referralScreenState.isInitialized()) REFERRAL_PROGRAM to singleTopTrue else WELCOME_PAGE to singleTopTrue + if (_referralScreenState.value.isInitialized()) REFERRAL_PROGRAM to singleTopTrue else WELCOME_PAGE to singleTopTrue } } .launchIn(viewModelScope) @@ -202,8 +201,8 @@ class ReferralViewModel @Inject constructor( .distinctUntilChanged() .onEach { newValue -> referrer = newValue.ifEmpty { null } - referralScreenState = - referralScreenState.copy(common = referralScreenState.common.copy(referrer = referrer)) + _referralScreenState.value = + _referralScreenState.value.copy(common = _referralScreenState.value.common.copy(referrer = referrer)) } .launchIn(viewModelScope) @@ -247,7 +246,7 @@ class ReferralViewModel @Inject constructor( fun onShareLink() { _shareLinkEvent.value = - referralScreenState.referralInvitationsCardState.wrappedTextState.text + _referralScreenState.value.referralInvitationsCardState.wrappedTextState.text } fun onBondMinus() { @@ -307,8 +306,8 @@ class ReferralViewModel @Inject constructor( fun onBondButtonClick() { viewModelScope.launch { tryCatch { - referralScreenState = - referralScreenState.copy(common = referralScreenState.common.copy(progress = true)) + _referralScreenState.value = + _referralScreenState.value.copy(common = _referralScreenState.value.common.copy(progress = true)) val result = interactor.observeBond(calcInvitationsAmount(bondInvitationsCount)) assetsRouter.showTxDetails(result) _navEvent.value = REFERRAL_PROGRAM to singleTopTrue @@ -319,8 +318,8 @@ class ReferralViewModel @Inject constructor( fun onUnbondButtonClick() { viewModelScope.launch { tryCatch { - referralScreenState = - referralScreenState.copy(common = referralScreenState.common.copy(progress = true)) + _referralScreenState.value = + _referralScreenState.value.copy(common = _referralScreenState.value.common.copy(progress = true)) val result = interactor.observeUnbond( calcInvitationsAmount(bondInvitationsCount), ) @@ -335,15 +334,15 @@ class ReferralViewModel @Inject constructor( viewModelScope.launch { tryCatch { val input = - referralScreenState.referrerInputState.value.text - referralScreenState = - referralScreenState.copy(common = referralScreenState.common.copy(progress = true)) + _referralScreenState.value.referrerInputState.value.text + _referralScreenState.value = + _referralScreenState.value.copy(common = _referralScreenState.value.common.copy(progress = true)) val referrerOk = interactor.isLinkOrAddressOk(input) val result = interactor.observeSetReferrer(referrerOk.second) assetsRouter.showTxDetails(result) _navEvent.value = - if (referralScreenState.isInitialized()) REFERRAL_PROGRAM to singleTopTrue else WELCOME_PAGE to singleTopTrue + if (_referralScreenState.value.isInitialized()) REFERRAL_PROGRAM to singleTopTrue else WELCOME_PAGE to singleTopTrue } } } @@ -369,13 +368,13 @@ class ReferralViewModel @Inject constructor( } val amount = calcInvitationsAmount(feeToken, bondInvitationsCount) - referralScreenState = - referralScreenState.copy( - common = referralScreenState.common.copy( + _referralScreenState.value = + _referralScreenState.value.copy( + common = _referralScreenState.value.common.copy( progress = false, activate = buttonActiveValidation ), - bondState = referralScreenState.bondState.copy( + bondState = _referralScreenState.value.bondState.copy( invitationsCount = bondInvitationsCount, invitationsAmount = amount, balance = feeToken.formatBalance(xorBalance) @@ -387,18 +386,15 @@ class ReferralViewModel @Inject constructor( private suspend fun updateTransactionReminderWarningVisibility(isUnbonding: Boolean) { val result = assetsInteractor.isNotEnoughXorLeftAfterTransaction( - primaryToken = feeToken(), - primaryTokenAmount = calcInvitationsAmount(referralScreenState.bondState.invitationsCount), - secondaryToken = null, - secondaryTokenAmount = null, + xorChange = calcInvitationsAmount(_referralScreenState.value.bondState.invitationsCount).let { + if (isUnbonding) -it else it + }, networkFeeInXor = extrinsicFee.orZero(), - isUnbonding = isUnbonding ) - referralScreenState = referralScreenState.copy( - bondState = referralScreenState.bondState.copy( + _referralScreenState.value = _referralScreenState.value.copy( + bondState = _referralScreenState.value.bondState.copy( shouldTransactionReminderInsufficientWarningBeShown = result, - transactionFeeToken = feeToken().symbol ) ) } @@ -474,13 +470,13 @@ class ReferralViewModel @Inject constructor( fun onReferrerInputChange(textValue: TextFieldValue) { currentEnteredReferrerLink = textValue.text viewModelScope.launch { - referralScreenState = referralScreenState.copy( - common = referralScreenState.common.copy( + _referralScreenState.value = _referralScreenState.value.copy( + common = _referralScreenState.value.common.copy( activate = interactor.isLinkOrAddressOk( textValue.text ).first ), - referrerInputState = referralScreenState.referrerInputState.copy( + referrerInputState = _referralScreenState.value.referrerInputState.copy( value = textValue ), ) @@ -488,8 +484,8 @@ class ReferralViewModel @Inject constructor( } fun openReferrerInput() { - referralScreenState = referralScreenState.copy( - referrerInputState = referralScreenState.referrerInputState.copy( + _referralScreenState.value = _referralScreenState.value.copy( + referrerInputState = _referralScreenState.value.referrerInputState.copy( value = TextFieldValue() ), ) diff --git a/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModelTest.kt b/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModelTest.kt index 6e5d7eb7d..b6738a39a 100644 --- a/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModelTest.kt +++ b/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModelTest.kt @@ -139,10 +139,6 @@ class ReferralViewModelTest { assetsInteractor.isNotEnoughXorLeftAfterTransaction( any(), any(), - any(), - any(), - any(), - any() ) } returns false @@ -189,7 +185,7 @@ class ReferralViewModelTest { val actualToolbarState = referralViewModel.toolbarState.getOrAwaitValue() assertTrue(actualToolbarState.type is SoramitsuToolbarType.Small) assertEquals(R.string.referral_toolbar_title, actualToolbarState.basic.title) - val actualScreenState = referralViewModel.referralScreenState + val actualScreenState = referralViewModel.referralScreenState.value assertEquals("my referrer", actualScreenState.common.referrer) coVerify { interactor.updateReferrals() } } @@ -205,20 +201,20 @@ class ReferralViewModelTest { assertTrue(toolbar.type is SoramitsuToolbarType.Small) referrerBalanceFlowEmit(BigDecimal.ZERO) advanceUntilIdle() - val state = referralViewModel.referralScreenState + val state = referralViewModel.referralScreenState.value assertNull(state.common.referrer) var navEvent = referralViewModel.navEvent.getOrAwaitValue() assertEquals(ReferralFeatureRoutes.WELCOME_PAGE, navEvent.first) coEvery { interactor.isLinkOrAddressOk("") } returns (false to "") referralViewModel.openReferrerInput() advanceUntilIdle() - assertEquals(false, referralViewModel.referralScreenState.common.activate) - assertEquals(false, referralViewModel.referralScreenState.common.progress) + assertEquals(false, referralViewModel.referralScreenState.value.common.activate) + assertEquals(false, referralViewModel.referralScreenState.value.common.progress) coEvery { interactor.isLinkOrAddressOk("cnVko") } returns (true to "cnVko") referralViewModel.onReferrerInputChange(TextFieldValue("cnVko")) advanceUntilIdle() - assertEquals(true, referralViewModel.referralScreenState.common.activate) - assertEquals("cnVko", referralViewModel.referralScreenState.referrerInputState.value.text) + assertEquals(true, referralViewModel.referralScreenState.value.common.activate) + assertEquals("cnVko", referralViewModel.referralScreenState.value.referrerInputState.value.text) coEvery { interactor.observeSetReferrer("cnVko") } returns "txhash" every { assetsRouter.showTxDetails(any(), any()) } returns Unit referralViewModel.onActivateLinkClick() @@ -256,10 +252,6 @@ class ReferralViewModelTest { assetsInteractor.isNotEnoughXorLeftAfterTransaction( any(), any(), - any(), - any(), - any(), - any() ) } referralViewModel.onBondMinus() @@ -268,10 +260,6 @@ class ReferralViewModelTest { assetsInteractor.isNotEnoughXorLeftAfterTransaction( any(), any(), - any(), - any(), - any(), - any() ) } } diff --git a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubViewModel.kt b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubViewModel.kt index 2eed116a3..5db44cc5e 100644 --- a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubViewModel.kt +++ b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubViewModel.kt @@ -89,7 +89,6 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import timber.log.Timber @HiltViewModel class CardsHubViewModel @Inject constructor( @@ -154,7 +153,6 @@ class CardsHubViewModel @Inject constructor( CardHubType.GET_SORA_CARD -> { soraCardInteractor.subscribeSoraCardStatus().map { status -> val mapped = mapKycStatus(status) - Timber.e("hub $status $mapped") cardHub to listOf( SoraCardState( visible = cardHub.visibility, From db231c2a4ffd182ee5a4d376dcde1a060e8c5c7b Mon Sep 17 00:00:00 2001 From: arvifox Date: Tue, 29 Aug 2023 14:12:16 +0300 Subject: [PATCH 04/20] sn-2888 referral banner --- .../jp/co/soramitsu/common/domain/CardHub.kt | 7 + .../presentation/compose/states/CardState.kt | 6 +- .../72.json | 638 ++++++++++++++++++ .../jp/co/soramitsu/core_db/AppDatabase.kt | 4 +- .../AddReferralCardHubMigration72.kt | 56 ++ .../data/repository/TestData.kt | 10 +- feature_wallet_impl/build.gradle | 1 + .../domain/CardsHubInteractorImpl.kt | 5 +- .../presentation/cardshub/BuyXorCard.kt | 59 +- .../presentation/cardshub/CardsHubFragment.kt | 26 +- .../cardshub/CardsHubViewModel.kt | 27 +- .../presentation/cardshub/ReferralCard.kt | 134 +++- .../editcardshub/EditCardsHubViewModel.kt | 1 + .../wallet/CardsHubViewModelTest.kt | 5 + 14 files changed, 900 insertions(+), 79 deletions(-) create mode 100644 core_db/schemas/jp.co.soramitsu.core_db.AppDatabase/72.json create mode 100644 core_db/src/main/java/jp/co/soramitsu/core_db/migrations/AddReferralCardHubMigration72.kt diff --git a/common/src/main/java/jp/co/soramitsu/common/domain/CardHub.kt b/common/src/main/java/jp/co/soramitsu/common/domain/CardHub.kt index ef228b600..670be3bd5 100644 --- a/common/src/main/java/jp/co/soramitsu/common/domain/CardHub.kt +++ b/common/src/main/java/jp/co/soramitsu/common/domain/CardHub.kt @@ -39,6 +39,7 @@ const val ASSETS_HUB_NAME = "assets" const val POOLS_HUB_NAME = "pools" const val GET_SORA_CARD_HUB_NAME = "get sora card" const val BUY_XOR_TOKEN_HUB_NAME = "buy xor token" +const val REFERRAL_SYSTEM_HUB_NAME = "referral system" data class CardHub( val cardType: CardHubType, @@ -65,6 +66,12 @@ enum class CardHubType( boundToAccount = false, R.string.common_buy_xor, ), + REFERRAL_SYSTEM( + REFERRAL_SYSTEM_HUB_NAME, + order = 2, + boundToAccount = false, + R.string.referral_toolbar_title, + ), ASSETS(ASSETS_HUB_NAME, order = 0, boundToAccount = true, R.string.liquid_assets), POOLS(POOLS_HUB_NAME, order = 1, boundToAccount = true, R.string.pooled_assets), diff --git a/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/states/CardState.kt b/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/states/CardState.kt index 789c0a183..bb5ad7453 100644 --- a/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/states/CardState.kt +++ b/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/states/CardState.kt @@ -125,7 +125,11 @@ data class SoraCardState( ) : CardState data class BuyXorState( - val visible: Boolean = false + val visible: Boolean = false, +) : CardState + +data class ReferralState( + val visible: Boolean = false, ) : CardState class FavoritePoolsCardState( diff --git a/core_db/schemas/jp.co.soramitsu.core_db.AppDatabase/72.json b/core_db/schemas/jp.co.soramitsu.core_db.AppDatabase/72.json new file mode 100644 index 000000000..12e52ed59 --- /dev/null +++ b/core_db/schemas/jp.co.soramitsu.core_db.AppDatabase/72.json @@ -0,0 +1,638 @@ +{ + "formatVersion": 1, + "database": { + "version": 72, + "identityHash": "f11930401f4296d64355e44fbf2c9e2f", + "entities": [ + { + "tableName": "assets", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`tokenId` TEXT NOT NULL, `accountAddress` TEXT NOT NULL, `displayAsset` INTEGER NOT NULL, `position` INTEGER NOT NULL, `free` TEXT NOT NULL, `reserved` TEXT NOT NULL, `miscFrozen` TEXT NOT NULL, `feeFrozen` TEXT NOT NULL, `bonded` TEXT NOT NULL, `redeemable` TEXT NOT NULL, `unbonding` TEXT NOT NULL, `visibility` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`tokenId`, `accountAddress`), FOREIGN KEY(`tokenId`) REFERENCES `tokens`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`accountAddress`) REFERENCES `accounts`(`substrateAddress`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "tokenId", + "columnName": "tokenId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accountAddress", + "columnName": "accountAddress", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "displayAsset", + "columnName": "displayAsset", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "free", + "columnName": "free", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "reserved", + "columnName": "reserved", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "miscFrozen", + "columnName": "miscFrozen", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "feeFrozen", + "columnName": "feeFrozen", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "bonded", + "columnName": "bonded", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "redeemable", + "columnName": "redeemable", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "unbonding", + "columnName": "unbonding", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "visibility", + "columnName": "visibility", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "tokenId", + "accountAddress" + ] + }, + "indices": [ + { + "name": "index_assets_accountAddress", + "unique": false, + "columnNames": [ + "accountAddress" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_assets_accountAddress` ON `${TABLE_NAME}` (`accountAddress`)" + } + ], + "foreignKeys": [ + { + "table": "tokens", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "tokenId" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "accounts", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "accountAddress" + ], + "referencedColumns": [ + "substrateAddress" + ] + } + ] + }, + { + "tableName": "tokens", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `symbol` TEXT NOT NULL, `precision` INTEGER NOT NULL, `isMintable` INTEGER NOT NULL, `whitelistName` TEXT NOT NULL, `isHidable` INTEGER NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "symbol", + "columnName": "symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "precision", + "columnName": "precision", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isMintable", + "columnName": "isMintable", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "whitelistName", + "columnName": "whitelistName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isHidable", + "columnName": "isHidable", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "fiatTokenPrices", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`tokenIdFiat` TEXT NOT NULL, `currencyId` TEXT NOT NULL, `fiatPrice` REAL NOT NULL, `fiatPriceTime` INTEGER NOT NULL, `fiatPricePrevH` REAL NOT NULL, `fiatPricePrevHTime` INTEGER NOT NULL, `fiatPricePrevD` REAL NOT NULL, `fiatPricePrevDTime` INTEGER NOT NULL, `fiatChange` REAL DEFAULT null, PRIMARY KEY(`tokenIdFiat`, `currencyId`), FOREIGN KEY(`tokenIdFiat`) REFERENCES `tokens`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "tokenIdFiat", + "columnName": "tokenIdFiat", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "currencyId", + "columnName": "currencyId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "fiatPrice", + "columnName": "fiatPrice", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "fiatPriceTime", + "columnName": "fiatPriceTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "fiatPricePrevH", + "columnName": "fiatPricePrevH", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "fiatPricePrevHTime", + "columnName": "fiatPricePrevHTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "fiatPricePrevD", + "columnName": "fiatPricePrevD", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "fiatPricePrevDTime", + "columnName": "fiatPricePrevDTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "fiatChange", + "columnName": "fiatChange", + "affinity": "REAL", + "notNull": false, + "defaultValue": "null" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "tokenIdFiat", + "currencyId" + ] + }, + "indices": [], + "foreignKeys": [ + { + "table": "tokens", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "tokenIdFiat" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "allpools", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`tokenIdBase` TEXT NOT NULL, `tokenIdTarget` TEXT NOT NULL, `reserveBase` TEXT NOT NULL, `reserveTarget` TEXT NOT NULL, `totalIssuance` TEXT NOT NULL, `reservesAccount` TEXT NOT NULL, PRIMARY KEY(`tokenIdBase`, `tokenIdTarget`))", + "fields": [ + { + "fieldPath": "tokenIdBase", + "columnName": "tokenIdBase", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "tokenIdTarget", + "columnName": "tokenIdTarget", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "reserveBase", + "columnName": "reserveBase", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "reserveTarget", + "columnName": "reserveTarget", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "totalIssuance", + "columnName": "totalIssuance", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "reservesAccount", + "columnName": "reservesAccount", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "tokenIdBase", + "tokenIdTarget" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "userpools", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`userTokenIdBase` TEXT NOT NULL, `userTokenIdTarget` TEXT NOT NULL, `accountAddress` TEXT NOT NULL, `poolProvidersBalance` TEXT NOT NULL, `favorite` INTEGER NOT NULL, `sortOrder` INTEGER NOT NULL, PRIMARY KEY(`userTokenIdBase`, `userTokenIdTarget`, `accountAddress`), FOREIGN KEY(`accountAddress`) REFERENCES `accounts`(`substrateAddress`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`userTokenIdBase`, `userTokenIdTarget`) REFERENCES `allpools`(`tokenIdBase`, `tokenIdTarget`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "userTokenIdBase", + "columnName": "userTokenIdBase", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "userTokenIdTarget", + "columnName": "userTokenIdTarget", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accountAddress", + "columnName": "accountAddress", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "poolProvidersBalance", + "columnName": "poolProvidersBalance", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "favorite", + "columnName": "favorite", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "sortOrder", + "columnName": "sortOrder", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "userTokenIdBase", + "userTokenIdTarget", + "accountAddress" + ] + }, + "indices": [ + { + "name": "index_userpools_accountAddress", + "unique": false, + "columnNames": [ + "accountAddress" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_userpools_accountAddress` ON `${TABLE_NAME}` (`accountAddress`)" + } + ], + "foreignKeys": [ + { + "table": "accounts", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "accountAddress" + ], + "referencedColumns": [ + "substrateAddress" + ] + }, + { + "table": "allpools", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "userTokenIdBase", + "userTokenIdTarget" + ], + "referencedColumns": [ + "tokenIdBase", + "tokenIdTarget" + ] + } + ] + }, + { + "tableName": "poolBaseTokens", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`tokenId` TEXT NOT NULL, `dexId` INTEGER NOT NULL, PRIMARY KEY(`tokenId`))", + "fields": [ + { + "fieldPath": "tokenId", + "columnName": "tokenId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dexId", + "columnName": "dexId", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "tokenId" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "accounts", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`substrateAddress` TEXT NOT NULL, `accountName` TEXT NOT NULL, PRIMARY KEY(`substrateAddress`))", + "fields": [ + { + "fieldPath": "substrateAddress", + "columnName": "substrateAddress", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accountName", + "columnName": "accountName", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "substrateAddress" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "referrals", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`address` TEXT NOT NULL, `amount` TEXT NOT NULL, PRIMARY KEY(`address`))", + "fields": [ + { + "fieldPath": "address", + "columnName": "address", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "amount", + "columnName": "amount", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "address" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "nodes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`address` TEXT NOT NULL, `chain` TEXT NOT NULL, `name` TEXT NOT NULL, `isDefault` INTEGER NOT NULL, `isSelected` INTEGER NOT NULL, PRIMARY KEY(`address`))", + "fields": [ + { + "fieldPath": "address", + "columnName": "address", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "chain", + "columnName": "chain", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isDefault", + "columnName": "isDefault", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isSelected", + "columnName": "isSelected", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "address" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "cardsHub", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`cardId` TEXT NOT NULL, `accountAddress` TEXT NOT NULL, `visibility` INTEGER NOT NULL, `sortOrder` INTEGER NOT NULL, `collapsed` INTEGER NOT NULL, PRIMARY KEY(`cardId`, `accountAddress`), FOREIGN KEY(`accountAddress`) REFERENCES `accounts`(`substrateAddress`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "cardId", + "columnName": "cardId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accountAddress", + "columnName": "accountAddress", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "visibility", + "columnName": "visibility", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "sortOrder", + "columnName": "sortOrder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "collapsed", + "columnName": "collapsed", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "cardId", + "accountAddress" + ] + }, + "indices": [ + { + "name": "index_cardsHub_accountAddress", + "unique": false, + "columnNames": [ + "accountAddress" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_cardsHub_accountAddress` ON `${TABLE_NAME}` (`accountAddress`)" + } + ], + "foreignKeys": [ + { + "table": "accounts", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "accountAddress" + ], + "referencedColumns": [ + "substrateAddress" + ] + } + ] + }, + { + "tableName": "globalCardsHub", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`cardId` TEXT NOT NULL, `visibility` INTEGER NOT NULL, `sortOrder` INTEGER NOT NULL, `collapsed` INTEGER NOT NULL, PRIMARY KEY(`cardId`))", + "fields": [ + { + "fieldPath": "cardId", + "columnName": "cardId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "visibility", + "columnName": "visibility", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "sortOrder", + "columnName": "sortOrder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "collapsed", + "columnName": "collapsed", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "cardId" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f11930401f4296d64355e44fbf2c9e2f')" + ] + } +} \ No newline at end of file diff --git a/core_db/src/main/java/jp/co/soramitsu/core_db/AppDatabase.kt b/core_db/src/main/java/jp/co/soramitsu/core_db/AppDatabase.kt index 32ca2cc9c..7f1ee93b3 100644 --- a/core_db/src/main/java/jp/co/soramitsu/core_db/AppDatabase.kt +++ b/core_db/src/main/java/jp/co/soramitsu/core_db/AppDatabase.kt @@ -53,6 +53,7 @@ import jp.co.soramitsu.core_db.migrations.migration_CardHub_65_66 import jp.co.soramitsu.core_db.migrations.migration_CardHub_66_67 import jp.co.soramitsu.core_db.migrations.migration_PoolOrderReservesAccount_64_65 import jp.co.soramitsu.core_db.migrations.migration_PoolsTables_69_70 +import jp.co.soramitsu.core_db.migrations.migration_addReferralCardHub_71_72 import jp.co.soramitsu.core_db.migrations.migration_poolsBaseToken_61_62 import jp.co.soramitsu.core_db.migrations.migration_reorderBaseToken_62_63 import jp.co.soramitsu.core_db.model.AssetLocal @@ -69,7 +70,7 @@ import jp.co.soramitsu.core_db.model.UserPoolLocal @TypeConverters(BigDecimalNullableConverter::class) @Database( - version = 71, + version = 72, entities = [ AssetLocal::class, TokenLocal::class, @@ -119,6 +120,7 @@ abstract class AppDatabase : RoomDatabase() { .addMigrations(migration_CardHub_65_66) .addMigrations(migration_CardHub_66_67) .addMigrations(migration_PoolsTables_69_70) + .addMigrations(migration_addReferralCardHub_71_72) .build() } } diff --git a/core_db/src/main/java/jp/co/soramitsu/core_db/migrations/AddReferralCardHubMigration72.kt b/core_db/src/main/java/jp/co/soramitsu/core_db/migrations/AddReferralCardHubMigration72.kt new file mode 100644 index 000000000..4c3db0f69 --- /dev/null +++ b/core_db/src/main/java/jp/co/soramitsu/core_db/migrations/AddReferralCardHubMigration72.kt @@ -0,0 +1,56 @@ +/* +This file is part of the SORA network and Polkaswap app. + +Copyright (c) 2020, 2021, Polka Biome Ltd. All rights reserved. +SPDX-License-Identifier: BSD-4-Clause + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list +of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this +list of conditions and the following disclaimer in the documentation and/or other +materials provided with the distribution. + +All advertising materials mentioning features or use of this software must display +the following acknowledgement: This product includes software developed by Polka Biome +Ltd., SORA, and Polkaswap. + +Neither the name of the Polka Biome Ltd. nor the names of its contributors may be used +to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY Polka Biome Ltd. AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Polka Biome Ltd. BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package jp.co.soramitsu.core_db.migrations + +import android.content.ContentValues +import android.database.sqlite.SQLiteDatabase +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase +import jp.co.soramitsu.common.domain.CardHubType + +val migration_addReferralCardHub_71_72 = object : Migration(71, 72) { + + override fun migrate(database: SupportSQLiteDatabase) { + database.beginTransaction() + val type = CardHubType.REFERRAL_SYSTEM + val globalCardValues = ContentValues().apply { + put("cardId", type.hubName) + put("visibility", 1) + put("sortOrder", type.order) + put("collapsed", 0) + } + database.insert("globalCardsHub", SQLiteDatabase.CONFLICT_REPLACE, globalCardValues) + database.setTransactionSuccessful() + database.endTransaction() + } +} diff --git a/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/TestData.kt b/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/TestData.kt index 9e1aa510c..9a1a09b8e 100644 --- a/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/TestData.kt +++ b/feature_account_impl/src/test/java/jp/co/soramitsu/feature_account_impl/data/repository/TestData.kt @@ -60,13 +60,19 @@ object TestData { cardId = CardHubType.GET_SORA_CARD.hubName, visibility = true, sortOrder = CardHubType.GET_SORA_CARD.order, - collapsed = false + collapsed = false, ), GlobalCardHubLocal( cardId = CardHubType.BUY_XOR_TOKEN.hubName, visibility = true, sortOrder = CardHubType.BUY_XOR_TOKEN.order, - collapsed = false + collapsed = false, + ), + GlobalCardHubLocal( + cardId = CardHubType.REFERRAL_SYSTEM.hubName, + visibility = true, + sortOrder = CardHubType.REFERRAL_SYSTEM.order, + collapsed = false, ) ) } diff --git a/feature_wallet_impl/build.gradle b/feature_wallet_impl/build.gradle index 86fc53785..567639836 100644 --- a/feature_wallet_impl/build.gradle +++ b/feature_wallet_impl/build.gradle @@ -78,6 +78,7 @@ dependencies { implementation project(":feature_main_api") implementation project(":feature_blockexplorer_api") implementation project(":feature_polkaswap_api") + implementation project(":feature_referral_api") implementation project(":feature_sora_card_api") implementation sharedUtilsDep diff --git a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/domain/CardsHubInteractorImpl.kt b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/domain/CardsHubInteractorImpl.kt index 648826d94..18e4c4999 100644 --- a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/domain/CardsHubInteractorImpl.kt +++ b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/domain/CardsHubInteractorImpl.kt @@ -67,17 +67,18 @@ class CardsHubInteractorImpl @Inject constructor( suspend fun updateCardVisibilityOnCardHub(cardId: String, visible: Boolean) { when (cardId) { CardHubType.GET_SORA_CARD.hubName, + CardHubType.REFERRAL_SYSTEM.hubName, CardHubType.BUY_XOR_TOKEN.hubName -> { walletRepository.updateCardVisibilityOnGlobalCardsHub( cardId = cardId, - visible = visible + visible = visible, ) } CardHubType.ASSETS.hubName, CardHubType.POOLS.hubName -> { walletRepository.updateCardVisibilityOnCardsHub( cardId = cardId, - visible = visible + visible = visible, ) } } diff --git a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/BuyXorCard.kt b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/BuyXorCard.kt index 25638614a..69c9ccbe8 100644 --- a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/BuyXorCard.kt +++ b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/BuyXorCard.kt @@ -32,7 +32,6 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_wallet_impl.presentation.cardshub -import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -63,44 +62,41 @@ import jp.co.soramitsu.ui_core.theme.customTypography @Composable fun BuyXorCard( - visible: Boolean, onCloseCard: () -> Unit, onBuyXorClicked: () -> Unit, ) { - AnimatedVisibility(visible = visible) { - ContentCard( - modifier = Modifier.fillMaxWidth(), - onClick = onBuyXorClicked, + ContentCard( + modifier = Modifier.fillMaxWidth(), + onClick = onBuyXorClicked, + ) { + Box( + modifier = Modifier + .fillMaxWidth() ) { - Box( - modifier = Modifier - .fillMaxWidth() + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.Bottom, + horizontalArrangement = Arrangement.SpaceBetween ) { - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.Bottom, - horizontalArrangement = Arrangement.SpaceBetween - ) { - BuyXorContent(onBuyXorClicked = onBuyXorClicked) + BuyXorContent(onBuyXorClicked = onBuyXorClicked) - Image( - painter = painterResource(R.drawable.ic_buy_xor_banner_sora), - contentDescription = null - ) - } - - BleachedButton( - modifier = Modifier - .wrapContentWidth() - .align(Alignment.TopEnd) - .padding(Dimens.x1), - size = Size.ExtraSmall, - order = Order.TERTIARY, - shape = CircleShape, - onClick = onCloseCard, - leftIcon = painterResource(R.drawable.ic_cross), + Image( + painter = painterResource(R.drawable.ic_buy_xor_banner_sora), + contentDescription = null ) } + + BleachedButton( + modifier = Modifier + .wrapContentWidth() + .align(Alignment.TopEnd) + .padding(Dimens.x1), + size = Size.ExtraSmall, + order = Order.TERTIARY, + shape = CircleShape, + onClick = onCloseCard, + leftIcon = painterResource(R.drawable.ic_cross), + ) } } } @@ -153,7 +149,6 @@ private fun PreviewBuyXorCard() { .padding(Dimens.x3) ) { BuyXorCard( - visible = true, onCloseCard = {}, onBuyXorClicked = {} ) diff --git a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubFragment.kt b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubFragment.kt index 35e4e7949..e6e916b1f 100644 --- a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubFragment.kt +++ b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubFragment.kt @@ -34,7 +34,6 @@ package jp.co.soramitsu.feature_wallet_impl.presentation.cardshub import android.os.Bundle import android.view.View -import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.ScrollState import androidx.compose.foundation.layout.Column @@ -65,6 +64,7 @@ import jp.co.soramitsu.common_wallet.presentation.compose.components.PoolsList import jp.co.soramitsu.common_wallet.presentation.compose.states.BuyXorState import jp.co.soramitsu.common_wallet.presentation.compose.states.FavoriteAssetsCardState import jp.co.soramitsu.common_wallet.presentation.compose.states.FavoritePoolsCardState +import jp.co.soramitsu.common_wallet.presentation.compose.states.ReferralState import jp.co.soramitsu.common_wallet.presentation.compose.states.SoraCardState import jp.co.soramitsu.common_wallet.presentation.compose.states.TitledAmountCardState import jp.co.soramitsu.oauth.base.sdk.contract.SoraCardContract @@ -146,22 +146,24 @@ class CardsHubFragment : SoraBaseFragment() { } is SoraCardState -> { - AnimatedVisibility( - visible = cardState.visible - ) { - SoraCard( - state = cardState, - onCardStateClicked = viewModel::onCardStateClicked, - onCloseClicked = viewModel::onRemoveSoraCard - ) - } + SoraCard( + state = cardState, + onCardStateClicked = viewModel::onCardStateClicked, + onCloseClicked = viewModel::onRemoveSoraCard, + ) } is BuyXorState -> { BuyXorCard( - visible = cardState.visible, onBuyXorClicked = viewModel::onBuyCrypto, - onCloseCard = viewModel::onRemoveBuyXorToken + onCloseCard = viewModel::onRemoveBuyXorToken, + ) + } + + is ReferralState -> { + ReferralCard( + onStartClicked = viewModel::onStartReferral, + onCloseCard = viewModel::onRemoveReferralCard, ) } } diff --git a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubViewModel.kt b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubViewModel.kt index 5db44cc5e..1442222c5 100644 --- a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubViewModel.kt +++ b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubViewModel.kt @@ -57,6 +57,7 @@ import jp.co.soramitsu.common_wallet.presentation.compose.states.CardState import jp.co.soramitsu.common_wallet.presentation.compose.states.CardsState import jp.co.soramitsu.common_wallet.presentation.compose.states.FavoriteAssetsCardState import jp.co.soramitsu.common_wallet.presentation.compose.states.FavoritePoolsCardState +import jp.co.soramitsu.common_wallet.presentation.compose.states.ReferralState import jp.co.soramitsu.common_wallet.presentation.compose.states.SoraCardState import jp.co.soramitsu.common_wallet.presentation.compose.states.TitledAmountCardState import jp.co.soramitsu.common_wallet.presentation.compose.states.mapAssetsToCardState @@ -66,6 +67,7 @@ import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PoolsInteractor import jp.co.soramitsu.feature_polkaswap_api.launcher.PolkaswapRouter +import jp.co.soramitsu.feature_referral_api.ReferralRouter import jp.co.soramitsu.feature_sora_card_api.domain.SoraCardInteractor import jp.co.soramitsu.feature_sora_card_api.util.createSoraCardContract import jp.co.soramitsu.feature_wallet_api.launcher.WalletRouter @@ -101,6 +103,7 @@ class CardsHubViewModel @Inject constructor( private val router: WalletRouter, private val mainRouter: MainRouter, private val assetsRouter: AssetsRouter, + private val referralRouter: ReferralRouter, private val polkaswapRouter: PolkaswapRouter, private val connectionManager: ConnectionManager, private val soraCardInteractor: SoraCardInteractor, @@ -163,6 +166,14 @@ class CardsHubViewModel @Inject constructor( } } + CardHubType.REFERRAL_SYSTEM -> { + flow { + emit(listOf(ReferralState(visible = cardHub.visibility))) + }.map { + cardHub to it + } + } + CardHubType.BUY_XOR_TOKEN -> { flow { emit(listOf(BuyXorState(visible = cardHub.visibility))) @@ -275,6 +286,7 @@ class CardsHubViewModel @Inject constructor( CardHubType.GET_SORA_CARD -> (it.second as List).first() CardHubType.BUY_XOR_TOKEN -> (it.second as List).first() + CardHubType.REFERRAL_SYSTEM -> (it.second as List).first() } } } @@ -340,7 +352,7 @@ class CardsHubViewModel @Inject constructor( viewModelScope.launch { cardsHubInteractorImpl.updateCardVisibilityOnCardHub( CardHubType.GET_SORA_CARD.hubName, - visible = false + visible = false, ) } } @@ -354,6 +366,19 @@ class CardsHubViewModel @Inject constructor( } } + fun onRemoveReferralCard() { + viewModelScope.launch { + cardsHubInteractorImpl.updateCardVisibilityOnCardHub( + CardHubType.REFERRAL_SYSTEM.hubName, + visible = false, + ) + } + } + + fun onStartReferral() { + referralRouter.showReferrals() + } + fun onBuyCrypto() { if (!connectionManager.isConnected) return assetsRouter.showBuyCrypto() diff --git a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/ReferralCard.kt b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/ReferralCard.kt index 2b7c38fec..be16ec63b 100644 --- a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/ReferralCard.kt +++ b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/ReferralCard.kt @@ -33,52 +33,130 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_wallet_impl.presentation.cardshub import androidx.compose.foundation.Image -import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.layout.wrapContentWidth +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource -import androidx.compose.ui.unit.dp +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview import jp.co.soramitsu.common.R +import jp.co.soramitsu.ui_core.component.button.BleachedButton +import jp.co.soramitsu.ui_core.component.button.FilledButton +import jp.co.soramitsu.ui_core.component.button.properties.Order +import jp.co.soramitsu.ui_core.component.button.properties.Size +import jp.co.soramitsu.ui_core.component.card.ContentCard import jp.co.soramitsu.ui_core.resources.Dimens +import jp.co.soramitsu.ui_core.theme.customColors +import jp.co.soramitsu.ui_core.theme.customTypography @Composable -fun ReferralCard() { - Box( - modifier = Modifier - .fillMaxWidth() - // .wrapContentHeight() - // .height(IntrinsicSize.Min) - .background(Color.White, shape = RoundedCornerShape(10.dp)) - .padding(horizontal = Dimens.x2) +fun ReferralCard( + onStartClicked: () -> Unit, + onCloseCard: () -> Unit, +) { + ContentCard( + modifier = Modifier.fillMaxWidth(), + onClick = onStartClicked, ) { - Column( + Box( modifier = Modifier - .padding(vertical = Dimens.x1) - .align(alignment = Alignment.TopStart) - .wrapContentSize() + .fillMaxWidth() ) { - Text(text = "Invite friends") - Text(text = "Get 10% of your") - Text(text = "Start inviting") + Row( + modifier = Modifier.fillMaxWidth().wrapContentHeight(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + ReferralContent( + modifier = Modifier.weight(3f), + onStartClicked = onStartClicked, + ) + + Image( + modifier = Modifier.weight(2f), + painter = painterResource(R.drawable.image_friends), + contentDescription = null, + ) + } + + BleachedButton( + modifier = Modifier + .wrapContentWidth() + .align(Alignment.TopEnd) + .padding(Dimens.x1), + size = Size.ExtraSmall, + order = Order.TERTIARY, + shape = CircleShape, + onClick = onCloseCard, + leftIcon = painterResource(R.drawable.ic_cross), + ) } - Image( - painter = painterResource(id = R.drawable.image_friends), + } +} + +@Composable +private fun ReferralContent( + modifier: Modifier = Modifier, + onStartClicked: () -> Unit, +) { + Column( + modifier = modifier + .padding( + top = Dimens.x2, + bottom = Dimens.x3, + start = Dimens.x3, + end = Dimens.x3, + ), + verticalArrangement = Arrangement.SpaceBetween, + ) { + Text( + text = stringResource(R.string.settings_invite_title), + style = MaterialTheme.customTypography.headline2, + color = MaterialTheme.customColors.fgPrimary, + ) + + Text( + modifier = Modifier.padding(top = Dimens.x1), + text = stringResource(R.string.referral_title), + style = MaterialTheme.customTypography.paragraphXS, + color = MaterialTheme.customColors.fgPrimary, + ) + + FilledButton( modifier = Modifier - .height(120.dp) - .align(alignment = Alignment.TopEnd) - .offset(x = (0).dp, y = (-20).dp), - contentDescription = null + .wrapContentWidth() + .padding(top = Dimens.x2), + text = stringResource(R.string.referral_start_inviting), + size = Size.ExtraSmall, + order = Order.PRIMARY, + onClick = onStartClicked, + ) + } +} + +@Preview +@Composable +private fun PreviewReferralCard() { + Box( + modifier = Modifier + .fillMaxSize() + .padding(Dimens.x3) + ) { + ReferralCard( + onCloseCard = {}, + onStartClicked = {}, ) } } diff --git a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/editcardshub/EditCardsHubViewModel.kt b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/editcardshub/EditCardsHubViewModel.kt index 3a2c405d1..d27096c81 100644 --- a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/editcardshub/EditCardsHubViewModel.kt +++ b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/editcardshub/EditCardsHubViewModel.kt @@ -83,6 +83,7 @@ class EditCardsHubViewModel @Inject constructor( CardHubType.POOLS -> if (isVisible) HubCardVisibility.VISIBLE_AND_ENABLED else HubCardVisibility.NOT_VISIBLE_ENABLED CardHubType.GET_SORA_CARD -> if (isVisible) HubCardVisibility.VISIBLE_AND_ENABLED else HubCardVisibility.NOT_VISIBLE_ENABLED CardHubType.BUY_XOR_TOKEN -> if (isVisible) HubCardVisibility.VISIBLE_AND_ENABLED else HubCardVisibility.NOT_VISIBLE_ENABLED + CardHubType.REFERRAL_SYSTEM -> if (isVisible) HubCardVisibility.VISIBLE_AND_ENABLED else HubCardVisibility.NOT_VISIBLE_ENABLED } init { diff --git a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/wallet/CardsHubViewModelTest.kt b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/wallet/CardsHubViewModelTest.kt index 7292f5cf1..8d279b635 100644 --- a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/wallet/CardsHubViewModelTest.kt +++ b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/wallet/CardsHubViewModelTest.kt @@ -63,6 +63,7 @@ import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PoolsInteractor import jp.co.soramitsu.feature_polkaswap_api.launcher.PolkaswapRouter +import jp.co.soramitsu.feature_referral_api.ReferralRouter import jp.co.soramitsu.feature_sora_card_api.domain.SoraCardInteractor import jp.co.soramitsu.feature_sora_card_api.domain.models.SoraCardAvailabilityInfo import jp.co.soramitsu.feature_wallet_api.launcher.WalletRouter @@ -121,6 +122,9 @@ class CardsHubViewModelTest { @MockK private lateinit var assetsRouter: AssetsRouter + @MockK + private lateinit var referralRouter: ReferralRouter + @MockK private lateinit var router: WalletRouter @@ -215,6 +219,7 @@ class CardsHubViewModelTest { router, mainRouter, assetsRouter, + referralRouter, polkaswapRouter, connectionManager, soraCardInteractor, From 7c37e604e349b8bb832817037737211de77d3ed2 Mon Sep 17 00:00:00 2001 From: arvifox Date: Tue, 29 Aug 2023 16:14:28 +0300 Subject: [PATCH 05/20] sn-2891 synthetic fee --- common/src/main/res/values-ar/strings.xml | 3 +++ common/src/main/res/values-az/strings.xml | 3 +++ common/src/main/res/values-de/strings.xml | 3 +++ common/src/main/res/values-es/strings.xml | 3 +++ common/src/main/res/values-fa/strings.xml | 3 +++ common/src/main/res/values-fi/strings.xml | 3 +++ common/src/main/res/values-fr/strings.xml | 3 +++ common/src/main/res/values-hi-rIN/strings.xml | 3 +++ common/src/main/res/values-in/strings.xml | 3 +++ common/src/main/res/values-iw/strings.xml | 3 +++ common/src/main/res/values-ja/strings.xml | 3 +++ common/src/main/res/values-ms-rMY/strings.xml | 3 +++ common/src/main/res/values-nb/strings.xml | 3 +++ common/src/main/res/values-nl/strings.xml | 3 +++ common/src/main/res/values-pt/strings.xml | 3 +++ common/src/main/res/values-ru/strings.xml | 3 +++ common/src/main/res/values-sr/strings.xml | 3 +++ common/src/main/res/values-tr/strings.xml | 3 +++ common/src/main/res/values-vi/strings.xml | 3 +++ common/src/main/res/values-zh-rCN/strings.xml | 3 +++ common/src/main/res/values-zh-rTW/strings.xml | 3 +++ common/src/main/res/values/strings.xml | 3 +++ .../domain/model/SwapDetails.kt | 3 +++ .../domain/SwapInteractorImpl.kt | 12 +++++++++++ .../components/compose/SwapMainScreen.kt | 4 ++-- .../screens/swap/SwapViewModel.kt | 20 +++++++++++++------ .../presentation/states/SwapMainState.kt | 4 ++++ .../polkaswap/SwapViewModelTest.kt | 2 ++ 28 files changed, 103 insertions(+), 8 deletions(-) diff --git a/common/src/main/res/values-ar/strings.xml b/common/src/main/res/values-ar/strings.xml index 2bd410746..aede2e380 100644 --- a/common/src/main/res/values-ar/strings.xml +++ b/common/src/main/res/values-ar/strings.xml @@ -345,6 +345,9 @@ سيولة غير كافية رسوم حوض السيولة يذهب جزء من كل صفقة إلى موفري السيولة كحوافز للبروتوكول. + Synthetic token fee + Total fee + Total fee consists on fee سوق يضمن توجيه السيولة SMART أفضل سعر لأي معاملة من خلال الجمع بين أفضل خيارات الأسعار فقط من جميع الأسواق المتاحة. عند توفرها ، سيتم استخدام Token Bonding Curve (TBC) للسيولة طالما أن سعر الأصل في المتناول أكثر من أي مصادر أخرى ، حيث يتم استخدام مجمع XYK. TBC - الشراء فقط من منحنى الترابط المميز (السوق الأولية). هناك احتمال أن يصبح السعر غير مغري مقارنة بتجمع XYK (السوق الثانوية) ، ولكن القيمة المستلمة من المكافآت المكتسبة قد تكون أكثر ملاءمة بمرور الوقت. diff --git a/common/src/main/res/values-az/strings.xml b/common/src/main/res/values-az/strings.xml index b1ac07115..1e376f705 100644 --- a/common/src/main/res/values-az/strings.xml +++ b/common/src/main/res/values-az/strings.xml @@ -341,6 +341,9 @@ Qeyri-kifayət qədər likvidlik LP haqqı Hər bir ticarətin bir hissəsi protokol təşviqi olaraq likvidlik təminatçılarına keçir. + Sintetik token haqqı + Ümumi ödəniş + Ümumi ödəniş ödənişdən ibarətdir Bazar SMART liquidity routing ensures the best price for any transaction by combining only the best price options from all available markets. When available, Token Bonding Curve (TBC) will be used for liquidity as long as the asset price is more affordable than from other sources, upon which the XYK pool is utilized. TBC — buying only from the Token Bonding Curve (Primary Market). There is a possibility that the price can become unfavorable compared to the XYK pool (Secondary Market), but the value received from the vested rewards might turn out to be much more favorable over time. diff --git a/common/src/main/res/values-de/strings.xml b/common/src/main/res/values-de/strings.xml index b4ca69980..61c992683 100644 --- a/common/src/main/res/values-de/strings.xml +++ b/common/src/main/res/values-de/strings.xml @@ -341,6 +341,9 @@ Unzureichende Liquidität LP-Gebühr Ein Teil jeder Trade geht als Protokollanreiz an die Liquiditätsanbieter. + Synthetic token fee + Total fee + Total fee consists on fee Markt SMART Liquiditätsrouting gewährleistet den besten Preis für jede Transaktion, indem es nur die besten Preisoptionen aus allen verfügbaren Märkten kombiniert. Wenn verfügbar, wird die Token Bonding Curve (TBC) für die Liquidität verwendet, solange der Preis des Assets günstiger ist als aus anderen Quellen, auf die der XYK-Pool zurückgreift. TBC - Kauf nur von der Token Bonding Curve (Primärmarkt). Es besteht die Möglichkeit, dass der Preis im Vergleich zum XYK-Pool (Sekundärmarkt) ungünstig werden kann, aber der Wert, den man durch die verstärkten Rewards erhält, könnte sich im Laufe der Zeit als viel günstiger erweisen. diff --git a/common/src/main/res/values-es/strings.xml b/common/src/main/res/values-es/strings.xml index 240783435..e2124c330 100644 --- a/common/src/main/res/values-es/strings.xml +++ b/common/src/main/res/values-es/strings.xml @@ -341,6 +341,9 @@ Liquidez insuficiente Tarifa LP Una porción de cada trade va a los proveedores de liquidez como incentivo del protocolo + Synthetic token fee + Total fee + Total fee consists on fee Mercado SMART liquidity routing ensures the best price for any transaction by combining only the best price options from all available markets. When available, Token Bonding Curve (TBC) will be used for liquidity as long as the asset price is more affordable than from other sources, upon which the XYK pool is utilized. TBC — buying only from the Token Bonding Curve (Primary Market). There is a possibility that the price can become unfavorable compared to the XYK pool (Secondary Market), but the value received from the vested rewards might turn out to be much more favorable over time. diff --git a/common/src/main/res/values-fa/strings.xml b/common/src/main/res/values-fa/strings.xml index 8f88ca0fb..98ed727c2 100644 --- a/common/src/main/res/values-fa/strings.xml +++ b/common/src/main/res/values-fa/strings.xml @@ -341,6 +341,9 @@ نقدینگی ناکافی هزینه LP بخشی از هر معامله به عنوان مشوق پروتکل به ارائه دهندگان نقدینگی می‌رسد. + Synthetic token fee + Total fee + Total fee consists on fee بازار مسیریابی نقدینگی SMART با ترکیب بهترین گزینه‌های قیمت از همه بازارهای موجود، بهترین قیمت را برای هر معامله تضمین می‌کند. در صورت امکان Token Bonding Curve (TBC) برای نقدینگی استفاده خواهد شد تا زمانی که قیمت دارایی مقرون به صرفه‌تر از منابع دیگر باشد، که در این حالت از استخر XYK استفاده می‌شود. TBC - خرید فقط از Token Bonfing Curve (بازار اولیه). ممکن است قیمت در مقایسه با مخزن XYK (بازار ثانویه) نامطلوب تر باشد، اما ارزش دریافتی از پاداش‌های اختصاص داده شده ممکن است در طول زمان بسیار مطلوب تر شود. diff --git a/common/src/main/res/values-fi/strings.xml b/common/src/main/res/values-fi/strings.xml index db738371c..dccd77ce0 100644 --- a/common/src/main/res/values-fi/strings.xml +++ b/common/src/main/res/values-fi/strings.xml @@ -341,6 +341,9 @@ Riittämätön likviditeetti LP-maksu Osa jokaisesta kaupasta menee likviditeetin tarjoajille protokollakannustimena. + Synthetic token fee + Total fee + Total fee consists on fee Market SMART likviditeetin reititys varmistaa parhaan hinnan jokaiselle tapahtumalle, yhdistämällä vain parhaat hintavaihtoehdot kaikilta saatavilla olevilta markkinoilta. Token Bonding Curvea (TBC) käytetään mahdollisuuksien mukaan likviditeettiin niin kauan kun resurssien hinta on edullisempi kuin muista lähteistä, jolloin taas hyödynnetään XYK-poolia. TBC – ostaminen vain Token Bonding Curvesta (ensisijainen markkina). On mahdollista, että hinnasta tulee epäedullinen verrattuna XYK-pooliin (toissijainen markkina), mutta saavutetuista palkkioista saatu arvo saattaa osoittautua paljon edullisemmaksi ajan myötä. diff --git a/common/src/main/res/values-fr/strings.xml b/common/src/main/res/values-fr/strings.xml index 01cb982e5..2e1691520 100644 --- a/common/src/main/res/values-fr/strings.xml +++ b/common/src/main/res/values-fr/strings.xml @@ -341,6 +341,9 @@ Liquidité insuffisante Frais de LP Une partie de chaque transaction est reversée aux fournisseurs de liquidités à titre d\'incitation de la part du protocole + Synthetic token fee + Total fee + Total fee consists on fee Marché Le routage de la liquidité SMART garantit le meilleur prix pour toute transaction en combinant uniquement les meilleures options de prix de tous les marchés disponibles. Lorsqu\'elle est disponible, la courbe de liaison de jeton (TBC) sera utilisée pour la liquidité tant que le prix de l\'actif est plus abordable que celui des autres sources, sur lesquelles le pool XYK est utilisé. TBC - achat uniquement à partir de la courbe de liaison de jeton (marché primaire). Il est possible que le prix devienne défavorable par rapport au pool XYK (marché secondaire), mais la valeur reçue des récompenses acquises pourrait s\'avérer beaucoup plus favorable au fil du temps. diff --git a/common/src/main/res/values-hi-rIN/strings.xml b/common/src/main/res/values-hi-rIN/strings.xml index 3cd1d399b..911daf99f 100644 --- a/common/src/main/res/values-hi-rIN/strings.xml +++ b/common/src/main/res/values-hi-rIN/strings.xml @@ -341,6 +341,9 @@ अपर्याप्त Liquidity LP शुल्क प्रत्येक व्यापार का एक हिस्सा एक प्रोटोकॉल प्रोत्साहन के रूप में Liquidity प्रदाताओं को जाता है। + Synthetic token fee + Total fee + Total fee consists on fee बाज़ार स्मार्ट लिक्विडिटी रूटिंग सभी उपलब्ध बाजारों से केवल सर्वोत्तम मूल्य विकल्पों को मिलाकर किसी भी लेन-देन के लिए सर्वोत्तम मूल्य सुनिश्चित करता है। उपलब्ध होने पर, टोकन बॉन्डिंग कर्व (TBC) का उपयोग तरलता के लिए तब तक किया जाएगा जब तक कि संपत्ति की कीमत अन्य स्रोतों की तुलना में अधिक सस्ती हो, जिस पर XYK पूल का उपयोग किया जाता है। टीबीसी - केवल टोकन बॉन्डिंग वक्र (प्राथमिक बाजार) से खरीदना। एक संभावना है कि मूल्य XYK पूल (द्वितीयक बाजार) की तुलना में प्रतिकूल हो सकता है, लेकिन निहित पुरस्कारों से प्राप्त मूल्य समय के साथ और अधिक अनुकूल हो सकता है। diff --git a/common/src/main/res/values-in/strings.xml b/common/src/main/res/values-in/strings.xml index 4a18bdb8e..c7df47b36 100644 --- a/common/src/main/res/values-in/strings.xml +++ b/common/src/main/res/values-in/strings.xml @@ -340,6 +340,9 @@ Likuiditas tidak mencukupi Biaya LP Sebagian dari setiap perdagangan diberikan kepada penyedia likuiditas sebagai insentif protokol. + Synthetic token fee + Total fee + Total fee consists on fee Pasar SMART liquidity routing ensures the best price for any transaction by combining only the best price options from all available markets. When available, Token Bonding Curve (TBC) will be used for liquidity as long as the asset price is more affordable than from other sources, upon which the XYK pool is utilized. TBC — buying only from the Token Bonding Curve (Primary Market). There is a possibility that the price can become unfavorable compared to the XYK pool (Secondary Market), but the value received from the vested rewards might turn out to be much more favorable over time. diff --git a/common/src/main/res/values-iw/strings.xml b/common/src/main/res/values-iw/strings.xml index af19abba2..5d43449e4 100644 --- a/common/src/main/res/values-iw/strings.xml +++ b/common/src/main/res/values-iw/strings.xml @@ -343,6 +343,9 @@ אין מספיק נזילות עמלת מאגר נזילות חלק מכל עסקה הולך לספקי נזילות כתמריץ פרוטוקול. + Synthetic token fee + Total fee + Total fee consists on fee שוק ניתוב נזילות SMART מבטיח את המחיר הטוב ביותר לכל טרנזקציה על ידי שילוב אפשרויות המחיר הטובות ביותר בלבד מכל השווקים הזמינים. כאשר זמין, עקומת צירוף הטוקנים (TBC) תשמש לנזילות כל עוד מחיר הנכס משתלם יותר מאשר ממקורות אחרים, שעליהם מנוצל מאגר XYK. TBC - קנייה רק מעקומת צירוף הטוקנים (השוק העיקרי). קיימת אפשרות שהמחיר יכול להפוך לבלתי משתלם בהשוואה למאגר XYK (שוק משני), אך הערך המתקבל מהתגמולים המוענקים לאורך זמן עשוי להתברר כמשתלם הרבה יותר לטווח ארוך. diff --git a/common/src/main/res/values-ja/strings.xml b/common/src/main/res/values-ja/strings.xml index 33dbc024c..b33c0dd3b 100644 --- a/common/src/main/res/values-ja/strings.xml +++ b/common/src/main/res/values-ja/strings.xml @@ -340,6 +340,9 @@ 流動性不足 LP手数料 各取引の一部は、インセンティブとして流動性プロバイダー(LP)に送られます + Synthetic token fee + Total fee + Total fee consists on fee 市場 SMART流動性ルーティングは、利用可能なすべての市場から最良の価格オプションだけ組み合わせることで、あらゆる取引の最良の価格を保証します。XYKプールや他のプールが利用される場合より資産価格が手頃であれば、可能な限りトークン・ボンディング・カーブ(TBC)が流動性のために使用されます TBC — トークン・ボンディング・カーブ(一次市場)からのみ購入します。 XYKプール(二次市場)に比べて価格が不利になる可能性もありますが、既得の報酬から受け取る価値が、時間の経過とともにはるかに有利になる可能性があります diff --git a/common/src/main/res/values-ms-rMY/strings.xml b/common/src/main/res/values-ms-rMY/strings.xml index 8c705e741..7d1762f2e 100644 --- a/common/src/main/res/values-ms-rMY/strings.xml +++ b/common/src/main/res/values-ms-rMY/strings.xml @@ -340,6 +340,9 @@ Kecairan tidak mencukupi Bayaran LP Sebahagian daripada setiap dagangan diberikan kepada penyedia kecairan sebagai insentif protokol. + Synthetic token fee + Total fee + Total fee consists on fee Pasaran Penghalaan kecairan SMART memastikan harga terbaik untuk sebarang transaksi dengan menggabungkan hanya pilihan harga terbaik dari semua pasaran yang ada. Apabila tersedia, Token Bonding Curve (TBC) akan digunakan untuk kecairan selagi harga aset lebih berpatutan daripada sumber lain, di mana kolam XYK digunakan. TBC — membeli hanya daripada Lengkung Ikatan Token (Pasaran Utama). Terdapat kemungkinan bahawa harga boleh menjadi tidak menguntungkan berbanding dengan kolam XYK (Pasaran Sekunder), tetapi nilai yang diterima daripada ganjaran terletak hak mungkin berubah menjadi lebih baik dari masa ke masa. diff --git a/common/src/main/res/values-nb/strings.xml b/common/src/main/res/values-nb/strings.xml index d74ddaced..5846ff0db 100644 --- a/common/src/main/res/values-nb/strings.xml +++ b/common/src/main/res/values-nb/strings.xml @@ -341,6 +341,9 @@ Utilstrekkelig likviditet LP -avgift En del av hver handel går til likviditetsleverandører som et protokollinsentiv. + Synthetic token fee + Total fee + Total fee consists on fee Marked SMART liquidity routing ensures the best price for any transaction by combining only the best price options from all available markets. When available, Token Bonding Curve (TBC) will be used for liquidity as long as the asset price is more affordable than from other sources, upon which the XYK pool is utilized. TBC — buying only from the Token Bonding Curve (Primary Market). There is a possibility that the price can become unfavorable compared to the XYK pool (Secondary Market), but the value received from the vested rewards might turn out to be much more favorable over time. diff --git a/common/src/main/res/values-nl/strings.xml b/common/src/main/res/values-nl/strings.xml index d29fc1d66..f22cfda5d 100644 --- a/common/src/main/res/values-nl/strings.xml +++ b/common/src/main/res/values-nl/strings.xml @@ -341,6 +341,9 @@ Onvoldoende liquiditeit LP Vergoeding Een deel van elke transactie gaat naar liquiditeitsverschaffers als aanmoediging van het protocol. + Synthetic token fee + Total fee + Total fee consists on fee Markt SMART liquiditeitsroutering zorgt voor de beste prijs voor elke transactie door alleen de beste prijsopties uit alle beschikbare markten te combineren. Indien beschikbaar, zal de Token Bonding Curve (TBC) worden gebruikt voor liquiditeit zolang de activaprijs betaalbaarder is dan uit andere bronnen, waarop de XYK-pool wordt gebruikt. TBC - alleen kopen van de Token Bonding Curve (primaire markt). Er is een mogelijkheid dat de prijs ongunstig kan worden in vergelijking met de XYK-pool (secundaire markt), maar de waarde die wordt ontvangen van de gevestigde beloningen kan in de loop van de tijd veel gunstiger blijken te zijn. diff --git a/common/src/main/res/values-pt/strings.xml b/common/src/main/res/values-pt/strings.xml index 35966f0e1..4df46b280 100644 --- a/common/src/main/res/values-pt/strings.xml +++ b/common/src/main/res/values-pt/strings.xml @@ -341,6 +341,9 @@ Liquidez insuficiente Taxa de LP Uma porção de cada transação vai para os provedores de liquidez, como incentivo do protocolo. + Synthetic token fee + Total fee + Total fee consists on fee Mercado O roteamento de liquidez SMART assegura o melhor preço para qualquer transação, combinando apenas as melhores opções de preços de todos os mercados acessíveis. Quando disponível, a Curva Agregadora de Tokens (TBC) será usada para liquidez, desde que o preço do ativo seja mais económico do que o de outras fontes, que utilizam a pool XYK. TBC - compra apenas a partir da Curva Agregadora de Tokens (Mercado Primário). Há a possibilidade de o preço se tornar desfavorável em comparação com a pool XYK (Mercado Secundário), mas o valor das recompensas recebido pode vir a revelar-se muito mais favorável ao longo do tempo. diff --git a/common/src/main/res/values-ru/strings.xml b/common/src/main/res/values-ru/strings.xml index 52a355e04..65b027a7f 100644 --- a/common/src/main/res/values-ru/strings.xml +++ b/common/src/main/res/values-ru/strings.xml @@ -344,6 +344,9 @@ Недостаточная ликвидность Комиссия LP Часть каждой сделки является награждением для поставщиков ликвидности. + Комиссия за синтетический токен + Общая комиссия + Общая комиссия состоит из комиссии Рынок Маршрутизация ликвидности SMART обеспечивает лучшую цену для любой транзакции, комбинируя только лучшие варианты цены со всех доступных рынков. При наличии TBC будет использоваться для обеспечения ликвидности до тех пор, пока цена актива будет более доступной, чем из других источников, на которых используется пул XYK. TBC(Token Bonding Curve) — покупка только по кривой связывания токенов (первичный рынок). Есть вероятность того, что цена может стать невыгодной по сравнению с пулом XYK (вторичный рынок), но ценность, полученная от закрепленных вознаграждений, со временем может оказаться гораздо более выгодной. diff --git a/common/src/main/res/values-sr/strings.xml b/common/src/main/res/values-sr/strings.xml index eae64df61..56ce6511b 100644 --- a/common/src/main/res/values-sr/strings.xml +++ b/common/src/main/res/values-sr/strings.xml @@ -342,6 +342,9 @@ Недовољна ликвидност Naknada za likvidnost Deo svake transakcije ide provajderima likvidnosti kao protokolarni podsticaj. + Synthetic token fee + Total fee + Total fee consists on fee Tržište СМАРТ усмеравање ликвидности обезбеђује најбољу цену за било коју трансакцију комбиновањем само најбољих опција цена са свих доступних тржишта. Када је доступна, крива везивања токена (ТБЦ) ће се користити за ликвидност све док је цена средства приступачнија него из других извора, на основу којих се користи КСИК фонд. ТБЦ — куповина само са криве везивања токена (примарно тржиште). Постоји могућност да цена може постати неповољнија у поређењу са КСИК фондом (секундарно тржиште), али вредност добијена од стечених награда може се временом показати много повољнијом. diff --git a/common/src/main/res/values-tr/strings.xml b/common/src/main/res/values-tr/strings.xml index 242e2c9c3..fa85f8d10 100644 --- a/common/src/main/res/values-tr/strings.xml +++ b/common/src/main/res/values-tr/strings.xml @@ -341,6 +341,9 @@ Yetersiz likidite LP Ücreti Her takasın bir kısmı protokol teşviki olarak likidite sağlayıcılarına gider. + Synthetic token fee + Total fee + Total fee consists on fee Piyasa SMART likidite yönlendirmesi, mevcut piyasalardaki en iyi fiyat oranlarını birleştirerek herhangi bir işlem için en iyi fiyatı bulur. Mevcut olduğunda, fiyat, XYK havuzunun kullanıldığı diğer kaynaklardan daha uygun olduğu sürece Token Tahvil Eğrisi (TBC), likidite için kullanılacaktır. TBC — sadece Token Tahvil Eğrisinden (Birincil Piyasadan) satın alınması. Fiyat, XYK havuzuna (İkincil Piyasaya) göre daha olumsuz olabilir, ama bir süre sonra kilidi açılan ödüllerden gelen değer, daha olumlu olabilir. diff --git a/common/src/main/res/values-vi/strings.xml b/common/src/main/res/values-vi/strings.xml index 01ee4c10e..450249e3e 100644 --- a/common/src/main/res/values-vi/strings.xml +++ b/common/src/main/res/values-vi/strings.xml @@ -340,6 +340,9 @@ Không đủ thanh khoản Phí thanh khoản Một phần của mỗi giao dịch được chuyển đến các nhà cung cấp thanh khoản như một biện pháp khuyến khích. + Synthetic token fee + Total fee + Total fee consists on fee Thị trường SMART liquidity routing đảm bảo giá tốt nhất cho giao dịch bất kỳ bằng cách kết hợp mức giá tốt nhất hiện có trên thị trường. Khi thuận lợi, Token Bonding Curve (TBC) sẽ được dùng để tạo thanh khoản miễn là giá của tài sản hợp lý hơn các nguồn khác như pool (XYK). TBC - chỉ mua từ Token Bonding Curve (Primary Market). Giá có thể trở nên bất lợi so với XYK pool (Secondary Market), nhưng về lâu dài giá trị nhận được từ phần thưởng có thể lớn hơn nhiều. diff --git a/common/src/main/res/values-zh-rCN/strings.xml b/common/src/main/res/values-zh-rCN/strings.xml index ce3eb039a..47c0a3cb7 100644 --- a/common/src/main/res/values-zh-rCN/strings.xml +++ b/common/src/main/res/values-zh-rCN/strings.xml @@ -340,6 +340,9 @@ 流动性不足 流动性提供者费用 每笔交易的一部分作为协议激励奖励流动性提供者。 + Synthetic token fee + Total fee + Total fee consists on fee 市场 智能流动性路由通过从所有可用市场中仅选择最佳价格选项,确保任何交易的最佳价格。如果可用,将使用代币绑定曲线(TBC)提供流动性,只要资产价格比其他来源更实惠,否则将使用XYK池。 TBC - 仅从代币绑定曲线(一级市场)购买。价格可能会比XYK池(二级市场)不利,但随着时间的推移,从归属奖励中获得的价值可能会更有利。 diff --git a/common/src/main/res/values-zh-rTW/strings.xml b/common/src/main/res/values-zh-rTW/strings.xml index b0e8fb1f3..5bc5d5d00 100644 --- a/common/src/main/res/values-zh-rTW/strings.xml +++ b/common/src/main/res/values-zh-rTW/strings.xml @@ -340,6 +340,9 @@ 流動性不足 LP費用 每筆交易的一部分 作為協議激勵流向流動性提供者。 + Synthetic token fee + Total fee + Total fee consists on fee 市場 SMART 流動性路由通過僅結合所有可用市場的最佳價格選項來確保任何交易的最佳價格。如果可用,代幣綁定曲線 (TBC) 將用於流動性,只要資產價格比使用 XYK 池的其他來源更實惠。 TBC — 僅從 Token Bonding Curve(一級市場)購買。與 XYK 池(二級市場)相比,價格有可能變得不利,但隨著時間的推移,從既得獎勵中獲得的價值可能會變得更加有利。 diff --git a/common/src/main/res/values/strings.xml b/common/src/main/res/values/strings.xml index 200ff564f..d9d8eebe8 100644 --- a/common/src/main/res/values/strings.xml +++ b/common/src/main/res/values/strings.xml @@ -341,6 +341,9 @@ Insufficient liquidity LP Fee A portion of each trade goes to liquidity providers as a protocol incentive. + Synthetic token fee + Total fee + Total fee consists on fee Market SMART liquidity routing ensures the best price for any transaction by combining only the best price options from all available markets. When available, Token Bonding Curve (TBC) will be used for liquidity as long as the asset price is more affordable than from other sources, upon which the XYK pool is utilized. TBC — buying only from the Token Bonding Curve (Primary Market). There is a possibility that the price can become unfavorable compared to the XYK pool (Secondary Market), but the value received from the vested rewards might turn out to be much more favorable over time. diff --git a/feature_polkaswap_api/src/main/java/jp/co/soramitsu/feature_polkaswap_api/domain/model/SwapDetails.kt b/feature_polkaswap_api/src/main/java/jp/co/soramitsu/feature_polkaswap_api/domain/model/SwapDetails.kt index 29600ebf8..1c30739cd 100644 --- a/feature_polkaswap_api/src/main/java/jp/co/soramitsu/feature_polkaswap_api/domain/model/SwapDetails.kt +++ b/feature_polkaswap_api/src/main/java/jp/co/soramitsu/feature_polkaswap_api/domain/model/SwapDetails.kt @@ -44,8 +44,11 @@ data class SwapDetails( val networkFee: BigDecimal, val dex: PoolDex, val swapRoute: List? = null, + val feeMode: SwapFeeMode, ) +enum class SwapFeeMode { SYNTHETIC, NON_SYNTHETIC, BOTH } + data class SwapQuote( val amount: BigDecimal, val fee: BigDecimal, diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt index 82f947b46..5963a8ff8 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt @@ -52,6 +52,8 @@ import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PolkaswapReposito import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PolkaswapSubscriptionRepository import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.SwapInteractor import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapDetails +import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapFeeMode +import jp.co.soramitsu.sora.substrate.runtime.SubstrateOptionsProvider import kotlin.math.max import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow @@ -80,6 +82,7 @@ class SwapInteractorImpl( private var poolReservesFlowToken = MutableStateFlow?>(null) private val availableMarkets = mutableMapOf>() private var swapNetworkFee: BigDecimal? = null + private val syntheticRegex = SubstrateOptionsProvider.syntheticTokenRegex.toRegex() override suspend fun fetchSwapNetworkFee(feeToken: Token): BigDecimal { return swapNetworkFee ?: ( @@ -151,9 +154,18 @@ class SwapInteractorImpl( swapQuote.first.route?.mapNotNull { assetsRepository.getToken(it)?.symbol }, + getFeeMode(swapQuote.first.route), ) } + private fun getFeeMode(ids: List?): SwapFeeMode { + if (ids == null) return SwapFeeMode.NON_SYNTHETIC + val withoutxst = ids.filter { it != SubstrateOptionsProvider.xstTokenId } + if (withoutxst.all { it.matches(syntheticRegex) }) return SwapFeeMode.SYNTHETIC + if (withoutxst.all { it.matches(syntheticRegex).not() }) return SwapFeeMode.NON_SYNTHETIC + return SwapFeeMode.BOTH + } + override fun setSwapMarket(market: Market) { selectedSwapMarket.value = market } diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapMainScreen.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapMainScreen.kt index d7f1e8747..73c9cdfad 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapMainScreen.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapMainScreen.kt @@ -219,8 +219,8 @@ internal fun SwapMainScreen( if (state.details.lpFee.isNotEmpty()) { Spacer(modifier = Modifier.size(Dimens.x2)) DetailsItem( - text = stringResource(id = R.string.polkaswap_liqudity_fee), - hint = stringResource(id = R.string.polkaswap_liqudity_fee_info), + text = stringResource(id = state.details.lpFeeTitle), + hint = stringResource(id = state.details.lpFeeHint), value1 = state.details.lpFee, ) } diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt index 9b13c36a0..216814153 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt @@ -73,6 +73,7 @@ import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.SwapInteractor import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapDetails +import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapFeeMode import jp.co.soramitsu.feature_polkaswap_impl.presentation.states.SwapMainState import jp.co.soramitsu.feature_polkaswap_impl.presentation.states.defaultSwapDetailsState import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletInteractor @@ -763,42 +764,49 @@ class SwapViewModel @AssistedInject constructor( minmaxToken = _swapMainState.value.tokenFromState?.token maxMinToken = _swapMainState.value.tokenToState?.token } + val (title, desc) = when (details.feeMode) { + SwapFeeMode.SYNTHETIC -> R.string.polkaswap_liquidity_synthetic_fee to R.string.polkaswap_liqudity_fee_info + SwapFeeMode.NON_SYNTHETIC -> R.string.polkaswap_liqudity_fee to R.string.polkaswap_liqudity_fee_info + SwapFeeMode.BOTH -> R.string.polkaswap_liquidity_total_fee to R.string.polkaswap_liquidity_total_fee_desc + } _swapMainState.value = _swapMainState.value.copy( details = _swapMainState.value.details.copy( transactionFee = feeToken().printBalance( details.networkFee, numbersFormatter, - AssetHolder.ROUNDING + AssetHolder.ROUNDING, ), transactionFeeFiat = feeToken().printFiat( details.networkFee, - numbersFormatter + numbersFormatter, ), priceFromTo = p1, priceFromToTitle = "%s / %s".format( maxMinToken?.symbol.orEmpty(), - minmaxToken?.symbol.orEmpty() + minmaxToken?.symbol.orEmpty(), ), priceToFrom = p2, priceToFromTitle = "%s / %s".format( minmaxToken?.symbol.orEmpty(), - maxMinToken?.symbol.orEmpty() + maxMinToken?.symbol.orEmpty(), ), lpFee = feeToken().printBalance( details.liquidityFee, numbersFormatter, - AssetHolder.ROUNDING + AssetHolder.ROUNDING, ), minmaxTitle = minmaxTitle, minmaxHint = minmaxHint, minmaxValue = minmaxToken?.printBalance( details.minmax, numbersFormatter, - AssetHolder.ROUNDING + AssetHolder.ROUNDING, ).orEmpty(), minmaxValueFiat = minmaxToken?.printFiat(details.minmax, numbersFormatter) .orEmpty(), route = details.swapRoute?.joinToString("->").orEmpty(), + lpFeeTitle = title, + lpFeeHint = desc, ) ) } diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/SwapMainState.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/SwapMainState.kt index 5c6ccd2ef..706d9ae01 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/SwapMainState.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/SwapMainState.kt @@ -66,6 +66,8 @@ data class SwapDetailsState( val priceToFromTitle: String, val priceToFrom: String, val lpFee: String, + @StringRes val lpFeeTitle: Int, + @StringRes val lpFeeHint: Int, val route: String, val shouldTransactionReminderInsufficientWarningBeShown: Boolean, ) @@ -83,6 +85,8 @@ fun defaultSwapDetailsState() = priceToFromTitle = "", priceToFrom = "", lpFee = "", + lpFeeTitle = R.string.polkaswap_liqudity_fee, + lpFeeHint = R.string.polkaswap_liqudity_fee_info, route = "", shouldTransactionReminderInsufficientWarningBeShown = false, ) diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt index 224822860..f9f587b56 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt @@ -52,6 +52,7 @@ import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.SwapInteractor import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapDetails +import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapFeeMode import jp.co.soramitsu.feature_polkaswap_impl.presentation.screens.swap.SwapViewModel import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletInteractor import jp.co.soramitsu.test_data.PolkaswapTestData @@ -300,6 +301,7 @@ class SwapViewModelTest { networkFee, PoolDex(0, assetsListItems.first().tokenId, assetsListItems.last().tokenId), null, + SwapFeeMode.NON_SYNTHETIC, ) ) advanceUntilIdle() From 9b4402f19458e7072d7b07661dd64c462e9e3226 Mon Sep 17 00:00:00 2001 From: arvifox Date: Tue, 29 Aug 2023 17:13:40 +0300 Subject: [PATCH 06/20] sn-2891 synthetic fee description --- common/src/main/res/values-ar/strings.xml | 11 ++++++----- common/src/main/res/values-az/strings.xml | 5 +++-- common/src/main/res/values-de/strings.xml | 11 ++++++----- common/src/main/res/values-es/strings.xml | 11 ++++++----- common/src/main/res/values-fa/strings.xml | 11 ++++++----- common/src/main/res/values-fi/strings.xml | 11 ++++++----- common/src/main/res/values-fr/strings.xml | 11 ++++++----- common/src/main/res/values-hi-rIN/strings.xml | 11 ++++++----- common/src/main/res/values-in/strings.xml | 11 ++++++----- common/src/main/res/values-iw/strings.xml | 11 ++++++----- common/src/main/res/values-ja/strings.xml | 11 ++++++----- common/src/main/res/values-ms-rMY/strings.xml | 11 ++++++----- common/src/main/res/values-nb/strings.xml | 11 ++++++----- common/src/main/res/values-nl/strings.xml | 11 ++++++----- common/src/main/res/values-pt/strings.xml | 11 ++++++----- common/src/main/res/values-ru/strings.xml | 9 +++++---- common/src/main/res/values-sr/strings.xml | 11 ++++++----- common/src/main/res/values-tr/strings.xml | 11 ++++++----- common/src/main/res/values-vi/strings.xml | 11 ++++++----- common/src/main/res/values-zh-rCN/strings.xml | 11 ++++++----- common/src/main/res/values-zh-rTW/strings.xml | 11 ++++++----- common/src/main/res/values/strings.xml | 11 ++++++----- .../presentation/screens/swap/SwapViewModel.kt | 4 ++-- .../presentation/states/SwapMainState.kt | 4 ++-- 24 files changed, 132 insertions(+), 110 deletions(-) diff --git a/common/src/main/res/values-ar/strings.xml b/common/src/main/res/values-ar/strings.xml index aede2e380..09332611a 100644 --- a/common/src/main/res/values-ar/strings.xml +++ b/common/src/main/res/values-ar/strings.xml @@ -343,11 +343,12 @@ يتم تقدير المدخلات. ستبيع بحد أقصى %s أو ستتعثر المعاملة وتسترجع. الرصيد %s غير كافٍ سيولة غير كافية - رسوم حوض السيولة - يذهب جزء من كل صفقة إلى موفري السيولة كحوافز للبروتوكول. - Synthetic token fee - Total fee - Total fee consists on fee + رسوم حوض السيولة + يذهب جزء من كل صفقة إلى موفري السيولة كحوافز للبروتوكول. + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. سوق يضمن توجيه السيولة SMART أفضل سعر لأي معاملة من خلال الجمع بين أفضل خيارات الأسعار فقط من جميع الأسواق المتاحة. عند توفرها ، سيتم استخدام Token Bonding Curve (TBC) للسيولة طالما أن سعر الأصل في المتناول أكثر من أي مصادر أخرى ، حيث يتم استخدام مجمع XYK. TBC - الشراء فقط من منحنى الترابط المميز (السوق الأولية). هناك احتمال أن يصبح السعر غير مغري مقارنة بتجمع XYK (السوق الثانوية) ، ولكن القيمة المستلمة من المكافآت المكتسبة قد تكون أكثر ملاءمة بمرور الوقت. diff --git a/common/src/main/res/values-az/strings.xml b/common/src/main/res/values-az/strings.xml index 1e376f705..90679768e 100644 --- a/common/src/main/res/values-az/strings.xml +++ b/common/src/main/res/values-az/strings.xml @@ -339,9 +339,10 @@ Giriş hesablanır. Maksimum %s satacaqsınız və ya əməliyyat geri qaytarılacaq. Balans kifayət deyil Qeyri-kifayət qədər likvidlik - LP haqqı - Hər bir ticarətin bir hissəsi protokol təşviqi olaraq likvidlik təminatçılarına keçir. + LP haqqı + Hər bir ticarətin bir hissəsi protokol təşviqi olaraq likvidlik təminatçılarına keçir. Sintetik token haqqı + Sintetik ödəniş sintetik aktiv haqqı və qabaqcadan qaçmağın qarşısını almaq üçün dinamik ödənişdən ibarətdir. Sintetik aktivin haqqı aktivin qeydiyyatı zamanı müəyyən edilir və istənilən vaxt idarəetmə vasitəsilə dəyişdirilə bilər. Dinamik ödəniş oracle qiymətindəki faiz dəyişikliyinə əsaslanır. Ümumi ödəniş Ümumi ödəniş ödənişdən ibarətdir Bazar diff --git a/common/src/main/res/values-de/strings.xml b/common/src/main/res/values-de/strings.xml index 61c992683..bc29f81c5 100644 --- a/common/src/main/res/values-de/strings.xml +++ b/common/src/main/res/values-de/strings.xml @@ -339,11 +339,12 @@ Der Einsatz wird geschätzt. Du verkaufst höchstens %s oder die Transaktion wird rückgängig gemacht. Unzureichender %s-Saldo Unzureichende Liquidität - LP-Gebühr - Ein Teil jeder Trade geht als Protokollanreiz an die Liquiditätsanbieter. - Synthetic token fee - Total fee - Total fee consists on fee + LP-Gebühr + Ein Teil jeder Trade geht als Protokollanreiz an die Liquiditätsanbieter. + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Markt SMART Liquiditätsrouting gewährleistet den besten Preis für jede Transaktion, indem es nur die besten Preisoptionen aus allen verfügbaren Märkten kombiniert. Wenn verfügbar, wird die Token Bonding Curve (TBC) für die Liquidität verwendet, solange der Preis des Assets günstiger ist als aus anderen Quellen, auf die der XYK-Pool zurückgreift. TBC - Kauf nur von der Token Bonding Curve (Primärmarkt). Es besteht die Möglichkeit, dass der Preis im Vergleich zum XYK-Pool (Sekundärmarkt) ungünstig werden kann, aber der Wert, den man durch die verstärkten Rewards erhält, könnte sich im Laufe der Zeit als viel günstiger erweisen. diff --git a/common/src/main/res/values-es/strings.xml b/common/src/main/res/values-es/strings.xml index e2124c330..e2c524795 100644 --- a/common/src/main/res/values-es/strings.xml +++ b/common/src/main/res/values-es/strings.xml @@ -339,11 +339,12 @@ Se estima la entrada. Venderás un máximo de %s o la transacción se revertirá. Saldo insuficiente de %s Liquidez insuficiente - Tarifa LP - Una porción de cada trade va a los proveedores de liquidez como incentivo del protocolo - Synthetic token fee - Total fee - Total fee consists on fee + Tarifa LP + Una porción de cada trade va a los proveedores de liquidez como incentivo del protocolo + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Mercado SMART liquidity routing ensures the best price for any transaction by combining only the best price options from all available markets. When available, Token Bonding Curve (TBC) will be used for liquidity as long as the asset price is more affordable than from other sources, upon which the XYK pool is utilized. TBC — buying only from the Token Bonding Curve (Primary Market). There is a possibility that the price can become unfavorable compared to the XYK pool (Secondary Market), but the value received from the vested rewards might turn out to be much more favorable over time. diff --git a/common/src/main/res/values-fa/strings.xml b/common/src/main/res/values-fa/strings.xml index 98ed727c2..84d6f9434 100644 --- a/common/src/main/res/values-fa/strings.xml +++ b/common/src/main/res/values-fa/strings.xml @@ -339,11 +339,12 @@ مقدار پرداختی تخمینی است. حداکثر مقدار %s خواهید فروخت، در غیر اینصورت تراکنش برگشت خواهد خورد. مانده %s ناکافی نقدینگی ناکافی - هزینه LP - بخشی از هر معامله به عنوان مشوق پروتکل به ارائه دهندگان نقدینگی می‌رسد. - Synthetic token fee - Total fee - Total fee consists on fee + هزینه LP + بخشی از هر معامله به عنوان مشوق پروتکل به ارائه دهندگان نقدینگی می‌رسد. + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. بازار مسیریابی نقدینگی SMART با ترکیب بهترین گزینه‌های قیمت از همه بازارهای موجود، بهترین قیمت را برای هر معامله تضمین می‌کند. در صورت امکان Token Bonding Curve (TBC) برای نقدینگی استفاده خواهد شد تا زمانی که قیمت دارایی مقرون به صرفه‌تر از منابع دیگر باشد، که در این حالت از استخر XYK استفاده می‌شود. TBC - خرید فقط از Token Bonfing Curve (بازار اولیه). ممکن است قیمت در مقایسه با مخزن XYK (بازار ثانویه) نامطلوب تر باشد، اما ارزش دریافتی از پاداش‌های اختصاص داده شده ممکن است در طول زمان بسیار مطلوب تر شود. diff --git a/common/src/main/res/values-fi/strings.xml b/common/src/main/res/values-fi/strings.xml index dccd77ce0..f28081c42 100644 --- a/common/src/main/res/values-fi/strings.xml +++ b/common/src/main/res/values-fi/strings.xml @@ -339,11 +339,12 @@ Syöte on arvioitu. Myyt enintään %s tai kauppa palautuu. Riittämätön %s saldo Riittämätön likviditeetti - LP-maksu - Osa jokaisesta kaupasta menee likviditeetin tarjoajille protokollakannustimena. - Synthetic token fee - Total fee - Total fee consists on fee + LP-maksu + Osa jokaisesta kaupasta menee likviditeetin tarjoajille protokollakannustimena. + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Market SMART likviditeetin reititys varmistaa parhaan hinnan jokaiselle tapahtumalle, yhdistämällä vain parhaat hintavaihtoehdot kaikilta saatavilla olevilta markkinoilta. Token Bonding Curvea (TBC) käytetään mahdollisuuksien mukaan likviditeettiin niin kauan kun resurssien hinta on edullisempi kuin muista lähteistä, jolloin taas hyödynnetään XYK-poolia. TBC – ostaminen vain Token Bonding Curvesta (ensisijainen markkina). On mahdollista, että hinnasta tulee epäedullinen verrattuna XYK-pooliin (toissijainen markkina), mutta saavutetuista palkkioista saatu arvo saattaa osoittautua paljon edullisemmaksi ajan myötä. diff --git a/common/src/main/res/values-fr/strings.xml b/common/src/main/res/values-fr/strings.xml index 2e1691520..a2585784f 100644 --- a/common/src/main/res/values-fr/strings.xml +++ b/common/src/main/res/values-fr/strings.xml @@ -339,11 +339,12 @@ Le montant à fournir est estimé. Vous vendrez au maximum %s ou la transaction sera annulée. Solde %s insuffisant Liquidité insuffisante - Frais de LP - Une partie de chaque transaction est reversée aux fournisseurs de liquidités à titre d\'incitation de la part du protocole - Synthetic token fee - Total fee - Total fee consists on fee + Frais de LP + Une partie de chaque transaction est reversée aux fournisseurs de liquidités à titre d\'incitation de la part du protocole + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Marché Le routage de la liquidité SMART garantit le meilleur prix pour toute transaction en combinant uniquement les meilleures options de prix de tous les marchés disponibles. Lorsqu\'elle est disponible, la courbe de liaison de jeton (TBC) sera utilisée pour la liquidité tant que le prix de l\'actif est plus abordable que celui des autres sources, sur lesquelles le pool XYK est utilisé. TBC - achat uniquement à partir de la courbe de liaison de jeton (marché primaire). Il est possible que le prix devienne défavorable par rapport au pool XYK (marché secondaire), mais la valeur reçue des récompenses acquises pourrait s\'avérer beaucoup plus favorable au fil du temps. diff --git a/common/src/main/res/values-hi-rIN/strings.xml b/common/src/main/res/values-hi-rIN/strings.xml index 911daf99f..ee7c42bd5 100644 --- a/common/src/main/res/values-hi-rIN/strings.xml +++ b/common/src/main/res/values-hi-rIN/strings.xml @@ -339,11 +339,12 @@ इनपुट अनुमानित है। आप अधिकतम %s बेचेंगे या लेन-देन वापस हो जाएगा। अपर्याप्त %s राशि अपर्याप्त Liquidity - LP शुल्क - प्रत्येक व्यापार का एक हिस्सा एक प्रोटोकॉल प्रोत्साहन के रूप में Liquidity प्रदाताओं को जाता है। - Synthetic token fee - Total fee - Total fee consists on fee + LP शुल्क + प्रत्येक व्यापार का एक हिस्सा एक प्रोटोकॉल प्रोत्साहन के रूप में Liquidity प्रदाताओं को जाता है। + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. बाज़ार स्मार्ट लिक्विडिटी रूटिंग सभी उपलब्ध बाजारों से केवल सर्वोत्तम मूल्य विकल्पों को मिलाकर किसी भी लेन-देन के लिए सर्वोत्तम मूल्य सुनिश्चित करता है। उपलब्ध होने पर, टोकन बॉन्डिंग कर्व (TBC) का उपयोग तरलता के लिए तब तक किया जाएगा जब तक कि संपत्ति की कीमत अन्य स्रोतों की तुलना में अधिक सस्ती हो, जिस पर XYK पूल का उपयोग किया जाता है। टीबीसी - केवल टोकन बॉन्डिंग वक्र (प्राथमिक बाजार) से खरीदना। एक संभावना है कि मूल्य XYK पूल (द्वितीयक बाजार) की तुलना में प्रतिकूल हो सकता है, लेकिन निहित पुरस्कारों से प्राप्त मूल्य समय के साथ और अधिक अनुकूल हो सकता है। diff --git a/common/src/main/res/values-in/strings.xml b/common/src/main/res/values-in/strings.xml index c7df47b36..cf67f4154 100644 --- a/common/src/main/res/values-in/strings.xml +++ b/common/src/main/res/values-in/strings.xml @@ -338,11 +338,12 @@ Masukan diperkirakan. Anda akan menjual maksimum %s atau transaksi akan dibatalkan. Saldo %s tidak mencukupi Likuiditas tidak mencukupi - Biaya LP - Sebagian dari setiap perdagangan diberikan kepada penyedia likuiditas sebagai insentif protokol. - Synthetic token fee - Total fee - Total fee consists on fee + Biaya LP + Sebagian dari setiap perdagangan diberikan kepada penyedia likuiditas sebagai insentif protokol. + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Pasar SMART liquidity routing ensures the best price for any transaction by combining only the best price options from all available markets. When available, Token Bonding Curve (TBC) will be used for liquidity as long as the asset price is more affordable than from other sources, upon which the XYK pool is utilized. TBC — buying only from the Token Bonding Curve (Primary Market). There is a possibility that the price can become unfavorable compared to the XYK pool (Secondary Market), but the value received from the vested rewards might turn out to be much more favorable over time. diff --git a/common/src/main/res/values-iw/strings.xml b/common/src/main/res/values-iw/strings.xml index 5d43449e4..bcdc63ba7 100644 --- a/common/src/main/res/values-iw/strings.xml +++ b/common/src/main/res/values-iw/strings.xml @@ -341,11 +341,12 @@ הקלט מוערך. אתה תמכור לכל היותר %s או שהטרנזקציה תחזור. יתרה %s לא מספיקה אין מספיק נזילות - עמלת מאגר נזילות - חלק מכל עסקה הולך לספקי נזילות כתמריץ פרוטוקול. - Synthetic token fee - Total fee - Total fee consists on fee + עמלת מאגר נזילות + חלק מכל עסקה הולך לספקי נזילות כתמריץ פרוטוקול. + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. שוק ניתוב נזילות SMART מבטיח את המחיר הטוב ביותר לכל טרנזקציה על ידי שילוב אפשרויות המחיר הטובות ביותר בלבד מכל השווקים הזמינים. כאשר זמין, עקומת צירוף הטוקנים (TBC) תשמש לנזילות כל עוד מחיר הנכס משתלם יותר מאשר ממקורות אחרים, שעליהם מנוצל מאגר XYK. TBC - קנייה רק מעקומת צירוף הטוקנים (השוק העיקרי). קיימת אפשרות שהמחיר יכול להפוך לבלתי משתלם בהשוואה למאגר XYK (שוק משני), אך הערך המתקבל מהתגמולים המוענקים לאורך זמן עשוי להתברר כמשתלם הרבה יותר לטווח ארוך. diff --git a/common/src/main/res/values-ja/strings.xml b/common/src/main/res/values-ja/strings.xml index b33c0dd3b..e87f37c5e 100644 --- a/common/src/main/res/values-ja/strings.xml +++ b/common/src/main/res/values-ja/strings.xml @@ -338,11 +338,12 @@ 入力は推定です。最大で%s売らないと、取引は元に戻ります %s 残高不足 流動性不足 - LP手数料 - 各取引の一部は、インセンティブとして流動性プロバイダー(LP)に送られます - Synthetic token fee - Total fee - Total fee consists on fee + LP手数料 + 各取引の一部は、インセンティブとして流動性プロバイダー(LP)に送られます + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. 市場 SMART流動性ルーティングは、利用可能なすべての市場から最良の価格オプションだけ組み合わせることで、あらゆる取引の最良の価格を保証します。XYKプールや他のプールが利用される場合より資産価格が手頃であれば、可能な限りトークン・ボンディング・カーブ(TBC)が流動性のために使用されます TBC — トークン・ボンディング・カーブ(一次市場)からのみ購入します。 XYKプール(二次市場)に比べて価格が不利になる可能性もありますが、既得の報酬から受け取る価値が、時間の経過とともにはるかに有利になる可能性があります diff --git a/common/src/main/res/values-ms-rMY/strings.xml b/common/src/main/res/values-ms-rMY/strings.xml index 7d1762f2e..4193f5a37 100644 --- a/common/src/main/res/values-ms-rMY/strings.xml +++ b/common/src/main/res/values-ms-rMY/strings.xml @@ -338,11 +338,12 @@ Input dianggarkan. Anda akan menjual maksimum %s atau transaksi akan kembali. Baki %s tidak mencukupi Kecairan tidak mencukupi - Bayaran LP - Sebahagian daripada setiap dagangan diberikan kepada penyedia kecairan sebagai insentif protokol. - Synthetic token fee - Total fee - Total fee consists on fee + Bayaran LP + Sebahagian daripada setiap dagangan diberikan kepada penyedia kecairan sebagai insentif protokol. + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Pasaran Penghalaan kecairan SMART memastikan harga terbaik untuk sebarang transaksi dengan menggabungkan hanya pilihan harga terbaik dari semua pasaran yang ada. Apabila tersedia, Token Bonding Curve (TBC) akan digunakan untuk kecairan selagi harga aset lebih berpatutan daripada sumber lain, di mana kolam XYK digunakan. TBC — membeli hanya daripada Lengkung Ikatan Token (Pasaran Utama). Terdapat kemungkinan bahawa harga boleh menjadi tidak menguntungkan berbanding dengan kolam XYK (Pasaran Sekunder), tetapi nilai yang diterima daripada ganjaran terletak hak mungkin berubah menjadi lebih baik dari masa ke masa. diff --git a/common/src/main/res/values-nb/strings.xml b/common/src/main/res/values-nb/strings.xml index 5846ff0db..a60f90749 100644 --- a/common/src/main/res/values-nb/strings.xml +++ b/common/src/main/res/values-nb/strings.xml @@ -339,11 +339,12 @@ Inndata er estimert. Du vil selge maksimalt %s eller transaksjonen vil gå tilbake. Utilstrekkelig saldo %s Utilstrekkelig likviditet - LP -avgift - En del av hver handel går til likviditetsleverandører som et protokollinsentiv. - Synthetic token fee - Total fee - Total fee consists on fee + LP -avgift + En del av hver handel går til likviditetsleverandører som et protokollinsentiv. + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Marked SMART liquidity routing ensures the best price for any transaction by combining only the best price options from all available markets. When available, Token Bonding Curve (TBC) will be used for liquidity as long as the asset price is more affordable than from other sources, upon which the XYK pool is utilized. TBC — buying only from the Token Bonding Curve (Primary Market). There is a possibility that the price can become unfavorable compared to the XYK pool (Secondary Market), but the value received from the vested rewards might turn out to be much more favorable over time. diff --git a/common/src/main/res/values-nl/strings.xml b/common/src/main/res/values-nl/strings.xml index f22cfda5d..1064cb157 100644 --- a/common/src/main/res/values-nl/strings.xml +++ b/common/src/main/res/values-nl/strings.xml @@ -339,11 +339,12 @@ Invoer wordt geschat. U verkoopt maximaal %s of de transactie wordt teruggedraaid. Onvoldoende %s saldo Onvoldoende liquiditeit - LP Vergoeding - Een deel van elke transactie gaat naar liquiditeitsverschaffers als aanmoediging van het protocol. - Synthetic token fee - Total fee - Total fee consists on fee + LP Vergoeding + Een deel van elke transactie gaat naar liquiditeitsverschaffers als aanmoediging van het protocol. + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Markt SMART liquiditeitsroutering zorgt voor de beste prijs voor elke transactie door alleen de beste prijsopties uit alle beschikbare markten te combineren. Indien beschikbaar, zal de Token Bonding Curve (TBC) worden gebruikt voor liquiditeit zolang de activaprijs betaalbaarder is dan uit andere bronnen, waarop de XYK-pool wordt gebruikt. TBC - alleen kopen van de Token Bonding Curve (primaire markt). Er is een mogelijkheid dat de prijs ongunstig kan worden in vergelijking met de XYK-pool (secundaire markt), maar de waarde die wordt ontvangen van de gevestigde beloningen kan in de loop van de tijd veel gunstiger blijken te zijn. diff --git a/common/src/main/res/values-pt/strings.xml b/common/src/main/res/values-pt/strings.xml index 4df46b280..e65216f07 100644 --- a/common/src/main/res/values-pt/strings.xml +++ b/common/src/main/res/values-pt/strings.xml @@ -339,11 +339,12 @@ A quantia é estimada. Irá vender no máximo %s ou a transação será revertida. Saldo %s insuficiente Liquidez insuficiente - Taxa de LP - Uma porção de cada transação vai para os provedores de liquidez, como incentivo do protocolo. - Synthetic token fee - Total fee - Total fee consists on fee + Taxa de LP + Uma porção de cada transação vai para os provedores de liquidez, como incentivo do protocolo. + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Mercado O roteamento de liquidez SMART assegura o melhor preço para qualquer transação, combinando apenas as melhores opções de preços de todos os mercados acessíveis. Quando disponível, a Curva Agregadora de Tokens (TBC) será usada para liquidez, desde que o preço do ativo seja mais económico do que o de outras fontes, que utilizam a pool XYK. TBC - compra apenas a partir da Curva Agregadora de Tokens (Mercado Primário). Há a possibilidade de o preço se tornar desfavorável em comparação com a pool XYK (Mercado Secundário), mas o valor das recompensas recebido pode vir a revelar-se muito mais favorável ao longo do tempo. diff --git a/common/src/main/res/values-ru/strings.xml b/common/src/main/res/values-ru/strings.xml index 65b027a7f..78d1b8b2c 100644 --- a/common/src/main/res/values-ru/strings.xml +++ b/common/src/main/res/values-ru/strings.xml @@ -342,11 +342,12 @@ Оценочная сумма. Максимально будет продано %s или транзакция будет отменена. Недостаточный баланс %s Недостаточная ликвидность - Комиссия LP - Часть каждой сделки является награждением для поставщиков ликвидности. + Комиссия LP + Часть каждой сделки является награждением для поставщиков ликвидности. Комиссия за синтетический токен - Общая комиссия - Общая комиссия состоит из комиссии + Синтетическая комиссия состоит из комиссии за синтетический актив и динамической комиссии для предотвращения опережения. Плата за синтетические активы определяется при регистрации актива и может быть изменена в любое время посредством управления. Динамическая плата основана на процентном изменении цены оракула. + Комиссия обмена + Ваш своп включает в себя как синтетическую комиссию, так и комиссию LP.\nСинтетическая комиссия учитывается, когда обмен проходит через источник ликвидности XST для синтетических активов, а комиссия LP - когда своп проходит через пулы ликвидности. Рынок Маршрутизация ликвидности SMART обеспечивает лучшую цену для любой транзакции, комбинируя только лучшие варианты цены со всех доступных рынков. При наличии TBC будет использоваться для обеспечения ликвидности до тех пор, пока цена актива будет более доступной, чем из других источников, на которых используется пул XYK. TBC(Token Bonding Curve) — покупка только по кривой связывания токенов (первичный рынок). Есть вероятность того, что цена может стать невыгодной по сравнению с пулом XYK (вторичный рынок), но ценность, полученная от закрепленных вознаграждений, со временем может оказаться гораздо более выгодной. diff --git a/common/src/main/res/values-sr/strings.xml b/common/src/main/res/values-sr/strings.xml index 56ce6511b..501f19ad9 100644 --- a/common/src/main/res/values-sr/strings.xml +++ b/common/src/main/res/values-sr/strings.xml @@ -340,11 +340,12 @@ Улаз је процењен. Продаћете максимум %s или ће трансакција бити отказана. Nedovoljan balans Недовољна ликвидност - Naknada za likvidnost - Deo svake transakcije ide provajderima likvidnosti kao protokolarni podsticaj. - Synthetic token fee - Total fee - Total fee consists on fee + Naknada za likvidnost + Deo svake transakcije ide provajderima likvidnosti kao protokolarni podsticaj. + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Tržište СМАРТ усмеравање ликвидности обезбеђује најбољу цену за било коју трансакцију комбиновањем само најбољих опција цена са свих доступних тржишта. Када је доступна, крива везивања токена (ТБЦ) ће се користити за ликвидност све док је цена средства приступачнија него из других извора, на основу којих се користи КСИК фонд. ТБЦ — куповина само са криве везивања токена (примарно тржиште). Постоји могућност да цена може постати неповољнија у поређењу са КСИК фондом (секундарно тржиште), али вредност добијена од стечених награда може се временом показати много повољнијом. diff --git a/common/src/main/res/values-tr/strings.xml b/common/src/main/res/values-tr/strings.xml index fa85f8d10..425c8cc54 100644 --- a/common/src/main/res/values-tr/strings.xml +++ b/common/src/main/res/values-tr/strings.xml @@ -339,11 +339,12 @@ Giriş tahminidir. Maksimum %s satacaksınız veya işlem geri dönecek. Yetersiz %s bakiye Yetersiz likidite - LP Ücreti - Her takasın bir kısmı protokol teşviki olarak likidite sağlayıcılarına gider. - Synthetic token fee - Total fee - Total fee consists on fee + LP Ücreti + Her takasın bir kısmı protokol teşviki olarak likidite sağlayıcılarına gider. + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Piyasa SMART likidite yönlendirmesi, mevcut piyasalardaki en iyi fiyat oranlarını birleştirerek herhangi bir işlem için en iyi fiyatı bulur. Mevcut olduğunda, fiyat, XYK havuzunun kullanıldığı diğer kaynaklardan daha uygun olduğu sürece Token Tahvil Eğrisi (TBC), likidite için kullanılacaktır. TBC — sadece Token Tahvil Eğrisinden (Birincil Piyasadan) satın alınması. Fiyat, XYK havuzuna (İkincil Piyasaya) göre daha olumsuz olabilir, ama bir süre sonra kilidi açılan ödüllerden gelen değer, daha olumlu olabilir. diff --git a/common/src/main/res/values-vi/strings.xml b/common/src/main/res/values-vi/strings.xml index 450249e3e..027c49117 100644 --- a/common/src/main/res/values-vi/strings.xml +++ b/common/src/main/res/values-vi/strings.xml @@ -338,11 +338,12 @@ Dự tính đầu vào. Bạn sẽ bán tối đa %s hoặc giao dịch sẽ hoàn tác. Số dư không đủ %s Không đủ thanh khoản - Phí thanh khoản - Một phần của mỗi giao dịch được chuyển đến các nhà cung cấp thanh khoản như một biện pháp khuyến khích. - Synthetic token fee - Total fee - Total fee consists on fee + Phí thanh khoản + Một phần của mỗi giao dịch được chuyển đến các nhà cung cấp thanh khoản như một biện pháp khuyến khích. + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Thị trường SMART liquidity routing đảm bảo giá tốt nhất cho giao dịch bất kỳ bằng cách kết hợp mức giá tốt nhất hiện có trên thị trường. Khi thuận lợi, Token Bonding Curve (TBC) sẽ được dùng để tạo thanh khoản miễn là giá của tài sản hợp lý hơn các nguồn khác như pool (XYK). TBC - chỉ mua từ Token Bonding Curve (Primary Market). Giá có thể trở nên bất lợi so với XYK pool (Secondary Market), nhưng về lâu dài giá trị nhận được từ phần thưởng có thể lớn hơn nhiều. diff --git a/common/src/main/res/values-zh-rCN/strings.xml b/common/src/main/res/values-zh-rCN/strings.xml index 47c0a3cb7..5d9becd4b 100644 --- a/common/src/main/res/values-zh-rCN/strings.xml +++ b/common/src/main/res/values-zh-rCN/strings.xml @@ -338,11 +338,12 @@ 输入是估计的。您将卖出最大的%s,否则交易将被取消。 %s余额不足 流动性不足 - 流动性提供者费用 - 每笔交易的一部分作为协议激励奖励流动性提供者。 - Synthetic token fee - Total fee - Total fee consists on fee + 流动性提供者费用 + 每笔交易的一部分作为协议激励奖励流动性提供者。 + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. 市场 智能流动性路由通过从所有可用市场中仅选择最佳价格选项,确保任何交易的最佳价格。如果可用,将使用代币绑定曲线(TBC)提供流动性,只要资产价格比其他来源更实惠,否则将使用XYK池。 TBC - 仅从代币绑定曲线(一级市场)购买。价格可能会比XYK池(二级市场)不利,但随着时间的推移,从归属奖励中获得的价值可能会更有利。 diff --git a/common/src/main/res/values-zh-rTW/strings.xml b/common/src/main/res/values-zh-rTW/strings.xml index 5bc5d5d00..07523b4ac 100644 --- a/common/src/main/res/values-zh-rTW/strings.xml +++ b/common/src/main/res/values-zh-rTW/strings.xml @@ -338,11 +338,12 @@ 输入是估計的。您将賣出最大的 %s , 否則交易将被取消。 %s餘額不足 流動性不足 - LP費用 - 每筆交易的一部分 作為協議激勵流向流動性提供者。 - Synthetic token fee - Total fee - Total fee consists on fee + LP費用 + 每筆交易的一部分 作為協議激勵流向流動性提供者。 + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. 市場 SMART 流動性路由通過僅結合所有可用市場的最佳價格選項來確保任何交易的最佳價格。如果可用,代幣綁定曲線 (TBC) 將用於流動性,只要資產價格比使用 XYK 池的其他來源更實惠。 TBC — 僅從 Token Bonding Curve(一級市場)購買。與 XYK 池(二級市場)相比,價格有可能變得不利,但隨著時間的推移,從既得獎勵中獲得的價值可能會變得更加有利。 diff --git a/common/src/main/res/values/strings.xml b/common/src/main/res/values/strings.xml index d9d8eebe8..f23b120f8 100644 --- a/common/src/main/res/values/strings.xml +++ b/common/src/main/res/values/strings.xml @@ -339,11 +339,12 @@ Input is estimated. You will sell maximum %s or the transaction will revert. Insufficient %s balance Insufficient liquidity - LP Fee - A portion of each trade goes to liquidity providers as a protocol incentive. - Synthetic token fee - Total fee - Total fee consists on fee + LP Fee + A portion of each trade goes to liquidity providers as a protocol incentive. + Synthetic fee + The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. + Swap fee + Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Market SMART liquidity routing ensures the best price for any transaction by combining only the best price options from all available markets. When available, Token Bonding Curve (TBC) will be used for liquidity as long as the asset price is more affordable than from other sources, upon which the XYK pool is utilized. TBC — buying only from the Token Bonding Curve (Primary Market). There is a possibility that the price can become unfavorable compared to the XYK pool (Secondary Market), but the value received from the vested rewards might turn out to be much more favorable over time. diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt index 216814153..3eae9450a 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt @@ -765,8 +765,8 @@ class SwapViewModel @AssistedInject constructor( maxMinToken = _swapMainState.value.tokenToState?.token } val (title, desc) = when (details.feeMode) { - SwapFeeMode.SYNTHETIC -> R.string.polkaswap_liquidity_synthetic_fee to R.string.polkaswap_liqudity_fee_info - SwapFeeMode.NON_SYNTHETIC -> R.string.polkaswap_liqudity_fee to R.string.polkaswap_liqudity_fee_info + SwapFeeMode.SYNTHETIC -> R.string.polkaswap_liquidity_synthetic_fee to R.string.polkaswap_liquidity_synthetic_fee_desc + SwapFeeMode.NON_SYNTHETIC -> R.string.polkaswap_liquidity_fee to R.string.polkaswap_liquidity_fee_info SwapFeeMode.BOTH -> R.string.polkaswap_liquidity_total_fee to R.string.polkaswap_liquidity_total_fee_desc } _swapMainState.value = _swapMainState.value.copy( diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/SwapMainState.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/SwapMainState.kt index 706d9ae01..a2d4d40b3 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/SwapMainState.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/SwapMainState.kt @@ -85,8 +85,8 @@ fun defaultSwapDetailsState() = priceToFromTitle = "", priceToFrom = "", lpFee = "", - lpFeeTitle = R.string.polkaswap_liqudity_fee, - lpFeeHint = R.string.polkaswap_liqudity_fee_info, + lpFeeTitle = R.string.polkaswap_liquidity_fee, + lpFeeHint = R.string.polkaswap_liquidity_fee_info, route = "", shouldTransactionReminderInsufficientWarningBeShown = false, ) From ef8f3f894edd09aec2f494227453dbfe7f2ff758 Mon Sep 17 00:00:00 2001 From: arvifox Date: Tue, 29 Aug 2023 22:56:36 +0300 Subject: [PATCH 07/20] sn-2888 referral banner --- .../presentation/cardshub/ReferralCard.kt | 55 +++++++++++-------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/ReferralCard.kt b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/ReferralCard.kt index be16ec63b..8b05d0427 100644 --- a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/ReferralCard.kt +++ b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/ReferralCard.kt @@ -33,11 +33,8 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_wallet_impl.presentation.cardshub import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentHeight @@ -48,9 +45,12 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview +import androidx.constraintlayout.compose.ConstraintLayout +import androidx.constraintlayout.compose.Dimension import jp.co.soramitsu.common.R import jp.co.soramitsu.ui_core.component.button.BleachedButton import jp.co.soramitsu.ui_core.component.button.FilledButton @@ -74,18 +74,32 @@ fun ReferralCard( modifier = Modifier .fillMaxWidth() ) { - Row( - modifier = Modifier.fillMaxWidth().wrapContentHeight(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, + ConstraintLayout( + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight(), ) { + val (ref, image) = createRefs() ReferralContent( - modifier = Modifier.weight(3f), + modifier = Modifier + .constrainAs(ref) { + top.linkTo(parent.top) + start.linkTo(parent.start) + }, onStartClicked = onStartClicked, ) Image( - modifier = Modifier.weight(2f), + modifier = Modifier.constrainAs(image) { + start.linkTo(ref.end) + top.linkTo(parent.top) + end.linkTo(parent.end) + bottom.linkTo(ref.bottom) + width = Dimension.fillToConstraints + height = Dimension.fillToConstraints + }, + contentScale = ContentScale.Fit, + alignment = Alignment.CenterEnd, painter = painterResource(R.drawable.image_friends), contentDescription = null, ) @@ -115,11 +129,10 @@ private fun ReferralContent( modifier = modifier .padding( top = Dimens.x2, - bottom = Dimens.x3, + bottom = Dimens.x2, start = Dimens.x3, - end = Dimens.x3, - ), - verticalArrangement = Arrangement.SpaceBetween, + ) + .wrapContentHeight(), ) { Text( text = stringResource(R.string.settings_invite_title), @@ -137,7 +150,7 @@ private fun ReferralContent( FilledButton( modifier = Modifier .wrapContentWidth() - .padding(top = Dimens.x2), + .padding(top = Dimens.x1_5), text = stringResource(R.string.referral_start_inviting), size = Size.ExtraSmall, order = Order.PRIMARY, @@ -149,14 +162,8 @@ private fun ReferralContent( @Preview @Composable private fun PreviewReferralCard() { - Box( - modifier = Modifier - .fillMaxSize() - .padding(Dimens.x3) - ) { - ReferralCard( - onCloseCard = {}, - onStartClicked = {}, - ) - } + ReferralCard( + onCloseCard = {}, + onStartClicked = {}, + ) } From d599f47e5cd09ccae917ad52591106c02f340e40 Mon Sep 17 00:00:00 2001 From: arvifox Date: Wed, 30 Aug 2023 15:57:59 +0300 Subject: [PATCH 08/20] sn-2891 minor fixes --- build.gradle | 2 +- .../feature_polkaswap_impl/domain/SwapInteractorImpl.kt | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 1e9b03188..855404e7a 100644 --- a/build.gradle +++ b/build.gradle @@ -45,7 +45,7 @@ buildscript { composeCompiler : '1.4.6', composeConstraintLayout: '1.1.0-alpha05', uiCore : '0.1.0', - soraCard : '0.1.33', + soraCard : '0.1.34', lazySodium : '5.0.2', jna : '5.8.0', accompanist : '0.30.1', diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt index 5963a8ff8..166cff79e 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt @@ -160,9 +160,11 @@ class SwapInteractorImpl( private fun getFeeMode(ids: List?): SwapFeeMode { if (ids == null) return SwapFeeMode.NON_SYNTHETIC - val withoutxst = ids.filter { it != SubstrateOptionsProvider.xstTokenId } - if (withoutxst.all { it.matches(syntheticRegex) }) return SwapFeeMode.SYNTHETIC - if (withoutxst.all { it.matches(syntheticRegex).not() }) return SwapFeeMode.NON_SYNTHETIC + if (ids.all { it.matches(syntheticRegex).not() }) return SwapFeeMode.NON_SYNTHETIC + if (ids.all { + it.matches(syntheticRegex) || it == SubstrateOptionsProvider.xstTokenId || it == SubstrateOptionsProvider.xstusdTokenId + } + ) return SwapFeeMode.SYNTHETIC return SwapFeeMode.BOTH } From dfc7003aa57cfb2a99c2e99d0d0020a03cdab5d9 Mon Sep 17 00:00:00 2001 From: arvifox Date: Thu, 31 Aug 2023 13:38:00 +0300 Subject: [PATCH 09/20] version up --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 855404e7a..63258c5e0 100644 --- a/build.gradle +++ b/build.gradle @@ -45,7 +45,7 @@ buildscript { composeCompiler : '1.4.6', composeConstraintLayout: '1.1.0-alpha05', uiCore : '0.1.0', - soraCard : '0.1.34', + soraCard : '0.1.35', lazySodium : '5.0.2', jna : '5.8.0', accompanist : '0.30.1', From 014f77fb7fc43185670620a1f77490caddd139ab Mon Sep 17 00:00:00 2001 From: arvifox Date: Fri, 1 Sep 2023 14:07:53 +0300 Subject: [PATCH 10/20] minor fixes and refactoring --- android-foundation | 2 +- common/build.gradle | 1 + .../co/soramitsu/common/base/BaseFragment.kt | 81 ------------------- .../soramitsu/common/base/SoraBaseFragment.kt | 12 +++ .../common/di/modules/CommonModule.kt | 7 +- .../presentation/viewmodel/BaseViewModel.kt | 1 + .../common/resourses/ClipboardManager.kt | 46 ----------- .../demeter/data/DemeterFarmingRepository.kt | 17 +--- .../assetdetails/AssetDetailsFragment.kt | 8 +- .../assetdetails/AssetDetailsViewModel.kt | 13 +-- .../receiverequest/QRCodeFlowViewModel.kt | 8 +- .../screens/send/TransferAmountFragment.kt | 4 - .../screens/send/TransferAmountViewModel.kt | 10 +-- .../qr/QrCodeFlowViewModelTest.kt | 4 +- .../send/TransferAmountViewModelTest.kt | 4 +- feature_blockexplorer_impl/build.gradle | 1 + .../txdetails/TxDetailsFragment.kt | 6 -- .../txdetails/TxDetailsViewModel.kt | 13 +-- .../txdetails/TxDetailsViewModelTest.kt | 8 +- .../account_details/AccountDetailsFragment.kt | 5 -- .../AccountDetailsViewModel.kt | 11 +-- .../account_list/AccountListFragment.kt | 5 -- .../account_list/AccountListViewModel.kt | 13 +-- .../export_account/backup/BackupFragment.kt | 17 ---- .../export_account/backup/BackupViewModel.kt | 14 ++-- .../AccountDetailsViewModelTest.kt | 4 +- .../account_list/AccountListViewModelTest.kt | 12 +-- .../export/backup/BackupViewModelTest.kt | 15 ++-- .../PolkaswapSubscriptionRepositoryImpl.kt | 48 ++++++++++- .../domain/SwapInteractorImpl.kt | 18 +++-- .../components/compose/PoolDetailsScreen.kt | 1 - .../liquidityadd/LiquidityAddViewModel.kt | 5 +- .../card/details/SoraCardDetailsFragment.kt | 4 - .../card/details/SoraCardDetailsViewModel.kt | 11 +-- .../runtime/SubstrateOptionsProvider.kt | 49 ++++++----- .../sora/substrate/substrate/Extrinsics.kt | 50 +++--------- .../sora/substrate/substrate/SubstrateApi.kt | 2 - .../substrate/substrate/SubstrateApiImpl.kt | 69 ++-------------- .../substrate/substrate/SubstrateCalls.kt | 6 +- 39 files changed, 184 insertions(+), 421 deletions(-) delete mode 100644 common/src/main/java/jp/co/soramitsu/common/base/BaseFragment.kt delete mode 100644 common/src/main/java/jp/co/soramitsu/common/resourses/ClipboardManager.kt diff --git a/android-foundation b/android-foundation index a658dbc38..3ed681704 160000 --- a/android-foundation +++ b/android-foundation @@ -1 +1 @@ -Subproject commit a658dbc38c0ef638a21c141e1f50d2496906d2a1 +Subproject commit 3ed681704a011be7513d5eb66e0d6e0512e3cb6f diff --git a/common/build.gradle b/common/build.gradle index 1ce68aaf7..7900b592a 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -114,6 +114,7 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation project(":android-foundation") implementation project(":soracrypro") implementation activityKtxDep diff --git a/common/src/main/java/jp/co/soramitsu/common/base/BaseFragment.kt b/common/src/main/java/jp/co/soramitsu/common/base/BaseFragment.kt deleted file mode 100644 index 4e34b5e58..000000000 --- a/common/src/main/java/jp/co/soramitsu/common/base/BaseFragment.kt +++ /dev/null @@ -1,81 +0,0 @@ -/* -This file is part of the SORA network and Polkaswap app. - -Copyright (c) 2020, 2021, Polka Biome Ltd. All rights reserved. -SPDX-License-Identifier: BSD-4-Clause - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or other -materials provided with the distribution. - -All advertising materials mentioning features or use of this software must display -the following acknowledgement: This product includes software developed by Polka Biome -Ltd., SORA, and Polkaswap. - -Neither the name of the Polka Biome Ltd. nor the names of its contributors may be used -to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY Polka Biome Ltd. AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Polka Biome Ltd. BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package jp.co.soramitsu.common.base - -import android.os.Bundle -import android.view.View -import androidx.annotation.LayoutRes -import androidx.appcompat.app.AlertDialog -import androidx.fragment.app.Fragment -import androidx.lifecycle.LiveData -import jp.co.soramitsu.common.R -import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel - -abstract class BaseFragment(@LayoutRes layoutRes: Int) : Fragment(layoutRes) { - - abstract val viewModel: T - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - viewModel.errorLiveData.observe { - AlertDialog.Builder(requireActivity()) - .setTitle(R.string.common_error_general_title) - .setMessage(it) - .setPositiveButton(android.R.string.ok) { _, _ -> } - .show() - } - viewModel.alertDialogLiveData.observe { - AlertDialog.Builder(requireActivity()) - .setTitle(it.first) - .setMessage(it.second) - .setPositiveButton(android.R.string.ok) { _, _ -> } - .show() - } - - viewModel.errorFromResourceLiveData.observe { - showErrorFromResponse(it.first, it.second) - } - } - - protected fun showErrorFromResponse(title: Int, messageResId: Int) { - AlertDialog.Builder(requireActivity()) - .setTitle(title) - .setMessage(messageResId) - .setPositiveButton(android.R.string.ok) { _, _ -> } - .show() - } - - fun LiveData.observe(observer: (V) -> Unit) { - observe(viewLifecycleOwner, observer) - } -} diff --git a/common/src/main/java/jp/co/soramitsu/common/base/SoraBaseFragment.kt b/common/src/main/java/jp/co/soramitsu/common/base/SoraBaseFragment.kt index 0f250e601..cd4142e94 100644 --- a/common/src/main/java/jp/co/soramitsu/common/base/SoraBaseFragment.kt +++ b/common/src/main/java/jp/co/soramitsu/common/base/SoraBaseFragment.kt @@ -33,10 +33,12 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.common.base import android.annotation.SuppressLint +import android.os.Build import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.Toast import androidx.activity.compose.BackHandler import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.ScrollState @@ -70,6 +72,7 @@ import jp.co.soramitsu.common.presentation.compose.components.AlertDialogContent import jp.co.soramitsu.common.presentation.compose.components.Toolbar import jp.co.soramitsu.common.presentation.compose.theme.SoraAppTheme import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel +import jp.co.soramitsu.common.util.BuildUtils import jp.co.soramitsu.common.util.DebounceClickHandler import jp.co.soramitsu.common.util.ext.safeCast import jp.co.soramitsu.ui_core.theme.customColors @@ -90,6 +93,15 @@ abstract class SoraBaseFragment : Fragment() { activity?.safeCast()?.setColor(backgroundColor()) } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + if (BuildUtils.sdkAtLeast(Build.VERSION_CODES.TIRAMISU).not()) { + viewModel.copiedToast.observe { + Toast.makeText(requireActivity(), R.string.common_copied, Toast.LENGTH_SHORT).show() + } + } + } + @SuppressLint("UnusedMaterialScaffoldPaddingParameter") override fun onCreateView( inflater: LayoutInflater, diff --git a/common/src/main/java/jp/co/soramitsu/common/di/modules/CommonModule.kt b/common/src/main/java/jp/co/soramitsu/common/di/modules/CommonModule.kt index 393b88c7c..60e84d80e 100644 --- a/common/src/main/java/jp/co/soramitsu/common/di/modules/CommonModule.kt +++ b/common/src/main/java/jp/co/soramitsu/common/di/modules/CommonModule.kt @@ -32,6 +32,7 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.common.di.modules +import android.content.ClipboardManager import android.content.Context import android.graphics.Color import android.os.Build @@ -51,6 +52,7 @@ import java.security.SecureRandom import java.util.Locale import java.util.TimeZone import javax.inject.Singleton +import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.backup.BackupService import jp.co.soramitsu.common.BuildConfig import jp.co.soramitsu.common.account.AccountAvatarGenerator @@ -69,7 +71,6 @@ import jp.co.soramitsu.common.inappupdate.InAppUpdateManager import jp.co.soramitsu.common.interfaces.WithProgress import jp.co.soramitsu.common.io.FileManager import jp.co.soramitsu.common.io.FileManagerImpl -import jp.co.soramitsu.common.resourses.ClipboardManager import jp.co.soramitsu.common.resourses.LanguagesHolder import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.CryptoAssistant @@ -293,8 +294,8 @@ class CommonModule { @Provides @Singleton - fun provideClipBoardManager(@ApplicationContext context: Context): ClipboardManager { - return ClipboardManager(context.getSystemService(Context.CLIPBOARD_SERVICE) as android.content.ClipboardManager) + fun provideClipBoardManager(@ApplicationContext context: Context): BasicClipboardManager { + return BasicClipboardManager(context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager) } @Provides diff --git a/common/src/main/java/jp/co/soramitsu/common/presentation/viewmodel/BaseViewModel.kt b/common/src/main/java/jp/co/soramitsu/common/presentation/viewmodel/BaseViewModel.kt index 9f81a9fd6..294ea78b2 100644 --- a/common/src/main/java/jp/co/soramitsu/common/presentation/viewmodel/BaseViewModel.kt +++ b/common/src/main/java/jp/co/soramitsu/common/presentation/viewmodel/BaseViewModel.kt @@ -52,6 +52,7 @@ open class BaseViewModel : ViewModel() { val errorFromResourceLiveData = SingleLiveEvent>() val alertDialogLiveData = SingleLiveEvent>() val snackBarLiveData = SingleLiveEvent() + val copiedToast = SingleLiveEvent() protected val _toolbarState = MutableLiveData() val toolbarState: LiveData = _toolbarState diff --git a/common/src/main/java/jp/co/soramitsu/common/resourses/ClipboardManager.kt b/common/src/main/java/jp/co/soramitsu/common/resourses/ClipboardManager.kt deleted file mode 100644 index 583954374..000000000 --- a/common/src/main/java/jp/co/soramitsu/common/resourses/ClipboardManager.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* -This file is part of the SORA network and Polkaswap app. - -Copyright (c) 2020, 2021, Polka Biome Ltd. All rights reserved. -SPDX-License-Identifier: BSD-4-Clause - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or other -materials provided with the distribution. - -All advertising materials mentioning features or use of this software must display -the following acknowledgement: This product includes software developed by Polka Biome -Ltd., SORA, and Polkaswap. - -Neither the name of the Polka Biome Ltd. nor the names of its contributors may be used -to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY Polka Biome Ltd. AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Polka Biome Ltd. BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package jp.co.soramitsu.common.resourses - -import android.content.ClipData -import android.content.ClipboardManager - -class ClipboardManager( - private val clipboardManager: ClipboardManager -) { - - fun addToClipboard(label: String, text: String) { - val clip = ClipData.newPlainText(label, text) - clipboardManager.setPrimaryClip(clip) - } -} diff --git a/demeter/src/main/java/jp/co/soramitsu/demeter/data/DemeterFarmingRepository.kt b/demeter/src/main/java/jp/co/soramitsu/demeter/data/DemeterFarmingRepository.kt index 46c5610bf..e877533dc 100644 --- a/demeter/src/main/java/jp/co/soramitsu/demeter/data/DemeterFarmingRepository.kt +++ b/demeter/src/main/java/jp/co/soramitsu/demeter/data/DemeterFarmingRepository.kt @@ -40,7 +40,6 @@ import jp.co.soramitsu.common_wallet.data.AssetLocalToAssetMapper import jp.co.soramitsu.core_db.AppDatabase import jp.co.soramitsu.demeter.domain.DemeterFarmingPool import jp.co.soramitsu.feature_blockexplorer_api.data.SoraConfigManager -import jp.co.soramitsu.shared_utils.extensions.toHexString import jp.co.soramitsu.shared_utils.runtime.definitions.types.composite.Struct import jp.co.soramitsu.shared_utils.runtime.definitions.types.fromHex import jp.co.soramitsu.shared_utils.runtime.metadata.module @@ -50,6 +49,7 @@ import jp.co.soramitsu.shared_utils.ss58.SS58Encoder.toAccountId import jp.co.soramitsu.sora.substrate.runtime.Pallete import jp.co.soramitsu.sora.substrate.runtime.RuntimeManager import jp.co.soramitsu.sora.substrate.runtime.Storage +import jp.co.soramitsu.sora.substrate.runtime.mapToToken import jp.co.soramitsu.sora.substrate.substrate.SubstrateCalls interface DemeterFarmingRepository { @@ -123,18 +123,9 @@ internal class DemeterFarmingRepositoryImpl( ?.safeCast>() ?.filterIsInstance() ?.mapNotNull { instance -> - val baseToken = instance.get("baseAsset") - ?.get>("code")?.map { - (it as BigInteger).toByte() - }?.toByteArray()?.toHexString(true) - val poolToken = instance.get("poolAsset") - ?.get>("code")?.map { - (it as BigInteger).toByte() - }?.toByteArray()?.toHexString(true) - val rewardToken = instance.get("rewardAsset") - ?.get>("code")?.map { - (it as BigInteger).toByte() - }?.toByteArray()?.toHexString(true) + val baseToken = instance.mapToToken("baseAsset") + val poolToken = instance.mapToToken("poolAsset") + val rewardToken = instance.mapToToken("rewardAsset") val isFarm = instance.get("isFarm") val pooled = instance.get("pooledTokens") if (isFarm != null && baseToken != null && poolToken != null && rewardToken != null && pooled != null) { diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/assetdetails/AssetDetailsFragment.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/assetdetails/AssetDetailsFragment.kt index c01d67fb1..2afc76232 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/assetdetails/AssetDetailsFragment.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/assetdetails/AssetDetailsFragment.kt @@ -34,7 +34,6 @@ package jp.co.soramitsu.feature_assets_impl.presentation.screens.assetdetails import android.os.Bundle import android.view.View -import android.widget.Toast import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.ScrollState import androidx.compose.foundation.layout.Box @@ -56,7 +55,6 @@ import androidx.navigation.NavHostController import com.google.accompanist.navigation.animation.composable import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject -import jp.co.soramitsu.common.R import jp.co.soramitsu.common.base.SoraBaseFragment import jp.co.soramitsu.common.base.theOnlyRoute import jp.co.soramitsu.common.domain.BottomBarController @@ -174,11 +172,7 @@ class AssetDetailsFragment : SoraBaseFragment() { } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - (activity as BottomBarController).hideBottomBar() - viewModel.copyEvent.observe { - Toast.makeText(requireActivity(), R.string.common_copied, Toast.LENGTH_SHORT).show() - } - super.onViewCreated(view, savedInstanceState) + (activity as BottomBarController).hideBottomBar() } } diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/assetdetails/AssetDetailsViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/assetdetails/AssetDetailsViewModel.kt index 43b1fa252..d87b6ab8c 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/assetdetails/AssetDetailsViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/assetdetails/AssetDetailsViewModel.kt @@ -35,12 +35,12 @@ package jp.co.soramitsu.feature_assets_impl.presentation.screens.assetdetails import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue -import androidx.lifecycle.LiveData import androidx.lifecycle.viewModelScope import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import java.math.BigDecimal +import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.common.R import jp.co.soramitsu.common.domain.AssetHolder import jp.co.soramitsu.common.domain.formatFiatAmount @@ -48,11 +48,9 @@ import jp.co.soramitsu.common.domain.formatFiatChange import jp.co.soramitsu.common.domain.formatFiatOrEmpty import jp.co.soramitsu.common.domain.iconUri import jp.co.soramitsu.common.domain.printFiat -import jp.co.soramitsu.common.presentation.SingleLiveEvent import jp.co.soramitsu.common.presentation.compose.components.initSmallTitle2 import jp.co.soramitsu.common.presentation.trigger import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel -import jp.co.soramitsu.common.resourses.ClipboardManager import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.common.util.StringPair @@ -80,7 +78,7 @@ class AssetDetailsViewModel @AssistedInject constructor( private val assetsInteractor: AssetsInteractor, private val assetsRouter: AssetsRouter, private val walletRouter: WalletRouter, - private val clipboardManager: ClipboardManager, + private val clipboardManager: BasicClipboardManager, private val numbersFormatter: NumbersFormatter, private val poolsInteractor: PoolsInteractor, private val polkaswapRouter: PolkaswapRouter, @@ -101,9 +99,6 @@ class AssetDetailsViewModel @AssistedInject constructor( internal var state by mutableStateOf(AssetCardState(true, emptyAssetCardState)) private set - private val _copyEvent = SingleLiveEvent() - val copyEvent: LiveData = _copyEvent - private var xorAssetBalance: XorAssetBalance? = null init { @@ -207,8 +202,8 @@ class AssetDetailsViewModel @AssistedInject constructor( } fun onAssetIdClick() { - clipboardManager.addToClipboard("assetId", assetId) - _copyEvent.trigger() + clipboardManager.addToClipboard(assetId) + copiedToast.trigger() } fun onHistoryItemClick(txHash: String) { diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt index 8d919e905..9e73c9e1a 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt @@ -43,6 +43,7 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import java.math.BigDecimal +import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.common.R import jp.co.soramitsu.common.account.AccountAvatarGenerator import jp.co.soramitsu.common.domain.AssetAmountInputState @@ -53,7 +54,6 @@ import jp.co.soramitsu.common.io.FileManager import jp.co.soramitsu.common.presentation.SingleLiveEvent import jp.co.soramitsu.common.presentation.compose.uikit.tokens.ScreenStatus import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel -import jp.co.soramitsu.common.resourses.ClipboardManager import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.common.util.QrCodeGenerator @@ -86,7 +86,7 @@ class QRCodeFlowViewModel @AssistedInject constructor( private val coroutineManager: CoroutineManager, private val qrCodeGenerator: QrCodeGenerator, private val avatarGenerator: AccountAvatarGenerator, - private val clipboardManager: ClipboardManager, + private val clipboardManager: BasicClipboardManager, private val numbersFormatter: NumbersFormatter, private val resourceManager: ResourceManager, private val fileManager: FileManager, @@ -250,7 +250,7 @@ class QRCodeFlowViewModel @AssistedInject constructor( fun onUserAddressClickInReceiveScreen() { receiveTokenScreenState.untransformedUserAddress?.let { - clipboardManager.addToClipboard("Address", it) + clipboardManager.addToClipboard(it) } } @@ -336,7 +336,7 @@ class QRCodeFlowViewModel @AssistedInject constructor( fun onUserAddressClickInRequestConfirmScreen() { requestTokenByQrScreenState.untransformedUserAddress?.let { - clipboardManager.addToClipboard("Address", it) + clipboardManager.addToClipboard(it) } } diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountFragment.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountFragment.kt index 6eb1fca25..2fb3658ff 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountFragment.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountFragment.kt @@ -34,7 +34,6 @@ package jp.co.soramitsu.feature_assets_impl.presentation.screens.send import android.os.Bundle import android.view.View -import android.widget.Toast import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.ScrollState import androidx.compose.foundation.layout.Column @@ -189,9 +188,6 @@ class TransferAmountFragment : SoraBaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) (activity as BottomBarController).hideBottomBar() - viewModel.copiedAddressEvent.observe { - Toast.makeText(requireContext(), R.string.common_copied, Toast.LENGTH_SHORT).show() - } viewModel.transactionSuccessEvent.observe { activity?.let { ToastDialog( diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt index 728f76ad4..ee34c9935 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt @@ -41,6 +41,7 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import java.math.BigDecimal +import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.common.R import jp.co.soramitsu.common.account.AccountAvatarGenerator import jp.co.soramitsu.common.domain.Asset @@ -52,7 +53,6 @@ import jp.co.soramitsu.common.presentation.SingleLiveEvent import jp.co.soramitsu.common.presentation.compose.components.initSmallTitle2 import jp.co.soramitsu.common.presentation.trigger import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel -import jp.co.soramitsu.common.resourses.ClipboardManager import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.common.util.ext.isZero @@ -81,7 +81,7 @@ class TransferAmountViewModel @AssistedInject constructor( private val walletRouter: WalletRouter, private val assetsRouter: AssetsRouter, private val numbersFormatter: NumbersFormatter, - private val clipboardManager: ClipboardManager, + private val clipboardManager: BasicClipboardManager, private val resourceManager: ResourceManager, avatarGenerator: AccountAvatarGenerator, @Assisted("recipientId") private val recipientId: String, @@ -98,8 +98,6 @@ class TransferAmountViewModel @AssistedInject constructor( ): TransferAmountViewModel } - private val _copiedAddressEvent = SingleLiveEvent() - val copiedAddressEvent: LiveData = _copiedAddressEvent private val _transactionSuccessEvent = SingleLiveEvent() val transactionSuccessEvent: LiveData = _transactionSuccessEvent @@ -286,8 +284,8 @@ class TransferAmountViewModel @AssistedInject constructor( } fun copyAddress() { - clipboardManager.addToClipboard("Address", recipientId) - _copiedAddressEvent.trigger() + clipboardManager.addToClipboard(recipientId) + copiedToast.trigger() } fun onConfirmClick() { diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt index 1282b4e1b..684089c8c 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt @@ -43,12 +43,12 @@ import io.mockk.junit4.MockKRule import io.mockk.mockk import io.mockk.mockkStatic import io.mockk.verify +import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.common.account.AccountAvatarGenerator import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.common.domain.Asset import jp.co.soramitsu.common.domain.CoroutineManager import jp.co.soramitsu.common.io.FileManager -import jp.co.soramitsu.common.resourses.ClipboardManager import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.common.util.QrCodeGenerator @@ -109,7 +109,7 @@ class QrCodeFlowViewModelTest { private lateinit var avatarGenerator: AccountAvatarGenerator @MockK - private lateinit var clipboardManager: ClipboardManager + private lateinit var clipboardManager: BasicClipboardManager @MockK private lateinit var resourceManager: ResourceManager diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt index 6338abb78..9895723bd 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt @@ -42,11 +42,11 @@ import io.mockk.impl.annotations.MockK import io.mockk.junit4.MockKRule import io.mockk.mockk import io.mockk.mockkStatic +import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.common.R import jp.co.soramitsu.common.account.AccountAvatarGenerator import jp.co.soramitsu.common.domain.Token import jp.co.soramitsu.common.domain.iconUri -import jp.co.soramitsu.common.resourses.ClipboardManager import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.common.util.ext.equalTo @@ -104,7 +104,7 @@ class TransferAmountViewModelTest { private val mockedUri = mockk() @MockK - private lateinit var clipboardManager: ClipboardManager + private lateinit var clipboardManager: BasicClipboardManager private val recipientId = "recipientIdrecipientIdrecipientIdrecipientIdrecipientIdrecipientIdrecipientId" diff --git a/feature_blockexplorer_impl/build.gradle b/feature_blockexplorer_impl/build.gradle index 4abd9e4c5..4b9e6d4af 100644 --- a/feature_blockexplorer_impl/build.gradle +++ b/feature_blockexplorer_impl/build.gradle @@ -67,6 +67,7 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation project(":android-foundation") implementation project(":common") implementation project(":core_di") implementation project(":sorasubstrate") diff --git a/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsFragment.kt b/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsFragment.kt index 2bb147e5c..28657041e 100644 --- a/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsFragment.kt +++ b/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsFragment.kt @@ -34,7 +34,6 @@ package jp.co.soramitsu.feature_blockexplorer_impl.presentation.txdetails import android.os.Bundle import android.view.View -import android.widget.Toast import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.ScrollState import androidx.compose.foundation.layout.Column @@ -48,7 +47,6 @@ import androidx.navigation.NavHostController import com.google.accompanist.navigation.animation.composable import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject -import jp.co.soramitsu.common.R import jp.co.soramitsu.common.base.SoraBaseFragment import jp.co.soramitsu.common.base.theOnlyRoute import jp.co.soramitsu.common.domain.BottomBarController @@ -73,10 +71,6 @@ class TxDetailsFragment : SoraBaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) (activity as BottomBarController).hideBottomBar() - - viewModel.copyEvent.observe { - Toast.makeText(requireContext(), R.string.common_copied, Toast.LENGTH_SHORT).show() - } } @OptIn(ExperimentalAnimationApi::class) diff --git a/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModel.kt b/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModel.kt index 7259508fc..9cfb15233 100644 --- a/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModel.kt +++ b/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModel.kt @@ -35,22 +35,20 @@ package jp.co.soramitsu.feature_blockexplorer_impl.presentation.txdetails import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue -import androidx.lifecycle.LiveData import androidx.lifecycle.viewModelScope import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import java.math.BigDecimal import java.util.Date +import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.common.R import jp.co.soramitsu.common.date.DateTimeFormatter import jp.co.soramitsu.common.domain.AssetHolder import jp.co.soramitsu.common.domain.iconUri import jp.co.soramitsu.common.domain.printFiat -import jp.co.soramitsu.common.presentation.SingleLiveEvent import jp.co.soramitsu.common.presentation.trigger import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel -import jp.co.soramitsu.common.resourses.ClipboardManager import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor @@ -77,7 +75,7 @@ class TxDetailsViewModel @AssistedInject constructor( private val assetsInteractor: AssetsInteractor, private val walletInteractor: WalletInteractor, private val transactionHistoryHandler: TransactionHistoryHandler, - private val clipboardManager: ClipboardManager, + private val clipboardManager: BasicClipboardManager, private val resourceManager: ResourceManager, private val dateTimeFormatter: DateTimeFormatter, private val numbersFormatter: NumbersFormatter, @@ -89,9 +87,6 @@ class TxDetailsViewModel @AssistedInject constructor( fun create(txHash: String): TxDetailsViewModel } - private val _copyEvent = SingleLiveEvent() - val copyEvent: LiveData = _copyEvent - internal var txDetailsScreenState by mutableStateOf(emptyTxDetailsState) private set @@ -391,7 +386,7 @@ class TxDetailsViewModel @AssistedInject constructor( } fun onCopyClicked(text: String) { - clipboardManager.addToClipboard("copy item", text) - _copyEvent.trigger() + clipboardManager.addToClipboard(text) + copiedToast.trigger() } } diff --git a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModelTest.kt b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModelTest.kt index f5d7407fd..94b1a50e9 100644 --- a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModelTest.kt +++ b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModelTest.kt @@ -41,12 +41,12 @@ import io.mockk.junit4.MockKRule import io.mockk.mockk import io.mockk.mockkStatic import io.mockk.verify +import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.common.R import jp.co.soramitsu.common.date.DateTimeFormatter import jp.co.soramitsu.common.domain.Token import jp.co.soramitsu.common.domain.iconUri import jp.co.soramitsu.common.domain.printFiat -import jp.co.soramitsu.common.resourses.ClipboardManager import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor @@ -97,7 +97,7 @@ class TxDetailsViewModelTest { private lateinit var transactionHistoryHandler: TransactionHistoryHandler @MockK - private lateinit var clipboardManager: ClipboardManager + private lateinit var clipboardManager: BasicClipboardManager @MockK private lateinit var resourceManager: ResourceManager @@ -139,7 +139,7 @@ class TxDetailsViewModelTest { DateTimeFormatter.DD_MMM_YYYY_HH_MM ) } returns date - every { clipboardManager.addToClipboard("copy item", any()) } returns Unit + every { clipboardManager.addToClipboard(any()) } returns Unit viewModel = TxDetailsViewModel( assetsInteractor, @@ -574,6 +574,6 @@ class TxDetailsViewModelTest { val copyText = "text" viewModel.onCopyClicked(copyText) - verify { clipboardManager.addToClipboard("copy item", copyText) } + verify { clipboardManager.addToClipboard(copyText) } } } diff --git a/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/account_details/AccountDetailsFragment.kt b/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/account_details/AccountDetailsFragment.kt index 68be8e977..25a439108 100644 --- a/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/account_details/AccountDetailsFragment.kt +++ b/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/account_details/AccountDetailsFragment.kt @@ -35,7 +35,6 @@ package jp.co.soramitsu.feature_multiaccount_impl.presentation.export_account.ac import android.app.Activity import android.os.Bundle import android.view.View -import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.ScrollState @@ -97,10 +96,6 @@ class AccountDetailsFragment : SoraBaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - viewModel.copyEvent.observe { - Toast.makeText(requireActivity(), R.string.common_copied, Toast.LENGTH_SHORT).show() - } - viewModel.consentExceptionHandler.observe { consentHandlerLauncher.launch(it) } diff --git a/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/account_details/AccountDetailsViewModel.kt b/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/account_details/AccountDetailsViewModel.kt index c98eb0615..829bfdbeb 100644 --- a/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/account_details/AccountDetailsViewModel.kt +++ b/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/account_details/AccountDetailsViewModel.kt @@ -42,6 +42,7 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import java.net.SocketException +import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.backup.BackupService import jp.co.soramitsu.backup.domain.exceptions.AuthConsentException import jp.co.soramitsu.backup.domain.exceptions.FileNotFoundException @@ -58,7 +59,6 @@ import jp.co.soramitsu.common.presentation.SingleLiveEvent import jp.co.soramitsu.common.presentation.compose.components.initSmallTitle2 import jp.co.soramitsu.common.presentation.trigger import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel -import jp.co.soramitsu.common.resourses.ClipboardManager import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.ext.isPasswordSecure import jp.co.soramitsu.core.models.CryptoType @@ -78,7 +78,7 @@ class AccountDetailsViewModel @AssistedInject constructor( private val interactor: MultiaccountInteractor, private val router: MainRouter, private val resourceManager: ResourceManager, - private val clipboardManager: ClipboardManager, + private val clipboardManager: BasicClipboardManager, private val backupService: BackupService, private val coroutineManager: CoroutineManager, @Assisted("address") private val address: String, @@ -91,9 +91,6 @@ class AccountDetailsViewModel @AssistedInject constructor( ): AccountDetailsViewModel } - private val _copyEvent = SingleLiveEvent() - val copyEvent: LiveData = _copyEvent - private val _accountDetailsScreenState = MutableLiveData( AccountDetailsScreenState( InputTextState(value = TextFieldValue("")), @@ -195,8 +192,8 @@ class AccountDetailsViewModel @AssistedInject constructor( } fun onAddressCopy() { - clipboardManager.addToClipboard("address", address) - _copyEvent.trigger() + clipboardManager.addToClipboard(address) + copiedToast.trigger() } fun onBackupPasswordChanged(textFieldValue: TextFieldValue) { diff --git a/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/account_list/AccountListFragment.kt b/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/account_list/AccountListFragment.kt index b207e531e..79e31c67c 100644 --- a/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/account_list/AccountListFragment.kt +++ b/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/account_list/AccountListFragment.kt @@ -36,7 +36,6 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.Toast import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.ScrollState import androidx.compose.foundation.layout.Box @@ -74,10 +73,6 @@ class AccountListFragment : SoraBaseFragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View? { - viewModel.copiedAddressEvent.observe { - Toast.makeText(requireContext(), R.string.common_copied, Toast.LENGTH_SHORT).show() - } - viewModel.showOnboardingFlowEvent.observe { (requireActivity() as OnboardingNavigator).showOnboardingFlow() } diff --git a/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/account_list/AccountListViewModel.kt b/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/account_list/AccountListViewModel.kt index d36c5e71d..d90c844be 100644 --- a/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/account_list/AccountListViewModel.kt +++ b/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/account_list/AccountListViewModel.kt @@ -37,14 +37,13 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject +import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.common.R import jp.co.soramitsu.common.account.AccountAvatarGenerator import jp.co.soramitsu.common.presentation.SingleLiveEvent import jp.co.soramitsu.common.presentation.compose.components.initSmallTitle2 import jp.co.soramitsu.common.presentation.trigger import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel -import jp.co.soramitsu.common.resourses.ClipboardManager -import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_multiaccount_impl.domain.MultiaccountInteractor import jp.co.soramitsu.feature_multiaccount_impl.presentation.export_account.model.AccountListScreenState @@ -59,8 +58,7 @@ class AccountListViewModel @Inject constructor( private val interactor: MultiaccountInteractor, private val avatarGenerator: AccountAvatarGenerator, private val router: MainRouter, - private val clipboardManager: ClipboardManager, - private val resourceManager: ResourceManager + private val clipboardManager: BasicClipboardManager, ) : BaseViewModel() { private val _accountListScreenState = MutableLiveData() @@ -69,9 +67,6 @@ class AccountListViewModel @Inject constructor( private val _showOnboardingFlowEvent = SingleLiveEvent() val showOnboardingFlowEvent: LiveData = _showOnboardingFlowEvent - private val _copiedAddressEvent = SingleLiveEvent() - val copiedAddressEvent: LiveData = _copiedAddressEvent - private var toolbarActionModeEnabled = false init { @@ -116,8 +111,8 @@ class AccountListViewModel @Inject constructor( } fun onAccountLongClicked(address: String) { - clipboardManager.addToClipboard("address", address) - _copiedAddressEvent.trigger() + clipboardManager.addToClipboard(address) + copiedToast.trigger() } fun onAccountSelected(address: String) { diff --git a/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/backup/BackupFragment.kt b/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/backup/BackupFragment.kt index 5ff5956c1..cf4125b84 100644 --- a/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/backup/BackupFragment.kt +++ b/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/backup/BackupFragment.kt @@ -32,11 +32,6 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_multiaccount_impl.presentation.export_account.backup -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.Toast import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.ScrollState import androidx.compose.runtime.livedata.observeAsState @@ -46,7 +41,6 @@ import androidx.navigation.NavHostController import com.google.accompanist.navigation.animation.composable import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject -import jp.co.soramitsu.common.R import jp.co.soramitsu.common.base.SoraBaseFragment import jp.co.soramitsu.common.base.theOnlyRoute import jp.co.soramitsu.common.presentation.args.address @@ -84,15 +78,4 @@ class BackupFragment : SoraBaseFragment() { } } } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - viewModel.copyEvent.observe { - Toast.makeText(requireActivity(), R.string.common_copied, Toast.LENGTH_SHORT).show() - } - return super.onCreateView(inflater, container, savedInstanceState) - } } diff --git a/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/backup/BackupViewModel.kt b/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/backup/BackupViewModel.kt index 6e2db4252..009c6286d 100644 --- a/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/backup/BackupViewModel.kt +++ b/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/presentation/export_account/backup/BackupViewModel.kt @@ -38,11 +38,10 @@ import androidx.lifecycle.viewModelScope import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject -import jp.co.soramitsu.common.presentation.SingleLiveEvent +import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.common.presentation.compose.components.initMediumTitle2 import jp.co.soramitsu.common.presentation.trigger import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel -import jp.co.soramitsu.common.resourses.ClipboardManager import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.ext.addHexPrefix import jp.co.soramitsu.feature_main_api.launcher.MainRouter @@ -56,7 +55,7 @@ class BackupViewModel @AssistedInject constructor( private val multiAccountInteractor: MultiaccountInteractor, private val resourceManager: ResourceManager, private val mainRouter: MainRouter, - private val clipboardManager: ClipboardManager, + private val clipboardManager: BasicClipboardManager, @Assisted("type") private val type: ExportProtectionViewModel.Type, @Assisted("address") private val address: String ) : BaseViewModel() { @@ -72,9 +71,6 @@ class BackupViewModel @AssistedInject constructor( private val _backupScreenState = MutableLiveData() val backupScreenState: LiveData = _backupScreenState - private val _copyEvent = SingleLiveEvent() - val copyEvent: LiveData = _copyEvent - init { _toolbarState.value = initMediumTitle2("") viewModelScope.launch { @@ -100,11 +96,11 @@ class BackupViewModel @AssistedInject constructor( fun backupPressed() { _backupScreenState.value?.let { if (it.seedString.isNotEmpty()) { - clipboardManager.addToClipboard("Seed", it.seedString) + clipboardManager.addToClipboard(it.seedString) } else { - clipboardManager.addToClipboard("Mnemonic", it.mnemonicWords.joinToString(" ")) + clipboardManager.addToClipboard(it.mnemonicWords.joinToString(" ")) } - _copyEvent.trigger() + copiedToast.trigger() } } diff --git a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/account_details/AccountDetailsViewModelTest.kt b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/account_details/AccountDetailsViewModelTest.kt index df526ac38..fcfbda0d3 100644 --- a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/account_details/AccountDetailsViewModelTest.kt +++ b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/account_details/AccountDetailsViewModelTest.kt @@ -37,6 +37,7 @@ import androidx.activity.result.ActivityResultLauncher import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.compose.ui.text.input.TextFieldValue import androidx.navigation.NavController +import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.backup.BackupService import jp.co.soramitsu.backup.domain.models.BackupAccountType import jp.co.soramitsu.backup.domain.models.DecryptedBackupAccount @@ -45,7 +46,6 @@ import jp.co.soramitsu.backup.domain.models.Seed import jp.co.soramitsu.common.R import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.common.domain.CoroutineManager -import jp.co.soramitsu.common.resourses.ClipboardManager import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.core.models.CryptoType import jp.co.soramitsu.feature_main_api.launcher.MainRouter @@ -93,7 +93,7 @@ class AccountDetailsViewModelTest { private lateinit var mainRouter: MainRouter @Mock - private lateinit var copy: ClipboardManager + private lateinit var copy: BasicClipboardManager @Mock private lateinit var resourceManager: ResourceManager diff --git a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/account_list/AccountListViewModelTest.kt b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/account_list/AccountListViewModelTest.kt index 252824990..df724bfbd 100644 --- a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/account_list/AccountListViewModelTest.kt +++ b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/account_list/AccountListViewModelTest.kt @@ -34,11 +34,10 @@ package jp.co.soramitsu.feature_multiaccount_impl.export.account_list import android.graphics.drawable.PictureDrawable import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.common.R import jp.co.soramitsu.common.account.AccountAvatarGenerator import jp.co.soramitsu.common.account.SoraAccount -import jp.co.soramitsu.common.resourses.ClipboardManager -import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_multiaccount_impl.domain.MultiaccountInteractor import jp.co.soramitsu.feature_multiaccount_impl.presentation.export_account.account_list.AccountListViewModel @@ -90,10 +89,7 @@ class AccountListViewModelTest { private lateinit var drawable: PictureDrawable @Mock - private lateinit var clipboardManager: ClipboardManager - - @Mock - private lateinit var resourceManager: ResourceManager + private lateinit var clipboardManager: BasicClipboardManager private lateinit var accountListViewModel: AccountListViewModel @@ -131,7 +127,6 @@ class AccountListViewModelTest { avatarGenerator, mainRouter, clipboardManager, - resourceManager ) } @@ -174,8 +169,7 @@ class AccountListViewModelTest { accountListViewModel.onAccountLongClicked(address) - verify(clipboardManager).addToClipboard("address", address) - assertEquals(accountListViewModel.copiedAddressEvent.value, Unit) + verify(clipboardManager).addToClipboard(address) } @Test diff --git a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/backup/BackupViewModelTest.kt b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/backup/BackupViewModelTest.kt index 6e04d8d40..6b2364e0c 100644 --- a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/backup/BackupViewModelTest.kt +++ b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/export/backup/BackupViewModelTest.kt @@ -33,12 +33,10 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_multiaccount_impl.export.backup import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import jp.co.soramitsu.common.resourses.ClipboardManager +import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.ext.addHexPrefix -import jp.co.soramitsu.common.R as commonR import jp.co.soramitsu.feature_main_api.launcher.MainRouter -import jp.co.soramitsu.feature_multiaccount_impl.R import jp.co.soramitsu.feature_multiaccount_impl.domain.MultiaccountInteractor import jp.co.soramitsu.feature_multiaccount_impl.presentation.export_account.backup.BackupViewModel import jp.co.soramitsu.feature_multiaccount_impl.presentation.export_account.model.BackupScreenState @@ -58,6 +56,7 @@ import org.mockito.BDDMockito.given import org.mockito.Mock import org.mockito.junit.MockitoJUnitRunner import org.mockito.kotlin.verify +import jp.co.soramitsu.common.R as commonR @ExperimentalCoroutinesApi @RunWith(MockitoJUnitRunner::class) @@ -80,7 +79,7 @@ class BackupViewModelTest { private lateinit var interactor: MultiaccountInteractor @Mock - private lateinit var clipboardManager: ClipboardManager + private lateinit var clipboardManager: BasicClipboardManager private lateinit var viewModel: BackupViewModel @@ -135,15 +134,15 @@ class BackupViewModelTest { fun backupPressedWithSeed() { setUp(ExportProtectionViewModel.Type.SEED) viewModel.backupPressed() - verify(clipboardManager).addToClipboard("Seed", seed.addHexPrefix()) - viewModel.copyEvent.getOrAwaitValue() + verify(clipboardManager).addToClipboard(seed.addHexPrefix()) + viewModel.copiedToast.getOrAwaitValue() } @Test fun backupPressedWithPassphrase() { setUp(ExportProtectionViewModel.Type.PASSPHRASE) viewModel.backupPressed() - verify(clipboardManager).addToClipboard("Mnemonic", mnemo) - viewModel.copyEvent.getOrAwaitValue() + verify(clipboardManager).addToClipboard(mnemo) + viewModel.copiedToast.getOrAwaitValue() } } diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/data/repository/PolkaswapSubscriptionRepositoryImpl.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/data/repository/PolkaswapSubscriptionRepositoryImpl.kt index db77b5232..1c3dff0b1 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/data/repository/PolkaswapSubscriptionRepositoryImpl.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/data/repository/PolkaswapSubscriptionRepositoryImpl.kt @@ -38,6 +38,7 @@ import java.math.BigInteger import javax.inject.Inject import jp.co.soramitsu.common.domain.Market import jp.co.soramitsu.common.domain.Token +import jp.co.soramitsu.common.logger.FirebaseWrapper import jp.co.soramitsu.common.util.ext.safeCast import jp.co.soramitsu.common.util.mapBalance import jp.co.soramitsu.common_wallet.domain.model.LiquidityData @@ -53,18 +54,28 @@ import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapQuote import jp.co.soramitsu.feature_polkaswap_impl.data.mappers.SwapMarketMapper import jp.co.soramitsu.shared_utils.extensions.fromHex import jp.co.soramitsu.shared_utils.extensions.toHexString +import jp.co.soramitsu.shared_utils.runtime.definitions.types.composite.Struct import jp.co.soramitsu.shared_utils.runtime.definitions.types.fromHex import jp.co.soramitsu.shared_utils.runtime.metadata.module import jp.co.soramitsu.shared_utils.runtime.metadata.storage import jp.co.soramitsu.shared_utils.runtime.metadata.storageKey import jp.co.soramitsu.shared_utils.ss58.SS58Encoder.toAccountId +import jp.co.soramitsu.shared_utils.wsrpc.SocketService +import jp.co.soramitsu.shared_utils.wsrpc.executeAsync +import jp.co.soramitsu.shared_utils.wsrpc.mappers.nonNull +import jp.co.soramitsu.shared_utils.wsrpc.mappers.pojo +import jp.co.soramitsu.shared_utils.wsrpc.mappers.pojoList +import jp.co.soramitsu.shared_utils.wsrpc.request.runtime.storage.GetStorageRequest +import jp.co.soramitsu.sora.substrate.request.StateKeys import jp.co.soramitsu.sora.substrate.runtime.Pallete import jp.co.soramitsu.sora.substrate.runtime.RuntimeManager import jp.co.soramitsu.sora.substrate.runtime.Storage import jp.co.soramitsu.sora.substrate.runtime.assetIdFromKey +import jp.co.soramitsu.sora.substrate.runtime.mapToToken import jp.co.soramitsu.sora.substrate.runtime.poolTBCReserves import jp.co.soramitsu.sora.substrate.runtime.reservesKey import jp.co.soramitsu.sora.substrate.runtime.reservesKeyToken +import jp.co.soramitsu.sora.substrate.runtime.takeInt32 import jp.co.soramitsu.sora.substrate.substrate.SubstrateApi import jp.co.soramitsu.sora.substrate.substrate.SubstrateCalls import kotlinx.coroutines.flow.Flow @@ -82,13 +93,46 @@ class PolkaswapSubscriptionRepositoryImpl @Inject constructor( private val substrateCalls: SubstrateCalls, private val blockExplorerManager: BlockExplorerManager, private val runtimeManager: RuntimeManager, + private val socketService: SocketService, ) : PolkaswapSubscriptionRepository, PolkaswapBasicRepositoryImpl(db, blockExplorerManager) { + private suspend fun getPoolBaseTokens(): List> { + val metadataStorage = + runtimeManager.getRuntimeSnapshot().metadata + .module(Pallete.DEX_MANAGER.palletName) + .storage(Storage.DEX_INFOS.storageName) + val partialKey = metadataStorage.storageKey() + return runCatching { + socketService.executeAsync( + request = StateKeys(listOf(partialKey)), + mapper = pojoList().nonNull() + ).let { storageKeys -> + storageKeys.mapNotNull { storageKey -> + socketService.executeAsync( + request = GetStorageRequest(listOf(storageKey)), + mapper = pojo().nonNull(), + ) + .let { storage -> + val storageType = metadataStorage.type.value!! + val storageRawData = + storageType.fromHex(runtimeManager.getRuntimeSnapshot(), storage) + (storageRawData as? Struct.Instance)?.let { instance -> + instance.mapToToken("baseAssetId")?.let { token -> + storageKey.takeInt32() to token + } + } + } + } + } + } + .onFailure(FirebaseWrapper::recordException) + .getOrThrow() + } + override suspend fun updateAccountPools(address: String) { blockExplorerManager.updatePoolsSbApy() - // pool base tokens - val baseTokens = wsConnection.getPoolBaseTokens() + val baseTokens = getPoolBaseTokens() db.withTransaction { db.poolDao().clearPoolBaseTokens() db.poolDao().insertPoolBaseTokens( diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt index 166cff79e..ad94c1cbe 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt @@ -54,6 +54,7 @@ import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.SwapInteractor import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapDetails import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapFeeMode import jp.co.soramitsu.sora.substrate.runtime.SubstrateOptionsProvider +import jp.co.soramitsu.sora.substrate.runtime.isSynthetic import kotlin.math.max import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow @@ -82,7 +83,6 @@ class SwapInteractorImpl( private var poolReservesFlowToken = MutableStateFlow?>(null) private val availableMarkets = mutableMapOf>() private var swapNetworkFee: BigDecimal? = null - private val syntheticRegex = SubstrateOptionsProvider.syntheticTokenRegex.toRegex() override suspend fun fetchSwapNetworkFee(feeToken: Token): BigDecimal { return swapNetworkFee ?: ( @@ -159,13 +159,15 @@ class SwapInteractorImpl( } private fun getFeeMode(ids: List?): SwapFeeMode { - if (ids == null) return SwapFeeMode.NON_SYNTHETIC - if (ids.all { it.matches(syntheticRegex).not() }) return SwapFeeMode.NON_SYNTHETIC - if (ids.all { - it.matches(syntheticRegex) || it == SubstrateOptionsProvider.xstTokenId || it == SubstrateOptionsProvider.xstusdTokenId - } - ) return SwapFeeMode.SYNTHETIC - return SwapFeeMode.BOTH + fun String.isExtraSynthetic() = this.isSynthetic() || this == SubstrateOptionsProvider.xstusdTokenId + return when { + ids == null -> SwapFeeMode.NON_SYNTHETIC + ids.all { + it.isExtraSynthetic() || it == SubstrateOptionsProvider.xstTokenId + } -> SwapFeeMode.SYNTHETIC + ids.all { it.isExtraSynthetic().not() } -> SwapFeeMode.NON_SYNTHETIC + else -> SwapFeeMode.BOTH + } } override fun setSwapMarket(market: Market) { diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/PoolDetailsScreen.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/PoolDetailsScreen.kt index ceb93865c..dc04240bb 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/PoolDetailsScreen.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/PoolDetailsScreen.kt @@ -222,7 +222,6 @@ internal fun PoolDetailsScreen( text = stringResource( id = R.string.polkaswap_farming_unstake_to_remove, ), - maxLines = 1, ) } } diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt index 3823f855c..a0a55798e 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt @@ -72,6 +72,7 @@ import jp.co.soramitsu.feature_polkaswap_impl.presentation.states.LiquidityAddSt import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletInteractor import jp.co.soramitsu.feature_wallet_api.launcher.WalletRouter import jp.co.soramitsu.sora.substrate.runtime.SubstrateOptionsProvider +import jp.co.soramitsu.sora.substrate.runtime.isSynthetic import jp.co.soramitsu.ui_core.component.toolbar.Action import jp.co.soramitsu.ui_core.component.toolbar.BasicToolbarState import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarState @@ -154,8 +155,6 @@ class LiquidityAddViewModel @AssistedInject constructor( private var pairEnabled: Boolean = true private var pairPresented: Boolean = true - private val syntheticRegex = SubstrateOptionsProvider.syntheticTokenRegex.toRegex() - var addState by mutableStateOf( LiquidityAddState( btnState = ButtonState( @@ -524,7 +523,7 @@ class LiquidityAddViewModel @AssistedInject constructor( val curBase = bases.find { it.tokenId == addToken1 } val list = assets .filter { asset -> - asset.token.id.matches(syntheticRegex).not() + asset.token.id.isSynthetic().not() } .filter { asset -> if (addToken1 == SubstrateOptionsProvider.xstusdTokenId) { diff --git a/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/details/SoraCardDetailsFragment.kt b/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/details/SoraCardDetailsFragment.kt index 17f1a9cbc..a6b68165c 100644 --- a/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/details/SoraCardDetailsFragment.kt +++ b/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/details/SoraCardDetailsFragment.kt @@ -34,7 +34,6 @@ package jp.co.soramitsu.feature_sora_card_impl.presentation.get.card.details import android.os.Bundle import android.view.View -import android.widget.Toast import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.ScrollState import androidx.compose.foundation.layout.Arrangement @@ -70,9 +69,6 @@ class SoraCardDetailsFragment : SoraBaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { (activity as BottomBarController).hideBottomBar() super.onViewCreated(view, savedInstanceState) - viewModel.copiedAddressEvent.observe { - Toast.makeText(requireContext(), R.string.common_copied, Toast.LENGTH_SHORT).show() - } viewModel.shareLinkEvent.observe { share -> context?.let { c -> shareText(c, getString(R.string.common_share), share) diff --git a/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/details/SoraCardDetailsViewModel.kt b/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/details/SoraCardDetailsViewModel.kt index 59cd3cc59..27dfc1cf8 100644 --- a/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/details/SoraCardDetailsViewModel.kt +++ b/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/details/SoraCardDetailsViewModel.kt @@ -36,11 +36,11 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject +import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.common.R import jp.co.soramitsu.common.presentation.SingleLiveEvent import jp.co.soramitsu.common.presentation.trigger import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel -import jp.co.soramitsu.common.resourses.ClipboardManager import jp.co.soramitsu.feature_sora_card_api.domain.SoraCardInteractor import jp.co.soramitsu.ui_core.component.toolbar.BasicToolbarState import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarState @@ -52,12 +52,9 @@ import kotlinx.coroutines.launch @HiltViewModel class SoraCardDetailsViewModel @Inject constructor( private val soraCardInteractor: SoraCardInteractor, - private val clipboardManager: ClipboardManager, + private val clipboardManager: BasicClipboardManager, ) : BaseViewModel() { - private val _copiedAddressEvent = SingleLiveEvent() - val copiedAddressEvent: LiveData = _copiedAddressEvent - private val _shareLinkEvent = SingleLiveEvent() val shareLinkEvent: LiveData = _shareLinkEvent @@ -135,8 +132,8 @@ class SoraCardDetailsViewModel @Inject constructor( fun onIbanCardClick() { ibanCache?.let { - clipboardManager.addToClipboard("iban", it) - _copiedAddressEvent.trigger() + clipboardManager.addToClipboard(it) + copiedToast.trigger() } } diff --git a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/runtime/SubstrateOptionsProvider.kt b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/runtime/SubstrateOptionsProvider.kt index 382eeacf0..651efb3d4 100644 --- a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/runtime/SubstrateOptionsProvider.kt +++ b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/runtime/SubstrateOptionsProvider.kt @@ -37,16 +37,20 @@ import jp.co.soramitsu.common.data.network.dto.TokenInfoDto import jp.co.soramitsu.common.util.ext.addHexPrefix import jp.co.soramitsu.shared_utils.encrypt.EncryptionType import jp.co.soramitsu.shared_utils.extensions.fromHex +import jp.co.soramitsu.shared_utils.extensions.toHexString import jp.co.soramitsu.shared_utils.runtime.RuntimeSnapshot import jp.co.soramitsu.shared_utils.runtime.definitions.types.composite.Struct import jp.co.soramitsu.shared_utils.runtime.metadata.module import jp.co.soramitsu.shared_utils.runtime.metadata.storage import jp.co.soramitsu.shared_utils.runtime.metadata.storageKey +import jp.co.soramitsu.shared_utils.scale.dataType.uint32 import jp.co.soramitsu.shared_utils.ss58.SS58Encoder.toAccountId +import jp.co.soramitsu.sora.substrate.runtime.SubstrateOptionsProvider.syntheticTokenRegex +import jp.co.soramitsu.sora.substrate.substrate.fromHex object SubstrateOptionsProvider { const val mortalEraLength = 64 - const val syntheticTokenRegex = "0[xX]03[0-9a-fA-F]+" + val syntheticTokenRegex = "0[xX]03[0-9a-fA-F]+".toRegex() val encryptionType = EncryptionType.SR25519 val existentialDeposit: BigInteger = BigInteger.ZERO const val feeAssetId = "0x0200000000000000000000000000000000000000000000000000000000000000" @@ -56,10 +60,29 @@ object SubstrateOptionsProvider { const val ethTokenId = "0x0200070000000000000000000000000000000000000000000000000000000000" } +fun String.isSynthetic(): Boolean = this.matches(syntheticTokenRegex) + +fun Struct.Instance.getTokenId() = get>("code") + ?.map { (it as BigInteger).toByte() } + ?.toByteArray() + +fun Struct.Instance.mapToToken(field: String) = + this.get(field)?.getTokenId()?.toHexString(true) + +fun String.mapCodeToken() = Struct.Instance( + mapOf("code" to this.mapAssetId()) +) + +fun ByteArray.mapCodeToken() = Struct.Instance( + mapOf("code" to this.mapAssetId()) +) + fun String.mapAssetId() = this.fromHex().mapAssetId() fun ByteArray.mapAssetId() = this.toList().map { it.toInt().toBigInteger() } fun String.assetIdFromKey() = this.takeLast(64).addHexPrefix() + +fun String.takeInt32() = uint32.fromHex(this.takeLast(8)).toInt() fun Any.createAsset(id: String): TokenInfoDto? = (this as? List<*>)?.let { val s = (it[0] as? ByteArray)?.toString(Charsets.UTF_8) @@ -80,11 +103,7 @@ fun RuntimeSnapshot.poolTBCReserves(tokenId: ByteArray): String = .storage(Storage.RESERVES_COLLATERAL.storageName) .storageKey( this, - Struct.Instance( - mapOf( - "code" to tokenId.mapAssetId() - ) - ) + tokenId.mapCodeToken(), ) fun RuntimeSnapshot.reservesKey(baseTokenId: String, tokenId: ByteArray): String = @@ -92,16 +111,8 @@ fun RuntimeSnapshot.reservesKey(baseTokenId: String, tokenId: ByteArray): String .storage(Storage.RESERVES.storageName) .storageKey( this, - Struct.Instance( - mapOf( - "code" to baseTokenId.mapAssetId() - ) - ), - Struct.Instance( - mapOf( - "code" to tokenId.mapAssetId() - ) - ) + baseTokenId.mapCodeToken(), + tokenId.mapCodeToken(), ) fun RuntimeSnapshot.reservesKeyToken(baseTokenId: String): String = @@ -109,11 +120,7 @@ fun RuntimeSnapshot.reservesKeyToken(baseTokenId: String): String = .storage(Storage.RESERVES.storageName) .storageKey( this, - Struct.Instance( - mapOf( - "code" to baseTokenId.mapAssetId() - ) - ), + baseTokenId.mapCodeToken(), ) enum class Pallete(val palletName: String) { diff --git a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/Extrinsics.kt b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/Extrinsics.kt index ca087c0bd..41ef1fc68 100644 --- a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/Extrinsics.kt +++ b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/Extrinsics.kt @@ -40,7 +40,7 @@ import jp.co.soramitsu.shared_utils.runtime.extrinsic.ExtrinsicBuilder import jp.co.soramitsu.shared_utils.ss58.SS58Encoder.toAccountId import jp.co.soramitsu.sora.substrate.runtime.Method import jp.co.soramitsu.sora.substrate.runtime.Pallete -import jp.co.soramitsu.sora.substrate.runtime.mapAssetId +import jp.co.soramitsu.sora.substrate.runtime.mapCodeToken fun ExtrinsicBuilder.setReferrer(referrer: String) = this.call( @@ -66,12 +66,8 @@ fun ExtrinsicBuilder.swap( Method.SWAP.methodName, mapOf( "dex_id" to dexId.toBigInteger(), - "input_asset_id" to Struct.Instance( - mapOf("code" to inputAssetId.mapAssetId()) - ), - "output_asset_id" to Struct.Instance( - mapOf("code" to outputAssetId.mapAssetId()) - ), + "input_asset_id" to inputAssetId.mapCodeToken(), + "output_asset_id" to outputAssetId.mapCodeToken(), "swap_amount" to DictEnum.Entry( name = desired.backString, value = Struct.Instance( @@ -120,9 +116,7 @@ fun ExtrinsicBuilder.transfer( Pallete.ASSETS.palletName, Method.TRANSFER.methodName, mapOf( - "asset_id" to Struct.Instance( - mapOf("code" to assetId.mapAssetId()) - ), + "asset_id" to assetId.mapCodeToken(), "to" to to.toAccountId(), "amount" to amount ) @@ -156,12 +150,8 @@ fun ExtrinsicBuilder.removeLiquidity( Method.WITHDRAW_LIQUIDITY.methodName, mapOf( "dex_id" to dexId.toBigInteger(), - "output_asset_a" to Struct.Instance( - mapOf("code" to outputAssetIdA.mapAssetId()) - ), - "output_asset_b" to Struct.Instance( - mapOf("code" to outputAssetIdB.mapAssetId()) - ), + "output_asset_a" to outputAssetIdA.mapCodeToken(), + "output_asset_b" to outputAssetIdB.mapCodeToken(), "marker_asset_desired" to markerAssetDesired, "output_a_min" to outputAMin, "output_b_min" to outputBMin @@ -177,12 +167,8 @@ fun ExtrinsicBuilder.register( Method.REGISTER.methodName, mapOf( "dex_id" to dexId.toBigInteger(), - "base_asset_id" to Struct.Instance( - mapOf("code" to baseAssetId.mapAssetId()) - ), - "target_asset_id" to Struct.Instance( - mapOf("code" to targetAssetId.mapAssetId()) - ) + "base_asset_id" to baseAssetId.mapCodeToken(), + "target_asset_id" to targetAssetId.mapCodeToken(), ) ) @@ -195,12 +181,8 @@ fun ExtrinsicBuilder.initializePool( Method.INITIALIZE_POOL.methodName, mapOf( "dex_id" to dexId.toBigInteger(), - "asset_a" to Struct.Instance( - mapOf("code" to baseAssetId.mapAssetId()) - ), - "asset_b" to Struct.Instance( - mapOf("code" to targetAssetId.mapAssetId()) - ) + "asset_a" to baseAssetId.mapCodeToken(), + "asset_b" to targetAssetId.mapCodeToken(), ) ) @@ -217,12 +199,8 @@ fun ExtrinsicBuilder.depositLiquidity( Method.DEPOSIT_LIQUIDITY.methodName, mapOf( "dex_id" to dexId.toBigInteger(), - "input_asset_a" to Struct.Instance( - mapOf("code" to baseAssetId.mapAssetId()) - ), - "input_asset_b" to Struct.Instance( - mapOf("code" to targetAssetId.mapAssetId()) - ), + "input_asset_a" to baseAssetId.mapCodeToken(), + "input_asset_b" to targetAssetId.mapCodeToken(), "input_a_desired" to baseAssetAmount, "input_b_desired" to targetAssetAmount, "input_a_min" to amountFromMin, @@ -239,9 +217,7 @@ fun ExtrinsicBuilder.faucetTransfer( Pallete.FAUCET.palletName, Method.TRANSFER.methodName, mapOf( - "asset_id" to Struct.Instance( - mapOf("code" to assetId.mapAssetId()) - ), + "asset_id" to assetId.mapCodeToken(), "target" to target.toAccountId(), "amount" to amount ) diff --git a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateApi.kt b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateApi.kt index da31e5963..6f92b2fe3 100644 --- a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateApi.kt +++ b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateApi.kt @@ -78,8 +78,6 @@ interface SubstrateApi { address: String ): List>> - suspend fun getPoolBaseTokens(): List> - suspend fun isPairEnabled( inputAssetId: String, outputAssetId: String, diff --git a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateApiImpl.kt b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateApiImpl.kt index 82d7e4202..283b13ed1 100644 --- a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateApiImpl.kt +++ b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateApiImpl.kt @@ -60,7 +60,8 @@ import jp.co.soramitsu.sora.substrate.runtime.RuntimeManager import jp.co.soramitsu.sora.substrate.runtime.Storage import jp.co.soramitsu.sora.substrate.runtime.accountPoolsKey import jp.co.soramitsu.sora.substrate.runtime.assetIdFromKey -import jp.co.soramitsu.sora.substrate.runtime.mapAssetId +import jp.co.soramitsu.sora.substrate.runtime.getTokenId +import jp.co.soramitsu.sora.substrate.runtime.mapCodeToken import jp.co.soramitsu.sora.substrate.runtime.reservesKey // todo refactor it after migrate to substrate 4 @@ -69,54 +70,6 @@ class SubstrateApiImpl @Inject constructor( private val runtimeManager: RuntimeManager, ) : SubstrateApi { - override suspend fun getPoolBaseTokens(): List> { - val metadataStorage = - runtimeManager.getRuntimeSnapshot().metadata - .module(Pallete.DEX_MANAGER.palletName) - .storage(Storage.DEX_INFOS.storageName) - val partialKey = metadataStorage.storageKey() - val dexIdsList = socketService.executeAsync( - request = RuntimeRequest( - "dexManager_listDEXIds", - emptyList(), - ), - mapper = pojoList().nonNull() - ) - return runCatching { - socketService.executeAsync( - request = StateKeys(listOf(partialKey)), - mapper = pojoList().nonNull() - ).let { storageKeys -> - storageKeys.mapIndexedNotNull { storageIndex, storageKey -> - socketService.executeAsync( - request = GetStorageRequest(listOf(storageKey)), - mapper = pojo().nonNull(), - ) - .let { storage -> - val storageType = metadataStorage.type.value!! - val storageRawData = - storageType.fromHex(runtimeManager.getRuntimeSnapshot(), storage) - (storageRawData as? Struct.Instance)?.let { instance -> - instance.get("baseAssetId")?.let { id -> - id.get>("code")?.let { code -> - code.map { - (it as BigInteger).toByte() - } - }?.toByteArray()?.toHexString(true) - }?.let { token -> - dexIdsList.getOrNull(storageIndex)?.let { index -> - index to token - } - } - } - } - } - } - } - .onFailure(FirebaseWrapper::recordException) - .getOrThrow() - } - override suspend fun getUserPoolsTokenIdsKeys(address: String): List { val accountPoolsKey = runtimeManager.getRuntimeSnapshot().accountPoolsKey(address) return runCatching { @@ -148,11 +101,7 @@ class SubstrateApiImpl @Inject constructor( val tokens: List = if (storageRawData is List<*>) { storageRawData.filterIsInstance() .mapNotNull { struct -> - struct.get>("code")?.let { code -> - code.map { - (it as BigInteger).toByte() - } - }?.toByteArray() + struct.getTokenId() } } else { emptyList() @@ -224,16 +173,8 @@ class SubstrateApiImpl @Inject constructor( runtimeManager.getRuntimeSnapshot().metadata.module(Pallete.POOL_XYK.palletName) .storage(Storage.PROPERTIES.storageName).storageKey( runtimeManager.getRuntimeSnapshot(), - Struct.Instance( - mapOf( - "code" to baseTokenId.mapAssetId() - ) - ), - Struct.Instance( - mapOf( - "code" to tokenId.mapAssetId() - ) - ), + baseTokenId.mapCodeToken(), + tokenId.mapCodeToken(), ) return socketService.executeAsync( request = GetStorageRequest(listOf(storageKey)), diff --git a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateCalls.kt b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateCalls.kt index a5418d43f..bc1ee79a6 100644 --- a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateCalls.kt +++ b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateCalls.kt @@ -91,7 +91,7 @@ import jp.co.soramitsu.sora.substrate.runtime.RuntimeManager import jp.co.soramitsu.sora.substrate.runtime.Storage import jp.co.soramitsu.sora.substrate.runtime.assetIdFromKey import jp.co.soramitsu.sora.substrate.runtime.createAsset -import jp.co.soramitsu.sora.substrate.runtime.mapAssetId +import jp.co.soramitsu.sora.substrate.runtime.mapCodeToken import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emitAll import kotlinx.coroutines.flow.firstOrNull @@ -300,9 +300,7 @@ class SubstrateCalls @Inject constructor( storage.storageKey( runtimeManager.getRuntimeSnapshot(), accountId.toAccountId(), - Struct.Instance( - mapOf("code" to assetId.mapAssetId()) - ) + assetId.mapCodeToken(), ) } val request = StateQueryStorageAt(listOf(storageKeys)) From f72adace5c9259c5817409cabb776fdb66297247 Mon Sep 17 00:00:00 2001 From: arvifox Date: Tue, 5 Sep 2023 12:47:59 +0300 Subject: [PATCH 11/20] refactoring assets --- .../soramitsu/sora/di/app/modules/NavigationModule.kt | 2 +- .../java/jp/co/soramitsu/sora/navigation/Navigator.kt | 10 ++++++++-- .../data/{interfaces => }/AssetsRepository.kt | 2 +- .../domain/{interfaces => }/AssetsInteractor.kt | 2 +- .../domain/{interfaces => }/QrCodeInteractor.kt | 2 +- .../presentation/{launcher => }/AssetsRouter.kt | 2 +- .../feature_assets_impl/data/AssetsRepositoryImpl.kt | 2 +- .../feature_assets_impl/di/AssetsFeatureModule.kt | 6 +++--- .../feature_assets_impl/domain/AssetsInteractorImpl.kt | 4 ++-- .../feature_assets_impl/domain/QrCodeInteractorImpl.kt | 4 ++-- .../screens/assetdetails/AssetDetailsViewModel.kt | 4 ++-- .../screens/fullassetlist/FullAssetListViewModel.kt | 4 ++-- .../fullassetsettings/FullAssetSettingsViewModel.kt | 4 ++-- .../screens/receiverequest/QRCodeFlowViewModel.kt | 4 ++-- .../screens/send/TransferAmountViewModel.kt | 4 ++-- .../presentation/screens/txlist/TxListViewModel.kt | 4 ++-- .../feature_assets_impl/data/AssetsRepositoryTest.kt | 2 +- .../feature_assets_impl/domain/AssetsInteractorTest.kt | 4 ++-- .../feature_assets_impl/domain/QrCodeInteractorTest.kt | 8 ++------ .../assetsettings/AssetSettingsViewModelTest.kt | 4 ++-- .../presentation/qr/QrCodeFlowViewModelTest.kt | 4 ++-- .../presentation/send/TransferAmountViewModelTest.kt | 4 ++-- .../presentation/txlist/AssetSettingsViewModelTest.kt | 4 ++-- .../domain/TransactionHistoryHandlerImpl.kt | 2 +- .../presentation/screen/ActivitiesViewModel.kt | 4 ++-- .../presentation/txdetails/TxDetailsViewModel.kt | 2 +- .../domain/TransactionHistoryHandlerTest.kt | 2 +- .../presentation/screen/ActivitiesViewModelTest.kt | 5 ++--- .../presentation/txdetails/TxDetailsViewModelTest.kt | 2 +- .../feature_ecosystem_impl/di/EcoSystemModule.kt | 2 +- .../domain/EcoSystemTokensInteractor.kt | 2 +- .../presentation/explore/ExploreViewModel.kt | 2 +- .../explore/ExploreViewModelTest.kt | 2 +- .../domain/subs/BalanceFeatureStorageManager.kt | 2 +- .../feature_main_impl/presentation/MainViewModel.kt | 2 +- .../presentation/profile/ProfileViewModel.kt | 2 +- .../presentation/MainViewModelTest.kt | 2 +- .../presentation/profile/ProfileViewModelTest.kt | 2 +- .../domain/MultiaccountInteractor.kt | 2 +- .../domain/MultiaccountInteractorTest.kt | 2 +- .../di/PolkaswapFeatureModule.kt | 2 +- .../domain/PoolsInteractorImpl.kt | 2 +- .../domain/SwapInteractorImpl.kt | 2 +- .../screens/liquidityadd/LiquidityAddViewModel.kt | 4 ++-- .../liquidityremove/LiquidityRemoveViewModel.kt | 4 ++-- .../presentation/screens/swap/SwapViewModel.kt | 5 ++--- .../domain/PoolsInteractorTest.kt | 2 +- .../domain/SwapInteractorTest.kt | 2 +- .../presentation/polkaswap/SwapViewModelTest.kt | 4 ++-- .../liquidity/add/AddLiquidityViewModelTest.kt | 5 ++--- .../liquidity/remove/RemoveLiquidityViewModelTest.kt | 6 ++---- .../feature_referral_impl/domain/ReferralInteractor.kt | 2 +- .../presentation/ReferralViewModel.kt | 4 ++-- .../domain/ReferralInteractorTest.kt | 2 +- .../presentation/ReferralViewModelTest.kt | 4 ++-- .../domain/SoraCardInteractorImpl.kt | 2 +- .../presentation/get/card/GetSoraCardViewModel.kt | 2 +- .../presentation/get/card/GetSoraCardViewModelTest.kt | 2 +- .../feature_wallet_impl/di/WalletFeatureModule.kt | 2 +- .../feature_wallet_impl/domain/WalletInteractorImpl.kt | 2 +- .../presentation/cardshub/CardsHubViewModel.kt | 4 ++-- .../feature_wallet_impl/domain/WalletInteractorTest.kt | 2 +- .../presentation/wallet/CardsHubViewModelTest.kt | 4 ++-- 63 files changed, 98 insertions(+), 101 deletions(-) rename feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/data/{interfaces => }/AssetsRepository.kt (98%) rename feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/{interfaces => }/AssetsInteractor.kt (98%) rename feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/{interfaces => }/QrCodeInteractor.kt (97%) rename feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/{launcher => }/AssetsRouter.kt (96%) diff --git a/app/src/main/java/jp/co/soramitsu/sora/di/app/modules/NavigationModule.kt b/app/src/main/java/jp/co/soramitsu/sora/di/app/modules/NavigationModule.kt index 5ffd3e5d4..b8b366cd8 100644 --- a/app/src/main/java/jp/co/soramitsu/sora/di/app/modules/NavigationModule.kt +++ b/app/src/main/java/jp/co/soramitsu/sora/di/app/modules/NavigationModule.kt @@ -37,7 +37,7 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import javax.inject.Singleton -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.launcher.PolkaswapRouter import jp.co.soramitsu.feature_referral_api.ReferralRouter diff --git a/app/src/main/java/jp/co/soramitsu/sora/navigation/Navigator.kt b/app/src/main/java/jp/co/soramitsu/sora/navigation/Navigator.kt index 0cb9aab10..0bf5dfe6a 100644 --- a/app/src/main/java/jp/co/soramitsu/sora/navigation/Navigator.kt +++ b/app/src/main/java/jp/co/soramitsu/sora/navigation/Navigator.kt @@ -51,7 +51,7 @@ import jp.co.soramitsu.common.presentation.compose.webview.title import jp.co.soramitsu.common.presentation.compose.webview.url import jp.co.soramitsu.common.util.BuildUtils import jp.co.soramitsu.common.util.StringPair -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_assets_impl.presentation.screens.assetdetails.AssetDetailsFragment import jp.co.soramitsu.feature_assets_impl.presentation.screens.receiverequest.QRCodeFlowFragment import jp.co.soramitsu.feature_assets_impl.presentation.screens.send.TransferAmountFragment @@ -73,7 +73,13 @@ import jp.co.soramitsu.feature_sora_card_impl.presentation.get.card.GetSoraCardF import jp.co.soramitsu.feature_wallet_api.launcher.WalletRouter import jp.co.soramitsu.sora.R -class Navigator : MainRouter, WalletRouter, ReferralRouter, SelectNodeRouter, PolkaswapRouter, AssetsRouter { +class Navigator : + MainRouter, + WalletRouter, + ReferralRouter, + SelectNodeRouter, + PolkaswapRouter, + AssetsRouter { private var navController: NavController? = null diff --git a/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/data/interfaces/AssetsRepository.kt b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/data/AssetsRepository.kt similarity index 98% rename from feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/data/interfaces/AssetsRepository.kt rename to feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/data/AssetsRepository.kt index 1cc5d2372..f72d2408a 100644 --- a/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/data/interfaces/AssetsRepository.kt +++ b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/data/AssetsRepository.kt @@ -30,7 +30,7 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package jp.co.soramitsu.feature_assets_api.data.interfaces +package jp.co.soramitsu.feature_assets_api.data import java.math.BigDecimal import jp.co.soramitsu.common.account.SoraAccount diff --git a/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/interfaces/AssetsInteractor.kt b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/AssetsInteractor.kt similarity index 98% rename from feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/interfaces/AssetsInteractor.kt rename to feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/AssetsInteractor.kt index e7d971d69..771c9bc61 100644 --- a/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/interfaces/AssetsInteractor.kt +++ b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/AssetsInteractor.kt @@ -30,7 +30,7 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package jp.co.soramitsu.feature_assets_api.domain.interfaces +package jp.co.soramitsu.feature_assets_api.domain import java.math.BigDecimal import jp.co.soramitsu.common.account.SoraAccount diff --git a/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/interfaces/QrCodeInteractor.kt b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/QrCodeInteractor.kt similarity index 97% rename from feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/interfaces/QrCodeInteractor.kt rename to feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/QrCodeInteractor.kt index e7818b393..fb77a4908 100644 --- a/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/interfaces/QrCodeInteractor.kt +++ b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/QrCodeInteractor.kt @@ -30,7 +30,7 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package jp.co.soramitsu.feature_assets_api.domain.interfaces +package jp.co.soramitsu.feature_assets_api.domain interface QrCodeInteractor { diff --git a/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/launcher/AssetsRouter.kt b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/AssetsRouter.kt similarity index 96% rename from feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/launcher/AssetsRouter.kt rename to feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/AssetsRouter.kt index 4d1ac837e..03baf2311 100644 --- a/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/launcher/AssetsRouter.kt +++ b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/AssetsRouter.kt @@ -30,7 +30,7 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package jp.co.soramitsu.feature_assets_api.presentation.launcher +package jp.co.soramitsu.feature_assets_api.presentation interface AssetsRouter { diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/data/AssetsRepositoryImpl.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/data/AssetsRepositoryImpl.kt index 330be5427..b7e92b224 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/data/AssetsRepositoryImpl.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/data/AssetsRepositoryImpl.kt @@ -55,7 +55,7 @@ import jp.co.soramitsu.core_db.AppDatabase import jp.co.soramitsu.core_db.model.AssetLocal import jp.co.soramitsu.core_db.model.AssetTokenWithFiatLocal import jp.co.soramitsu.core_db.model.TokenLocal -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_blockexplorer_api.data.SoraConfigManager import jp.co.soramitsu.shared_utils.encrypt.keypair.substrate.Sr25519Keypair import jp.co.soramitsu.sora.substrate.models.ExtrinsicSubmitStatus diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/di/AssetsFeatureModule.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/di/AssetsFeatureModule.kt index 56fc7287b..6639e36ff 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/di/AssetsFeatureModule.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/di/AssetsFeatureModule.kt @@ -40,9 +40,9 @@ import javax.inject.Singleton import jp.co.soramitsu.common.domain.CoroutineManager import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.domain.interfaces.QrCodeInteractor +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.domain.QrCodeInteractor import jp.co.soramitsu.feature_assets_impl.data.AssetsRepositoryImpl import jp.co.soramitsu.feature_assets_impl.domain.AssetsInteractorImpl import jp.co.soramitsu.feature_assets_impl.domain.QrCodeInteractorImpl diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorImpl.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorImpl.kt index 4373e7370..9e5282152 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorImpl.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorImpl.kt @@ -46,8 +46,8 @@ import jp.co.soramitsu.common.util.ext.orZero import jp.co.soramitsu.common_wallet.data.XorAssetBalance import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_blockexplorer_api.data.TransactionHistoryRepository import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.TransactionBuilder import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.TransactionStatus diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/domain/QrCodeInteractorImpl.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/domain/QrCodeInteractorImpl.kt index bcc3f77f7..88bef23e3 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/domain/QrCodeInteractorImpl.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/domain/QrCodeInteractorImpl.kt @@ -37,8 +37,8 @@ import javax.inject.Inject import jp.co.soramitsu.common.domain.OptionsProvider import jp.co.soramitsu.common_wallet.domain.model.QrException import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository -import jp.co.soramitsu.feature_assets_api.domain.interfaces.QrCodeInteractor +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository +import jp.co.soramitsu.feature_assets_api.domain.QrCodeInteractor import jp.co.soramitsu.sora.substrate.runtime.RuntimeManager import jp.co.soramitsu.sora.substrate.runtime.SubstrateOptionsProvider diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/assetdetails/AssetDetailsViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/assetdetails/AssetDetailsViewModel.kt index d87b6ab8c..eac96bf70 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/assetdetails/AssetDetailsViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/assetdetails/AssetDetailsViewModel.kt @@ -58,8 +58,8 @@ import jp.co.soramitsu.common.util.ext.isZero import jp.co.soramitsu.common_wallet.data.XorAssetBalance import jp.co.soramitsu.common_wallet.domain.model.fiatSymbol import jp.co.soramitsu.common_wallet.presentation.compose.states.mapPoolsData -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_assets_impl.presentation.states.AssetCardState import jp.co.soramitsu.feature_assets_impl.presentation.states.FrozenXorDetailsModel import jp.co.soramitsu.feature_assets_impl.presentation.states.emptyAssetCardState diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetlist/FullAssetListViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetlist/FullAssetListViewModel.kt index 5eba2c68e..04663d8a0 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetlist/FullAssetListViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetlist/FullAssetListViewModel.kt @@ -46,8 +46,8 @@ import jp.co.soramitsu.common.domain.isMatchFilter import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.common_wallet.presentation.compose.states.mapAssetsToCardState -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_assets_impl.presentation.states.FullAssetListState import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.catch diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetsettings/FullAssetSettingsViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetsettings/FullAssetSettingsViewModel.kt index 6e26c5600..8c1591f65 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetsettings/FullAssetSettingsViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetsettings/FullAssetSettingsViewModel.kt @@ -46,8 +46,8 @@ import jp.co.soramitsu.common.domain.formatFiatAmount import jp.co.soramitsu.common.domain.isMatchFilter import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel import jp.co.soramitsu.common.util.NumbersFormatter -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_assets_impl.presentation.states.AssetSettingsState import kotlinx.coroutines.launch diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt index 9e73c9e1a..a1f51bbc5 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt @@ -61,8 +61,8 @@ import jp.co.soramitsu.common_wallet.domain.model.QrException import jp.co.soramitsu.common_wallet.presentation.compose.components.SelectSearchAssetState import jp.co.soramitsu.common_wallet.presentation.compose.states.mapAssetsToCardState import jp.co.soramitsu.common_wallet.presentation.compose.util.AmountFormat.getAssetBalanceText -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.domain.interfaces.QrCodeInteractor +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.domain.QrCodeInteractor import jp.co.soramitsu.feature_assets_impl.presentation.components.compose.receiverequest.ReceiveTokenByQrScreenState import jp.co.soramitsu.feature_assets_impl.presentation.components.compose.receiverequest.RequestTokenConfirmScreenState import jp.co.soramitsu.feature_assets_impl.presentation.components.compose.receiverequest.RequestTokenScreenState diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt index ee34c9935..066b4294c 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt @@ -61,8 +61,8 @@ import jp.co.soramitsu.common.util.ext.orZero import jp.co.soramitsu.common.view.ViewHelper import jp.co.soramitsu.common_wallet.presentation.compose.states.mapAssetsToCardState import jp.co.soramitsu.common_wallet.presentation.compose.util.PolkaswapFormulas -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_assets_impl.presentation.states.SendState import jp.co.soramitsu.feature_wallet_api.launcher.WalletRouter import jp.co.soramitsu.sora.substrate.runtime.SubstrateOptionsProvider diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/txlist/TxListViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/txlist/TxListViewModel.kt index a621fec57..c7df329b6 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/txlist/TxListViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/txlist/TxListViewModel.kt @@ -39,8 +39,8 @@ import dagger.assisted.AssistedInject import jp.co.soramitsu.common.R import jp.co.soramitsu.common.presentation.compose.components.initSmallTitle2 import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_blockexplorer_api.domain.TransactionHistoryHandler import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.launchIn diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/data/AssetsRepositoryTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/data/AssetsRepositoryTest.kt index 3729aa084..02937d1b1 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/data/AssetsRepositoryTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/data/AssetsRepositoryTest.kt @@ -42,7 +42,7 @@ import jp.co.soramitsu.core_db.dao.AssetDao import jp.co.soramitsu.core_db.model.AssetLocal import jp.co.soramitsu.core_db.model.AssetTokenWithFiatLocal import jp.co.soramitsu.core_db.model.TokenLocal -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_blockexplorer_api.data.SoraConfigManager import jp.co.soramitsu.shared_utils.encrypt.keypair.substrate.Sr25519Keypair import jp.co.soramitsu.sora.substrate.models.ExtrinsicSubmitStatus diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorTest.kt index c1ec9e2e6..3e4eec481 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorTest.kt @@ -45,8 +45,8 @@ import jp.co.soramitsu.common.domain.OptionsProvider import jp.co.soramitsu.common.domain.Token import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_blockexplorer_api.data.TransactionHistoryRepository import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.Transaction import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.TransactionBase diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/QrCodeInteractorTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/QrCodeInteractorTest.kt index 08257223d..9e773ad7f 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/QrCodeInteractorTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/domain/QrCodeInteractorTest.kt @@ -32,14 +32,11 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_assets_impl.domain -import io.mockk.every -import io.mockk.mockkObject import jp.co.soramitsu.common.account.SoraAccount -import jp.co.soramitsu.common.domain.OptionsProvider import jp.co.soramitsu.common_wallet.domain.model.QrException import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository -import jp.co.soramitsu.feature_assets_api.domain.interfaces.QrCodeInteractor +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository +import jp.co.soramitsu.feature_assets_api.domain.QrCodeInteractor import jp.co.soramitsu.sora.substrate.runtime.RuntimeManager import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest @@ -47,7 +44,6 @@ import org.junit.Assert import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.BDDMockito import org.mockito.Mock import org.mockito.junit.MockitoJUnitRunner import org.mockito.kotlin.given diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/assetsettings/AssetSettingsViewModelTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/assetsettings/AssetSettingsViewModelTest.kt index 3ddfee50e..d44a3d11f 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/assetsettings/AssetSettingsViewModelTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/assetsettings/AssetSettingsViewModelTest.kt @@ -42,8 +42,8 @@ import jp.co.soramitsu.common.domain.AssetHolder import jp.co.soramitsu.common.domain.Token import jp.co.soramitsu.common.domain.iconUri import jp.co.soramitsu.common.util.NumbersFormatter -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_assets_impl.presentation.screens.fullassetsettings.FullAssetSettingsViewModel import jp.co.soramitsu.feature_assets_impl.presentation.states.AssetSettingsState import jp.co.soramitsu.test_data.TestAssets diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt index 684089c8c..7876393cc 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt @@ -53,8 +53,8 @@ import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.common.util.QrCodeGenerator import jp.co.soramitsu.common.util.ext.Big100 -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.domain.interfaces.QrCodeInteractor +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.domain.QrCodeInteractor import jp.co.soramitsu.feature_assets_impl.presentation.screens.receiverequest.QRCodeFlowViewModel import jp.co.soramitsu.feature_wallet_api.launcher.WalletRouter import jp.co.soramitsu.test_data.TestAssets diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt index 9895723bd..67f8c50b1 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt @@ -50,8 +50,8 @@ import jp.co.soramitsu.common.domain.iconUri import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.common.util.ext.equalTo -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_assets_impl.presentation.screens.send.TransferAmountViewModel import jp.co.soramitsu.feature_wallet_api.launcher.WalletRouter import jp.co.soramitsu.test_data.PolkaswapTestData diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/txlist/AssetSettingsViewModelTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/txlist/AssetSettingsViewModelTest.kt index 09f036d9c..64fd6eb1e 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/txlist/AssetSettingsViewModelTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/txlist/AssetSettingsViewModelTest.kt @@ -41,8 +41,8 @@ import io.mockk.junit4.MockKRule import io.mockk.verify import jp.co.soramitsu.common.R import jp.co.soramitsu.common.resourses.ResourceManager -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_assets_impl.presentation.screens.txlist.TxListViewModel import jp.co.soramitsu.feature_blockexplorer_api.domain.HistoryState import jp.co.soramitsu.feature_blockexplorer_api.domain.TransactionHistoryHandler diff --git a/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/domain/TransactionHistoryHandlerImpl.kt b/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/domain/TransactionHistoryHandlerImpl.kt index a360f82dd..1c2618913 100644 --- a/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/domain/TransactionHistoryHandlerImpl.kt +++ b/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/domain/TransactionHistoryHandlerImpl.kt @@ -41,7 +41,7 @@ import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.DateTimeUtils import jp.co.soramitsu.common.util.ext.safeCast import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_blockexplorer_api.data.TransactionHistoryRepository import jp.co.soramitsu.feature_blockexplorer_api.domain.HistoryState import jp.co.soramitsu.feature_blockexplorer_api.domain.TransactionHistoryHandler diff --git a/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/screen/ActivitiesViewModel.kt b/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/screen/ActivitiesViewModel.kt index 8c9bef05e..2189b1431 100644 --- a/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/screen/ActivitiesViewModel.kt +++ b/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/screen/ActivitiesViewModel.kt @@ -36,8 +36,8 @@ import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_blockexplorer_api.domain.TransactionHistoryHandler import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletInteractor diff --git a/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModel.kt b/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModel.kt index 9cfb15233..57ef3afd2 100644 --- a/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModel.kt +++ b/feature_blockexplorer_impl/src/main/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModel.kt @@ -51,7 +51,7 @@ import jp.co.soramitsu.common.presentation.trigger import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_blockexplorer_api.domain.TransactionHistoryHandler import jp.co.soramitsu.feature_blockexplorer_api.presentation.txdetails.BasicTxDetailsItem import jp.co.soramitsu.feature_blockexplorer_api.presentation.txdetails.BasicTxDetailsState diff --git a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/domain/TransactionHistoryHandlerTest.kt b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/domain/TransactionHistoryHandlerTest.kt index 0fb3635a7..778f99c15 100644 --- a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/domain/TransactionHistoryHandlerTest.kt +++ b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/domain/TransactionHistoryHandlerTest.kt @@ -51,7 +51,7 @@ import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.common.util.ext.safeCast import jp.co.soramitsu.common.util.ext.unsafeCast import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_blockexplorer_api.data.TransactionHistoryRepository import jp.co.soramitsu.feature_blockexplorer_api.domain.HistoryState import jp.co.soramitsu.feature_blockexplorer_api.domain.TransactionHistoryHandler diff --git a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/screen/ActivitiesViewModelTest.kt b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/screen/ActivitiesViewModelTest.kt index 410b4caa8..a84828bc8 100644 --- a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/screen/ActivitiesViewModelTest.kt +++ b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/screen/ActivitiesViewModelTest.kt @@ -38,8 +38,8 @@ import io.mockk.coVerify import io.mockk.every import io.mockk.impl.annotations.MockK import io.mockk.junit4.MockKRule -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_blockexplorer_api.domain.HistoryState import jp.co.soramitsu.feature_blockexplorer_api.domain.TransactionHistoryHandler import jp.co.soramitsu.feature_main_api.launcher.MainRouter @@ -57,7 +57,6 @@ import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule import org.junit.runner.RunWith -import org.mockito.Mock import org.mockito.junit.MockitoJUnitRunner @ExperimentalCoroutinesApi diff --git a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModelTest.kt b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModelTest.kt index 94b1a50e9..16adbf192 100644 --- a/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModelTest.kt +++ b/feature_blockexplorer_impl/src/test/java/jp/co/soramitsu/feature_blockexplorer_impl/presentation/txdetails/TxDetailsViewModelTest.kt @@ -49,7 +49,7 @@ import jp.co.soramitsu.common.domain.iconUri import jp.co.soramitsu.common.domain.printFiat import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_blockexplorer_api.domain.TransactionHistoryHandler import jp.co.soramitsu.feature_blockexplorer_api.presentation.txdetails.BasicTxDetailsItem import jp.co.soramitsu.feature_blockexplorer_api.presentation.txdetails.BasicTxDetailsState diff --git a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/di/EcoSystemModule.kt b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/di/EcoSystemModule.kt index 7c85b08a2..084445d8e 100644 --- a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/di/EcoSystemModule.kt +++ b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/di/EcoSystemModule.kt @@ -38,7 +38,7 @@ import dagger.hilt.InstallIn import dagger.hilt.android.components.ViewModelComponent import dagger.hilt.android.scopes.ViewModelScoped import jp.co.soramitsu.common.domain.CoroutineManager -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_blockexplorer_api.data.BlockExplorerManager import jp.co.soramitsu.feature_ecosystem_impl.domain.EcoSystemPoolsInteractor import jp.co.soramitsu.feature_ecosystem_impl.domain.EcoSystemPoolsInteractorImpl diff --git a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/domain/EcoSystemTokensInteractor.kt b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/domain/EcoSystemTokensInteractor.kt index f742227fd..ecd820e51 100644 --- a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/domain/EcoSystemTokensInteractor.kt +++ b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/domain/EcoSystemTokensInteractor.kt @@ -35,7 +35,7 @@ package jp.co.soramitsu.feature_ecosystem_impl.domain import jp.co.soramitsu.common.util.ext.compareNullDesc import jp.co.soramitsu.common.util.ext.multiplyNullable import jp.co.soramitsu.common.util.mapBalance -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_blockexplorer_api.data.BlockExplorerManager import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map diff --git a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/explore/ExploreViewModel.kt b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/explore/ExploreViewModel.kt index 3b760cddb..d1b1f4cdf 100644 --- a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/explore/ExploreViewModel.kt +++ b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/explore/ExploreViewModel.kt @@ -36,7 +36,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel import jp.co.soramitsu.common.util.StringPair -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_ecosystem_impl.presentation.ExploreRoutes import jp.co.soramitsu.feature_polkaswap_api.launcher.PolkaswapRouter import jp.co.soramitsu.sora.substrate.runtime.SubstrateOptionsProvider diff --git a/feature_ecosystem_impl/src/test/java/jp/co/soramitsu/feature_ecosystem_impl/explore/ExploreViewModelTest.kt b/feature_ecosystem_impl/src/test/java/jp/co/soramitsu/feature_ecosystem_impl/explore/ExploreViewModelTest.kt index 1ced51113..6efa6dfba 100644 --- a/feature_ecosystem_impl/src/test/java/jp/co/soramitsu/feature_ecosystem_impl/explore/ExploreViewModelTest.kt +++ b/feature_ecosystem_impl/src/test/java/jp/co/soramitsu/feature_ecosystem_impl/explore/ExploreViewModelTest.kt @@ -37,7 +37,7 @@ import io.mockk.every import io.mockk.impl.annotations.MockK import io.mockk.junit4.MockKRule import io.mockk.verify -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_ecosystem_impl.presentation.explore.ExploreViewModel import jp.co.soramitsu.feature_polkaswap_api.launcher.PolkaswapRouter import jp.co.soramitsu.test_shared.MainCoroutineRule diff --git a/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/domain/subs/BalanceFeatureStorageManager.kt b/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/domain/subs/BalanceFeatureStorageManager.kt index 10f0b4cf8..7f1f871a0 100644 --- a/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/domain/subs/BalanceFeatureStorageManager.kt +++ b/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/domain/subs/BalanceFeatureStorageManager.kt @@ -34,7 +34,7 @@ package jp.co.soramitsu.feature_main_impl.domain.subs import javax.inject.Inject import jp.co.soramitsu.common.domain.SingleFeatureStorageManager -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletRepository import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.onEach diff --git a/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModel.kt b/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModel.kt index 0ca723e33..d84ca28ee 100644 --- a/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModel.kt +++ b/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModel.kt @@ -42,7 +42,7 @@ import jp.co.soramitsu.common.domain.RepeatStrategyBuilder import jp.co.soramitsu.common.presentation.SingleLiveEvent import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel import jp.co.soramitsu.common.util.ext.setValueIfNew -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_blockexplorer_api.data.BlockExplorerManager import jp.co.soramitsu.feature_main_impl.domain.PinCodeInteractor import jp.co.soramitsu.feature_main_impl.domain.subs.GlobalSubscriptionManager diff --git a/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/presentation/profile/ProfileViewModel.kt b/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/presentation/profile/ProfileViewModel.kt index 232b6e5d5..3d7ce44de 100644 --- a/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/presentation/profile/ProfileViewModel.kt +++ b/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/presentation/profile/ProfileViewModel.kt @@ -43,7 +43,7 @@ import jp.co.soramitsu.common.R import jp.co.soramitsu.common.presentation.SingleLiveEvent import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel import jp.co.soramitsu.common.util.BuildUtils -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_blockexplorer_api.data.SoraConfigManager import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_main_impl.domain.MainInteractor diff --git a/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModelTest.kt b/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModelTest.kt index b11dadb5a..05b1d3ad8 100644 --- a/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModelTest.kt +++ b/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModelTest.kt @@ -43,7 +43,7 @@ import io.mockk.verify import jp.co.soramitsu.common.domain.CoroutineManager import jp.co.soramitsu.common.domain.RepeatStrategy import jp.co.soramitsu.common.domain.RepeatStrategyBuilder -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_main_impl.domain.PinCodeInteractor import jp.co.soramitsu.feature_main_impl.domain.subs.GlobalSubscriptionManager import jp.co.soramitsu.feature_select_node_api.NodeManager diff --git a/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/profile/ProfileViewModelTest.kt b/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/profile/ProfileViewModelTest.kt index dd43fcd69..f051d3b07 100644 --- a/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/profile/ProfileViewModelTest.kt +++ b/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/profile/ProfileViewModelTest.kt @@ -39,7 +39,7 @@ import io.mockk.impl.annotations.MockK import io.mockk.junit4.MockKRule import io.mockk.verify import jp.co.soramitsu.common.domain.ChainNode -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_blockexplorer_api.data.SoraConfigManager import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_main_impl.domain.MainInteractor diff --git a/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/domain/MultiaccountInteractor.kt b/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/domain/MultiaccountInteractor.kt index 2898ec99c..3e5ddf59b 100644 --- a/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/domain/MultiaccountInteractor.kt +++ b/feature_multiaccount_impl/src/main/java/jp/co/soramitsu/feature_multiaccount_impl/domain/MultiaccountInteractor.kt @@ -39,7 +39,7 @@ import jp.co.soramitsu.common.io.FileManager import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository import jp.co.soramitsu.feature_account_api.domain.model.OnboardingState -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.shared_utils.encrypt.keypair.Keypair import jp.co.soramitsu.sora.substrate.runtime.RuntimeManager import kotlinx.coroutines.flow.Flow diff --git a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/domain/MultiaccountInteractorTest.kt b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/domain/MultiaccountInteractorTest.kt index c36142792..b593d9c31 100644 --- a/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/domain/MultiaccountInteractorTest.kt +++ b/feature_multiaccount_impl/src/test/java/jp/co/soramitsu/feature_multiaccount_impl/domain/MultiaccountInteractorTest.kt @@ -44,7 +44,7 @@ import jp.co.soramitsu.common.io.FileManager import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository import jp.co.soramitsu.feature_account_api.domain.model.OnboardingState -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.shared_utils.encrypt.keypair.substrate.Sr25519Keypair import jp.co.soramitsu.sora.substrate.runtime.RuntimeManager import jp.co.soramitsu.test_shared.MainCoroutineRule diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/di/PolkaswapFeatureModule.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/di/PolkaswapFeatureModule.kt index 26ef4e8dc..705b10bb3 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/di/PolkaswapFeatureModule.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/di/PolkaswapFeatureModule.kt @@ -39,7 +39,7 @@ import dagger.hilt.components.SingletonComponent import javax.inject.Singleton import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_blockexplorer_api.data.TransactionHistoryRepository import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.TransactionBuilder import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PolkaswapExtrinsicRepository diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/PoolsInteractorImpl.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/PoolsInteractorImpl.kt index 727d0c3b3..ad900b9a1 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/PoolsInteractorImpl.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/PoolsInteractorImpl.kt @@ -48,7 +48,7 @@ import jp.co.soramitsu.common_wallet.presentation.compose.util.PolkaswapFormulas import jp.co.soramitsu.common_wallet.presentation.compose.util.PolkaswapFormulas.estimateAddingShareOfPool import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_blockexplorer_api.data.TransactionHistoryRepository import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.TransactionBuilder import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.TransactionLiquidityType diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt index ad94c1cbe..011ed6d7b 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt @@ -43,7 +43,7 @@ import jp.co.soramitsu.common.util.ext.isZero import jp.co.soramitsu.common_wallet.domain.model.WithDesired import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_blockexplorer_api.data.TransactionHistoryRepository import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.TransactionBuilder import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.TransactionStatus diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt index a0a55798e..df1a0ab35 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt @@ -61,8 +61,8 @@ import jp.co.soramitsu.common_wallet.presentation.compose.components.SelectSearc import jp.co.soramitsu.common_wallet.presentation.compose.states.mapAssetsToCardState import jp.co.soramitsu.common_wallet.presentation.compose.util.AmountFormat import jp.co.soramitsu.common_wallet.presentation.compose.util.PolkaswapFormulas -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PoolsInteractor import jp.co.soramitsu.feature_polkaswap_impl.presentation.states.LiquidityAddConfirmState diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityremove/LiquidityRemoveViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityremove/LiquidityRemoveViewModel.kt index 645f69337..1c7e2e73b 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityremove/LiquidityRemoveViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityremove/LiquidityRemoveViewModel.kt @@ -56,8 +56,8 @@ import jp.co.soramitsu.common_wallet.domain.model.CommonUserPoolData import jp.co.soramitsu.common_wallet.presentation.compose.util.AmountFormat import jp.co.soramitsu.common_wallet.presentation.compose.util.PolkaswapFormulas import jp.co.soramitsu.demeter.domain.DemeterFarmingInteractor -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PoolsInteractor import jp.co.soramitsu.feature_polkaswap_impl.presentation.states.LiquidityRemoveConfirmState import jp.co.soramitsu.feature_polkaswap_impl.presentation.states.LiquidityRemoveEstimatedState diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt index 3eae9450a..93d1e55be 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt @@ -68,8 +68,8 @@ import jp.co.soramitsu.common_wallet.presentation.compose.components.SelectSearc import jp.co.soramitsu.common_wallet.presentation.compose.states.mapAssetsToCardState import jp.co.soramitsu.common_wallet.presentation.compose.util.AmountFormat import jp.co.soramitsu.common_wallet.presentation.compose.util.PolkaswapFormulas -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.SwapInteractor import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapDetails @@ -90,7 +90,6 @@ import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/domain/PoolsInteractorTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/domain/PoolsInteractorTest.kt index 5024490e4..cf516afbf 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/domain/PoolsInteractorTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/domain/PoolsInteractorTest.kt @@ -37,7 +37,7 @@ import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.common_wallet.domain.model.WithDesired import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_blockexplorer_api.data.TransactionHistoryRepository import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.TransactionBuilder import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PolkaswapExtrinsicRepository diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorTest.kt index f360cd5f8..c0175b723 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorTest.kt @@ -35,7 +35,7 @@ package jp.co.soramitsu.feature_polkaswap_impl.domain import androidx.arch.core.executor.testing.InstantTaskExecutorRule import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_blockexplorer_api.data.TransactionHistoryRepository import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.TransactionBuilder import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PolkaswapExtrinsicRepository diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt index f9f587b56..b56b9144e 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt @@ -47,8 +47,8 @@ import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.common_wallet.presentation.compose.components.SelectSearchAssetState import jp.co.soramitsu.common_wallet.presentation.compose.states.AssetItemCardState import jp.co.soramitsu.common_wallet.presentation.compose.states.mapAssetsToCardState -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.SwapInteractor import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapDetails diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt index 458dde500..cf22a5ab2 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt @@ -47,8 +47,8 @@ import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.common.util.ext.equalTo import jp.co.soramitsu.common_wallet.domain.model.LiquidityData -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PoolsInteractor import jp.co.soramitsu.feature_polkaswap_impl.presentation.screens.liquidityadd.LiquidityAddViewModel @@ -82,7 +82,6 @@ import org.mockito.Mockito import org.mockito.Mockito.verify import org.mockito.junit.MockitoJUnitRunner import org.mockito.kotlin.any -import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.times import java.math.BigDecimal import org.mockito.kotlin.verify as kVerify diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/remove/RemoveLiquidityViewModelTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/remove/RemoveLiquidityViewModelTest.kt index bd0bab202..ae226fc29 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/remove/RemoveLiquidityViewModelTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/remove/RemoveLiquidityViewModelTest.kt @@ -36,10 +36,9 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule import jp.co.soramitsu.common.R import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PoolsInteractor -import jp.co.soramitsu.demeter.domain.DemeterFarmingInteractor import jp.co.soramitsu.feature_polkaswap_impl.presentation.screens.liquidityremove.LiquidityRemoveViewModel import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletInteractor import jp.co.soramitsu.feature_wallet_api.launcher.WalletRouter @@ -68,7 +67,6 @@ import org.mockito.BDDMockito.given import org.mockito.Mock import org.mockito.junit.MockitoJUnitRunner import org.mockito.kotlin.any -import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.times import org.mockito.kotlin.verify import java.math.BigDecimal diff --git a/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/domain/ReferralInteractor.kt b/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/domain/ReferralInteractor.kt index e21b2a512..130ffcccf 100644 --- a/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/domain/ReferralInteractor.kt +++ b/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/domain/ReferralInteractor.kt @@ -40,7 +40,7 @@ import jp.co.soramitsu.common.util.ext.truncateUserAddress import jp.co.soramitsu.common.util.mapBalance import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_blockexplorer_api.data.TransactionHistoryRepository import jp.co.soramitsu.feature_referral_api.data.ReferralRepository import jp.co.soramitsu.feature_referral_impl.domain.model.Referral diff --git a/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModel.kt b/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModel.kt index 0884654ac..6828b9461 100644 --- a/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModel.kt +++ b/feature_referral_impl/src/main/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModel.kt @@ -50,8 +50,8 @@ import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.common.util.ext.lazyAsync import jp.co.soramitsu.common.util.ext.orZero -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_referral_impl.domain.ReferralInteractor import jp.co.soramitsu.feature_referral_impl.presentation.ReferralFeatureRoutes.BOND_XOR diff --git a/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/domain/ReferralInteractorTest.kt b/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/domain/ReferralInteractorTest.kt index 046ece96d..03a84bffc 100644 --- a/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/domain/ReferralInteractorTest.kt +++ b/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/domain/ReferralInteractorTest.kt @@ -36,7 +36,7 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_blockexplorer_api.data.TransactionHistoryRepository import jp.co.soramitsu.feature_referral_api.data.ReferralRepository import jp.co.soramitsu.feature_referral_impl.domain.model.Referral diff --git a/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModelTest.kt b/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModelTest.kt index b6738a39a..c9292c05e 100644 --- a/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModelTest.kt +++ b/feature_referral_impl/src/test/java/jp/co/soramitsu/feature_referral_impl/presentation/ReferralViewModelTest.kt @@ -46,8 +46,8 @@ import jp.co.soramitsu.common.R import jp.co.soramitsu.common.domain.Asset import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_referral_impl.domain.ReferralInteractor import jp.co.soramitsu.feature_referral_impl.domain.model.Referral diff --git a/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/domain/SoraCardInteractorImpl.kt b/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/domain/SoraCardInteractorImpl.kt index 3a6bc82eb..cdf3339e7 100644 --- a/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/domain/SoraCardInteractorImpl.kt +++ b/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/domain/SoraCardInteractorImpl.kt @@ -42,7 +42,7 @@ import jp.co.soramitsu.common.util.ext.divideBy import jp.co.soramitsu.common.util.ext.greaterThan import jp.co.soramitsu.common.util.ext.safeDivide import jp.co.soramitsu.demeter.domain.DemeterFarmingInteractor -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_blockexplorer_api.data.BlockExplorerManager import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PoolsInteractor import jp.co.soramitsu.feature_sora_card_api.domain.SoraCardInteractor diff --git a/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/GetSoraCardViewModel.kt b/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/GetSoraCardViewModel.kt index 15cf00c9e..8897ab62e 100644 --- a/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/GetSoraCardViewModel.kt +++ b/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/GetSoraCardViewModel.kt @@ -44,7 +44,7 @@ import jp.co.soramitsu.common.presentation.SingleLiveEvent import jp.co.soramitsu.common.presentation.compose.components.initSmallTitle2 import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel import jp.co.soramitsu.common.resourses.ResourceManager -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.launcher.PolkaswapRouter import jp.co.soramitsu.feature_sora_card_api.domain.SoraCardInteractor diff --git a/feature_sora_card_impl/src/test/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/GetSoraCardViewModelTest.kt b/feature_sora_card_impl/src/test/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/GetSoraCardViewModelTest.kt index ff3835152..70d242e0e 100644 --- a/feature_sora_card_impl/src/test/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/GetSoraCardViewModelTest.kt +++ b/feature_sora_card_impl/src/test/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/GetSoraCardViewModelTest.kt @@ -38,7 +38,7 @@ import io.mockk.mockkObject import jp.co.soramitsu.common.R import jp.co.soramitsu.common.domain.OptionsProvider import jp.co.soramitsu.common.resourses.ResourceManager -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.launcher.PolkaswapRouter import jp.co.soramitsu.feature_sora_card_api.domain.SoraCardInteractor diff --git a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/di/WalletFeatureModule.kt b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/di/WalletFeatureModule.kt index 697124d57..e765ed5d8 100644 --- a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/di/WalletFeatureModule.kt +++ b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/di/WalletFeatureModule.kt @@ -43,7 +43,7 @@ import jp.co.soramitsu.common.domain.POOLS_HUB_NAME import jp.co.soramitsu.common.domain.SingleFeatureStorageManager import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_blockexplorer_api.data.TransactionHistoryRepository import jp.co.soramitsu.feature_wallet_api.data.BuyCryptoDataSource import jp.co.soramitsu.feature_wallet_api.domain.interfaces.BuyCryptoRepository diff --git a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/domain/WalletInteractorImpl.kt b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/domain/WalletInteractorImpl.kt index 71e986ec6..5e210d597 100644 --- a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/domain/WalletInteractorImpl.kt +++ b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/domain/WalletInteractorImpl.kt @@ -36,7 +36,7 @@ import jp.co.soramitsu.common.account.SoraAccount import jp.co.soramitsu.common.domain.Token import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_blockexplorer_api.data.TransactionHistoryRepository import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletInteractor import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletRepository diff --git a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubViewModel.kt b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubViewModel.kt index 1442222c5..b264250b0 100644 --- a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubViewModel.kt +++ b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubViewModel.kt @@ -62,8 +62,8 @@ import jp.co.soramitsu.common_wallet.presentation.compose.states.SoraCardState import jp.co.soramitsu.common_wallet.presentation.compose.states.TitledAmountCardState import jp.co.soramitsu.common_wallet.presentation.compose.states.mapAssetsToCardState import jp.co.soramitsu.common_wallet.presentation.compose.states.mapPoolsData -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PoolsInteractor import jp.co.soramitsu.feature_polkaswap_api.launcher.PolkaswapRouter diff --git a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/domain/WalletInteractorTest.kt b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/domain/WalletInteractorTest.kt index f357bbbbc..57f4006d6 100644 --- a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/domain/WalletInteractorTest.kt +++ b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/domain/WalletInteractorTest.kt @@ -43,7 +43,7 @@ import jp.co.soramitsu.common.domain.OptionsProvider import jp.co.soramitsu.common.domain.Token import jp.co.soramitsu.feature_account_api.domain.interfaces.CredentialsRepository import jp.co.soramitsu.feature_account_api.domain.interfaces.UserRepository -import jp.co.soramitsu.feature_assets_api.data.interfaces.AssetsRepository +import jp.co.soramitsu.feature_assets_api.data.AssetsRepository import jp.co.soramitsu.feature_blockexplorer_api.data.TransactionHistoryRepository import jp.co.soramitsu.feature_blockexplorer_api.presentation.txhistory.TransactionBuilder import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletInteractor diff --git a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/wallet/CardsHubViewModelTest.kt b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/wallet/CardsHubViewModelTest.kt index 8d279b635..bfa8e0d6b 100644 --- a/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/wallet/CardsHubViewModelTest.kt +++ b/feature_wallet_impl/src/test/java/jp/co/soramitsu/feature_wallet_impl/presentation/wallet/CardsHubViewModelTest.kt @@ -58,8 +58,8 @@ import jp.co.soramitsu.common.domain.iconUri import jp.co.soramitsu.common.interfaces.WithProgress import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter -import jp.co.soramitsu.feature_assets_api.domain.interfaces.AssetsInteractor -import jp.co.soramitsu.feature_assets_api.presentation.launcher.AssetsRouter +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PoolsInteractor import jp.co.soramitsu.feature_polkaswap_api.launcher.PolkaswapRouter From aaf5c3aa1ea1442f0b5479b73aeccc86a19963e5 Mon Sep 17 00:00:00 2001 From: arvifox Date: Tue, 5 Sep 2023 17:09:39 +0300 Subject: [PATCH 12/20] sn-2891 token search feature --- .../co/soramitsu/sora/navigation/Navigator.kt | 3 +- build.gradle | 4 +- .../soramitsu/common/base/SoraBaseFragment.kt | 1 + .../compose/components/Toolbar.kt | 2 + .../uikit/organisms/LoadableContentCard.kt | 46 +--- .../presentation/viewmodel/BaseViewModel.kt | 2 + common/src/main/res/values-ar/strings.xml | 6 - common/src/main/res/values-az/strings.xml | 6 - common/src/main/res/values-de/strings.xml | 6 - common/src/main/res/values-es/strings.xml | 6 - common/src/main/res/values-fa/strings.xml | 6 - common/src/main/res/values-fi/strings.xml | 6 - common/src/main/res/values-fr/strings.xml | 6 - common/src/main/res/values-hi-rIN/strings.xml | 6 - common/src/main/res/values-in/strings.xml | 6 - common/src/main/res/values-iw/strings.xml | 6 - common/src/main/res/values-ja/strings.xml | 6 - common/src/main/res/values-ms-rMY/strings.xml | 6 - common/src/main/res/values-nb/strings.xml | 6 - common/src/main/res/values-nl/strings.xml | 6 - common/src/main/res/values-pt/strings.xml | 6 - common/src/main/res/values-ru/strings.xml | 6 - common/src/main/res/values-sr/strings.xml | 6 - common/src/main/res/values-tr/strings.xml | 6 - common/src/main/res/values-vi/strings.xml | 10 +- common/src/main/res/values-zh-rCN/strings.xml | 10 +- common/src/main/res/values-zh-rTW/strings.xml | 6 - common/src/main/res/values/strings.xml | 6 - .../main/res/values/stringsnottranslate.xml | 4 + .../presentation/compose/BasicPoolListItem.kt | 2 +- .../components/SelectSearchTokenScreen.kt | 71 ------ feature_assets_api/build.gradle | 27 +++ .../selectsearchtoken/SelectSearchToken.kt | 114 ++++----- .../SelectSearchTokenViewModel.kt | 99 ++++++++ .../receiverequest/QRCodeMainScreen.kt | 5 +- .../receiverequest/ReceiveTokenScreen.kt | 28 +-- .../RequestTokenConfirmScreen.kt | 17 +- .../receiverequest/RequestTokenScreen.kt | 34 +-- .../fullassetlist/FullAssetListFragment.kt | 2 +- .../FullAssetSettingsFragment.kt | 2 +- .../receiverequest/QRCodeFlowFragment.kt | 40 ++-- .../receiverequest/QRCodeFlowViewModel.kt | 163 ++++++------- .../screens/send/TransferAmountFragment.kt | 10 +- .../screens/send/TransferAmountViewModel.kt | 105 +++++---- .../presentation/states/SendState.kt | 3 +- .../qr/QrCodeFlowViewModelTest.kt | 27 ++- .../send/TransferAmountViewModelTest.kt | 6 +- .../allcurrencies/AllCurrenciesScreen.kt | 2 +- .../presentation/allpools/AllPoolsScreen.kt | 2 +- .../presentation/profile/ProfileViewModel.kt | 2 +- .../domain/model/SwapDetails.kt | 3 - .../PolkaswapSubscriptionRepositoryImpl.kt | 27 ++- .../domain/SwapInteractorImpl.kt | 138 +++++------ .../compose/LiquidityAddConfirmScreen.kt | 3 +- .../components/compose/LiquidityAddScreen.kt | 6 +- .../components/compose/SwapConfirmScreen.kt | 1 - .../components/compose/SwapMainScreen.kt | 5 +- .../fullpoollist/FullPoolListFragment.kt | 2 +- .../FullPoolSettingsFragment.kt | 2 +- .../liquidityadd/LiquidityAddFragment.kt | 29 +-- .../liquidityadd/LiquidityAddViewModel.kt | 221 +++++++++--------- .../presentation/screens/swap/SwapFragment.kt | 19 +- .../screens/swap/SwapViewModel.kt | 36 +-- .../presentation/states/LiquidityAddState.kt | 3 - .../presentation/states/SwapMainState.kt | 6 - .../polkaswap/SwapViewModelTest.kt | 28 +-- .../add/AddLiquidityViewModelTest.kt | 56 +---- .../get/card/GetSoraCardViewModel.kt | 2 +- .../launcher/WalletRouter.kt | 2 +- .../cardshub/CardsHubViewModel.kt | 2 +- .../sora/substrate/substrate/SubstrateApi.kt | 10 - .../substrate/substrate/SubstrateApiImpl.kt | 26 --- 72 files changed, 637 insertions(+), 953 deletions(-) delete mode 100644 common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/components/SelectSearchTokenScreen.kt rename common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/components/SelectSearchAssetView.kt => feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/selectsearchtoken/SelectSearchToken.kt (52%) create mode 100644 feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/selectsearchtoken/SelectSearchTokenViewModel.kt diff --git a/app/src/main/java/jp/co/soramitsu/sora/navigation/Navigator.kt b/app/src/main/java/jp/co/soramitsu/sora/navigation/Navigator.kt index 0bf5dfe6a..a400426f0 100644 --- a/app/src/main/java/jp/co/soramitsu/sora/navigation/Navigator.kt +++ b/app/src/main/java/jp/co/soramitsu/sora/navigation/Navigator.kt @@ -234,12 +234,11 @@ class Navigator : navController?.popBackStack() } - override fun openQrCodeFlow(shouldNavigateToScannerDirectly: Boolean, isLaunchedFromSoraCard: Boolean) { + override fun openQrCodeFlow(shouldNavigateToScannerDirectly: Boolean) { navController?.navigate( R.id.qrCodeFlow, QRCodeFlowFragment.createBundle( shouldNavigateToScanner = shouldNavigateToScannerDirectly, - isLaunchedFromSoraCard = isLaunchedFromSoraCard ) ) } diff --git a/build.gradle b/build.gradle index 63258c5e0..fad1226b4 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ buildscript { composeMaterial : '1.4.3', composeCompiler : '1.4.6', composeConstraintLayout: '1.1.0-alpha05', - uiCore : '0.1.0', - soraCard : '0.1.35', + uiCore : '0.1.2', + soraCard : '0.1.38', lazySodium : '5.0.2', jna : '5.8.0', accompanist : '0.30.1', diff --git a/common/src/main/java/jp/co/soramitsu/common/base/SoraBaseFragment.kt b/common/src/main/java/jp/co/soramitsu/common/base/SoraBaseFragment.kt index cd4142e94..9ef589751 100644 --- a/common/src/main/java/jp/co/soramitsu/common/base/SoraBaseFragment.kt +++ b/common/src/main/java/jp/co/soramitsu/common/base/SoraBaseFragment.kt @@ -193,6 +193,7 @@ abstract class SoraBaseFragment : Fragment() { onNavClick = { debounceClickHandler.debounceClick(::onNavClicked) }, onActionClick = viewModel::onAction, onMenuItemClick = viewModel::onMenuItem, + onSearch = viewModel::onToolbarSearch, ) } ) { padding -> diff --git a/common/src/main/java/jp/co/soramitsu/common/presentation/compose/components/Toolbar.kt b/common/src/main/java/jp/co/soramitsu/common/presentation/compose/components/Toolbar.kt index 334a6fd9b..865f1a9ed 100644 --- a/common/src/main/java/jp/co/soramitsu/common/presentation/compose/components/Toolbar.kt +++ b/common/src/main/java/jp/co/soramitsu/common/presentation/compose/components/Toolbar.kt @@ -91,6 +91,7 @@ fun Toolbar( onNavClick: (() -> Unit)? = null, onActionClick: (() -> Unit)? = null, onMenuItemClick: ((Action) -> Unit)? = null, + onSearch: ((String) -> Unit)? = null, ) { if (toolbarState != null && toolbarState.basic.visibility) { val elevation = remember(scrollState) { @@ -111,6 +112,7 @@ fun Toolbar( onNavigate = onNavClick, onAction = onActionClick, onMenuItemClicked = onMenuItemClick, + onSearch = onSearch, ) } } diff --git a/common/src/main/java/jp/co/soramitsu/common/presentation/compose/uikit/organisms/LoadableContentCard.kt b/common/src/main/java/jp/co/soramitsu/common/presentation/compose/uikit/organisms/LoadableContentCard.kt index 3ad76d9a2..7e9747ea5 100644 --- a/common/src/main/java/jp/co/soramitsu/common/presentation/compose/uikit/organisms/LoadableContentCard.kt +++ b/common/src/main/java/jp/co/soramitsu/common/presentation/compose/uikit/organisms/LoadableContentCard.kt @@ -49,40 +49,22 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import jp.co.soramitsu.common.R -import jp.co.soramitsu.common.presentation.compose.uikit.tokens.Image import jp.co.soramitsu.common.presentation.compose.uikit.tokens.ScreenStatus -import jp.co.soramitsu.common.presentation.compose.uikit.tokens.Text -import jp.co.soramitsu.common.presentation.compose.uikit.tokens.retrievePainter -import jp.co.soramitsu.common.presentation.compose.uikit.tokens.retrieveString import jp.co.soramitsu.ui_core.component.card.ContentCard import jp.co.soramitsu.ui_core.resources.Dimens import jp.co.soramitsu.ui_core.theme.customColors -data class LoadableContentCardState( - val screenStatus: ScreenStatus -) { - val isLoading: Boolean = screenStatus === ScreenStatus.LOADING - - val isErrorCaught: Boolean = screenStatus === ScreenStatus.ERROR - - val errorImage: Image = Image.ResImage( - id = R.drawable.ic_error_80 - ) - - val errorText: Text = Text.StringRes( - id = R.string.common_error_general_title - ) -} - @Composable fun LoadableContentCard( modifier: Modifier, innerPadding: PaddingValues, cornerRadius: Dp, - state: LoadableContentCardState, + state: ScreenStatus, onTryAgainClick: () -> Unit, contentWhenLoaded: @Composable () -> Unit, ) { @@ -91,8 +73,8 @@ fun LoadableContentCard( innerPadding = innerPadding, cornerRadius = cornerRadius ) { - when { - state.isLoading -> { + when (state) { + ScreenStatus.LOADING -> { Box { CircularProgressIndicator( modifier = Modifier @@ -101,13 +83,13 @@ fun LoadableContentCard( ) } } - state.isErrorCaught -> { + ScreenStatus.ERROR -> { Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Image( - painter = state.errorImage.retrievePainter(), + painter = painterResource(id = R.drawable.ic_error_80), contentDescription = null ) Divider( @@ -118,7 +100,7 @@ fun LoadableContentCard( modifier = Modifier.clickable { onTryAgainClick.invoke() }, - text = state.errorText.retrieveString(), + text = stringResource(id = R.string.common_error_general_title), ) } } @@ -139,9 +121,7 @@ private fun PreviewLoadableContentCard_LOADING() { innerPadding = PaddingValues( all = Dimens.x3 ), - state = LoadableContentCardState( - screenStatus = ScreenStatus.LOADING - ), + state = ScreenStatus.LOADING, cornerRadius = Dimens.x4, contentWhenLoaded = { Box(modifier = Modifier.fillMaxSize()) { @@ -166,9 +146,7 @@ private fun PreviewLoadableContentCard_READY_TO_RENDER() { all = Dimens.x3 ), cornerRadius = Dimens.x4, - state = LoadableContentCardState( - screenStatus = ScreenStatus.READY_TO_RENDER - ), + state = ScreenStatus.READY_TO_RENDER, contentWhenLoaded = { Box(modifier = Modifier.fillMaxSize()) { Text( @@ -191,9 +169,7 @@ private fun PreviewLoadableContentCard_ERROR() { innerPadding = PaddingValues( all = Dimens.x3 ), - state = LoadableContentCardState( - screenStatus = ScreenStatus.ERROR - ), + state = ScreenStatus.ERROR, cornerRadius = Dimens.x4, contentWhenLoaded = { Box(modifier = Modifier.fillMaxSize()) { diff --git a/common/src/main/java/jp/co/soramitsu/common/presentation/viewmodel/BaseViewModel.kt b/common/src/main/java/jp/co/soramitsu/common/presentation/viewmodel/BaseViewModel.kt index 294ea78b2..26c4b3d22 100644 --- a/common/src/main/java/jp/co/soramitsu/common/presentation/viewmodel/BaseViewModel.kt +++ b/common/src/main/java/jp/co/soramitsu/common/presentation/viewmodel/BaseViewModel.kt @@ -116,6 +116,8 @@ open class BaseViewModel : ViewModel() { open fun onMenuItem(action: Action) = Unit + open fun onToolbarSearch(value: String) = Unit + open fun onAction() = Unit suspend fun tryCatchFinally(finally: () -> Unit, block: suspend () -> Unit) { diff --git a/common/src/main/res/values-ar/strings.xml b/common/src/main/res/values-ar/strings.xml index 09332611a..970cc1bf8 100644 --- a/common/src/main/res/values-ar/strings.xml +++ b/common/src/main/res/values-ar/strings.xml @@ -66,7 +66,6 @@ نشاط و إصدار التطبيق - APY العربية Azerbaijani رجوع @@ -345,8 +344,6 @@ سيولة غير كافية رسوم حوض السيولة يذهب جزء من كل صفقة إلى موفري السيولة كحوافز للبروتوكول. - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. سوق @@ -369,9 +366,6 @@ ذكي تبديل تمت المبادلة - TBC - XYK - APY المكافأة الاستراتيجية إزالة تفاصيل المسبح سيولتك ستظهر هنا diff --git a/common/src/main/res/values-az/strings.xml b/common/src/main/res/values-az/strings.xml index 90679768e..748a286a5 100644 --- a/common/src/main/res/values-az/strings.xml +++ b/common/src/main/res/values-az/strings.xml @@ -66,7 +66,6 @@ Fəaliyyət Proqram versiyası - APY Ərəb dili Azerbaijani Geri @@ -341,8 +340,6 @@ Qeyri-kifayət qədər likvidlik LP haqqı Hər bir ticarətin bir hissəsi protokol təşviqi olaraq likvidlik təminatçılarına keçir. - Sintetik token haqqı - Sintetik ödəniş sintetik aktiv haqqı və qabaqcadan qaçmağın qarşısını almaq üçün dinamik ödənişdən ibarətdir. Sintetik aktivin haqqı aktivin qeydiyyatı zamanı müəyyən edilir və istənilən vaxt idarəetmə vasitəsilə dəyişdirilə bilər. Dinamik ödəniş oracle qiymətindəki faiz dəyişikliyinə əsaslanır. Ümumi ödəniş Ümumi ödəniş ödənişdən ibarətdir Bazar @@ -365,9 +362,6 @@ Ağıllı Mübadilə edin Dəyişdirildi - TBC - XYK - Strateji bonus apy Sil Pool details Likvidliyiniz burada görünəcək diff --git a/common/src/main/res/values-de/strings.xml b/common/src/main/res/values-de/strings.xml index bc29f81c5..48f04cce1 100644 --- a/common/src/main/res/values-de/strings.xml +++ b/common/src/main/res/values-de/strings.xml @@ -66,7 +66,6 @@ Activity und App-Version - APY Arabisch Azerbaijani Zurück @@ -341,8 +340,6 @@ Unzureichende Liquidität LP-Gebühr Ein Teil jeder Trade geht als Protokollanreiz an die Liquiditätsanbieter. - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Markt @@ -365,9 +362,6 @@ Smart Tausch Getauscht - TBC - XYK - Strategischer Bonus APY Entfernen Pool details Du hast noch keine aktiven Pools.\nFüge Liquidität hinzu, um Belohnungen zu erhalten diff --git a/common/src/main/res/values-es/strings.xml b/common/src/main/res/values-es/strings.xml index e2c524795..b2b163e76 100644 --- a/common/src/main/res/values-es/strings.xml +++ b/common/src/main/res/values-es/strings.xml @@ -66,7 +66,6 @@ Activity y App version - APY Árabe Azerbaijani Atrás @@ -341,8 +340,6 @@ Liquidez insuficiente Tarifa LP Una porción de cada trade va a los proveedores de liquidez como incentivo del protocolo - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Mercado @@ -365,9 +362,6 @@ Inteligente Intercambiar Intercambiado - TBC - XYK - Strategic bonus apy Remove Detalles de la Liquidez You don\'t have any active pools yet.\nAdd liquidity to earn rewards diff --git a/common/src/main/res/values-fa/strings.xml b/common/src/main/res/values-fa/strings.xml index 84d6f9434..6148625cf 100644 --- a/common/src/main/res/values-fa/strings.xml +++ b/common/src/main/res/values-fa/strings.xml @@ -66,7 +66,6 @@ Activity و نسخه App - APY عرب Azerbaijani بازگشت @@ -341,8 +340,6 @@ نقدینگی ناکافی هزینه LP بخشی از هر معامله به عنوان مشوق پروتکل به ارائه دهندگان نقدینگی می‌رسد. - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. بازار @@ -365,9 +362,6 @@ هوشمند تبدیل مبادله شد - TBC - XYK - نرخ سود سالانه پاداش استراتژیک حذف Pool details شما هنوز هیچ مخزن فعالی ندارید. برای کسب پاداش، نقدینگی اضافه کنید diff --git a/common/src/main/res/values-fi/strings.xml b/common/src/main/res/values-fi/strings.xml index f28081c42..4a293454a 100644 --- a/common/src/main/res/values-fi/strings.xml +++ b/common/src/main/res/values-fi/strings.xml @@ -66,7 +66,6 @@ Activity ja Sovelluksen versio - APY Arab Azerbaijani Takaisin @@ -341,8 +340,6 @@ Riittämätön likviditeetti LP-maksu Osa jokaisesta kaupasta menee likviditeetin tarjoajille protokollakannustimena. - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Market @@ -365,9 +362,6 @@ Smart Swap Swapped - TBC - XYK - Strateginen bonus apy Poista Pool details Likviditeettisi näkyy täällä diff --git a/common/src/main/res/values-fr/strings.xml b/common/src/main/res/values-fr/strings.xml index a2585784f..0172300a7 100644 --- a/common/src/main/res/values-fr/strings.xml +++ b/common/src/main/res/values-fr/strings.xml @@ -66,7 +66,6 @@ Activité et Version de l\'application - APY Arabe Azerbaïdjanais Retour @@ -341,8 +340,6 @@ Liquidité insuffisante Frais de LP Une partie de chaque transaction est reversée aux fournisseurs de liquidités à titre d\'incitation de la part du protocole - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Marché @@ -365,9 +362,6 @@ Intelligent Échanger Échangé - TBC - XYK - APY de bonus stratégique Retirer Détails du pool Vous n\'avez pas encore de pools actifs.\n Ajoutez des liquidités pour gagner des récompenses diff --git a/common/src/main/res/values-hi-rIN/strings.xml b/common/src/main/res/values-hi-rIN/strings.xml index ee7c42bd5..05b1708a0 100644 --- a/common/src/main/res/values-hi-rIN/strings.xml +++ b/common/src/main/res/values-hi-rIN/strings.xml @@ -66,7 +66,6 @@ गतिविधि और ऐप संस्करण - APY अरब Azerbaijani पीछे @@ -341,8 +340,6 @@ अपर्याप्त Liquidity LP शुल्क प्रत्येक व्यापार का एक हिस्सा एक प्रोटोकॉल प्रोत्साहन के रूप में Liquidity प्रदाताओं को जाता है। - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. बाज़ार @@ -365,9 +362,6 @@ बुद्धिमान स्वैप बदला गया - टीबीसी - XYK - रणनीतिक बोनस apy हटाये पूल विवरण आपके पास अभी तक कोई सक्रिय पूल नहीं है।\n पुरस्कार अर्जित करने के लिए तरलता जोड़ें diff --git a/common/src/main/res/values-in/strings.xml b/common/src/main/res/values-in/strings.xml index cf67f4154..aa162be57 100644 --- a/common/src/main/res/values-in/strings.xml +++ b/common/src/main/res/values-in/strings.xml @@ -66,7 +66,6 @@ Activity dan App version - APY Arab Azerbaijani Back @@ -340,8 +339,6 @@ Likuiditas tidak mencukupi Biaya LP Sebagian dari setiap perdagangan diberikan kepada penyedia likuiditas sebagai insentif protokol. - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Pasar @@ -364,9 +361,6 @@ Cerdas Swap Bertukar - TBC - XYK - Strategic bonus apy Remove Pool details You don\'t have any active pools yet.\nAdd liquidity to earn rewards diff --git a/common/src/main/res/values-iw/strings.xml b/common/src/main/res/values-iw/strings.xml index bcdc63ba7..54fab06bf 100644 --- a/common/src/main/res/values-iw/strings.xml +++ b/common/src/main/res/values-iw/strings.xml @@ -66,7 +66,6 @@ פעילות ו גרסת אפליקציה - APY ערבית אזרבייג\'נית חזור @@ -343,8 +342,6 @@ אין מספיק נזילות עמלת מאגר נזילות חלק מכל עסקה הולך לספקי נזילות כתמריץ פרוטוקול. - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. שוק @@ -367,9 +364,6 @@ Smart החלף הוחלף - TBC - XYK - בונוס אסטרטגי apy הסר פרטי המאגר עדיין אין לך מאגרים פעילים.\nהוסף נזילות כדי להרוויח תגמולים diff --git a/common/src/main/res/values-ja/strings.xml b/common/src/main/res/values-ja/strings.xml index e87f37c5e..8e2fb1fcd 100644 --- a/common/src/main/res/values-ja/strings.xml +++ b/common/src/main/res/values-ja/strings.xml @@ -66,7 +66,6 @@ 履歴 アプリのバージョン - APY アラビア語 Azerbaijani 戻る @@ -340,8 +339,6 @@ 流動性不足 LP手数料 各取引の一部は、インセンティブとして流動性プロバイダー(LP)に送られます - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. 市場 @@ -364,9 +361,6 @@ SMART スワップ スワップ済み - TBC - XYK - 戦略的ボーナスAPY(年収率) 削除 プールの詳細 アクティブなプールがまだありません。\n流動性を追加して報酬を獲得してください diff --git a/common/src/main/res/values-ms-rMY/strings.xml b/common/src/main/res/values-ms-rMY/strings.xml index 4193f5a37..9fe73a2d3 100644 --- a/common/src/main/res/values-ms-rMY/strings.xml +++ b/common/src/main/res/values-ms-rMY/strings.xml @@ -66,7 +66,6 @@ Aktiviti dan Versi aplikasi - APY Arab Azerbaijan Kembali @@ -340,8 +339,6 @@ Kecairan tidak mencukupi Bayaran LP Sebahagian daripada setiap dagangan diberikan kepada penyedia kecairan sebagai insentif protokol. - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Pasaran @@ -364,9 +361,6 @@ Pintar Tukar Ditukar - TBC - XYK - Bonus strategik apy Buang Butiran kolam Kecairan anda akan muncul di sini diff --git a/common/src/main/res/values-nb/strings.xml b/common/src/main/res/values-nb/strings.xml index a60f90749..f895037a1 100644 --- a/common/src/main/res/values-nb/strings.xml +++ b/common/src/main/res/values-nb/strings.xml @@ -66,7 +66,6 @@ Activity og App version - APY Arabisk Azerbaijani Back @@ -341,8 +340,6 @@ Utilstrekkelig likviditet LP -avgift En del av hver handel går til likviditetsleverandører som et protokollinsentiv. - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Marked @@ -365,9 +362,6 @@ Smart Bytte Byttet - TBC - XYK - Strategic bonus apy Remove Pool details You don\'t have any active pools yet.\nAdd liquidity to earn rewards diff --git a/common/src/main/res/values-nl/strings.xml b/common/src/main/res/values-nl/strings.xml index 1064cb157..976cf3a20 100644 --- a/common/src/main/res/values-nl/strings.xml +++ b/common/src/main/res/values-nl/strings.xml @@ -66,7 +66,6 @@ Activity en App versie - APY Arabisch Azerbaijani Back @@ -341,8 +340,6 @@ Onvoldoende liquiditeit LP Vergoeding Een deel van elke transactie gaat naar liquiditeitsverschaffers als aanmoediging van het protocol. - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Markt @@ -365,9 +362,6 @@ Slim Omruil Omgewisseld - TBC - XYK - Strategische bonus apy Verwijder Pool details Uw liquiditeit zal hier verschijnen diff --git a/common/src/main/res/values-pt/strings.xml b/common/src/main/res/values-pt/strings.xml index e65216f07..83c1be991 100644 --- a/common/src/main/res/values-pt/strings.xml +++ b/common/src/main/res/values-pt/strings.xml @@ -66,7 +66,6 @@ Actividade e Versão da aplicação - APY Árabe Azerbaijani Anterior @@ -341,8 +340,6 @@ Liquidez insuficiente Taxa de LP Uma porção de cada transação vai para os provedores de liquidez, como incentivo do protocolo. - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Mercado @@ -365,9 +362,6 @@ Inteligente Swap Cambiado - TBC - XYK - APY de bónus estratégico Remover Pool details Ainda não tem nenhuma pool ativa. Adicione liquidez para ganhar recompensas diff --git a/common/src/main/res/values-ru/strings.xml b/common/src/main/res/values-ru/strings.xml index 78d1b8b2c..33d467d9f 100644 --- a/common/src/main/res/values-ru/strings.xml +++ b/common/src/main/res/values-ru/strings.xml @@ -66,7 +66,6 @@ Активность и Версия приложения - ГПД Арабский Азербайджанский Назад @@ -344,8 +343,6 @@ Недостаточная ликвидность Комиссия LP Часть каждой сделки является награждением для поставщиков ликвидности. - Комиссия за синтетический токен - Синтетическая комиссия состоит из комиссии за синтетический актив и динамической комиссии для предотвращения опережения. Плата за синтетические активы определяется при регистрации актива и может быть изменена в любое время посредством управления. Динамическая плата основана на процентном изменении цены оракула. Комиссия обмена Ваш своп включает в себя как синтетическую комиссию, так и комиссию LP.\nСинтетическая комиссия учитывается, когда обмен проходит через источник ликвидности XST для синтетических активов, а комиссия LP - когда своп проходит через пулы ликвидности. Рынок @@ -368,9 +365,6 @@ Smart Обмен Продано - TBC - XYK - Strategic bonus apy Забрать Информация о пуле У вас пока нет активных пулов.\nДобавьте ликвидность, чтобы получить вознаграждение diff --git a/common/src/main/res/values-sr/strings.xml b/common/src/main/res/values-sr/strings.xml index 501f19ad9..ede350cf8 100644 --- a/common/src/main/res/values-sr/strings.xml +++ b/common/src/main/res/values-sr/strings.xml @@ -66,7 +66,6 @@ Aktivnost и Верзија апликације - APY Арапски Azerbaijani Nazad @@ -342,8 +341,6 @@ Недовољна ликвидност Naknada za likvidnost Deo svake transakcije ide provajderima likvidnosti kao protokolarni podsticaj. - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Tržište @@ -366,9 +363,6 @@ Pametan Zameni Заменио - TBC - XYK - Стратешки бонус апи Уклони Pool details Још увек немате активних пула. Додајте ликвидност да бисте зарадили награде diff --git a/common/src/main/res/values-tr/strings.xml b/common/src/main/res/values-tr/strings.xml index 425c8cc54..a67583c78 100644 --- a/common/src/main/res/values-tr/strings.xml +++ b/common/src/main/res/values-tr/strings.xml @@ -66,7 +66,6 @@ Activity ve Uygulama sürümü - APY Arapça Azerbaijani Back @@ -341,8 +340,6 @@ Yetersiz likidite LP Ücreti Her takasın bir kısmı protokol teşviki olarak likidite sağlayıcılarına gider. - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Piyasa @@ -365,9 +362,6 @@ Akıllı Takas Takas edildi - TBC - XYK - Önemli bonus faizi Kaldır Pool details Henüz aktif havuzlarınız yok.\nÖdül kazanmak için likidite ekleyin diff --git a/common/src/main/res/values-vi/strings.xml b/common/src/main/res/values-vi/strings.xml index 027c49117..9c31ea75b 100644 --- a/common/src/main/res/values-vi/strings.xml +++ b/common/src/main/res/values-vi/strings.xml @@ -66,7 +66,6 @@ Hoạt động Phiên bản ứng dụng - APY Tiếng Ả Rập Azerbaijani Trở lại @@ -340,10 +339,8 @@ Không đủ thanh khoản Phí thanh khoản Một phần của mỗi giao dịch được chuyển đến các nhà cung cấp thanh khoản như một biện pháp khuyến khích. - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. - Swap fee - Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. + Phí hoán đổi + Hoán đổi của bạn bao gồm cả phí Tổng hợp và phí LP.\n Phí tổng hợp được tính khi hoán đổi đi qua nguồn thanh khoản XST cho tài sản tổng hợp và phí LP khi hoán đổi đi qua nhóm thanh khoản. Thị trường SMART liquidity routing đảm bảo giá tốt nhất cho giao dịch bất kỳ bằng cách kết hợp mức giá tốt nhất hiện có trên thị trường. Khi thuận lợi, Token Bonding Curve (TBC) sẽ được dùng để tạo thanh khoản miễn là giá của tài sản hợp lý hơn các nguồn khác như pool (XYK). TBC - chỉ mua từ Token Bonding Curve (Primary Market). Giá có thể trở nên bất lợi so với XYK pool (Secondary Market), nhưng về lâu dài giá trị nhận được từ phần thưởng có thể lớn hơn nhiều. @@ -364,9 +361,6 @@ Thông minh Đổi Đã hoán đổi - TBC - XYK - Apy tiền thưởng chiến lược Rút Chi tiết Pool Bạn chưa tham gia bất kỳ pool nào.\nThêm thanh khoản để kiếm phần thưởng diff --git a/common/src/main/res/values-zh-rCN/strings.xml b/common/src/main/res/values-zh-rCN/strings.xml index 5d9becd4b..3e2b6212c 100644 --- a/common/src/main/res/values-zh-rCN/strings.xml +++ b/common/src/main/res/values-zh-rCN/strings.xml @@ -66,7 +66,6 @@ 活动 应用程序版本 - 年收益率 阿拉伯语 阿塞拜疆语 返回 @@ -340,10 +339,8 @@ 流动性不足 流动性提供者费用 每笔交易的一部分作为协议激励奖励流动性提供者。 - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. - Swap fee - Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. + 兑换费用 + 你的兑换涉及到合成费用和流动性提供者费用。\n当兑换通过合成资产的XST流动性来源时,会计算合成费用;而当兑换通过流动性池时,则会计算流动性提供者费用。 市场 智能流动性路由通过从所有可用市场中仅选择最佳价格选项,确保任何交易的最佳价格。如果可用,将使用代币绑定曲线(TBC)提供流动性,只要资产价格比其他来源更实惠,否则将使用XYK池。 TBC - 仅从代币绑定曲线(一级市场)购买。价格可能会比XYK池(二级市场)不利,但随着时间的推移,从归属奖励中获得的价值可能会更有利。 @@ -364,9 +361,6 @@ 智能模式 兑换 已兑换 - TBC - XYK - 战略红利APY 移除 流动池详情 您还没有任何生效的流动池。\n赶快来增加流动性以赚取奖励哦 diff --git a/common/src/main/res/values-zh-rTW/strings.xml b/common/src/main/res/values-zh-rTW/strings.xml index 07523b4ac..a4ba9e966 100644 --- a/common/src/main/res/values-zh-rTW/strings.xml +++ b/common/src/main/res/values-zh-rTW/strings.xml @@ -66,7 +66,6 @@ 活動 應用版本 - APY 阿拉伯 Azerbaijani 返回 @@ -340,8 +339,6 @@ 流動性不足 LP費用 每筆交易的一部分 作為協議激勵流向流動性提供者。 - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. 市場 @@ -364,9 +361,6 @@ 智能 兌換 已兌換 - 待定 - XYK - 戰略紅利 消除 Pool details 您還沒有任何活動池。\n增加流動性以賺取獎勵 diff --git a/common/src/main/res/values/strings.xml b/common/src/main/res/values/strings.xml index f23b120f8..eccc3c69c 100644 --- a/common/src/main/res/values/strings.xml +++ b/common/src/main/res/values/strings.xml @@ -66,7 +66,6 @@ Activity and App version - APY Arab Azerbaijani Back @@ -341,8 +340,6 @@ Insufficient liquidity LP Fee A portion of each trade goes to liquidity providers as a protocol incentive. - Synthetic fee - The synthetic fee is composed of a synthetic asset fee and a dynamic fee to prevent front-running. The synthetic asset fee is determined upon the asset registration and can be changed at any time through governance. The dynamic fee is based on the percentage change in the oracle price. Swap fee Your swap involves both a Synthetic fee and an LP fee.\nThe Synthetic fee is accounted when the swap goes through the XST liquidity source for synthetic assets, and the LP fee when the swap goes through liquidity pools. Market @@ -365,9 +362,6 @@ Smart Swap Swapped - TBC - XYK - Strategic bonus apy Remove Pool details You don\'t have any active pools yet.\nAdd liquidity to earn rewards diff --git a/common/src/main/res/values/stringsnottranslate.xml b/common/src/main/res/values/stringsnottranslate.xml index 629229a23..dea848407 100644 --- a/common/src/main/res/values/stringsnottranslate.xml +++ b/common/src/main/res/values/stringsnottranslate.xml @@ -51,5 +51,9 @@ PSWAP JSON Google + APY + XYK + TBC + SB APY diff --git a/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/BasicPoolListItem.kt b/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/BasicPoolListItem.kt index c6168ea37..5be15dd8b 100644 --- a/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/BasicPoolListItem.kt +++ b/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/BasicPoolListItem.kt @@ -175,7 +175,7 @@ fun BasicPoolListItem( ) } Text( - text = "%s %s".format(state.text3, stringResource(id = R.string.common_apy)), + text = "%s %s".format(state.text3, stringResource(id = R.string.polkaswap_apy)), modifier = Modifier .background( color = MaterialTheme.customColors.bgSurfaceVariant, diff --git a/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/components/SelectSearchTokenScreen.kt b/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/components/SelectSearchTokenScreen.kt deleted file mode 100644 index 83f88ccd9..000000000 --- a/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/components/SelectSearchTokenScreen.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* -This file is part of the SORA network and Polkaswap app. - -Copyright (c) 2020, 2021, Polka Biome Ltd. All rights reserved. -SPDX-License-Identifier: BSD-4-Clause - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or other -materials provided with the distribution. - -All advertising materials mentioning features or use of this software must display -the following acknowledgement: This product includes software developed by Polka Biome -Ltd., SORA, and Polkaswap. - -Neither the name of the Polka Biome Ltd. nor the names of its contributors may be used -to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY Polka Biome Ltd. AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Polka Biome Ltd. BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package jp.co.soramitsu.common_wallet.presentation.compose.components - -import androidx.compose.foundation.ScrollState -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import jp.co.soramitsu.ui_core.component.card.ContentCard -import jp.co.soramitsu.ui_core.resources.Dimens - -@Composable -fun SelectSearchTokenScreen( - state: SelectSearchAssetState, - scrollState: ScrollState, - onAssetSelect: (String) -> Unit, -) { - Column( - modifier = Modifier - .fillMaxSize() - .padding(horizontal = Dimens.x2) - ) { - ContentCard( - modifier = Modifier - .fillMaxWidth() - .wrapContentHeight(), - innerPadding = PaddingValues(Dimens.x3) - ) { - SelectSearchAssetView( - state = state, - scrollState = scrollState, - onSelect = onAssetSelect, - ) - } - } -} diff --git a/feature_assets_api/build.gradle b/feature_assets_api/build.gradle index 2f2da5726..d2a560f92 100644 --- a/feature_assets_api/build.gradle +++ b/feature_assets_api/build.gradle @@ -31,6 +31,15 @@ android { } } + buildFeatures { + viewBinding true + compose true + } + + composeOptions { + kotlinCompilerExtensionVersion versions.composeCompiler + } + flavorDimensions "default" productFlavors { @@ -63,6 +72,24 @@ dependencies { implementation coroutineAndroidDep implementation coroutineDep + implementation uiCoreDep + implementation hiltNavComposeDep + + implementation composeUiDep + implementation composeThemeAdapterDep + implementation composeFoundationDep + implementation composeMaterialDep + implementation composeAnimationDep + implementation composeActivityDep + implementation composeViewModelDep + implementation composeToolingPreviewDep + implementation composeLiveDataDep + implementation composeConstraintLayoutDep + implementation composeLifecycleDep + debugImplementation composeToolingDep + implementation navigationComposeDep + implementation accompanistNavAnimationDep + implementation xNetworkingDep implementation daggerDep diff --git a/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/components/SelectSearchAssetView.kt b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/selectsearchtoken/SelectSearchToken.kt similarity index 52% rename from common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/components/SelectSearchAssetView.kt rename to feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/selectsearchtoken/SelectSearchToken.kt index 1ad590130..050a8074e 100644 --- a/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/presentation/compose/components/SelectSearchAssetView.kt +++ b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/selectsearchtoken/SelectSearchToken.kt @@ -30,103 +30,91 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package jp.co.soramitsu.common_wallet.presentation.compose.components +package jp.co.soramitsu.feature_assets_api.presentation.selectsearchtoken import androidx.compose.foundation.ScrollState import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.Divider import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.Preview -import jp.co.soramitsu.common.util.ext.testTagAsId +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import jp.co.soramitsu.common.presentation.compose.components.ContentCardEndless +import jp.co.soramitsu.common_wallet.presentation.compose.components.AssetItem import jp.co.soramitsu.common_wallet.presentation.compose.states.AssetItemCardState import jp.co.soramitsu.common_wallet.presentation.compose.states.previewAssetItemCardStateList -import jp.co.soramitsu.ui_core.component.searchview.SearchView -import jp.co.soramitsu.ui_core.component.searchview.SearchViewState import jp.co.soramitsu.ui_core.resources.Dimens data class SelectSearchAssetState( - val filter: String, - val fullList: List, + val list: List, ) -private fun isFilterMatch(asset: AssetItemCardState, filter: String): Boolean { - return asset.tokenName.lowercase().contains(filter.lowercase()) || - asset.tokenSymbol.lowercase().contains(filter.lowercase()) || - asset.tokenId.lowercase().contains(filter.lowercase()) -} - -private fun filterAssets(list: List, filter: String): List { - return list.filter { - isFilterMatch(it, filter) +@Composable +fun SelectSearchTokenScreen( + scrollState: ScrollState, + filter: String, + viewModel: SelectSearchTokenViewModel = hiltViewModel(), + onAssetSelect: (String) -> Unit, +) { + val state = viewModel.state.collectAsStateWithLifecycle().value + LaunchedEffect(filter) { + viewModel.onFilterChange(filter) } + SelectSearchTokenCard( + scrollState = scrollState, + state = state, + onAssetSelect = onAssetSelect, + ) } @Composable -fun SelectSearchAssetView( - state: SelectSearchAssetState, +private fun SelectSearchTokenCard( scrollState: ScrollState, - onSelect: (String) -> Unit, + state: SelectSearchAssetState, + onAssetSelect: (String) -> Unit, ) { - var fieldValue by remember { mutableStateOf(TextFieldValue(text = state.filter)) } - var filtered = filterAssets( - state.fullList, - fieldValue.text, - ) - Column( + ContentCardEndless( modifier = Modifier - .fillMaxWidth() - .wrapContentHeight() - .verticalScroll(scrollState) + .padding(start = Dimens.x2, end = Dimens.x2, top = Dimens.x2) + .fillMaxSize(), + innerPadding = PaddingValues(top = Dimens.x3), ) { - SearchView( + Column( modifier = Modifier - .testTagAsId("tokenSearchField") - .fillMaxWidth() - .wrapContentHeight(), - state = SearchViewState(value = fieldValue), - onValueChange = { - fieldValue = it - filtered = filterAssets(state.fullList, it.text) - }, - onAction = { - fieldValue = TextFieldValue("") - }, - ) - Divider(color = Color.Transparent, modifier = Modifier.height(Dimens.x2)) - filtered.forEachIndexed { index, assetState -> - AssetItem( - assetState = assetState, - testTag = "${assetState.tokenSymbol}Element", - onClick = onSelect, - ) - if (index < filtered.lastIndex) { - Divider(color = Color.Transparent, modifier = Modifier.height(Dimens.x2)) + .fillMaxSize() + .verticalScroll(scrollState) + ) { + state.list.forEachIndexed { index, assetState -> + AssetItem( + assetState = assetState, + testTag = "${assetState.tokenSymbol}Element", + onClick = onAssetSelect, + ) + if (index < state.list.lastIndex) { + Divider(color = Color.Transparent, modifier = Modifier.height(Dimens.x1)) + } } } } } -@Preview(showBackground = true) @Composable -private fun PreviewSelectSearchAssetView() { - SelectSearchAssetView( +@Preview +private fun PreviewSelectSearchTokenCard() { + SelectSearchTokenCard( + scrollState = rememberScrollState(), state = SelectSearchAssetState( - filter = "some", - fullList = previewAssetItemCardStateList, + list = previewAssetItemCardStateList, ), - scrollState = rememberScrollState(), - onSelect = {}, + onAssetSelect = {}, ) } diff --git a/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/selectsearchtoken/SelectSearchTokenViewModel.kt b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/selectsearchtoken/SelectSearchTokenViewModel.kt new file mode 100644 index 000000000..d76245699 --- /dev/null +++ b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/selectsearchtoken/SelectSearchTokenViewModel.kt @@ -0,0 +1,99 @@ +/* +This file is part of the SORA network and Polkaswap app. + +Copyright (c) 2020, 2021, Polka Biome Ltd. All rights reserved. +SPDX-License-Identifier: BSD-4-Clause + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list +of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this +list of conditions and the following disclaimer in the documentation and/or other +materials provided with the distribution. + +All advertising materials mentioning features or use of this software must display +the following acknowledgement: This product includes software developed by Polka Biome +Ltd., SORA, and Polkaswap. + +Neither the name of the Polka Biome Ltd. nor the names of its contributors may be used +to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY Polka Biome Ltd. AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Polka Biome Ltd. BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package jp.co.soramitsu.feature_assets_api.presentation.selectsearchtoken + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject +import jp.co.soramitsu.common.domain.Asset +import jp.co.soramitsu.common.domain.isMatchFilter +import jp.co.soramitsu.common.util.NumbersFormatter +import jp.co.soramitsu.common_wallet.presentation.compose.states.mapAssetsToCardState +import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.launch + +@HiltViewModel +class SelectSearchTokenViewModel @Inject constructor( + private val interactor: AssetsInteractor, + private val numbersFormatter: NumbersFormatter, +) : ViewModel() { + + private val _state = MutableStateFlow(SelectSearchAssetState(emptyList())) + val state = _state.asStateFlow() + + private var filter: String = "" + private val assets = mutableListOf() + + init { + viewModelScope.launch { + interactor.subscribeAssetsActiveOfCurAccount() + .catch { + // todo add + } + .collectLatest { + assets.clear() + assets.addAll(it) + reCalcFilter() + } + } + } + + fun onFilterChange(value: String) { + filter = value + reCalcFilter() + } + + private fun reCalcFilter() { + val curFilter = filter.lowercase() + val list = if (curFilter.isBlank()) { + mapAssetsToCardState(assets, numbersFormatter) + } else { + buildList { + addAll( + mapAssetsToCardState( + assets.filter { + it.token.isMatchFilter(curFilter) + }, + numbersFormatter + ) + ) + } + } + _state.value = _state.value.copy(list = list) + } +} diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/receiverequest/QRCodeMainScreen.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/receiverequest/QRCodeMainScreen.kt index 3ae646dec..1c1cbf0d3 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/receiverequest/QRCodeMainScreen.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/receiverequest/QRCodeMainScreen.kt @@ -73,7 +73,6 @@ fun QrCodeMainScreen( requestToken_onUserAddressClick: () -> Unit, requestToken_onAmountChanged: (BigDecimal) -> Unit, requestToken_onTokenSelect: () -> Unit, - requestToken_onFocusChange: (Boolean) -> Unit, requestToken_onCreateRequestClick: () -> Unit, requestToken_onTryAgainClick: () -> Unit, ) { @@ -137,9 +136,8 @@ fun QrCodeMainScreen( onUserAddressClick = requestToken_onUserAddressClick, onAmountChanged = requestToken_onAmountChanged, onTokenSelect = requestToken_onTokenSelect, - onFocusChange = requestToken_onFocusChange, onCreateRequestClick = requestToken_onCreateRequestClick, - onTryAgainClick = requestToken_onTryAgainClick + onTryAgainClick = requestToken_onTryAgainClick, ) } } @@ -173,7 +171,6 @@ private fun PreviewQrCodeMainScreen() { requestToken_onUserAddressClick = {}, requestToken_onAmountChanged = {}, requestToken_onTokenSelect = {}, - requestToken_onFocusChange = {}, requestToken_onCreateRequestClick = {}, requestToken_onTryAgainClick = {} ) diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/receiverequest/ReceiveTokenScreen.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/receiverequest/ReceiveTokenScreen.kt index c9228d746..5d0d3d260 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/receiverequest/ReceiveTokenScreen.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/receiverequest/ReceiveTokenScreen.kt @@ -49,17 +49,17 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import jp.co.soramitsu.common.R import jp.co.soramitsu.common.presentation.compose.uikit.molecules.ListTile import jp.co.soramitsu.common.presentation.compose.uikit.molecules.ListTileState import jp.co.soramitsu.common.presentation.compose.uikit.organisms.LoadableContentCard -import jp.co.soramitsu.common.presentation.compose.uikit.organisms.LoadableContentCardState import jp.co.soramitsu.common.presentation.compose.uikit.tokens.Image import jp.co.soramitsu.common.presentation.compose.uikit.tokens.ScreenStatus import jp.co.soramitsu.common.presentation.compose.uikit.tokens.Text import jp.co.soramitsu.common.presentation.compose.uikit.tokens.retrievePainter -import jp.co.soramitsu.common.presentation.compose.uikit.tokens.retrieveString import jp.co.soramitsu.ui_core.component.button.BleachedButton import jp.co.soramitsu.ui_core.component.button.FilledButton import jp.co.soramitsu.ui_core.component.button.properties.Order @@ -71,15 +71,9 @@ data class ReceiveTokenByQrScreenState( val untransformedQrBitmap: Bitmap?, val untransformedUserName: String?, val untransformedAvatarDrawable: Drawable?, - val untransformedUserAddress: String? + val untransformedUserAddress: String?, ) { - val loadableContentCardState by lazy { - LoadableContentCardState( - screenStatus = screenStatus - ) - } - val qrCodeImage: Image get() { if (untransformedQrBitmap == null) @@ -132,12 +126,6 @@ data class ReceiveTokenByQrScreenState( screenStatus === ScreenStatus.READY_TO_RENDER && untransformedUserAddress != null && untransformedAvatarDrawable != null - - val shareQRCodeButtonIcon: Image = Image.ResImage(id = R.drawable.ic_new_arrow_up_24) - - val shareQRCodeButtonText: Text = Text.StringRes(id = R.string.common_share) - - val scanQRCodeButtonText: Text = Text.StringRes(id = R.string.commom_scan_qr) } @Composable @@ -169,7 +157,7 @@ fun ReceiveTokenByQrScreen( all = Dimens.x1_5 ), cornerRadius = Dimens.x4, - state = state.loadableContentCardState, + state = state.screenStatus, contentWhenLoaded = { Image( painter = state.qrCodeImage.retrievePainter(), @@ -185,7 +173,7 @@ fun ReceiveTokenByQrScreen( all = Dimens.x1_5 ), cornerRadius = Dimens.x4, - state = state.loadableContentCardState, + state = state.screenStatus, onTryAgainClick = onTryAgainClick ) { ListTile( @@ -202,9 +190,9 @@ fun ReceiveTokenByQrScreen( .fillMaxWidth(), size = Size.Large, order = Order.SECONDARY, - leftIcon = state.shareQRCodeButtonIcon.retrievePainter(), + leftIcon = painterResource(id = R.drawable.ic_new_arrow_up_24), enabled = state.isShareQRCodeEnabled, - text = state.shareQRCodeButtonText.retrieveString(), + text = stringResource(id = R.string.common_share), onClick = onShareCodeClick ) } @@ -214,7 +202,7 @@ fun ReceiveTokenByQrScreen( .align(Alignment.BottomCenter), size = Size.Large, order = Order.SECONDARY, - text = state.scanQRCodeButtonText.retrieveString(), + text = stringResource(id = R.string.commom_scan_qr), onClick = onScanQrClick ) } diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/receiverequest/RequestTokenConfirmScreen.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/receiverequest/RequestTokenConfirmScreen.kt index a40263f07..ed51dfe4e 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/receiverequest/RequestTokenConfirmScreen.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/receiverequest/RequestTokenConfirmScreen.kt @@ -58,7 +58,6 @@ import jp.co.soramitsu.common.presentation.compose.components.previewAssetAmount import jp.co.soramitsu.common.presentation.compose.uikit.molecules.ListTile import jp.co.soramitsu.common.presentation.compose.uikit.molecules.ListTileState import jp.co.soramitsu.common.presentation.compose.uikit.organisms.LoadableContentCard -import jp.co.soramitsu.common.presentation.compose.uikit.organisms.LoadableContentCardState import jp.co.soramitsu.common.presentation.compose.uikit.tokens.Image import jp.co.soramitsu.common.presentation.compose.uikit.tokens.ScreenStatus import jp.co.soramitsu.common.presentation.compose.uikit.tokens.Text @@ -80,12 +79,6 @@ data class RequestTokenConfirmScreenState( val assetAmountInputState: AssetAmountInputState? ) { - val loadableContentCardState by lazy { - LoadableContentCardState( - screenStatus = screenStatus - ) - } - val qrCodeImage: Image get() { if (untransformedQrBitmap == null) @@ -152,7 +145,6 @@ fun RequestTokenConfirmScreen( scrollState: ScrollState, state: RequestTokenConfirmScreenState, onUserAddressClick: () -> Unit, - onFocusChange: (Boolean) -> Unit, onShareCodeClick: () -> Unit, onTryAgainClick: () -> Unit ) { @@ -172,7 +164,7 @@ fun RequestTokenConfirmScreen( all = Dimens.x1_5 ), cornerRadius = Dimens.x4, - state = state.loadableContentCardState, + state = state.screenStatus, contentWhenLoaded = { Image( painter = state.qrCodeImage.retrievePainter(), @@ -188,7 +180,7 @@ fun RequestTokenConfirmScreen( all = Dimens.x1_5 ), cornerRadius = Dimens.x4, - state = state.loadableContentCardState, + state = state.screenStatus, onTryAgainClick = onTryAgainClick ) { ListTile( @@ -204,7 +196,7 @@ fun RequestTokenConfirmScreen( modifier = Modifier.fillMaxWidth(), innerPadding = PaddingValues(vertical = Dimens.x1), cornerRadius = Dimens.x4, - state = state.loadableContentCardState, + state = state.screenStatus, onTryAgainClick = onTryAgainClick ) { Column { @@ -225,7 +217,7 @@ fun RequestTokenConfirmScreen( state = state.assetAmountInputState, onAmountChange = { /* No ability to change amount while confirming */ }, onSelectToken = { /* No ability to reselect token while confirming */ }, - onFocusChange = onFocusChange, + onFocusChange = {}, ) } } @@ -256,7 +248,6 @@ fun PreviewRequestTokenConfirmScreen() { assetAmountInputState = previewAssetAmountInputState ), onUserAddressClick = {}, - onFocusChange = {}, onShareCodeClick = {}, onTryAgainClick = {}, ) diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/receiverequest/RequestTokenScreen.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/receiverequest/RequestTokenScreen.kt index bbb239eb0..418b4445a 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/receiverequest/RequestTokenScreen.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/receiverequest/RequestTokenScreen.kt @@ -58,6 +58,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import java.math.BigDecimal import jp.co.soramitsu.common.R @@ -67,11 +68,9 @@ import jp.co.soramitsu.common.presentation.compose.components.previewAssetAmount import jp.co.soramitsu.common.presentation.compose.uikit.molecules.ListTile import jp.co.soramitsu.common.presentation.compose.uikit.molecules.ListTileState import jp.co.soramitsu.common.presentation.compose.uikit.organisms.LoadableContentCard -import jp.co.soramitsu.common.presentation.compose.uikit.organisms.LoadableContentCardState import jp.co.soramitsu.common.presentation.compose.uikit.tokens.Image import jp.co.soramitsu.common.presentation.compose.uikit.tokens.ScreenStatus import jp.co.soramitsu.common.presentation.compose.uikit.tokens.Text -import jp.co.soramitsu.common.presentation.compose.uikit.tokens.retrieveString import jp.co.soramitsu.ui_core.component.button.FilledButton import jp.co.soramitsu.ui_core.component.button.properties.Order import jp.co.soramitsu.ui_core.component.button.properties.Size @@ -84,20 +83,9 @@ data class RequestTokenScreenState( val untransformedUserName: String?, val untransformedAvatarDrawable: Drawable?, val untransformedUserAddress: String?, - val assetAmountInputState: AssetAmountInputState? + val assetAmountInputState: AssetAmountInputState?, ) { - val loadableContentCardState by lazy { - LoadableContentCardState( - screenStatus = screenStatus - ) - } - - val recipientAddressTitle: Text = - Text.StringRes( - id = R.string.recipient_address - ) - val recipientAddressHeader: Text get() { if (untransformedUserName == null) @@ -110,7 +98,7 @@ data class RequestTokenScreenState( ) } - val recipientAddressAvatar: Image + private val recipientAddressAvatar: Image get() { if (untransformedAvatarDrawable == null) return Image.ResImage( @@ -146,10 +134,6 @@ data class RequestTokenScreenState( screenStatus === ScreenStatus.READY_TO_RENDER && untransformedUserAddress != null && untransformedAvatarDrawable != null - - val createQRRequestButtonIcon: Int = R.drawable.ic_chevron_right_24 - - val createQRRequestButtonText: Text = Text.StringRes(id = R.string.common_create_qr_request) } @Composable @@ -162,7 +146,6 @@ fun RequestTokenScreen( onUserAddressClick: () -> Unit, onAmountChanged: (BigDecimal) -> Unit, onTokenSelect: () -> Unit, - onFocusChange: (Boolean) -> Unit, onCreateRequestClick: () -> Unit, onTryAgainClick: () -> Unit ) { @@ -197,7 +180,7 @@ fun RequestTokenScreen( .wrapContentHeight(), innerPadding = PaddingValues(Dimens.x3), cornerRadius = Dimens.x4, - state = state.loadableContentCardState, + state = state.screenStatus, onTryAgainClick = onTryAgainClick ) { Column( @@ -209,9 +192,7 @@ fun RequestTokenScreen( modifier = Modifier .wrapContentHeight() .fillMaxWidth(), - text = state.recipientAddressTitle - .retrieveString() - .uppercase(), + text = stringResource(id = R.string.recipient_address).uppercase(), style = MaterialTheme.customTypography.headline4, color = MaterialTheme.customColors.fgSecondary, ) @@ -232,7 +213,7 @@ fun RequestTokenScreen( focusRequester = focusRequester, onAmountChange = onAmountChanged, onSelectToken = onTokenSelect, - onFocusChange = onFocusChange, + onFocusChange = {}, ) FilledButton( modifier = Modifier @@ -242,7 +223,7 @@ fun RequestTokenScreen( ), size = Size.Large, order = Order.PRIMARY, - text = state.createQRRequestButtonText.retrieveString(), + text = stringResource(id = R.string.common_create_qr_request), enabled = state.isCreateQRRequestEnabled, onClick = onCreateRequestClick ) @@ -267,7 +248,6 @@ private fun PreviewRequestTokenScreen() { onUserAddressClick = {}, onAmountChanged = {}, onTokenSelect = {}, - onFocusChange = {}, onCreateRequestClick = {}, onTryAgainClick = {}, ) diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetlist/FullAssetListFragment.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetlist/FullAssetListFragment.kt index ca32bd90a..b9e72f3aa 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetlist/FullAssetListFragment.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetlist/FullAssetListFragment.kt @@ -110,6 +110,7 @@ class FullAssetListFragment : SoraBaseFragment() { title = "", navIcon = jp.co.soramitsu.ui_core.R.drawable.ic_cross_24, actionLabel = R.string.common_edit, + searchValue = "", ), type = SoramitsuToolbarType.Small(), ), @@ -117,7 +118,6 @@ class FullAssetListFragment : SoraBaseFragment() { elevation = 0.dp, onAction = viewModel::onAction, onNavigate = viewModel::onNavIcon, - searchInitial = "", onSearch = viewModel::searchAssets, ) val state = viewModel.state diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetsettings/FullAssetSettingsFragment.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetsettings/FullAssetSettingsFragment.kt index f3609473b..f2f385293 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetsettings/FullAssetSettingsFragment.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetsettings/FullAssetSettingsFragment.kt @@ -101,6 +101,7 @@ class FullAssetSettingsFragment : SoraBaseFragment() title = "", navIcon = jp.co.soramitsu.ui_core.R.drawable.ic_cross_24, actionLabel = R.string.common_done, + searchValue = "", ), type = SoramitsuToolbarType.Small(), ), @@ -108,7 +109,6 @@ class FullAssetSettingsFragment : SoraBaseFragment() elevation = 0.dp, onAction = viewModel::onCloseClick, onNavigate = viewModel::onCloseClick, - searchInitial = "", onSearch = { viewModel.searchAssets(it) itemTouchHelperCallback.isDraggable = it.isBlank() diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowFragment.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowFragment.kt index dc736d51c..44122ae93 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowFragment.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowFragment.kt @@ -39,19 +39,18 @@ import androidx.activity.result.ActivityResultLauncher import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.ScrollState import androidx.fragment.app.viewModels +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import com.google.accompanist.navigation.animation.composable import com.journeyapps.barcodescanner.ScanOptions import com.permissionx.guolindev.PermissionX import dagger.hilt.android.AndroidEntryPoint -import javax.inject.Inject import jp.co.soramitsu.androidfoundation.intent.ShareUtil import jp.co.soramitsu.common.R import jp.co.soramitsu.common.base.SoraBaseFragment import jp.co.soramitsu.common.domain.BottomBarController -import jp.co.soramitsu.common_wallet.presentation.compose.components.SelectSearchTokenScreen -import jp.co.soramitsu.core_di.viewmodel.CustomViewModelFactory +import jp.co.soramitsu.feature_assets_api.presentation.selectsearchtoken.SelectSearchTokenScreen import jp.co.soramitsu.feature_assets_impl.presentation.components.compose.receiverequest.QrCodeMainScreen import jp.co.soramitsu.feature_assets_impl.presentation.components.compose.receiverequest.RequestTokenConfirmScreen import jp.co.soramitsu.feature_assets_impl.presentation.screens.scan.QRCodeScannerActivity @@ -60,17 +59,7 @@ import jp.co.soramitsu.feature_assets_impl.presentation.screens.scan.ScanTextCon @AndroidEntryPoint class QRCodeFlowFragment : SoraBaseFragment() { - @Inject - lateinit var vmf: QRCodeFlowViewModel.AssistedQRCodeFlowViewModelFactory - - override val viewModel: QRCodeFlowViewModel by viewModels { - CustomViewModelFactory { - vmf.create( - isLaunchedFromSoraCard = requireArguments() - .getBoolean(IS_LAUNCHED_FROM_SORA_CARD) - ) - } - } + override val viewModel: QRCodeFlowViewModel by viewModels() private val barcodeScanOptions by lazy { ScanOptions() @@ -88,8 +77,8 @@ class QRCodeFlowFragment : SoraBaseFragment() { } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - (activity as BottomBarController).hideBottomBar() super.onViewCreated(view, savedInstanceState) + (activity as BottomBarController).hideBottomBar() parseFragmentArguments() @@ -120,10 +109,12 @@ class QRCodeFlowFragment : SoraBaseFragment() { navController: NavHostController ) { composable(route = QRCodeFlowRoute.MainScreen.route) { + val qrState = viewModel.receiveTokenByQrScreenState.collectAsStateWithLifecycle() + val screenState = viewModel.requestTokenScreenState.collectAsStateWithLifecycle() QrCodeMainScreen( scrollState = scrollState, - receiveTokenByQrScreenState = viewModel.receiveTokenScreenState, - requestTokenScreenState = viewModel.requestTokenByQrScreenState, + receiveTokenByQrScreenState = qrState.value, + requestTokenScreenState = screenState.value, receiveToken_onUserAddressClick = viewModel::onUserAddressClickInReceiveScreen, receiveToken_onScanQrClick = { PermissionX.init(this@QRCodeFlowFragment) @@ -141,49 +132,46 @@ class QRCodeFlowFragment : SoraBaseFragment() { requestToken_onTokenSelect = { navController.navigate(QRCodeFlowRoute.SelectToken.route) }, - requestToken_onFocusChange = viewModel::onFocusChange, requestToken_onCreateRequestClick = { viewModel.onLoadRequestConfirmScreenDataAgainClick() navController.navigate(QRCodeFlowRoute.ConfirmRequestByQRCode.route) }, - requestToken_onTryAgainClick = viewModel::onLoadRequestScreenDataClick + requestToken_onTryAgainClick = viewModel::onLoadRequestScreenDataClick, ) } composable(route = QRCodeFlowRoute.SelectToken.route) { + val filter = viewModel.selectTokenScreenState.collectAsStateWithLifecycle() SelectSearchTokenScreen( - state = viewModel.selectTokenScreenState, scrollState = scrollState, onAssetSelect = { viewModel.onSelectToken(it) navController.popBackStack() }, + filter = filter.value, ) } composable(route = QRCodeFlowRoute.ConfirmRequestByQRCode.route) { + val state = viewModel.requestTokenConfirmScreenState.collectAsStateWithLifecycle() RequestTokenConfirmScreen( scrollState = scrollState, - state = viewModel.requestTokenConfirmScreenState, + state = state.value, onUserAddressClick = viewModel::onUserAddressClickInRequestConfirmScreen, - onFocusChange = viewModel::onFocusChange, onShareCodeClick = viewModel::onShareQrCodeInRequestConfirmScreen, - onTryAgainClick = viewModel::onLoadRequestConfirmScreenDataAgainClick + onTryAgainClick = viewModel::onLoadRequestConfirmScreenDataAgainClick, ) } } companion object { - const val IS_LAUNCHED_FROM_SORA_CARD = "is_launched_from_sora_card" const val NAVIGATE_TO_SCANNER_DIRECTLY_KEY = "navigate_to_scanner_activity" fun createBundle( shouldNavigateToScanner: Boolean = false, - isLaunchedFromSoraCard: Boolean = false ) = Bundle().apply { putBoolean(NAVIGATE_TO_SCANNER_DIRECTLY_KEY, shouldNavigateToScanner) - putBoolean(IS_LAUNCHED_FROM_SORA_CARD, isLaunchedFromSoraCard) } } } diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt index a1f51bbc5..f688fb3cf 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt @@ -34,15 +34,11 @@ package jp.co.soramitsu.feature_assets_impl.presentation.screens.receiverequest import android.graphics.Bitmap import android.net.Uri -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue import androidx.lifecycle.LiveData import androidx.lifecycle.viewModelScope -import dagger.assisted.Assisted -import dagger.assisted.AssistedFactory -import dagger.assisted.AssistedInject +import dagger.hilt.android.lifecycle.HiltViewModel import java.math.BigDecimal +import javax.inject.Inject import jp.co.soramitsu.androidfoundation.phone.BasicClipboardManager import jp.co.soramitsu.common.R import jp.co.soramitsu.common.account.AccountAvatarGenerator @@ -58,8 +54,6 @@ import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.common.util.QrCodeGenerator import jp.co.soramitsu.common_wallet.domain.model.QrException -import jp.co.soramitsu.common_wallet.presentation.compose.components.SelectSearchAssetState -import jp.co.soramitsu.common_wallet.presentation.compose.states.mapAssetsToCardState import jp.co.soramitsu.common_wallet.presentation.compose.util.AmountFormat.getAssetBalanceText import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_assets_api.domain.QrCodeInteractor @@ -72,6 +66,8 @@ import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarState import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarType import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flowOn @@ -80,7 +76,8 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -class QRCodeFlowViewModel @AssistedInject constructor( +@HiltViewModel +class QRCodeFlowViewModel @Inject constructor( private val interactor: AssetsInteractor, private val qrCodeInteractor: QrCodeInteractor, private val coroutineManager: CoroutineManager, @@ -91,34 +88,20 @@ class QRCodeFlowViewModel @AssistedInject constructor( private val resourceManager: ResourceManager, private val fileManager: FileManager, private val walletRouter: WalletRouter, - @Assisted("IS_LAUNCHED_FROM_SORA_CARD") val isLaunchedFromSoraCard: Boolean ) : BaseViewModel() { - @AssistedFactory - interface AssistedQRCodeFlowViewModelFactory { - fun create( - @Assisted("IS_LAUNCHED_FROM_SORA_CARD") isLaunchedFromSoraCard: Boolean - ): QRCodeFlowViewModel - } - private var currentTokenId: String? = null - private val requestAmountCacheFlow = MutableSharedFlow( - replay = 1, - extraBufferCapacity = 0, - onBufferOverflow = BufferOverflow.DROP_OLDEST - ) - private val requestByQrScreenReloadMutableSharedFlow = MutableSharedFlow( replay = 1, extraBufferCapacity = 0, - onBufferOverflow = BufferOverflow.DROP_OLDEST + onBufferOverflow = BufferOverflow.DROP_OLDEST, ) private val _shareQrCodeLiveData = SingleLiveEvent>() val shareQrCodeEvent: LiveData> = _shareQrCodeLiveData - var receiveTokenScreenState by mutableStateOf( + private val _receiveTokenByQrScreenState = MutableStateFlow( ReceiveTokenByQrScreenState( screenStatus = ScreenStatus.LOADING, untransformedQrBitmap = null, @@ -127,28 +110,23 @@ class QRCodeFlowViewModel @AssistedInject constructor( untransformedUserAddress = null ) ) - private set + val receiveTokenByQrScreenState = _receiveTokenByQrScreenState.asStateFlow() - var requestTokenByQrScreenState by mutableStateOf( + private val _requestTokenScreenState = MutableStateFlow( RequestTokenScreenState( screenStatus = ScreenStatus.LOADING, untransformedUserName = null, untransformedAvatarDrawable = null, untransformedUserAddress = null, - assetAmountInputState = null + assetAmountInputState = null, ) ) - private set + val requestTokenScreenState = _requestTokenScreenState.asStateFlow() - var selectTokenScreenState by mutableStateOf( - SelectSearchAssetState( - filter = "", - fullList = emptyList() - ) - ) - private set + private val _selectTokenScreenState = MutableStateFlow("") + val selectTokenScreenState = _selectTokenScreenState.asStateFlow() - var requestTokenConfirmScreenState by mutableStateOf( + private val _requestTokenConfirmScreenState = MutableStateFlow( RequestTokenConfirmScreenState( screenStatus = ScreenStatus.LOADING, untransformedQrBitmap = null, @@ -158,17 +136,10 @@ class QRCodeFlowViewModel @AssistedInject constructor( assetAmountInputState = null ) ) - private set + val requestTokenConfirmScreenState = _requestTokenConfirmScreenState.asStateFlow() private val loadRequestByQrScreenDataFlowJob = interactor.subscribeAssetsActiveOfCurAccount() - .onEach { - selectTokenScreenState = selectTokenScreenState.copy( - fullList = mapAssetsToCardState( - assets = it, - nf = numbersFormatter - ) - ) - }.combine(requestByQrScreenReloadMutableSharedFlow) { assets, _ -> + .combine(requestByQrScreenReloadMutableSharedFlow) { assets, _ -> val assetInUse = currentTokenId?.let { tokenID -> assets.find { it.token.id == tokenID } } ?: assets.first() @@ -177,35 +148,42 @@ class QRCodeFlowViewModel @AssistedInject constructor( accountName to substrateAddress } - requestTokenByQrScreenState = requestTokenByQrScreenState.copy( + _requestTokenScreenState.value = _requestTokenScreenState.value.copy( untransformedUserName = userName, untransformedAvatarDrawable = avatarGenerator.createAvatar( address = userAddress, - sizeInDp = AVATAR_SIZE_IN_DP + sizeInDp = AVATAR_SIZE_IN_DP, ), untransformedUserAddress = userAddress, - assetAmountInputState = AssetAmountInputState( + assetAmountInputState = if (_requestTokenScreenState.value.assetAmountInputState == null) AssetAmountInputState( token = assetInUse.token, balance = getAssetBalanceText( asset = assetInUse, nf = numbersFormatter, - precision = DEFAULT_TOKEN_PRINT_PRECISION + precision = DEFAULT_TOKEN_PRINT_PRECISION, ), amount = BigDecimal.ZERO, initialAmount = null, amountFiat = "", enabled = false, - ) + ) else _requestTokenScreenState.value.assetAmountInputState!!.copy( + token = assetInUse.token, + balance = getAssetBalanceText( + asset = assetInUse, + nf = numbersFormatter, + precision = DEFAULT_TOKEN_PRINT_PRECISION, + ), + ), ) }.catch { onError(it) - requestTokenByQrScreenState = - requestTokenByQrScreenState.copy( + _requestTokenScreenState.value = + _requestTokenScreenState.value.copy( screenStatus = ScreenStatus.ERROR ) }.onEach { - requestTokenByQrScreenState = - requestTokenByQrScreenState.copy( + _requestTokenScreenState.value = + _requestTokenScreenState.value.copy( screenStatus = ScreenStatus.READY_TO_RENDER, ) }.flowOn(coroutineManager.io) @@ -225,6 +203,10 @@ class QRCodeFlowViewModel @AssistedInject constructor( override fun startScreen(): String = QRCodeFlowRoute.MainScreen.route + override fun onToolbarSearch(value: String) { + _selectTokenScreenState.value = value + } + override fun onCurrentDestinationChanged(curDest: String) { _toolbarState.value?.let { state -> _toolbarState.value = state.copy( @@ -236,6 +218,8 @@ class QRCodeFlowViewModel @AssistedInject constructor( QRCodeFlowRoute.ConfirmRequestByQRCode.route -> R.string.receive_tokens else -> "" }, + searchEnabled = curDest == QRCodeFlowRoute.SelectToken.route, + searchValue = if (curDest == QRCodeFlowRoute.SelectToken.route) _selectTokenScreenState.value else "", ) ) } @@ -246,16 +230,14 @@ class QRCodeFlowViewModel @AssistedInject constructor( loadRequestByQrScreenDataFlowJob.cancel() } - /* Receive Token Screen Begin */ - fun onUserAddressClickInReceiveScreen() { - receiveTokenScreenState.untransformedUserAddress?.let { + _receiveTokenByQrScreenState.value.untransformedUserAddress?.let { clipboardManager.addToClipboard(it) } } fun onShareQrCodeInReceiveScreen() = - with(receiveTokenScreenState) { + with(_receiveTokenByQrScreenState.value) { if (untransformedQrBitmap == null || untransformedUserAddress == null) return@with @@ -296,52 +278,35 @@ class QRCodeFlowViewModel @AssistedInject constructor( loadReceiveByQrCodeScreenData() } - /* Receive Token Screen End */ - - /* Request Token Screen Begin */ - fun onRequestAmountChange(amount: BigDecimal) { - requestTokenByQrScreenState = requestTokenByQrScreenState.copy( - assetAmountInputState = requestTokenByQrScreenState.assetAmountInputState?.copy( + _requestTokenScreenState.value = _requestTokenScreenState.value.copy( + assetAmountInputState = _requestTokenScreenState.value.assetAmountInputState?.copy( amount = amount, - amountFiat = requestTokenByQrScreenState.assetAmountInputState?.token?.printFiat( + amountFiat = _requestTokenScreenState.value.assetAmountInputState?.token?.printFiat( amount, numbersFormatter ).orEmpty() ) ) - requestAmountCacheFlow.tryEmit(amount) - } - - fun onFocusChange(boolean: Boolean) { - // Do nothing } fun onLoadRequestScreenDataClick() { requestByQrScreenReloadMutableSharedFlow.tryEmit(Unit) } - /* Request Token Screen End */ - - /* Select Token Screen Begin */ - fun onSelectToken(tokenId: String) { currentTokenId = tokenId requestByQrScreenReloadMutableSharedFlow.tryEmit(Unit) } - /* Select Token Screen End */ - - /* Request Token Confirm Screen Begin */ - fun onUserAddressClickInRequestConfirmScreen() { - requestTokenByQrScreenState.untransformedUserAddress?.let { + _requestTokenScreenState.value.untransformedUserAddress?.let { clipboardManager.addToClipboard(it) } } fun onShareQrCodeInRequestConfirmScreen() = - with(requestTokenConfirmScreenState) { + with(_requestTokenConfirmScreenState.value) { if (untransformedQrBitmap == null || untransformedUserAddress == null || assetAmountInputState?.token == null @@ -365,8 +330,6 @@ class QRCodeFlowViewModel @AssistedInject constructor( loadRequestConfirmScreenData() } - /* Request Token Confirm Screen End */ - private fun generateMessageForUser( tokenSymbol: String, userAddress: String @@ -391,7 +354,7 @@ class QRCodeFlowViewModel @AssistedInject constructor( userName = userName ) - receiveTokenScreenState = receiveTokenScreenState.copy( + _receiveTokenByQrScreenState.value = _receiveTokenByQrScreenState.value.copy( screenStatus = ScreenStatus.READY_TO_RENDER, untransformedUserName = userName, untransformedAvatarDrawable = avatarGenerator.createAvatar(userAddress, AVATAR_SIZE_IN_DP), @@ -400,7 +363,7 @@ class QRCodeFlowViewModel @AssistedInject constructor( ) } catch (e: Exception) { onError(e) - receiveTokenScreenState = receiveTokenScreenState.copy( + _receiveTokenByQrScreenState.value = _receiveTokenByQrScreenState.value.copy( screenStatus = ScreenStatus.ERROR, ) } @@ -412,8 +375,16 @@ class QRCodeFlowViewModel @AssistedInject constructor( try { val userPublicKey = interactor.getPublicKeyHex(true) + _requestTokenScreenState.value.assetAmountInputState?.let { assetAmountInputState -> + _requestTokenScreenState.value = _requestTokenScreenState.value.copy( + assetAmountInputState = assetAmountInputState.copy( + initialAmount = assetAmountInputState.amount, + ) + ) + } + val untransformedQrBitmap = - requestTokenByQrScreenState.run { + _requestTokenScreenState.value.run { if (untransformedUserName == null || untransformedUserAddress == null) return@run null @@ -424,34 +395,34 @@ class QRCodeFlowViewModel @AssistedInject constructor( userAddress = untransformedUserAddress, userPublicKey = userPublicKey, userName = untransformedUserName, - tokenId = requestTokenByQrScreenState.assetAmountInputState + tokenId = _requestTokenScreenState.value.assetAmountInputState ?.token?.id, - amount = requestTokenByQrScreenState.assetAmountInputState + amount = _requestTokenScreenState.value.assetAmountInputState ?.amount.toString() ) ) } - requestTokenConfirmScreenState = requestTokenConfirmScreenState.copy( + _requestTokenConfirmScreenState.value = _requestTokenConfirmScreenState.value.copy( screenStatus = ScreenStatus.READY_TO_RENDER, untransformedQrBitmap = untransformedQrBitmap, - untransformedUserName = requestTokenByQrScreenState + untransformedUserName = _requestTokenScreenState.value .untransformedUserName, - untransformedAvatarDrawable = requestTokenByQrScreenState + untransformedAvatarDrawable = _requestTokenScreenState.value .untransformedAvatarDrawable, - untransformedUserAddress = requestTokenByQrScreenState + untransformedUserAddress = _requestTokenScreenState.value .untransformedUserAddress, - assetAmountInputState = requestTokenByQrScreenState + assetAmountInputState = _requestTokenScreenState.value .assetAmountInputState?.copy( - initialAmount = requestTokenByQrScreenState + initialAmount = _requestTokenScreenState.value .assetAmountInputState?.amount, enabled = false, - readOnly = true + readOnly = true, ) ) } catch (e: Exception) { onError(e) - requestTokenConfirmScreenState = requestTokenConfirmScreenState.copy( + _requestTokenConfirmScreenState.value = _requestTokenConfirmScreenState.value.copy( screenStatus = ScreenStatus.ERROR, ) } diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountFragment.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountFragment.kt index 2fb3658ff..2fa065135 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountFragment.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountFragment.kt @@ -45,6 +45,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.fragment.app.viewModels +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import com.google.accompanist.navigation.animation.composable @@ -55,8 +56,8 @@ import jp.co.soramitsu.common.base.SoraBaseFragment import jp.co.soramitsu.common.domain.BottomBarController import jp.co.soramitsu.common.presentation.compose.components.PercentContainer import jp.co.soramitsu.common.presentation.view.ToastDialog -import jp.co.soramitsu.common_wallet.presentation.compose.components.SelectSearchTokenScreen import jp.co.soramitsu.core_di.viewmodel.CustomViewModelFactory +import jp.co.soramitsu.feature_assets_api.presentation.selectsearchtoken.SelectSearchTokenScreen import jp.co.soramitsu.feature_assets_impl.presentation.components.compose.send.SendConfirmScreen import jp.co.soramitsu.feature_assets_impl.presentation.components.compose.send.SendScreen import jp.co.soramitsu.ui_core.resources.Dimens @@ -110,7 +111,7 @@ class TransferAmountFragment : SoraBaseFragment() { .fillMaxSize() .padding(horizontal = Dimens.x2) ) { - val state = viewModel.sendState + val state = viewModel.sendState.collectAsStateWithLifecycle().value SendConfirmScreen( address = state.address, icon = state.icon, @@ -126,10 +127,11 @@ class TransferAmountFragment : SoraBaseFragment() { } } composable(SendRoutes.selectToken) { + val state = viewModel.sendState.collectAsStateWithLifecycle().value SelectSearchTokenScreen( - state = viewModel.sendState.selectSearchAssetState, scrollState = scrollState, onAssetSelect = onTokenChange, + filter = state.searchFilter, ) } composable( @@ -158,7 +160,7 @@ class TransferAmountFragment : SoraBaseFragment() { .padding(top = Dimens.x1) .fillMaxSize() ) { - val state = viewModel.sendState + val state = viewModel.sendState.collectAsStateWithLifecycle().value SendScreen( address = state.address, icon = state.icon, diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt index 066b4294c..7b60699fe 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt @@ -32,9 +32,6 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_assets_impl.presentation.screens.send -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue import androidx.lifecycle.LiveData import androidx.lifecycle.viewModelScope import dagger.assisted.Assisted @@ -59,7 +56,6 @@ import jp.co.soramitsu.common.util.ext.isZero import jp.co.soramitsu.common.util.ext.nullZero import jp.co.soramitsu.common.util.ext.orZero import jp.co.soramitsu.common.view.ViewHelper -import jp.co.soramitsu.common_wallet.presentation.compose.states.mapAssetsToCardState import jp.co.soramitsu.common_wallet.presentation.compose.util.PolkaswapFormulas import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter @@ -67,6 +63,7 @@ import jp.co.soramitsu.feature_assets_impl.presentation.states.SendState import jp.co.soramitsu.feature_wallet_api.launcher.WalletRouter import jp.co.soramitsu.sora.substrate.runtime.SubstrateOptionsProvider import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collectLatest @@ -110,12 +107,13 @@ class TransferAmountViewModel @AssistedInject constructor( private var curTokenId: String = assetId private var hasXorReminderWarningBeenChecked = false - internal var sendState by mutableStateOf( + private val _sendState = MutableStateFlow( SendState( address = recipientId, icon = avatarGenerator.createAvatar(recipientId, 40), ) ) + internal val sendState = _sendState.asStateFlow() override fun startScreen(): String = SendRoutes.start @@ -129,11 +127,6 @@ class TransferAmountViewModel @AssistedInject constructor( .collectLatest { list -> assetsList.clear() assetsList.addAll(list) - sendState = sendState.copy( - selectSearchAssetState = sendState.selectSearchAssetState.copy( - fullList = mapAssetsToCardState(list, numbersFormatter) - ) - ) updateCurAsset() feeAsset = list.find { it.token.id == SubstrateOptionsProvider.feeAssetId } ?.also { asset -> @@ -141,7 +134,7 @@ class TransferAmountViewModel @AssistedInject constructor( calcTransactionFee(asset) } } - sendState.input?.amount?.let { + _sendState.value.input?.amount?.let { checkEnteredAmount(it) } } @@ -153,7 +146,7 @@ class TransferAmountViewModel @AssistedInject constructor( .onEach { amount -> checkEnteredAmount(amount) }.filter { - sendState.input?.token?.id == SubstrateOptionsProvider.feeAssetId || + _sendState.value.input?.token?.id == SubstrateOptionsProvider.feeAssetId || !hasXorReminderWarningBeenChecked }.onEach { updateTransactionReminderWarningVisibility() @@ -164,8 +157,8 @@ class TransferAmountViewModel @AssistedInject constructor( private fun updateCurAsset() { curAsset = assetsList.find { it.token.id == curTokenId }?.also { asset -> - if (sendState.input == null) { - sendState = sendState.copy( + if (_sendState.value.input == null) { + _sendState.value = _sendState.value.copy( input = AssetAmountInputState( token = asset.token, balance = getAssetBalanceText(asset), @@ -178,12 +171,12 @@ class TransferAmountViewModel @AssistedInject constructor( ) ) } else { - sendState = sendState.copy( - input = sendState.input?.copy( + _sendState.value = _sendState.value.copy( + input = _sendState.value.input?.copy( token = asset.token, balance = getAssetBalanceText(asset), amountFiat = asset.token.printFiat( - sendState.input?.amount.orZero(), + _sendState.value.input?.amount.orZero(), numbersFormatter ), ) @@ -193,7 +186,7 @@ class TransferAmountViewModel @AssistedInject constructor( } private suspend fun updateTransactionReminderWarningVisibility() = - with(sendState.input) { + with(_sendState.value.input) { if (this == null) return@with @@ -202,7 +195,7 @@ class TransferAmountViewModel @AssistedInject constructor( xorChange = if (token.id == SubstrateOptionsProvider.feeAssetId) amount else null, ) - sendState = sendState.copy( + _sendState.value = _sendState.value.copy( shouldTransactionReminderInsufficientWarningBeShown = result, ) } @@ -210,12 +203,18 @@ class TransferAmountViewModel @AssistedInject constructor( fun onTokenChange(tokenId: String) { curTokenId = tokenId updateCurAsset() - sendState.input?.amount?.let { + _sendState.value.input?.amount?.let { checkEnteredAmount(it) } hasXorReminderWarningBeenChecked = false } + override fun onToolbarSearch(value: String) { + _sendState.value = _sendState.value.copy( + searchFilter = value, + ) + } + override fun onCurrentDestinationChanged(curDest: String) { _toolbarState.value?.let { state -> when (currentDestination) { @@ -223,12 +222,13 @@ class TransferAmountViewModel @AssistedInject constructor( _toolbarState.value = state.copy( basic = state.basic.copy( title = R.string.common_enter_amount, + searchEnabled = false, ) ) - sendState = sendState.copy( - input = sendState.input?.copy( + _sendState.value = _sendState.value.copy( + input = _sendState.value.input?.copy( readOnly = false, - initialAmount = sendState.input?.amount?.nullZero() + initialAmount = _sendState.value.input?.amount?.nullZero() ), ) } @@ -237,6 +237,8 @@ class TransferAmountViewModel @AssistedInject constructor( _toolbarState.value = state.copy( basic = state.basic.copy( title = R.string.choose_token, + searchEnabled = true, + searchValue = _sendState.value.searchFilter, ) ) } @@ -245,10 +247,11 @@ class TransferAmountViewModel @AssistedInject constructor( _toolbarState.value = state.copy( basic = state.basic.copy( title = R.string.confirm_sending, + searchEnabled = false, ) ) - sendState = sendState.copy( - input = sendState.input?.copy( + _sendState.value = _sendState.value.copy( + input = _sendState.value.input?.copy( readOnly = true, ), ) @@ -271,11 +274,11 @@ class TransferAmountViewModel @AssistedInject constructor( recipientId, feeAsset.token, BigDecimal.ONE, ).also { if (it != null) { - sendState = sendState.copy( + _sendState.value = _sendState.value.copy( feeLoading = false, fee = feeAsset.token.printBalance(it, numbersFormatter, AssetHolder.ROUNDING), feeFiat = feeAsset.token.printFiat(it, numbersFormatter), - input = sendState.input?.copy( + input = _sendState.value.input?.copy( enabled = true, ), ) @@ -290,10 +293,10 @@ class TransferAmountViewModel @AssistedInject constructor( fun onConfirmClick() { val curAsset = curAsset ?: return - val amount = sendState.input?.amount ?: return + val amount = _sendState.value.input?.amount ?: return val fee = fee ?: return viewModelScope.launch { - sendState = sendState.copy( + _sendState.value = _sendState.value.copy( inProgress = true ) var success = "" @@ -308,7 +311,7 @@ class TransferAmountViewModel @AssistedInject constructor( } catch (t: Throwable) { onError(t) } finally { - sendState = sendState.copy( + _sendState.value = _sendState.value.copy( inProgress = false ) if (success.isNotEmpty()) @@ -324,8 +327,8 @@ class TransferAmountViewModel @AssistedInject constructor( val curAsset = curAsset ?: return when { amount.isZero() -> { - sendState = sendState.copy( - input = sendState.input?.copy( + _sendState.value = _sendState.value.copy( + input = _sendState.value.input?.copy( error = false, errorHint = "", ), @@ -334,8 +337,8 @@ class TransferAmountViewModel @AssistedInject constructor( } feeAsset.balance.transferable < fee -> { - sendState = sendState.copy( - input = sendState.input?.copy( + _sendState.value = _sendState.value.copy( + input = _sendState.value.input?.copy( error = true, errorHint = resourceManager.getString(R.string.error_transaction_fee_title), ), @@ -344,8 +347,8 @@ class TransferAmountViewModel @AssistedInject constructor( } curAsset.balance.transferable < amount -> { - sendState = sendState.copy( - input = sendState.input?.copy( + _sendState.value = _sendState.value.copy( + input = _sendState.value.input?.copy( error = true, errorHint = resourceManager.getString(R.string.amount_error_no_funds), ), @@ -354,8 +357,8 @@ class TransferAmountViewModel @AssistedInject constructor( } (curAsset.token.id == feeAsset.token.id) && (curAsset.balance.transferable < amount + fee) -> { - sendState = sendState.copy( - input = sendState.input?.copy( + _sendState.value = _sendState.value.copy( + input = _sendState.value.input?.copy( error = true, errorHint = resourceManager.getString(R.string.amount_error_no_funds), ), @@ -364,8 +367,8 @@ class TransferAmountViewModel @AssistedInject constructor( } (curAsset.token.id == feeAsset.token.id) && (curAsset.balance.transferable - amount - fee < SubstrateOptionsProvider.existentialDeposit.toBigDecimal()) -> { - sendState = sendState.copy( - input = sendState.input?.copy( + _sendState.value = _sendState.value.copy( + input = _sendState.value.input?.copy( error = true, errorHint = resourceManager.getString(R.string.wallet_send_existential_warning_message), ), @@ -374,8 +377,8 @@ class TransferAmountViewModel @AssistedInject constructor( } else -> { - sendState = sendState.copy( - input = sendState.input?.copy( + _sendState.value = _sendState.value.copy( + input = _sendState.value.input?.copy( error = false, errorHint = "", ), @@ -386,18 +389,18 @@ class TransferAmountViewModel @AssistedInject constructor( } fun onReviewClick() { - sendState = sendState.copy( - input = sendState.input?.copy( - initialAmount = sendState.input?.amount.orZero() + _sendState.value = _sendState.value.copy( + input = _sendState.value.input?.copy( + initialAmount = _sendState.value.input?.amount.orZero() ) ) } fun amountChanged(value: BigDecimal) { - sendState = sendState.copy( - input = sendState.input?.copy( + _sendState.value = _sendState.value.copy( + input = _sendState.value.input?.copy( amount = value, - amountFiat = sendState.input?.token?.printFiat( + amountFiat = _sendState.value.input?.token?.printFiat( value, numbersFormatter ).orEmpty() @@ -417,11 +420,11 @@ class TransferAmountViewModel @AssistedInject constructor( if (curAsset.token.id == SubstrateOptionsProvider.feeAssetId && amount > BigDecimal.ZERO) { amount = subtractFee(amount, curAsset.balance.transferable, fee) } - sendState = sendState.copy( - input = sendState.input?.copy( + _sendState.value = _sendState.value.copy( + input = _sendState.value.input?.copy( amount = amount, initialAmount = amount, - amountFiat = sendState.input?.token?.printFiat( + amountFiat = _sendState.value.input?.token?.printFiat( amount, numbersFormatter ).orEmpty() diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/states/SendState.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/states/SendState.kt index 327156007..6ad771af9 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/states/SendState.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/states/SendState.kt @@ -34,7 +34,6 @@ package jp.co.soramitsu.feature_assets_impl.presentation.states import android.graphics.drawable.Drawable import jp.co.soramitsu.common.domain.AssetAmountInputState -import jp.co.soramitsu.common_wallet.presentation.compose.components.SelectSearchAssetState internal data class SendState( val address: String, @@ -45,6 +44,6 @@ internal data class SendState( val fee: String = "", val feeFiat: String = "", val feeLoading: Boolean = true, - val selectSearchAssetState: SelectSearchAssetState = SelectSearchAssetState("", emptyList()), + val searchFilter: String = "", val shouldTransactionReminderInsufficientWarningBeShown: Boolean = false, ) diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt index 7876393cc..e5edd7981 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/qr/QrCodeFlowViewModelTest.kt @@ -150,7 +150,6 @@ class QrCodeFlowViewModelTest { resourceManager = resourceManager, fileManager = fileManager, walletRouter = walletRouter, - isLaunchedFromSoraCard = false, ) } @@ -161,33 +160,33 @@ class QrCodeFlowViewModelTest { viewModel.onLoadRequestConfirmScreenDataAgainClick() advanceUntilIdle() Assert.assertEquals( - viewModel.requestTokenByQrScreenState.recipientAddressHeader, - viewModel.requestTokenConfirmScreenState.userAddressTitle + viewModel.requestTokenScreenState.value.recipientAddressHeader, + viewModel.requestTokenConfirmScreenState.value.userAddressTitle ) Assert.assertEquals( - viewModel.requestTokenByQrScreenState.recipientAddressBody, - viewModel.requestTokenConfirmScreenState.userAddressBody + viewModel.requestTokenScreenState.value.recipientAddressBody, + viewModel.requestTokenConfirmScreenState.value.userAddressBody ) Assert.assertEquals( - viewModel.requestTokenByQrScreenState.assetAmountInputState?.token?.id, - viewModel.requestTokenConfirmScreenState.assetAmountInputState?.token?.id + viewModel.requestTokenScreenState.value.assetAmountInputState?.token?.id, + viewModel.requestTokenConfirmScreenState.value.assetAmountInputState?.token?.id ) Assert.assertEquals( - viewModel.requestTokenByQrScreenState.assetAmountInputState?.amount, - viewModel.requestTokenConfirmScreenState.assetAmountInputState?.amount + viewModel.requestTokenScreenState.value.assetAmountInputState?.amount, + viewModel.requestTokenConfirmScreenState.value.assetAmountInputState?.amount ) Assert.assertEquals( - viewModel.requestTokenByQrScreenState.assetAmountInputState?.amountFiat, - viewModel.requestTokenConfirmScreenState.assetAmountInputState?.amountFiat + viewModel.requestTokenScreenState.value.assetAmountInputState?.amountFiat, + viewModel.requestTokenConfirmScreenState.value.assetAmountInputState?.amountFiat ) Assert.assertEquals( - viewModel.requestTokenByQrScreenState.assetAmountInputState?.amount, - viewModel.requestTokenConfirmScreenState.assetAmountInputState?.initialAmount + viewModel.requestTokenScreenState.value.assetAmountInputState?.amount, + viewModel.requestTokenConfirmScreenState.value.assetAmountInputState?.initialAmount ) } @@ -212,7 +211,7 @@ class QrCodeFlowViewModelTest { advanceUntilIdle() Assert.assertEquals( assetInUse.token.id, - viewModel.requestTokenByQrScreenState.assetAmountInputState?.token?.id + viewModel.requestTokenScreenState.value.assetAmountInputState?.token?.id ) } diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt index 67f8c50b1..e577df282 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/send/TransferAmountViewModelTest.kt @@ -143,7 +143,7 @@ class TransferAmountViewModelTest { val state = transferAmountViewModel.sendState assertEquals( "recipientIdrecipientIdrecipientIdrecipientIdrecipientIdrecipientIdrecipientId", - state.address + state.value.address ) } @@ -154,7 +154,7 @@ class TransferAmountViewModelTest { transferAmountViewModel.optionSelected(75) advanceUntilIdle() val state = transferAmountViewModel.sendState - assertTrue(state.input?.amount?.equalTo(BigDecimal.valueOf(3)) == true) + assertTrue(state.value.input?.amount?.equalTo(BigDecimal.valueOf(3)) == true) } @Test @@ -164,7 +164,7 @@ class TransferAmountViewModelTest { transferAmountViewModel.optionSelected(75) advanceUntilIdle() val state = transferAmountViewModel.sendState - assertTrue(state.input?.amount?.equalTo(BigDecimal.valueOf(0.000075)) == true) + assertTrue(state.value.input?.amount?.equalTo(BigDecimal.valueOf(0.000075)) == true) } private fun initViewModel( diff --git a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allcurrencies/AllCurrenciesScreen.kt b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allcurrencies/AllCurrenciesScreen.kt index 505f405d9..60ddbebd0 100644 --- a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allcurrencies/AllCurrenciesScreen.kt +++ b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allcurrencies/AllCurrenciesScreen.kt @@ -86,12 +86,12 @@ private fun ColumnScope.AllCurrenciesInternal( basic = BasicToolbarState( title = R.string.common_currencies, navIcon = jp.co.soramitsu.ui_core.R.drawable.ic_arrow_left, + searchValue = state.filter, ), type = SoramitsuToolbarType.Small(), ), elevation = 0.dp, onNavigate = onNavIconClicked, - searchInitial = state.filter, onSearch = onSearch, ) ContentCardEndless( diff --git a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allpools/AllPoolsScreen.kt b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allpools/AllPoolsScreen.kt index 08c0f020e..19e89c684 100644 --- a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allpools/AllPoolsScreen.kt +++ b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allpools/AllPoolsScreen.kt @@ -92,12 +92,12 @@ private fun ColumnScope.AllPoolsInternal( title = R.string.discovery_polkaswap_pools, menu = listOf(Action.Plus()), navIcon = jp.co.soramitsu.ui_core.R.drawable.ic_arrow_left, + searchValue = state.filter, ), type = SoramitsuToolbarType.Small(), ), elevation = 0.dp, onNavigate = onNavIconClicked, - searchInitial = state.filter, onSearch = onSearch, onMenuItemClicked = { onPoolPlus.invoke() }, ) diff --git a/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/presentation/profile/ProfileViewModel.kt b/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/presentation/profile/ProfileViewModel.kt index 3d7ce44de..68e211af9 100644 --- a/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/presentation/profile/ProfileViewModel.kt +++ b/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/presentation/profile/ProfileViewModel.kt @@ -181,7 +181,7 @@ class ProfileViewModel @Inject constructor( when (soraCardResult) { is SoraCardResult.NavigateTo -> { when (soraCardResult.screen) { - OutwardsScreen.DEPOSIT -> walletRouter.openQrCodeFlow(isLaunchedFromSoraCard = true) + OutwardsScreen.DEPOSIT -> walletRouter.openQrCodeFlow() OutwardsScreen.SWAP -> polkaswapRouter.showSwap(tokenToId = SubstrateOptionsProvider.feeAssetId) OutwardsScreen.BUY -> assetsRouter.showBuyCrypto() } diff --git a/feature_polkaswap_api/src/main/java/jp/co/soramitsu/feature_polkaswap_api/domain/model/SwapDetails.kt b/feature_polkaswap_api/src/main/java/jp/co/soramitsu/feature_polkaswap_api/domain/model/SwapDetails.kt index 1c30739cd..29600ebf8 100644 --- a/feature_polkaswap_api/src/main/java/jp/co/soramitsu/feature_polkaswap_api/domain/model/SwapDetails.kt +++ b/feature_polkaswap_api/src/main/java/jp/co/soramitsu/feature_polkaswap_api/domain/model/SwapDetails.kt @@ -44,11 +44,8 @@ data class SwapDetails( val networkFee: BigDecimal, val dex: PoolDex, val swapRoute: List? = null, - val feeMode: SwapFeeMode, ) -enum class SwapFeeMode { SYNTHETIC, NON_SYNTHETIC, BOTH } - data class SwapQuote( val amount: BigDecimal, val fee: BigDecimal, diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/data/repository/PolkaswapSubscriptionRepositoryImpl.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/data/repository/PolkaswapSubscriptionRepositoryImpl.kt index 1c3dff0b1..a33cba885 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/data/repository/PolkaswapSubscriptionRepositoryImpl.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/data/repository/PolkaswapSubscriptionRepositoryImpl.kt @@ -36,6 +36,7 @@ import androidx.room.withTransaction import java.math.BigDecimal import java.math.BigInteger import javax.inject.Inject +import jp.co.soramitsu.common.data.network.dto.SwapFeeDto import jp.co.soramitsu.common.domain.Market import jp.co.soramitsu.common.domain.Token import jp.co.soramitsu.common.logger.FirebaseWrapper @@ -65,6 +66,7 @@ import jp.co.soramitsu.shared_utils.wsrpc.executeAsync import jp.co.soramitsu.shared_utils.wsrpc.mappers.nonNull import jp.co.soramitsu.shared_utils.wsrpc.mappers.pojo import jp.co.soramitsu.shared_utils.wsrpc.mappers.pojoList +import jp.co.soramitsu.shared_utils.wsrpc.request.runtime.RuntimeRequest import jp.co.soramitsu.shared_utils.wsrpc.request.runtime.storage.GetStorageRequest import jp.co.soramitsu.sora.substrate.request.StateKeys import jp.co.soramitsu.sora.substrate.runtime.Pallete @@ -259,15 +261,22 @@ class PolkaswapSubscriptionRepositoryImpl @Inject constructor( feeToken: Token, dexId: Int, ): SwapQuote? { - return wsConnection.getSwapFees( - tokenId1, - tokenId2, - mapBalance(amount, feeToken.precision), - swapVariant.backString, - marketMapper.mapMarketsToStrings(markets), - marketMapper.mapMarketsToFilter(markets), - dexId, - )?.let { + val response = socketService.executeAsync( + request = RuntimeRequest( + "liquidityProxy_quote", + listOf( + dexId, + tokenId1, + tokenId2, + mapBalance(amount, feeToken.precision).toString(), + swapVariant.backString, + marketMapper.mapMarketsToStrings(markets), + marketMapper.mapMarketsToFilter(markets), + ) + ), + mapper = pojo(), + ).result + return response?.let { SwapQuote( mapBalance(it.amount, feeToken.precision), mapBalance(it.fee, feeToken.precision), diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt index 011ed6d7b..9eeba9a81 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/domain/SwapInteractorImpl.kt @@ -52,19 +52,13 @@ import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PolkaswapReposito import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PolkaswapSubscriptionRepository import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.SwapInteractor import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapDetails -import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapFeeMode -import jp.co.soramitsu.sora.substrate.runtime.SubstrateOptionsProvider -import jp.co.soramitsu.sora.substrate.runtime.isSynthetic import kotlin.math.max import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.debounce -import kotlinx.coroutines.flow.filterNotNull -import kotlinx.coroutines.flow.flatMapLatest -import kotlinx.coroutines.flow.merge +import kotlinx.coroutines.flow.flow @ExperimentalCoroutinesApi class SwapInteractorImpl( @@ -154,22 +148,9 @@ class SwapInteractorImpl( swapQuote.first.route?.mapNotNull { assetsRepository.getToken(it)?.symbol }, - getFeeMode(swapQuote.first.route), ) } - private fun getFeeMode(ids: List?): SwapFeeMode { - fun String.isExtraSynthetic() = this.isSynthetic() || this == SubstrateOptionsProvider.xstusdTokenId - return when { - ids == null -> SwapFeeMode.NON_SYNTHETIC - ids.all { - it.isExtraSynthetic() || it == SubstrateOptionsProvider.xstTokenId - } -> SwapFeeMode.SYNTHETIC - ids.all { it.isExtraSynthetic().not() } -> SwapFeeMode.NON_SYNTHETIC - else -> SwapFeeMode.BOTH - } - } - override fun setSwapMarket(market: Market) { selectedSwapMarket.value = market } @@ -203,62 +184,69 @@ class SwapInteractorImpl( override fun observeSwap(): Flow = swapResult.observe() - override fun observePoolReserves(): Flow { - return poolReservesFlowToken.asStateFlow().filterNotNull() - .combine(selectedSwapMarket.asStateFlow().filterNotNull()) { tokens, market -> - tokens to market - }.flatMapLatest { - val flows = mutableListOf>() - if (it.second == Market.XYK || it.second == Market.SMART) { - val tfrom = it.first.first - val tto = it.first.second - val dexs = getPoolDexList() - if (!dexs.hasToken(tfrom) && !dexs.hasToken(tto)) { - dexs.forEach { dex -> - flows.add( - polkaswapSubscriptionRepository.observePoolXYKReserves(dex.tokenId, tfrom) - ) - flows.add( - polkaswapSubscriptionRepository.observePoolXYKReserves(dex.tokenId, tto) - ) - } - } else if (dexs.hasToken(tfrom) && dexs.hasToken(tto)) { - flows.add( - polkaswapSubscriptionRepository.observePoolXYKReserves(tto, tfrom) - ) - flows.add( - polkaswapSubscriptionRepository.observePoolXYKReserves(tfrom, tto) - ) - } else { - val (inDex, inNot) = if (dexs.hasToken(tfrom)) tfrom to tto else tto to tfrom - flows.add( - polkaswapSubscriptionRepository.observePoolXYKReserves(inDex, inNot) - ) - dexs.filter { dex -> - dex.tokenId != inDex - }.forEach { dex -> - flows.add( - polkaswapSubscriptionRepository.observePoolXYKReserves(dex.tokenId, inDex) - ) - flows.add( - polkaswapSubscriptionRepository.observePoolXYKReserves(dex.tokenId, inNot) - ) - } - } - flows.add( - polkaswapSubscriptionRepository.observePoolXYKReserves( - it.first.first, - it.first.second - ) - ) - } - if (it.second == Market.TBC || it.second == Market.SMART) { - flows.add(polkaswapSubscriptionRepository.observePoolTBCReserves(it.first.first)) - } - flows.merge() - }.debounce(500) + override fun observePoolReserves(): Flow = flow { + while (true) { + emit("observePoolReserves") + delay(5000) + } } +// override fun observePoolReserves(): Flow { +// return poolReservesFlowToken.asStateFlow().filterNotNull() +// .combine(selectedSwapMarket.asStateFlow().filterNotNull()) { tokens, market -> +// tokens to market +// }.flatMapLatest { (tokens, market) -> +// val flows = mutableListOf>() +// if (market == Market.XYK || market == Market.SMART) { +// val tfrom = tokens.first +// val tto = tokens.second +// val dexs = getPoolDexList() +// if (!dexs.hasToken(tfrom) && !dexs.hasToken(tto)) { +// dexs.forEach { dex -> +// flows.add( +// polkaswapSubscriptionRepository.observePoolXYKReserves(dex.tokenId, tfrom) +// ) +// flows.add( +// polkaswapSubscriptionRepository.observePoolXYKReserves(dex.tokenId, tto) +// ) +// } +// } else if (dexs.hasToken(tfrom) && dexs.hasToken(tto)) { +// flows.add( +// polkaswapSubscriptionRepository.observePoolXYKReserves(tto, tfrom) +// ) +// flows.add( +// polkaswapSubscriptionRepository.observePoolXYKReserves(tfrom, tto) +// ) +// } else { +// val (inDex, inNot) = if (dexs.hasToken(tfrom)) tfrom to tto else tto to tfrom +// flows.add( +// polkaswapSubscriptionRepository.observePoolXYKReserves(inDex, inNot) +// ) +// dexs.filter { dex -> +// dex.tokenId != inDex +// }.forEach { dex -> +// flows.add( +// polkaswapSubscriptionRepository.observePoolXYKReserves(dex.tokenId, inDex) +// ) +// flows.add( +// polkaswapSubscriptionRepository.observePoolXYKReserves(dex.tokenId, inNot) +// ) +// } +// } +// flows.add( +// polkaswapSubscriptionRepository.observePoolXYKReserves( +// tokens.first, +// tokens.second +// ) +// ) +// } +// if (market == Market.TBC || market == Market.SMART) { +// flows.add(polkaswapSubscriptionRepository.observePoolTBCReserves(tokens.first)) +// } +// flows.merge() +// }.debounce(500) +// } + override suspend fun fetchAvailableSources(tokenId1: String, tokenId2: String): Set? { poolReservesFlowToken.value = tokenId1 to tokenId2 val allBaseDexs = getPoolDexList() diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityAddConfirmScreen.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityAddConfirmScreen.kt index 3a6c93bac..6549fe1ef 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityAddConfirmScreen.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityAddConfirmScreen.kt @@ -85,6 +85,7 @@ import jp.co.soramitsu.ui_core.theme.customTypography @Composable internal fun LiquidityAddConfirmScreen( state: LiquidityAddState, + slippage: Double, onConfirmClick: () -> Unit, ) { Column( @@ -195,7 +196,7 @@ internal fun LiquidityAddConfirmScreen( horizontalArrangement = Arrangement.Center, ) { MarketSelector( - value = "${state.slippage}%", + value = "$slippage%", description = stringResource(id = R.string.slippage), onClick = {}, ) diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityAddScreen.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityAddScreen.kt index a3f1e2812..597b5a516 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityAddScreen.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/LiquidityAddScreen.kt @@ -76,6 +76,7 @@ import jp.co.soramitsu.ui_core.theme.customTypography @Composable internal fun LiquidityAddScreen( state: LiquidityAddState, + slippage: Double, onFocusChange1: (Boolean) -> Unit, onFocusChange2: (Boolean) -> Unit, onAmountChange1: (BigDecimal) -> Unit, @@ -141,7 +142,7 @@ internal fun LiquidityAddScreen( horizontalArrangement = Arrangement.Center, ) { MarketSelector( - value = "${state.slippage}%", + value = "$slippage%", description = stringResource(id = R.string.slippage), onClick = onSlippageClick, ) @@ -262,7 +263,6 @@ private fun PreviewLiquidityRemoveScreen() { loading = false, ), pairNotExist = true, - slippage = 0.3, hintVisible = false, estimated = LiquidityAddEstimatedState( token1 = "XOR", @@ -290,11 +290,11 @@ private fun PreviewLiquidityRemoveScreen() { loading = false, ), ), - selectSearchAssetState = null, shouldTransactionReminderInsufficientWarningBeShown = true, ), onSelect1 = {}, onSelect2 = {}, + slippage = 0.34, ) } } diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapConfirmScreen.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapConfirmScreen.kt index f11e86447..0a03b4490 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapConfirmScreen.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapConfirmScreen.kt @@ -255,7 +255,6 @@ private fun Preview() { tokenFromState = previewAssetAmountInputState, tokenToState = previewAssetAmountInputState, slippage = 0.5, - selectSearchAssetState = null, market = Market.SMART, selectMarketState = null, details = defaultSwapDetailsState(), diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapMainScreen.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapMainScreen.kt index 73c9cdfad..3cb6685d0 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapMainScreen.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/compose/SwapMainScreen.kt @@ -219,8 +219,8 @@ internal fun SwapMainScreen( if (state.details.lpFee.isNotEmpty()) { Spacer(modifier = Modifier.size(Dimens.x2)) DetailsItem( - text = stringResource(id = state.details.lpFeeTitle), - hint = stringResource(id = state.details.lpFeeHint), + text = stringResource(id = R.string.polkaswap_liquidity_total_fee), + hint = stringResource(id = R.string.polkaswap_liquidity_total_fee_desc), value1 = state.details.lpFee, ) } @@ -236,7 +236,6 @@ private fun PreviewSwapMainScreen() { tokenFromState = previewAssetAmountInputState, tokenToState = previewAssetAmountInputState, slippage = 0.2, - selectSearchAssetState = null, market = Market.SMART, selectMarketState = null, details = defaultSwapDetailsState(), diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoollist/FullPoolListFragment.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoollist/FullPoolListFragment.kt index 0bd99f482..a0dfd4c10 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoollist/FullPoolListFragment.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoollist/FullPoolListFragment.kt @@ -101,6 +101,7 @@ class FullPoolListFragment : SoraBaseFragment() { title = "", navIcon = jp.co.soramitsu.ui_core.R.drawable.ic_cross_24, actionLabel = R.string.common_edit, + searchValue = "", ), type = SoramitsuToolbarType.Small(), ), @@ -108,7 +109,6 @@ class FullPoolListFragment : SoraBaseFragment() { elevation = 0.dp, onAction = viewModel::onAction, onNavigate = viewModel::onNavIcon, - searchInitial = "", onSearch = viewModel::searchAssets, ) val state = viewModel.state diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoolsettings/FullPoolSettingsFragment.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoolsettings/FullPoolSettingsFragment.kt index bc5cdd018..155caee54 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoolsettings/FullPoolSettingsFragment.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoolsettings/FullPoolSettingsFragment.kt @@ -101,6 +101,7 @@ class FullPoolSettingsFragment : SoraBaseFragment() { title = "", navIcon = jp.co.soramitsu.ui_core.R.drawable.ic_cross_24, actionLabel = R.string.common_done, + searchValue = "", ), type = SoramitsuToolbarType.Small(), ), @@ -108,7 +109,6 @@ class FullPoolSettingsFragment : SoraBaseFragment() { elevation = 0.dp, onAction = viewModel::onCloseClick, onNavigate = viewModel::onCloseClick, - searchInitial = "", onSearch = { viewModel.searchAssets(it) itemTouchHelperCallback.isDraggable = it.isBlank() diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddFragment.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddFragment.kt index 7c6c41241..9f1c389d1 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddFragment.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddFragment.kt @@ -49,6 +49,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.stringResource import androidx.fragment.app.viewModels +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import com.google.accompanist.navigation.animation.composable @@ -58,8 +59,8 @@ import jp.co.soramitsu.common.R import jp.co.soramitsu.common.base.SoraBaseFragment import jp.co.soramitsu.common.domain.BottomBarController import jp.co.soramitsu.common.presentation.compose.components.PercentContainer -import jp.co.soramitsu.common_wallet.presentation.compose.components.SelectSearchTokenScreen import jp.co.soramitsu.core_di.viewmodel.CustomViewModelFactory +import jp.co.soramitsu.feature_assets_api.presentation.selectsearchtoken.SelectSearchTokenScreen import jp.co.soramitsu.feature_polkaswap_impl.presentation.components.compose.LiquidityAddConfirmScreen import jp.co.soramitsu.feature_polkaswap_impl.presentation.components.compose.LiquidityAddScreen import jp.co.soramitsu.feature_polkaswap_impl.presentation.screens.swap.SwapSlippageScreen @@ -116,14 +117,12 @@ class LiquidityAddFragment : SoraBaseFragment() { } val type = requireNotNull(entry.arguments?.getString(LiquidityAddRoutes.selectTokenParamName)) - val state = viewModel.addState.selectSearchAssetState - if (state != null) { - SelectSearchTokenScreen( - state = state, - scrollState = scrollState, - onAssetSelect = { id -> onTokenSelected.invoke(id, type) }, - ) - } + val state = viewModel.searchTokenFilter.collectAsStateWithLifecycle() + SelectSearchTokenScreen( + scrollState = scrollState, + onAssetSelect = { id -> onTokenSelected.invoke(id, type) }, + filter = state.value, + ) } composable(LiquidityAddRoutes.slippage) { val onSlippageEntered: (Double) -> Unit = { f -> @@ -131,13 +130,15 @@ class LiquidityAddFragment : SoraBaseFragment() { navController.popBackStack() } SwapSlippageScreen( - value = viewModel.addState.slippage, + value = viewModel.stateSlippage.collectAsStateWithLifecycle().value, onDone = onSlippageEntered, ) } composable(LiquidityAddRoutes.confirm) { + val state = viewModel.addState.collectAsStateWithLifecycle() LiquidityAddConfirmScreen( - state = viewModel.addState, + state = state.value, + slippage = viewModel.stateSlippage.collectAsStateWithLifecycle().value, onConfirmClick = viewModel::onConfirmClick, ) } @@ -159,7 +160,8 @@ class LiquidityAddFragment : SoraBaseFragment() { percentageVisibility.value = f viewModel.onAmount2Focused() } - if (viewModel.addState.hintVisible) { + val state = viewModel.addState.collectAsStateWithLifecycle() + if (state.value.hintVisible) { AlertDialog( title = { Text( @@ -211,7 +213,8 @@ class LiquidityAddFragment : SoraBaseFragment() { navController.navigate(LiquidityAddRoutes.confirm) } LiquidityAddScreen( - state = viewModel.addState, + state = state.value, + slippage = viewModel.stateSlippage.collectAsStateWithLifecycle().value, onFocusChange1 = onFocus1, onFocusChange2 = onFocus2, onAmountChange1 = viewModel::onAmount1Change, diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt index df1a0ab35..2ee701953 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt @@ -33,7 +33,6 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_polkaswap_impl.presentation.screens.liquidityadd import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.viewModelScope import dagger.assisted.Assisted @@ -57,13 +56,10 @@ import jp.co.soramitsu.common.util.ext.nullZero import jp.co.soramitsu.common.view.ViewHelper import jp.co.soramitsu.common_wallet.domain.model.LiquidityData import jp.co.soramitsu.common_wallet.domain.model.WithDesired -import jp.co.soramitsu.common_wallet.presentation.compose.components.SelectSearchAssetState -import jp.co.soramitsu.common_wallet.presentation.compose.states.mapAssetsToCardState import jp.co.soramitsu.common_wallet.presentation.compose.util.AmountFormat import jp.co.soramitsu.common_wallet.presentation.compose.util.PolkaswapFormulas import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter -import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PoolsInteractor import jp.co.soramitsu.feature_polkaswap_impl.presentation.states.LiquidityAddConfirmState import jp.co.soramitsu.feature_polkaswap_impl.presentation.states.LiquidityAddEstimatedState @@ -82,6 +78,7 @@ import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collectLatest @@ -100,7 +97,6 @@ class LiquidityAddViewModel @AssistedInject constructor( private val assetsInteractor: AssetsInteractor, private val assetsRouter: AssetsRouter, private val router: WalletRouter, - private val mainRouter: MainRouter, private val walletInteractor: WalletInteractor, private val poolsInteractor: PoolsInteractor, private val numbersFormatter: NumbersFormatter, @@ -155,14 +151,19 @@ class LiquidityAddViewModel @AssistedInject constructor( private var pairEnabled: Boolean = true private var pairPresented: Boolean = true - var addState by mutableStateOf( + private val _searchTokenFilter = MutableStateFlow("") + val searchTokenFilter = _searchTokenFilter.asStateFlow() + + private val _stateSlippage = MutableStateFlow(0.5) + val stateSlippage = _stateSlippage.asStateFlow() + + private val _addState = MutableStateFlow( LiquidityAddState( btnState = ButtonState( text = resourceManager.getString(R.string.choose_tokens), enabled = false, loading = false, ), - slippage = 0.5, assetState1 = null, assetState2 = null, hintVisible = false, @@ -190,10 +191,10 @@ class LiquidityAddViewModel @AssistedInject constructor( loading = false, ), ), - selectSearchAssetState = null, shouldTransactionReminderInsufficientWarningBeShown = false, ) ) + val addState = _addState.asStateFlow() override fun startScreen(): String = LiquidityAddRoutes.start @@ -224,15 +225,15 @@ class LiquidityAddViewModel @AssistedInject constructor( .collectLatest { assets.clear() assets.addAll(it) - if (addState.assetState1 == null) { + if (_addState.value.assetState1 == null) { val a = assets.first { t -> t.token.id == token1Id } - addState = addState.copy( + _addState.value = _addState.value.copy( assetState1 = buildInitialAssetState(a), ) } - if (addState.assetState2 == null && token2Id != null) { + if (_addState.value.assetState2 == null && token2Id != null) { val a = assets.first { t -> t.token.id == token2Id } - addState = addState.copy( + _addState.value = _addState.value.copy( assetState2 = buildInitialAssetState(a), ) } @@ -248,7 +249,7 @@ class LiquidityAddViewModel @AssistedInject constructor( desired = WithDesired.INPUT onChangedProperty.set(false) }.filter { - addState.assetState1?.token?.id == SubstrateOptionsProvider.feeAssetId || + _addState.value.assetState1?.token?.id == SubstrateOptionsProvider.feeAssetId || !hasXorReminderWarningBeenChecked }.onEach { updateTransactionReminderWarningVisibility() @@ -267,6 +268,10 @@ class LiquidityAddViewModel @AssistedInject constructor( } } + override fun onToolbarSearch(value: String) { + _searchTokenFilter.value = value + } + override fun onCurrentDestinationChanged(curDest: String) { _toolbarState.value?.let { state -> _toolbarState.value = state.copy( @@ -281,7 +286,9 @@ class LiquidityAddViewModel @AssistedInject constructor( navIcon = when (curDest) { LiquidityAddRoutes.start -> R.drawable.ic_settings_info else -> R.drawable.ic_arrow_left - } + }, + searchEnabled = curDest == LiquidityAddRoutes.selectToken, + searchValue = if (curDest == LiquidityAddRoutes.selectToken) _searchTokenFilter.value else "", ), ) } @@ -289,8 +296,8 @@ class LiquidityAddViewModel @AssistedInject constructor( override fun onNavIcon() { if (currentDestination == LiquidityAddRoutes.start) { - addState = addState.copy( - hintVisible = addState.hintVisible.not() + _addState.value = _addState.value.copy( + hintVisible = _addState.value.hintVisible.not() ) } else { super.onNavIcon() @@ -302,14 +309,14 @@ class LiquidityAddViewModel @AssistedInject constructor( } fun dismissHint() { - addState = addState.copy( - hintVisible = addState.hintVisible.not() + _addState.value = _addState.value.copy( + hintVisible = _addState.value.hintVisible.not() ) } private fun setButtonLoading(loading: Boolean) { - addState = addState.copy( - btnState = addState.btnState.copy( + _addState.value = _addState.value.copy( + btnState = _addState.value.btnState.copy( loading = loading, ), ) @@ -323,15 +330,15 @@ class LiquidityAddViewModel @AssistedInject constructor( } else !(SubstrateOptionsProvider.feeAssetId == addToken1 && (amountFrom + networkFee) > balance1) val (text, enabled) = when { - (addState.assetState2?.token == null) -> { + (_addState.value.assetState2?.token == null) -> { resourceManager.getString(R.string.choose_tokens) to false } - (addState.assetState1?.token != null && amountFrom == BigDecimal.ZERO) -> { + (_addState.value.assetState1?.token != null && amountFrom == BigDecimal.ZERO) -> { resourceManager.getString(R.string.common_enter_amount) to false } - (addState.assetState2?.token != null && amountTo == BigDecimal.ZERO) -> { + (_addState.value.assetState2?.token != null && amountTo == BigDecimal.ZERO) -> { resourceManager.getString(R.string.common_enter_amount) to false } @@ -348,8 +355,8 @@ class LiquidityAddViewModel @AssistedInject constructor( } } - addState = addState.copy( - btnState = addState.btnState.copy( + _addState.value = _addState.value.copy( + btnState = _addState.value.btnState.copy( text = text, enabled = enabled, ) @@ -357,8 +364,8 @@ class LiquidityAddViewModel @AssistedInject constructor( } private suspend fun recalculateData() { - val tokenFrom = addState.assetState1?.token - val tokenTo = addState.assetState2?.token + val tokenFrom = _addState.value.assetState1?.token + val tokenTo = _addState.value.assetState2?.token val basedAmount = if (desired == WithDesired.INPUT) amountFrom else amountTo val targetAmount = if (desired == WithDesired.INPUT) amountTo else amountFrom @@ -381,7 +388,7 @@ class LiquidityAddViewModel @AssistedInject constructor( basedAmount, targetAmount, desired, - addState.slippage, + _stateSlippage.value, pairEnabled, pairPresented ) @@ -390,11 +397,11 @@ class LiquidityAddViewModel @AssistedInject constructor( liquidityDetails = details details.targetAmount.let { if (desired == WithDesired.INPUT) { - addState = addState.copy( - assetState2 = addState.assetState2?.copy( + _addState.value = _addState.value.copy( + assetState2 = _addState.value.assetState2?.copy( amount = it, initialAmount = it, - amountFiat = addState.assetState2?.token?.printFiat( + amountFiat = _addState.value.assetState2?.token?.printFiat( it, numbersFormatter ).orEmpty(), @@ -403,11 +410,11 @@ class LiquidityAddViewModel @AssistedInject constructor( ) amountTo = it } else { - addState = addState.copy( - assetState1 = addState.assetState1?.copy( + _addState.value = _addState.value.copy( + assetState1 = _addState.value.assetState1?.copy( amount = it, initialAmount = it, - amountFiat = addState.assetState1?.token?.printFiat( + amountFiat = _addState.value.assetState1?.token?.printFiat( it, numbersFormatter ).orEmpty(), @@ -424,15 +431,15 @@ class LiquidityAddViewModel @AssistedInject constructor( } private suspend fun updateLiquidityDetails(details: LiquidityDetails) { - val tokenFrom = addState.assetState1?.token - val tokenTo = addState.assetState2?.token + val tokenFrom = _addState.value.assetState1?.token + val tokenTo = _addState.value.assetState2?.token if (tokenFrom == null || tokenTo == null) { return } - addState = addState.copy( - estimated = addState.estimated.copy( + _addState.value = _addState.value.copy( + estimated = _addState.value.estimated.copy( token1 = tokenFrom.symbol, token2 = tokenTo.symbol, token1Value = numbersFormatter.formatBigDecimal( @@ -450,7 +457,7 @@ class LiquidityAddViewModel @AssistedInject constructor( ) ), ), - prices = addState.prices.copy( + prices = _addState.value.prices.copy( pair1 = PER_FORMAT.format(tokenFrom.symbol, tokenTo.symbol), pair1Value = numbersFormatter.formatBigDecimal( details.perFirst, @@ -481,7 +488,7 @@ class LiquidityAddViewModel @AssistedInject constructor( } private suspend fun updateTransactionReminderWarningVisibility() = - with(addState) { + with(_addState.value) { if (assetState1 == null) return@with @@ -490,7 +497,7 @@ class LiquidityAddViewModel @AssistedInject constructor( xorChange = if (assetState1.token.id == SubstrateOptionsProvider.feeAssetId) assetState1.amount else null, ) - addState = addState.copy( + _addState.value = _addState.value.copy( shouldTransactionReminderInsufficientWarningBeShown = result, ) } @@ -500,16 +507,12 @@ class LiquidityAddViewModel @AssistedInject constructor( viewModelScope.launch { val bases = poolsInteractor.getPoolDexList().map { it.tokenId } val list = assets.filter { it.token.id in bases && it.token.id != addToken2 } - addState = addState.copy( - selectSearchAssetState = SelectSearchAssetState( - filter = "", - fullList = mapAssetsToCardState(list, numbersFormatter), - ), - assetState1 = addState.assetState1?.copy( - initialAmount = addState.assetState1?.amount?.nullZero(), + _addState.value = _addState.value.copy( + assetState1 = _addState.value.assetState1?.copy( + initialAmount = _addState.value.assetState1?.amount?.nullZero(), ), - assetState2 = addState.assetState2?.copy( - initialAmount = addState.assetState2?.amount?.nullZero(), + assetState2 = _addState.value.assetState2?.copy( + initialAmount = _addState.value.assetState2?.amount?.nullZero(), ), ) } @@ -542,16 +545,12 @@ class LiquidityAddViewModel @AssistedInject constructor( asset.token.id != addToken1 } } - addState = addState.copy( - selectSearchAssetState = SelectSearchAssetState( - filter = "", - fullList = mapAssetsToCardState(list, numbersFormatter), + _addState.value = _addState.value.copy( + assetState1 = _addState.value.assetState1?.copy( + initialAmount = _addState.value.assetState1?.amount?.nullZero(), ), - assetState1 = addState.assetState1?.copy( - initialAmount = addState.assetState1?.amount?.nullZero(), - ), - assetState2 = addState.assetState2?.copy( - initialAmount = addState.assetState2?.amount?.nullZero(), + assetState2 = _addState.value.assetState2?.copy( + initialAmount = _addState.value.assetState2?.amount?.nullZero(), ), ) } @@ -559,10 +558,10 @@ class LiquidityAddViewModel @AssistedInject constructor( } fun onToken1Change(id: String) { - if (id == addState.assetState1?.token?.id) return - addState.assetState1?.let { state -> + if (id == _addState.value.assetState1?.token?.id) return + _addState.value.assetState1?.let { state -> val a = assets.first { t -> t.token.id == id } - addState = addState.copy( + _addState.value = _addState.value.copy( assetState1 = state.copy( token = a.token, balance = getAssetBalanceText(a), @@ -575,10 +574,10 @@ class LiquidityAddViewModel @AssistedInject constructor( } fun onToken2Change(id: String) { - if (id == addState.assetState2?.token?.id) return + if (id == _addState.value.assetState2?.token?.id) return val a = assets.first { t -> t.token.id == id } - val state = addState.assetState2 - addState = addState.copy( + val state = _addState.value.assetState2 + _addState.value = _addState.value.copy( assetState2 = state?.copy( token = a.token, balance = getAssetBalanceText(a), @@ -590,8 +589,8 @@ class LiquidityAddViewModel @AssistedInject constructor( } private fun setTokensFromArgs() { - val token1State = addState.assetState1?.token - val token2State = addState.assetState2?.token + val token1State = _addState.value.assetState1?.token + val token2State = _addState.value.assetState2?.token if (token1State?.id != addToken1 || token2State?.id != addToken2) { cleanUpSubscriptions() } @@ -604,8 +603,8 @@ class LiquidityAddViewModel @AssistedInject constructor( assets.find { it.token.id == addToken1 }?.let { asset -> balance1 = asset.balance.transferable - addState = addState.copy( - assetState1 = addState.assetState1?.copy( + _addState.value = _addState.value.copy( + assetState1 = _addState.value.assetState1?.copy( balance = getAssetBalanceText(asset), token = asset.token, ) @@ -613,8 +612,8 @@ class LiquidityAddViewModel @AssistedInject constructor( } assets.find { it.token.id == addToken2 }?.let { asset -> balance2 = asset.balance.transferable - addState = addState.copy( - assetState2 = addState.assetState2?.copy( + _addState.value = _addState.value.copy( + assetState2 = _addState.value.assetState2?.copy( balance = getAssetBalanceText(asset), token = asset.token, ) @@ -683,7 +682,7 @@ class LiquidityAddViewModel @AssistedInject constructor( fetchLiquidityData() } else { liquidityData = localData - addState = addState.copy( + _addState.value = _addState.value.copy( pairNotExist = false, ) } @@ -694,8 +693,8 @@ class LiquidityAddViewModel @AssistedInject constructor( } private suspend fun fetchLiquidityData() { - val tokenFrom = addState.assetState1?.token - val tokenTo = addState.assetState2?.token + val tokenFrom = _addState.value.assetState1?.token + val tokenTo = _addState.value.assetState2?.token if (tokenFrom == null || tokenTo == null) { return } @@ -703,34 +702,32 @@ class LiquidityAddViewModel @AssistedInject constructor( liquidityData = withContext(coroutineManager.io) { poolsInteractor.getLiquidityData(tokenFrom, tokenTo, pairEnabled, pairPresented) } - addState = addState.copy( + _addState.value = _addState.value.copy( pairNotExist = liquidityData.secondReserves.isZero() && liquidityData.firstReserves.isZero(), ) } fun onSlippageClick() { - addState = addState.copy( - assetState1 = addState.assetState1?.copy( - initialAmount = addState.assetState1?.amount?.nullZero(), + _addState.value = _addState.value.copy( + assetState1 = _addState.value.assetState1?.copy( + initialAmount = _addState.value.assetState1?.amount?.nullZero(), ), - assetState2 = addState.assetState2?.copy( - initialAmount = addState.assetState2?.amount?.nullZero(), + assetState2 = _addState.value.assetState2?.copy( + initialAmount = _addState.value.assetState2?.amount?.nullZero(), ), ) } fun slippageChanged(slippageTolerance: Double) { - addState = addState.copy( - slippage = slippageTolerance, - ) + _stateSlippage.value = slippageTolerance onChangedProperty.set(false) } fun onAmount1Change(value: BigDecimal) { - addState = addState.copy( - assetState1 = addState.assetState1?.copy( + _addState.value = _addState.value.copy( + assetState1 = _addState.value.assetState1?.copy( amount = value, - amountFiat = addState.assetState1?.token?.printFiat( + amountFiat = _addState.value.assetState1?.token?.printFiat( value, numbersFormatter ).orEmpty() @@ -740,10 +737,10 @@ class LiquidityAddViewModel @AssistedInject constructor( } fun onAmount2Change(value: BigDecimal) { - addState = addState.copy( - assetState2 = addState.assetState2?.copy( + _addState.value = _addState.value.copy( + assetState2 = _addState.value.assetState2?.copy( amount = value, - amountFiat = addState.assetState2?.token?.printFiat( + amountFiat = _addState.value.assetState2?.token?.printFiat( value, numbersFormatter ).orEmpty() @@ -765,8 +762,8 @@ class LiquidityAddViewModel @AssistedInject constructor( } fun optionSelected(percent: Int) { - val tokenFrom = addState.assetState1?.token - val tokenTo = addState.assetState2?.token + val tokenFrom = _addState.value.assetState1?.token + val tokenTo = _addState.value.assetState2?.token if (desired == WithDesired.INPUT && tokenFrom != null) { val amount = PolkaswapFormulas.calculateAmountByPercentage( @@ -777,8 +774,8 @@ class LiquidityAddViewModel @AssistedInject constructor( }, percent.toDouble(), tokenFrom.precision ) - addState = addState.copy( - assetState1 = addState.assetState1?.copy( + _addState.value = _addState.value.copy( + assetState1 = _addState.value.assetState1?.copy( amountFiat = tokenFrom.printFiat(amount, numbersFormatter), amount = amount, initialAmount = amount, @@ -792,8 +789,8 @@ class LiquidityAddViewModel @AssistedInject constructor( percent.toDouble(), tokenTo.precision ) - addState = addState.copy( - assetState2 = addState.assetState2?.copy( + _addState.value = _addState.value.copy( + assetState2 = _addState.value.assetState2?.copy( amountFiat = tokenTo.printFiat(amount, numbersFormatter), amount = amount, initialAmount = amount, @@ -804,12 +801,12 @@ class LiquidityAddViewModel @AssistedInject constructor( } fun onConfirmClick() { - addState.assetState1?.let { state1 -> - addState.assetState2?.let { state2 -> + _addState.value.assetState1?.let { state1 -> + _addState.value.assetState2?.let { state2 -> viewModelScope.launch { - addState = addState.copy( - confirm = addState.confirm.copy( - btnState = addState.confirm.btnState.copy( + _addState.value = _addState.value.copy( + confirm = _addState.value.confirm.copy( + btnState = _addState.value.confirm.btnState.copy( enabled = false, loading = true, ) @@ -824,14 +821,14 @@ class LiquidityAddViewModel @AssistedInject constructor( amountTo, pairEnabled, pairPresented, - addState.slippage, + _stateSlippage.value, ) } catch (t: Throwable) { onError(t) } finally { - addState = addState.copy( - confirm = addState.confirm.copy( - btnState = addState.confirm.btnState.copy( + _addState.value = _addState.value.copy( + confirm = _addState.value.confirm.copy( + btnState = _addState.value.confirm.btnState.copy( enabled = false, loading = false, ), @@ -839,8 +836,8 @@ class LiquidityAddViewModel @AssistedInject constructor( ) ) delay(700) - addState = addState.copy( - confirm = addState.confirm.copy( + _addState.value = _addState.value.copy( + confirm = _addState.value.confirm.copy( confirmResult = null ) ) @@ -854,16 +851,16 @@ class LiquidityAddViewModel @AssistedInject constructor( } fun onReviewClick() { - val tokenFrom = addState.assetState1?.token - val tokenTo = addState.assetState2?.token + val tokenFrom = _addState.value.assetState1?.token + val tokenTo = _addState.value.assetState2?.token if (tokenFrom == null || tokenTo == null) { return } - addState = addState.copy( - confirm = addState.confirm.copy( + _addState.value = _addState.value.copy( + confirm = _addState.value.confirm.copy( text = resourceManager.getString(R.string.remove_pool_confirmation_description) - .format(addState.slippage), - btnState = addState.btnState.copy( + .format(_stateSlippage.value), + btnState = _addState.value.btnState.copy( text = resourceManager.getString(R.string.common_confirm), enabled = true, loading = false, diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapFragment.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapFragment.kt index 98f6464cc..d6cb400b6 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapFragment.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapFragment.kt @@ -60,8 +60,8 @@ import jp.co.soramitsu.common.presentation.args.tokenFromId import jp.co.soramitsu.common.presentation.args.tokenToId import jp.co.soramitsu.common.presentation.compose.components.PercentContainer import jp.co.soramitsu.common.presentation.compose.components.PolkaswapDisclaimer -import jp.co.soramitsu.common_wallet.presentation.compose.components.SelectSearchTokenScreen import jp.co.soramitsu.core_di.viewmodel.CustomViewModelFactory +import jp.co.soramitsu.feature_assets_api.presentation.selectsearchtoken.SelectSearchTokenScreen import jp.co.soramitsu.feature_polkaswap_impl.presentation.components.compose.SwapConfirmScreen import jp.co.soramitsu.feature_polkaswap_impl.presentation.components.compose.SwapMainScreen import jp.co.soramitsu.feature_polkaswap_impl.presentation.components.compose.SwapMarketsScreen @@ -134,21 +134,20 @@ class SwapFragment : SoraBaseFragment() { } } val type = requireNotNull(it.arguments?.getString(SwapRoutes.selectTokenParamName)) - val state = viewModel.swapMainState.collectAsStateWithLifecycle().value.selectSearchAssetState - if (state != null) { - SelectSearchTokenScreen( - state = state, - scrollState = scrollState, - onAssetSelect = { id -> onTokenSelected.invoke(id, type) }, - ) - } + val state = viewModel.swapTokensFilter.collectAsStateWithLifecycle() + SelectSearchTokenScreen( + scrollState = scrollState, + onAssetSelect = { id -> onTokenSelected.invoke(id, type) }, + filter = state.value, + ) } composable(SwapRoutes.markets) { val onMarketSelected: (Market) -> Unit = { viewModel.onMarketSelected(it) navController.popBackStack() } - val state = viewModel.swapMainState.collectAsStateWithLifecycle().value.selectMarketState + val state = + viewModel.swapMainState.collectAsStateWithLifecycle().value.selectMarketState if (state != null) { SwapMarketsScreen( selected = state.first, diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt index 93d1e55be..abc5d23c7 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt @@ -46,7 +46,6 @@ import jp.co.soramitsu.common.R import jp.co.soramitsu.common.domain.Asset import jp.co.soramitsu.common.domain.AssetAmountInputState import jp.co.soramitsu.common.domain.AssetHolder -import jp.co.soramitsu.common.domain.CoroutineManager import jp.co.soramitsu.common.domain.Market import jp.co.soramitsu.common.domain.SuspendableProperty import jp.co.soramitsu.common.domain.Token @@ -64,8 +63,6 @@ import jp.co.soramitsu.common.util.ext.nullZero import jp.co.soramitsu.common.util.ext.orZero import jp.co.soramitsu.common.view.ViewHelper import jp.co.soramitsu.common_wallet.domain.model.WithDesired -import jp.co.soramitsu.common_wallet.presentation.compose.components.SelectSearchAssetState -import jp.co.soramitsu.common_wallet.presentation.compose.states.mapAssetsToCardState import jp.co.soramitsu.common_wallet.presentation.compose.util.AmountFormat import jp.co.soramitsu.common_wallet.presentation.compose.util.PolkaswapFormulas import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor @@ -73,7 +70,6 @@ import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.SwapInteractor import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapDetails -import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapFeeMode import jp.co.soramitsu.feature_polkaswap_impl.presentation.states.SwapMainState import jp.co.soramitsu.feature_polkaswap_impl.presentation.states.defaultSwapDetailsState import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletInteractor @@ -104,7 +100,6 @@ class SwapViewModel @AssistedInject constructor( private val resourceManager: ResourceManager, private val mainRouter: MainRouter, private val assetsRouter: AssetsRouter, - private val coroutineManager: CoroutineManager, @Assisted("idfrom") private val token1Id: String, @Assisted("idto") private val token2Id: String, @Assisted("isLaunchedFromSoraCard") private val isLaunchedFromSoraCard: Boolean @@ -156,7 +151,6 @@ class SwapViewModel @AssistedInject constructor( tokenFromState = null, tokenToState = null, slippage = 0.5, - selectSearchAssetState = null, market = Market.SMART, selectMarketState = null, details = defaultSwapDetailsState(), @@ -176,6 +170,9 @@ class SwapViewModel @AssistedInject constructor( ) val swapMainState = _swapMainState.asStateFlow() + private val _swapTokensFilter = MutableStateFlow("") + val swapTokensFilter = _swapTokensFilter.asStateFlow() + private var amountFromPrev: BigDecimal = BigDecimal.ZERO private var amountToPrev: BigDecimal = BigDecimal.ZERO private val amountFrom: BigDecimal @@ -185,6 +182,10 @@ class SwapViewModel @AssistedInject constructor( override fun startScreen(): String = SwapRoutes.start + override fun onToolbarSearch(value: String) { + _swapTokensFilter.value = value + } + override fun onCurrentDestinationChanged(curDest: String) { _toolbarState.value?.let { state -> _toolbarState.value = state.copy( @@ -196,6 +197,8 @@ class SwapViewModel @AssistedInject constructor( SwapRoutes.selectToken -> R.string.common_choose_asset else -> "" }, + searchEnabled = curDest == SwapRoutes.selectToken, + searchValue = if (curDest == SwapRoutes.selectToken) _swapTokensFilter.value else "" ) ) } @@ -417,13 +420,6 @@ class SwapViewModel @AssistedInject constructor( fun fromCardClicked() { if (assetsList.isNotEmpty()) { _swapMainState.value = _swapMainState.value.copy( - selectSearchAssetState = SelectSearchAssetState( - filter = "", - fullList = mapAssetsToCardState( - assetsList.filter { it.token.id != _swapMainState.value.tokenToState?.token?.id.orEmpty() }, - numbersFormatter - ) - ), tokenFromState = _swapMainState.value.tokenFromState?.copy( initialAmount = _swapMainState.value.tokenFromState?.amount?.nullZero(), ), @@ -437,13 +433,6 @@ class SwapViewModel @AssistedInject constructor( fun toCardClicked() { if (assetsList.isNotEmpty()) { _swapMainState.value = _swapMainState.value.copy( - selectSearchAssetState = SelectSearchAssetState( - filter = "", - fullList = mapAssetsToCardState( - assetsList.filter { it.token.id != _swapMainState.value.tokenFromState?.token?.id.orEmpty() }, - numbersFormatter - ) - ), tokenFromState = _swapMainState.value.tokenFromState?.copy( initialAmount = _swapMainState.value.tokenFromState?.amount?.nullZero(), ), @@ -763,11 +752,6 @@ class SwapViewModel @AssistedInject constructor( minmaxToken = _swapMainState.value.tokenFromState?.token maxMinToken = _swapMainState.value.tokenToState?.token } - val (title, desc) = when (details.feeMode) { - SwapFeeMode.SYNTHETIC -> R.string.polkaswap_liquidity_synthetic_fee to R.string.polkaswap_liquidity_synthetic_fee_desc - SwapFeeMode.NON_SYNTHETIC -> R.string.polkaswap_liquidity_fee to R.string.polkaswap_liquidity_fee_info - SwapFeeMode.BOTH -> R.string.polkaswap_liquidity_total_fee to R.string.polkaswap_liquidity_total_fee_desc - } _swapMainState.value = _swapMainState.value.copy( details = _swapMainState.value.details.copy( transactionFee = feeToken().printBalance( @@ -804,8 +788,6 @@ class SwapViewModel @AssistedInject constructor( minmaxValueFiat = minmaxToken?.printFiat(details.minmax, numbersFormatter) .orEmpty(), route = details.swapRoute?.joinToString("->").orEmpty(), - lpFeeTitle = title, - lpFeeHint = desc, ) ) } diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/LiquidityAddState.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/LiquidityAddState.kt index f6b4ce30f..22347916e 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/LiquidityAddState.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/LiquidityAddState.kt @@ -34,18 +34,15 @@ package jp.co.soramitsu.feature_polkaswap_impl.presentation.states import jp.co.soramitsu.common.domain.AssetAmountInputState import jp.co.soramitsu.common.presentation.compose.states.ButtonState -import jp.co.soramitsu.common_wallet.presentation.compose.components.SelectSearchAssetState data class LiquidityAddState( val btnState: ButtonState, - val slippage: Double, val assetState1: AssetAmountInputState?, val assetState2: AssetAmountInputState?, val estimated: LiquidityAddEstimatedState, val prices: LiquidityAddPricesState, val confirm: LiquidityAddConfirmState, val pairNotExist: Boolean? = null, - val selectSearchAssetState: SelectSearchAssetState?, val hintVisible: Boolean, val shouldTransactionReminderInsufficientWarningBeShown: Boolean, ) diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/SwapMainState.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/SwapMainState.kt index a2d4d40b3..98ca187ed 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/SwapMainState.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/SwapMainState.kt @@ -38,13 +38,11 @@ import jp.co.soramitsu.common.R import jp.co.soramitsu.common.domain.AssetAmountInputState import jp.co.soramitsu.common.domain.Market import jp.co.soramitsu.common.presentation.compose.states.ButtonState -import jp.co.soramitsu.common_wallet.presentation.compose.components.SelectSearchAssetState data class SwapMainState( val tokenFromState: AssetAmountInputState?, val tokenToState: AssetAmountInputState?, val slippage: Double, - val selectSearchAssetState: SelectSearchAssetState?, val market: Market, val selectMarketState: Pair>?, val details: SwapDetailsState, @@ -66,8 +64,6 @@ data class SwapDetailsState( val priceToFromTitle: String, val priceToFrom: String, val lpFee: String, - @StringRes val lpFeeTitle: Int, - @StringRes val lpFeeHint: Int, val route: String, val shouldTransactionReminderInsufficientWarningBeShown: Boolean, ) @@ -85,8 +81,6 @@ fun defaultSwapDetailsState() = priceToFromTitle = "", priceToFrom = "", lpFee = "", - lpFeeTitle = R.string.polkaswap_liquidity_fee, - lpFeeHint = R.string.polkaswap_liquidity_fee_info, route = "", shouldTransactionReminderInsufficientWarningBeShown = false, ) diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt index b56b9144e..0d1ba71fb 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/SwapViewModelTest.kt @@ -38,13 +38,11 @@ import io.mockk.every import io.mockk.mockkStatic import jp.co.soramitsu.common.R import jp.co.soramitsu.common.domain.Asset -import jp.co.soramitsu.common.domain.CoroutineManager import jp.co.soramitsu.common.domain.Market import jp.co.soramitsu.common.domain.PoolDex import jp.co.soramitsu.common.presentation.compose.states.ButtonState import jp.co.soramitsu.common.resourses.ResourceManager import jp.co.soramitsu.common.util.NumbersFormatter -import jp.co.soramitsu.common_wallet.presentation.compose.components.SelectSearchAssetState import jp.co.soramitsu.common_wallet.presentation.compose.states.AssetItemCardState import jp.co.soramitsu.common_wallet.presentation.compose.states.mapAssetsToCardState import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor @@ -52,7 +50,6 @@ import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.SwapInteractor import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapDetails -import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapFeeMode import jp.co.soramitsu.feature_polkaswap_impl.presentation.screens.swap.SwapViewModel import jp.co.soramitsu.feature_wallet_api.domain.interfaces.WalletInteractor import jp.co.soramitsu.test_data.PolkaswapTestData @@ -102,9 +99,6 @@ class SwapViewModelTest { @Mock private lateinit var assetsInteractor: AssetsInteractor - @Mock - private lateinit var coroutineManager: CoroutineManager - @Mock private lateinit var walletInteractor: WalletInteractor @@ -169,10 +163,9 @@ class SwapViewModelTest { resourceManager, mainRouter, assetsRouter, - coroutineManager, firstTokenId ?: TestAssets.xorAsset().token.id, secondTokenId ?: "", - isLaunchedFromSoraCard = false + isLaunchedFromSoraCard = false, ) } @@ -238,24 +231,6 @@ class SwapViewModelTest { assertFalse(viewModel.swapMainState.value.swapButtonState.enabled) } - @Test - fun fromAndToCardClicked() = runTest { - initViewModel() - advanceUntilIdle() - viewModel.fromCardClicked() - advanceUntilIdle() - assertEquals(viewModel.swapMainState.value.selectSearchAssetState?.fullList, assetsListItems) - viewModel.fromAssetSelected(assetsListItems[0].tokenId) - - viewModel.toCardClicked() - assertEquals( - SelectSearchAssetState( - filter = "", - fullList = assetsListItems.filter { it.tokenId != viewModel.swapMainState.value.tokenFromState?.token?.id }), - viewModel.swapMainState.value.selectSearchAssetState, - ) - } - @Test fun fromInputPercentCalledWithLowBalance() = runTest { initViewModel() @@ -301,7 +276,6 @@ class SwapViewModelTest { networkFee, PoolDex(0, assetsListItems.first().tokenId, assetsListItems.last().tokenId), null, - SwapFeeMode.NON_SYNTHETIC, ) ) advanceUntilIdle() diff --git a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt index cf22a5ab2..cc34a84ec 100644 --- a/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt +++ b/feature_polkaswap_impl/src/test/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/polkaswap/liquidity/add/AddLiquidityViewModelTest.kt @@ -121,9 +121,6 @@ class AddLiquidityViewModelTest { private val mockedUri = Mockito.mock(Uri::class.java) - @Mock - private lateinit var mainRouter: MainRouter - private lateinit var viewModel: LiquidityAddViewModel private fun setUpViewModel( @@ -134,7 +131,6 @@ class AddLiquidityViewModelTest { assetsInteractor, assetsRouter, router, - mainRouter, walletInteractor, poolsInteractor, NumbersFormatter(), @@ -180,20 +176,6 @@ class AddLiquidityViewModelTest { any() ) ).willReturn(LIQUIDITY_DETAILS) - given(poolsInteractor.getPoolDexList()).willReturn( - listOf( - PoolDex( - 0, - TestTokens.xorToken.id, - TestTokens.xorToken.symbol - ), - PoolDex( - 1, - TestTokens.xstusdToken.id, - TestTokens.xstusdToken.symbol, - ) - ) - ) given(assetsInteractor.subscribeAssetsActiveOfCurAccount()).willReturn( flowOf( listOf( @@ -225,7 +207,7 @@ class AddLiquidityViewModelTest { fun `init viewModel EXPECT initial button state text`() = runTest { setUpViewModel(null) advanceUntilIdle() - assertEquals("Choose tokens", viewModel.addState.btnState.text) + assertEquals("Choose tokens", viewModel.addState.value.btnState.text) } @Test @@ -236,21 +218,7 @@ class AddLiquidityViewModelTest { .willReturn(flowOf(true)) setUpViewModel(TestTokens.valToken.id) advanceUntilIdle() - assertEquals("Enter amount", viewModel.addState.btnState.text) - } - - @Test - fun `choose token clicked EXPECT navigate to asset list screen`() = runTest { - setUpViewModel(null) - advanceUntilIdle() - viewModel.onToken2Click() - advanceUntilIdle() - assertEquals(3, viewModel.addState.selectSearchAssetState?.fullList?.size) - viewModel.onToken1Change(TestTokens.xstusdToken.id) - advanceUntilIdle() - viewModel.onToken2Click() - advanceUntilIdle() - assertEquals(2, viewModel.addState.selectSearchAssetState?.fullList?.size) + assertEquals("Enter amount", viewModel.addState.value.btnState.text) } @Test @@ -259,7 +227,7 @@ class AddLiquidityViewModelTest { advanceUntilIdle() viewModel.slippageChanged(1.0) advanceUntilIdle() - assertEquals(1.0, viewModel.addState.slippage, 0.01) + assertEquals(1.0, viewModel.stateSlippage.value, 0.01) } @Test @@ -268,7 +236,7 @@ class AddLiquidityViewModelTest { advanceUntilIdle() viewModel.onAmount1Change(BigDecimal("110.34")) advanceUntilIdle() - assertEquals(BigDecimal("110.34"), viewModel.addState.assetState1?.amount) + assertEquals(BigDecimal("110.34"), viewModel.addState.value.assetState1?.amount) } @Test @@ -281,7 +249,7 @@ class AddLiquidityViewModelTest { advanceUntilIdle() viewModel.onAmount2Change(BigDecimal("110.34")) advanceUntilIdle() - assertEquals(BigDecimal("110.34"), viewModel.addState.assetState2?.amount) + assertEquals(BigDecimal("110.34"), viewModel.addState.value.assetState2?.amount) } @Test @@ -307,7 +275,7 @@ class AddLiquidityViewModelTest { setUpViewModel(VAL_ASSET.token.id) advanceUntilIdle() - assertEquals(VAL_ASSET.token, viewModel.addState.assetState2?.token) + assertEquals(VAL_ASSET.token, viewModel.addState.value.assetState2?.token) } @Test @@ -315,7 +283,7 @@ class AddLiquidityViewModelTest { setUpViewModel(null) advanceUntilIdle() - assertEquals(XOR_ASSET.token, viewModel.addState.assetState1?.token) + assertEquals(XOR_ASSET.token, viewModel.addState.value.assetState1?.token) } @Test @@ -331,7 +299,7 @@ class AddLiquidityViewModelTest { viewModel.optionSelected(50) advanceUntilIdle() - assertTrue(viewModel.addState.assetState1?.amount?.equalTo(BigDecimal(0.5)) == true) + assertTrue(viewModel.addState.value.assetState1?.amount?.equalTo(BigDecimal(0.5)) == true) } @Test @@ -347,7 +315,7 @@ class AddLiquidityViewModelTest { viewModel.optionSelected(50) advanceUntilIdle() - assertTrue(viewModel.addState.assetState2?.amount?.equalTo(BigDecimal(0.5)) == true) + assertTrue(viewModel.addState.value.assetState2?.amount?.equalTo(BigDecimal(0.5)) == true) } @Test @@ -370,7 +338,7 @@ class AddLiquidityViewModelTest { setUpViewModel(VAL_ASSET.token.id) advanceUntilIdle() - val pair = viewModel.addState.pairNotExist + val pair = viewModel.addState.value.pairNotExist assertTrue(pair == true) } @@ -383,7 +351,7 @@ class AddLiquidityViewModelTest { setUpViewModel(VAL_ASSET.token.id) advanceUntilIdle() - val pair = viewModel.addState.pairNotExist + val pair = viewModel.addState.value.pairNotExist assertTrue(pair == false) } @@ -399,7 +367,7 @@ class AddLiquidityViewModelTest { viewModel.onAmount1Change(BigDecimal("110.34")) viewModel.onAmount2Change(BigDecimal("110.34")) advanceUntilIdle() - assertEquals("1", viewModel.addState.prices.pair1Value) + assertEquals("1", viewModel.addState.value.prices.pair1Value) } @Test diff --git a/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/GetSoraCardViewModel.kt b/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/GetSoraCardViewModel.kt index 8897ab62e..4ddc1fc5e 100644 --- a/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/GetSoraCardViewModel.kt +++ b/feature_sora_card_impl/src/main/java/jp/co/soramitsu/feature_sora_card_impl/presentation/get/card/GetSoraCardViewModel.kt @@ -115,7 +115,7 @@ class GetSoraCardViewModel @AssistedInject constructor( when (soraCardResult) { is SoraCardResult.NavigateTo -> { when (soraCardResult.screen) { - OutwardsScreen.DEPOSIT -> walletRouter.openQrCodeFlow(isLaunchedFromSoraCard = true) + OutwardsScreen.DEPOSIT -> walletRouter.openQrCodeFlow() OutwardsScreen.SWAP -> polkaswapRouter.showSwap(tokenToId = SubstrateOptionsProvider.feeAssetId) OutwardsScreen.BUY -> assetsRouter.showBuyCrypto() } diff --git a/feature_wallet_api/src/main/java/jp/co/soramitsu/feature_wallet_api/launcher/WalletRouter.kt b/feature_wallet_api/src/main/java/jp/co/soramitsu/feature_wallet_api/launcher/WalletRouter.kt index 42dfd6be5..7812ed98d 100644 --- a/feature_wallet_api/src/main/java/jp/co/soramitsu/feature_wallet_api/launcher/WalletRouter.kt +++ b/feature_wallet_api/src/main/java/jp/co/soramitsu/feature_wallet_api/launcher/WalletRouter.kt @@ -48,7 +48,7 @@ interface WalletRouter { fun returnToAddLiquidity(tokenFrom: Token? = null, tokenTo: Token? = null) - fun openQrCodeFlow(shouldNavigateToScannerDirectly: Boolean = false, isLaunchedFromSoraCard: Boolean = false) + fun openQrCodeFlow(shouldNavigateToScannerDirectly: Boolean = false) fun openEditCardsHub() } diff --git a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubViewModel.kt b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubViewModel.kt index b264250b0..0b9ab996a 100644 --- a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubViewModel.kt +++ b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/CardsHubViewModel.kt @@ -233,7 +233,7 @@ class CardsHubViewModel @Inject constructor( when (soraCardResult) { is SoraCardResult.NavigateTo -> { when (soraCardResult.screen) { - OutwardsScreen.DEPOSIT -> router.openQrCodeFlow(isLaunchedFromSoraCard = true) + OutwardsScreen.DEPOSIT -> router.openQrCodeFlow() OutwardsScreen.SWAP -> polkaswapRouter.showSwap(tokenToId = SubstrateOptionsProvider.feeAssetId) OutwardsScreen.BUY -> assetsRouter.showBuyCrypto() } diff --git a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateApi.kt b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateApi.kt index 6f92b2fe3..7ba963d04 100644 --- a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateApi.kt +++ b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateApi.kt @@ -34,21 +34,11 @@ package jp.co.soramitsu.sora.substrate.substrate import java.math.BigInteger import jp.co.soramitsu.common.data.network.dto.PoolDataDto -import jp.co.soramitsu.common.data.network.dto.SwapFeeDto interface SubstrateApi { suspend fun isSwapAvailable(tokenId1: String, tokenId2: String, dexId: Int): Boolean suspend fun fetchAvailableSources(tokenId1: String, tokenId2: String, dexId: Int): List - suspend fun getSwapFees( - tokenId1: String, - tokenId2: String, - amount: BigInteger, - swapVariant: String, - market: List, - filter: String, - dexId: Int, - ): SwapFeeDto? suspend fun getPoolReserveAccount( baseTokenId: String, diff --git a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateApiImpl.kt b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateApiImpl.kt index 283b13ed1..17d399861 100644 --- a/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateApiImpl.kt +++ b/sorasubstrate/src/main/java/jp/co/soramitsu/sora/substrate/substrate/SubstrateApiImpl.kt @@ -35,7 +35,6 @@ package jp.co.soramitsu.sora.substrate.substrate import java.math.BigInteger import javax.inject.Inject import jp.co.soramitsu.common.data.network.dto.PoolDataDto -import jp.co.soramitsu.common.data.network.dto.SwapFeeDto import jp.co.soramitsu.common.logger.FirebaseWrapper import jp.co.soramitsu.shared_utils.extensions.fromHex import jp.co.soramitsu.shared_utils.extensions.toHexString @@ -277,31 +276,6 @@ class SubstrateApiImpl @Inject constructor( mapper = pojoList().nonNull(), ) - override suspend fun getSwapFees( - tokenId1: String, - tokenId2: String, - amount: BigInteger, - swapVariant: String, - market: List, - filter: String, - dexId: Int, - ): SwapFeeDto? = - socketService.executeAsync( - request = RuntimeRequest( - "liquidityProxy_quote", - listOf( - dexId, - tokenId1, - tokenId2, - amount.toString(), - swapVariant, - market, - filter - ) - ), - mapper = pojo(), - ).result - override suspend fun isPairEnabled( inputAssetId: String, outputAssetId: String, From ff1a301de58fada0afa5bf3b065334a80dabdf3a Mon Sep 17 00:00:00 2001 From: arvifox Date: Wed, 6 Sep 2023 08:59:29 +0300 Subject: [PATCH 13/20] sn-2891 token search feature --- common/src/main/res/values-ar/strings.xml | 1 + common/src/main/res/values-az/strings.xml | 1 + common/src/main/res/values-de/strings.xml | 1 + common/src/main/res/values-es/strings.xml | 1 + common/src/main/res/values-fa/strings.xml | 1 + common/src/main/res/values-fi/strings.xml | 1 + common/src/main/res/values-fr/strings.xml | 1 + common/src/main/res/values-hi-rIN/strings.xml | 1 + common/src/main/res/values-in/strings.xml | 1 + common/src/main/res/values-iw/strings.xml | 1 + common/src/main/res/values-ja/strings.xml | 1 + common/src/main/res/values-ms-rMY/strings.xml | 1 + common/src/main/res/values-nb/strings.xml | 1 + common/src/main/res/values-nl/strings.xml | 1 + common/src/main/res/values-pt/strings.xml | 1 + common/src/main/res/values-ru/strings.xml | 1 + common/src/main/res/values-sr/strings.xml | 1 + common/src/main/res/values-tr/strings.xml | 1 + common/src/main/res/values-vi/strings.xml | 1 + common/src/main/res/values-zh-rCN/strings.xml | 1 + common/src/main/res/values-zh-rTW/strings.xml | 1 + common/src/main/res/values/strings.xml | 1 + .../selectsearchtoken/SelectSearchToken.kt | 73 +++++++++++++++---- .../SelectSearchTokenViewModel.kt | 23 ++++-- .../receiverequest/QRCodeFlowFragment.kt | 2 +- .../receiverequest/QRCodeFlowViewModel.kt | 9 ++- .../screens/send/TransferAmountFragment.kt | 2 +- .../screens/send/TransferAmountViewModel.kt | 6 +- .../presentation/states/SendState.kt | 4 +- .../liquidityadd/LiquidityAddFragment.kt | 2 +- .../liquidityadd/LiquidityAddViewModel.kt | 16 ++-- .../presentation/screens/swap/SwapFragment.kt | 2 +- .../screens/swap/SwapViewModel.kt | 9 ++- 33 files changed, 128 insertions(+), 42 deletions(-) diff --git a/common/src/main/res/values-ar/strings.xml b/common/src/main/res/values-ar/strings.xml index 970cc1bf8..e3efa308f 100644 --- a/common/src/main/res/values-ar/strings.xml +++ b/common/src/main/res/values-ar/strings.xml @@ -462,6 +462,7 @@ مسار Show my QR code البحث عن الأصول + لا توجد نتائج بحث البحث عن عنوان الحساب بحث أو إضافة عنوان جديد Select account to import diff --git a/common/src/main/res/values-az/strings.xml b/common/src/main/res/values-az/strings.xml index 748a286a5..03c4c800e 100644 --- a/common/src/main/res/values-az/strings.xml +++ b/common/src/main/res/values-az/strings.xml @@ -438,6 +438,7 @@ Route Show my QR code Search assets + Axtarış nəticələri yoxdur Hesab ünvanını axtarın Yeni ünvan axtarın və ya əlavə edin Select account to import diff --git a/common/src/main/res/values-de/strings.xml b/common/src/main/res/values-de/strings.xml index 48f04cce1..a370dbb67 100644 --- a/common/src/main/res/values-de/strings.xml +++ b/common/src/main/res/values-de/strings.xml @@ -438,6 +438,7 @@ Route Show my QR code Search assets + Keine Suchergebnisse Kontoadresse suchen Suchen oder Hinzufügen einer neuen Adresse Select account to import diff --git a/common/src/main/res/values-es/strings.xml b/common/src/main/res/values-es/strings.xml index b2b163e76..375933338 100644 --- a/common/src/main/res/values-es/strings.xml +++ b/common/src/main/res/values-es/strings.xml @@ -438,6 +438,7 @@ Ruta Show my QR code Buscar activos + No hay resultados de búsqueda Buscar dirección de la cuenta Search or add a new address Select account to import diff --git a/common/src/main/res/values-fa/strings.xml b/common/src/main/res/values-fa/strings.xml index 6148625cf..1fa20f2a2 100644 --- a/common/src/main/res/values-fa/strings.xml +++ b/common/src/main/res/values-fa/strings.xml @@ -438,6 +438,7 @@ Route Show my QR code Search assets + هیچ نتیجه ای برای جستجو یافت نشد جستجو آدرس حساب جستجو یا افزودن یک آدرس جدید Select account to import diff --git a/common/src/main/res/values-fi/strings.xml b/common/src/main/res/values-fi/strings.xml index 4a293454a..b4461ad93 100644 --- a/common/src/main/res/values-fi/strings.xml +++ b/common/src/main/res/values-fi/strings.xml @@ -438,6 +438,7 @@ Route Show my QR code Search assets + Ei hakutuloksia Hae tilin osoite Hae tai lisää uusi osoite Select account to import diff --git a/common/src/main/res/values-fr/strings.xml b/common/src/main/res/values-fr/strings.xml index 0172300a7..76fa90e6b 100644 --- a/common/src/main/res/values-fr/strings.xml +++ b/common/src/main/res/values-fr/strings.xml @@ -438,6 +438,7 @@ Route Afficher mon code QR Rechercher des actifs + Aucun résultat trouvé Recherche de l\'adresse du compte Chercher ou ajouter une nouvelle adresse Sélectionnez un compte à importer diff --git a/common/src/main/res/values-hi-rIN/strings.xml b/common/src/main/res/values-hi-rIN/strings.xml index 05b1708a0..20511f848 100644 --- a/common/src/main/res/values-hi-rIN/strings.xml +++ b/common/src/main/res/values-hi-rIN/strings.xml @@ -438,6 +438,7 @@ मार्ग Show my QR code संपत्ति खोजें + खोजने पर कोई परिणाम नहीं मिला खाता पता खोजें\n नया पता खोजें या जोड़ें Select account to import diff --git a/common/src/main/res/values-in/strings.xml b/common/src/main/res/values-in/strings.xml index aa162be57..b54051ee6 100644 --- a/common/src/main/res/values-in/strings.xml +++ b/common/src/main/res/values-in/strings.xml @@ -433,6 +433,7 @@ Route Show my QR code Search assets + Tidak ada hasil pencarian Cari alamat akun Search or add a new address Select account to import diff --git a/common/src/main/res/values-iw/strings.xml b/common/src/main/res/values-iw/strings.xml index 54fab06bf..421bb75c7 100644 --- a/common/src/main/res/values-iw/strings.xml +++ b/common/src/main/res/values-iw/strings.xml @@ -450,6 +450,7 @@ מסלול הצג את קוד ה-QR שלי חפש נכסים + אין תוצאות חיפוש חפש כתובת חשבון חפש או הוסף כתובת חדשה בחר חשבון לייבוא diff --git a/common/src/main/res/values-ja/strings.xml b/common/src/main/res/values-ja/strings.xml index 8e2fb1fcd..174466b27 100644 --- a/common/src/main/res/values-ja/strings.xml +++ b/common/src/main/res/values-ja/strings.xml @@ -432,6 +432,7 @@ ルート Show my QR code アセットの検索 + 検索結果が存在しません アカウントのアドレスを検索 検索または新規アドレスを追加 Select account to import diff --git a/common/src/main/res/values-ms-rMY/strings.xml b/common/src/main/res/values-ms-rMY/strings.xml index 9fe73a2d3..3ea821896 100644 --- a/common/src/main/res/values-ms-rMY/strings.xml +++ b/common/src/main/res/values-ms-rMY/strings.xml @@ -432,6 +432,7 @@ Laluan Tunjukkan kod QR saya Cari aset + Tiada hasil carian Cari alamat akaun Cari atau tambah alamat baharu Pilih akaun untuk diimport diff --git a/common/src/main/res/values-nb/strings.xml b/common/src/main/res/values-nb/strings.xml index f895037a1..4b8edb83f 100644 --- a/common/src/main/res/values-nb/strings.xml +++ b/common/src/main/res/values-nb/strings.xml @@ -438,6 +438,7 @@ Route Show my QR code Search assets + Ingen søkeresultater Søk etter kontoadresse Search or add a new address Select account to import diff --git a/common/src/main/res/values-nl/strings.xml b/common/src/main/res/values-nl/strings.xml index 976cf3a20..144dda0d8 100644 --- a/common/src/main/res/values-nl/strings.xml +++ b/common/src/main/res/values-nl/strings.xml @@ -438,6 +438,7 @@ Route Show my QR code Assets zoeken + Geen resultaten gevonden Accountadres zoeken Zoek of voeg een nieuw adres toe Select account to import diff --git a/common/src/main/res/values-pt/strings.xml b/common/src/main/res/values-pt/strings.xml index 83c1be991..fc8ac1175 100644 --- a/common/src/main/res/values-pt/strings.xml +++ b/common/src/main/res/values-pt/strings.xml @@ -438,6 +438,7 @@ Route Show my QR code Search assets + Nenhum resultado de pesquisa Pesquisar endereço de conta Pesquisar ou adicionar um novo endereço Select account to import diff --git a/common/src/main/res/values-ru/strings.xml b/common/src/main/res/values-ru/strings.xml index 33d467d9f..90b074f45 100644 --- a/common/src/main/res/values-ru/strings.xml +++ b/common/src/main/res/values-ru/strings.xml @@ -456,6 +456,7 @@ Путь Показать мой QR-код Поиск ассетов + Нет результатов Поиск адреса Поиск или добавление нового адреса Выберите аккаунт для импорта diff --git a/common/src/main/res/values-sr/strings.xml b/common/src/main/res/values-sr/strings.xml index ede350cf8..8fd11a7eb 100644 --- a/common/src/main/res/values-sr/strings.xml +++ b/common/src/main/res/values-sr/strings.xml @@ -443,6 +443,7 @@ Route Show my QR code Search assets + Нема резултата претраге Претражите адресу налога Претражите или додајте нову адресу Select account to import diff --git a/common/src/main/res/values-tr/strings.xml b/common/src/main/res/values-tr/strings.xml index a67583c78..7c0cd2389 100644 --- a/common/src/main/res/values-tr/strings.xml +++ b/common/src/main/res/values-tr/strings.xml @@ -438,6 +438,7 @@ Route Show my QR code Search assets + Arama sonucu bulunamadı Hesap adresini ara Yeni bir adres arayın veya ekleyin Select account to import diff --git a/common/src/main/res/values-vi/strings.xml b/common/src/main/res/values-vi/strings.xml index 9c31ea75b..6287b0cf9 100644 --- a/common/src/main/res/values-vi/strings.xml +++ b/common/src/main/res/values-vi/strings.xml @@ -432,6 +432,7 @@ Route Hiển thị mã QR của tôi Tìm kiếm tài sản + Không có kết quả tìm kiếm Tìm kiếm địa chỉ tài khoản Tìm kiếm hoặc thêm địa chỉ mới Chọn tài khoản để nhập diff --git a/common/src/main/res/values-zh-rCN/strings.xml b/common/src/main/res/values-zh-rCN/strings.xml index 3e2b6212c..6a5297d01 100644 --- a/common/src/main/res/values-zh-rCN/strings.xml +++ b/common/src/main/res/values-zh-rCN/strings.xml @@ -432,6 +432,7 @@ 路径 显示我的二维码 搜索资产 + 无搜索结果 搜索账户地址 搜索或添加新地址 选择要导入的账户 diff --git a/common/src/main/res/values-zh-rTW/strings.xml b/common/src/main/res/values-zh-rTW/strings.xml index a4ba9e966..c57c30d07 100644 --- a/common/src/main/res/values-zh-rTW/strings.xml +++ b/common/src/main/res/values-zh-rTW/strings.xml @@ -433,6 +433,7 @@ Route Show my QR code 搜索資產 + 無搜尋結果 搜索賬戶地址 搜索或添加新地址 Select account to import diff --git a/common/src/main/res/values/strings.xml b/common/src/main/res/values/strings.xml index eccc3c69c..acb048a2b 100644 --- a/common/src/main/res/values/strings.xml +++ b/common/src/main/res/values/strings.xml @@ -438,6 +438,7 @@ Route Show my QR code Search assets + No results Search account address Search or add a new address Select account to import diff --git a/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/selectsearchtoken/SelectSearchToken.kt b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/selectsearchtoken/SelectSearchToken.kt index 050a8074e..54f8ba94a 100644 --- a/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/selectsearchtoken/SelectSearchToken.kt +++ b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/selectsearchtoken/SelectSearchToken.kt @@ -33,41 +33,58 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_assets_api.presentation.selectsearchtoken import androidx.compose.foundation.ScrollState +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.Divider +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import jp.co.soramitsu.common.R import jp.co.soramitsu.common.presentation.compose.components.ContentCardEndless import jp.co.soramitsu.common_wallet.presentation.compose.components.AssetItem import jp.co.soramitsu.common_wallet.presentation.compose.states.AssetItemCardState import jp.co.soramitsu.common_wallet.presentation.compose.states.previewAssetItemCardStateList import jp.co.soramitsu.ui_core.resources.Dimens +import jp.co.soramitsu.ui_core.theme.customColors +import jp.co.soramitsu.ui_core.theme.customTypography data class SelectSearchAssetState( val list: List, ) +data class SearchTokenFilter( + val filter: String, + val tokenIds: List, +) + +val emptySearchTokenFilter = SearchTokenFilter("", emptyList()) + @Composable fun SelectSearchTokenScreen( scrollState: ScrollState, - filter: String, + searchTokenFilter: SearchTokenFilter, viewModel: SelectSearchTokenViewModel = hiltViewModel(), onAssetSelect: (String) -> Unit, ) { val state = viewModel.state.collectAsStateWithLifecycle().value - LaunchedEffect(filter) { - viewModel.onFilterChange(filter) + LaunchedEffect(searchTokenFilter) { + viewModel.onFilterChange(searchTokenFilter) } SelectSearchTokenCard( scrollState = scrollState, @@ -88,19 +105,31 @@ private fun SelectSearchTokenCard( .fillMaxSize(), innerPadding = PaddingValues(top = Dimens.x3), ) { - Column( - modifier = Modifier - .fillMaxSize() - .verticalScroll(scrollState) - ) { - state.list.forEachIndexed { index, assetState -> - AssetItem( - assetState = assetState, - testTag = "${assetState.tokenSymbol}Element", - onClick = onAssetSelect, + if (state.list.isEmpty()) { + Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { + Text( + modifier = Modifier.wrapContentSize(), + text = stringResource(id = R.string.search_empty_state), + textAlign = TextAlign.Center, + style = MaterialTheme.customTypography.paragraphM, + color = MaterialTheme.customColors.fgSecondary, ) - if (index < state.list.lastIndex) { - Divider(color = Color.Transparent, modifier = Modifier.height(Dimens.x1)) + } + } else { + Column( + modifier = Modifier + .fillMaxSize() + .verticalScroll(scrollState) + ) { + state.list.forEachIndexed { index, assetState -> + AssetItem( + assetState = assetState, + testTag = "${assetState.tokenSymbol}Element", + onClick = onAssetSelect, + ) + if (index < state.list.lastIndex) { + Divider(color = Color.Transparent, modifier = Modifier.height(Dimens.x1)) + } } } } @@ -109,7 +138,7 @@ private fun SelectSearchTokenCard( @Composable @Preview -private fun PreviewSelectSearchTokenCard() { +private fun PreviewSelectSearchTokenCard1() { SelectSearchTokenCard( scrollState = rememberScrollState(), state = SelectSearchAssetState( @@ -118,3 +147,15 @@ private fun PreviewSelectSearchTokenCard() { onAssetSelect = {}, ) } + +@Composable +@Preview +private fun PreviewSelectSearchTokenCard2() { + SelectSearchTokenCard( + scrollState = rememberScrollState(), + state = SelectSearchAssetState( + list = emptyList(), + ), + onAssetSelect = {}, + ) +} diff --git a/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/selectsearchtoken/SelectSearchTokenViewModel.kt b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/selectsearchtoken/SelectSearchTokenViewModel.kt index d76245699..99d1a08ea 100644 --- a/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/selectsearchtoken/SelectSearchTokenViewModel.kt +++ b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/presentation/selectsearchtoken/SelectSearchTokenViewModel.kt @@ -56,7 +56,7 @@ class SelectSearchTokenViewModel @Inject constructor( private val _state = MutableStateFlow(SelectSearchAssetState(emptyList())) val state = _state.asStateFlow() - private var filter: String = "" + private var searchTokenFilter = emptySearchTokenFilter private val assets = mutableListOf() init { @@ -73,21 +73,28 @@ class SelectSearchTokenViewModel @Inject constructor( } } - fun onFilterChange(value: String) { - filter = value + fun onFilterChange(value: SearchTokenFilter) { + searchTokenFilter = value reCalcFilter() } + private val tokenFilterInclude: (Asset) -> Boolean = { + searchTokenFilter.tokenIds.contains(it.token.id) + } + private fun reCalcFilter() { - val curFilter = filter.lowercase() - val list = if (curFilter.isBlank()) { - mapAssetsToCardState(assets, numbersFormatter) + val tokensFiltered = + if (searchTokenFilter.tokenIds.isEmpty()) assets + else assets.filter(tokenFilterInclude) + val curFilterValue = searchTokenFilter.filter.lowercase() + val list = if (curFilterValue.isBlank()) { + mapAssetsToCardState(tokensFiltered, numbersFormatter) } else { buildList { addAll( mapAssetsToCardState( - assets.filter { - it.token.isMatchFilter(curFilter) + tokensFiltered.filter { + it.token.isMatchFilter(curFilterValue) }, numbersFormatter ) diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowFragment.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowFragment.kt index 44122ae93..e36df3a0e 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowFragment.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowFragment.kt @@ -148,7 +148,7 @@ class QRCodeFlowFragment : SoraBaseFragment() { viewModel.onSelectToken(it) navController.popBackStack() }, - filter = filter.value, + searchTokenFilter = filter.value, ) } diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt index f688fb3cf..9fdcbd044 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/receiverequest/QRCodeFlowViewModel.kt @@ -57,6 +57,7 @@ import jp.co.soramitsu.common_wallet.domain.model.QrException import jp.co.soramitsu.common_wallet.presentation.compose.util.AmountFormat.getAssetBalanceText import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_assets_api.domain.QrCodeInteractor +import jp.co.soramitsu.feature_assets_api.presentation.selectsearchtoken.emptySearchTokenFilter import jp.co.soramitsu.feature_assets_impl.presentation.components.compose.receiverequest.ReceiveTokenByQrScreenState import jp.co.soramitsu.feature_assets_impl.presentation.components.compose.receiverequest.RequestTokenConfirmScreenState import jp.co.soramitsu.feature_assets_impl.presentation.components.compose.receiverequest.RequestTokenScreenState @@ -123,7 +124,7 @@ class QRCodeFlowViewModel @Inject constructor( ) val requestTokenScreenState = _requestTokenScreenState.asStateFlow() - private val _selectTokenScreenState = MutableStateFlow("") + private val _selectTokenScreenState = MutableStateFlow(emptySearchTokenFilter) val selectTokenScreenState = _selectTokenScreenState.asStateFlow() private val _requestTokenConfirmScreenState = MutableStateFlow( @@ -204,7 +205,9 @@ class QRCodeFlowViewModel @Inject constructor( override fun startScreen(): String = QRCodeFlowRoute.MainScreen.route override fun onToolbarSearch(value: String) { - _selectTokenScreenState.value = value + _selectTokenScreenState.value = _selectTokenScreenState.value.copy( + filter = value, + ) } override fun onCurrentDestinationChanged(curDest: String) { @@ -219,7 +222,7 @@ class QRCodeFlowViewModel @Inject constructor( else -> "" }, searchEnabled = curDest == QRCodeFlowRoute.SelectToken.route, - searchValue = if (curDest == QRCodeFlowRoute.SelectToken.route) _selectTokenScreenState.value else "", + searchValue = if (curDest == QRCodeFlowRoute.SelectToken.route) _selectTokenScreenState.value.filter else "", ) ) } diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountFragment.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountFragment.kt index 2fa065135..20dd39bc7 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountFragment.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountFragment.kt @@ -131,7 +131,7 @@ class TransferAmountFragment : SoraBaseFragment() { SelectSearchTokenScreen( scrollState = scrollState, onAssetSelect = onTokenChange, - filter = state.searchFilter, + searchTokenFilter = state.searchFilter, ) } composable( diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt index 7b60699fe..244238069 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/send/TransferAmountViewModel.kt @@ -211,7 +211,9 @@ class TransferAmountViewModel @AssistedInject constructor( override fun onToolbarSearch(value: String) { _sendState.value = _sendState.value.copy( - searchFilter = value, + searchFilter = _sendState.value.searchFilter.copy( + filter = value, + ), ) } @@ -238,7 +240,7 @@ class TransferAmountViewModel @AssistedInject constructor( basic = state.basic.copy( title = R.string.choose_token, searchEnabled = true, - searchValue = _sendState.value.searchFilter, + searchValue = _sendState.value.searchFilter.filter, ) ) } diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/states/SendState.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/states/SendState.kt index 6ad771af9..1cf4af285 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/states/SendState.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/states/SendState.kt @@ -34,6 +34,8 @@ package jp.co.soramitsu.feature_assets_impl.presentation.states import android.graphics.drawable.Drawable import jp.co.soramitsu.common.domain.AssetAmountInputState +import jp.co.soramitsu.feature_assets_api.presentation.selectsearchtoken.SearchTokenFilter +import jp.co.soramitsu.feature_assets_api.presentation.selectsearchtoken.emptySearchTokenFilter internal data class SendState( val address: String, @@ -44,6 +46,6 @@ internal data class SendState( val fee: String = "", val feeFiat: String = "", val feeLoading: Boolean = true, - val searchFilter: String = "", + val searchFilter: SearchTokenFilter = emptySearchTokenFilter, val shouldTransactionReminderInsufficientWarningBeShown: Boolean = false, ) diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddFragment.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddFragment.kt index 9f1c389d1..5b0718d10 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddFragment.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddFragment.kt @@ -121,7 +121,7 @@ class LiquidityAddFragment : SoraBaseFragment() { SelectSearchTokenScreen( scrollState = scrollState, onAssetSelect = { id -> onTokenSelected.invoke(id, type) }, - filter = state.value, + searchTokenFilter = state.value, ) } composable(LiquidityAddRoutes.slippage) { diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt index 2ee701953..39bf766dc 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/liquidityadd/LiquidityAddViewModel.kt @@ -32,8 +32,6 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_polkaswap_impl.presentation.screens.liquidityadd -import androidx.compose.runtime.getValue -import androidx.compose.runtime.setValue import androidx.lifecycle.viewModelScope import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -60,6 +58,7 @@ import jp.co.soramitsu.common_wallet.presentation.compose.util.AmountFormat import jp.co.soramitsu.common_wallet.presentation.compose.util.PolkaswapFormulas import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter +import jp.co.soramitsu.feature_assets_api.presentation.selectsearchtoken.emptySearchTokenFilter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PoolsInteractor import jp.co.soramitsu.feature_polkaswap_impl.presentation.states.LiquidityAddConfirmState import jp.co.soramitsu.feature_polkaswap_impl.presentation.states.LiquidityAddEstimatedState @@ -151,7 +150,7 @@ class LiquidityAddViewModel @AssistedInject constructor( private var pairEnabled: Boolean = true private var pairPresented: Boolean = true - private val _searchTokenFilter = MutableStateFlow("") + private val _searchTokenFilter = MutableStateFlow(emptySearchTokenFilter) val searchTokenFilter = _searchTokenFilter.asStateFlow() private val _stateSlippage = MutableStateFlow(0.5) @@ -269,7 +268,7 @@ class LiquidityAddViewModel @AssistedInject constructor( } override fun onToolbarSearch(value: String) { - _searchTokenFilter.value = value + _searchTokenFilter.value = _searchTokenFilter.value.copy(filter = value) } override fun onCurrentDestinationChanged(curDest: String) { @@ -287,8 +286,9 @@ class LiquidityAddViewModel @AssistedInject constructor( LiquidityAddRoutes.start -> R.drawable.ic_settings_info else -> R.drawable.ic_arrow_left }, + menu = if (curDest == LiquidityAddRoutes.selectToken) emptyList() else listOf(Action.Close()), searchEnabled = curDest == LiquidityAddRoutes.selectToken, - searchValue = if (curDest == LiquidityAddRoutes.selectToken) _searchTokenFilter.value else "", + searchValue = if (curDest == LiquidityAddRoutes.selectToken) _searchTokenFilter.value.filter else "", ), ) } @@ -515,6 +515,9 @@ class LiquidityAddViewModel @AssistedInject constructor( initialAmount = _addState.value.assetState2?.amount?.nullZero(), ), ) + _searchTokenFilter.value = _searchTokenFilter.value.copy( + tokenIds = list.map { it.token.id }, + ) } } } @@ -553,6 +556,9 @@ class LiquidityAddViewModel @AssistedInject constructor( initialAmount = _addState.value.assetState2?.amount?.nullZero(), ), ) + _searchTokenFilter.value = _searchTokenFilter.value.copy( + tokenIds = list.map { it.token.id }, + ) } } } diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapFragment.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapFragment.kt index d6cb400b6..81d270c67 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapFragment.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapFragment.kt @@ -138,7 +138,7 @@ class SwapFragment : SoraBaseFragment() { SelectSearchTokenScreen( scrollState = scrollState, onAssetSelect = { id -> onTokenSelected.invoke(id, type) }, - filter = state.value, + searchTokenFilter = state.value, ) } composable(SwapRoutes.markets) { diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt index abc5d23c7..abb8e143e 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt @@ -67,6 +67,7 @@ import jp.co.soramitsu.common_wallet.presentation.compose.util.AmountFormat import jp.co.soramitsu.common_wallet.presentation.compose.util.PolkaswapFormulas import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter +import jp.co.soramitsu.feature_assets_api.presentation.selectsearchtoken.emptySearchTokenFilter import jp.co.soramitsu.feature_main_api.launcher.MainRouter import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.SwapInteractor import jp.co.soramitsu.feature_polkaswap_api.domain.model.SwapDetails @@ -170,7 +171,7 @@ class SwapViewModel @AssistedInject constructor( ) val swapMainState = _swapMainState.asStateFlow() - private val _swapTokensFilter = MutableStateFlow("") + private val _swapTokensFilter = MutableStateFlow(emptySearchTokenFilter) val swapTokensFilter = _swapTokensFilter.asStateFlow() private var amountFromPrev: BigDecimal = BigDecimal.ZERO @@ -183,7 +184,9 @@ class SwapViewModel @AssistedInject constructor( override fun startScreen(): String = SwapRoutes.start override fun onToolbarSearch(value: String) { - _swapTokensFilter.value = value + _swapTokensFilter.value = _swapTokensFilter.value.copy( + filter = value, + ) } override fun onCurrentDestinationChanged(curDest: String) { @@ -198,7 +201,7 @@ class SwapViewModel @AssistedInject constructor( else -> "" }, searchEnabled = curDest == SwapRoutes.selectToken, - searchValue = if (curDest == SwapRoutes.selectToken) _swapTokensFilter.value else "" + searchValue = if (curDest == SwapRoutes.selectToken) _swapTokensFilter.value.filter else "" ) ) } From ac037d74518d319dbc0f53247e3ec0547245ad7e Mon Sep 17 00:00:00 2001 From: arvifox Date: Wed, 6 Sep 2023 18:47:21 +0300 Subject: [PATCH 14/20] sn-1991, fiat delta 24h --- build.gradle | 2 +- .../jp/co/soramitsu/common/domain/Fiat.kt | 2 +- .../jp/co/soramitsu/core_db/dao/AssetDao.kt | 6 ++ .../domain/AssetsInteractor.kt | 2 + .../domain/AssetsInteractorImpl.kt | 4 + .../data/BlockExplorerManager.kt | 78 ++++++++++++------- .../presentation/MainViewModel.kt | 7 ++ .../presentation/MainViewModelTest.kt | 2 + 8 files changed, 73 insertions(+), 30 deletions(-) diff --git a/build.gradle b/build.gradle index fad1226b4..d33b8ed03 100644 --- a/build.gradle +++ b/build.gradle @@ -39,7 +39,7 @@ buildscript { insetter : '0.6.0', truth : '1.1.5', lottie : '4.2.0', - xNetworking : '0.0.60', + xNetworking : '0.0.61', compose : '1.4.3', composeMaterial : '1.4.3', composeCompiler : '1.4.6', diff --git a/common/src/main/java/jp/co/soramitsu/common/domain/Fiat.kt b/common/src/main/java/jp/co/soramitsu/common/domain/Fiat.kt index cfcfa6c0f..1f977f19e 100644 --- a/common/src/main/java/jp/co/soramitsu/common/domain/Fiat.kt +++ b/common/src/main/java/jp/co/soramitsu/common/domain/Fiat.kt @@ -62,7 +62,7 @@ fun fiatChange(curValue: Double?, newValue: Double): Double = if (curValue == null || curValue == 0.0) { 0.0 } else { - newValue / curValue - 1 + (newValue / curValue) - 1 } fun Token.calcFiat(amount: BigDecimal): Double? = fiatPrice?.let { diff --git a/core_db/src/main/java/jp/co/soramitsu/core_db/dao/AssetDao.kt b/core_db/src/main/java/jp/co/soramitsu/core_db/dao/AssetDao.kt index 9ff067fad..e26358d2f 100644 --- a/core_db/src/main/java/jp/co/soramitsu/core_db/dao/AssetDao.kt +++ b/core_db/src/main/java/jp/co/soramitsu/core_db/dao/AssetDao.kt @@ -220,4 +220,10 @@ interface AssetDao { @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertFiatPrice(prices: List) + + @Query("select * from fiatTokenPrices where currencyId=:isoCode") + suspend fun getFiatTokenPriceLocal(isoCode: String): List + + @Query("update fiatTokenPrices set fiatPrice=:fiat, fiatPriceTime=:time where tokenIdFiat=:tokenId and currencyId=:isoCode") + suspend fun updateFiatValueOfToken(tokenId: String, isoCode: String, fiat: Double, time: Long) } diff --git a/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/AssetsInteractor.kt b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/AssetsInteractor.kt index 771c9bc61..8b8eed006 100644 --- a/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/AssetsInteractor.kt +++ b/feature_assets_api/src/main/java/jp/co/soramitsu/feature_assets_api/domain/AssetsInteractor.kt @@ -66,6 +66,8 @@ interface AssetsInteractor { suspend fun isWhitelistedToken(tokenId: String): Boolean + suspend fun getTokensList(): List + suspend fun observeTransfer( to: String, token: Token, diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorImpl.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorImpl.kt index 9e5282152..1115d0b59 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorImpl.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/domain/AssetsInteractorImpl.kt @@ -126,6 +126,10 @@ class AssetsInteractorImpl constructor( return assetsRepository.isWhitelistedToken(tokenId) } + override suspend fun getTokensList(): List { + return assetsRepository.tokensList() + } + override suspend fun observeTransfer( to: String, token: Token, diff --git a/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/BlockExplorerManager.kt b/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/BlockExplorerManager.kt index 933ab38f4..103f1ab8a 100644 --- a/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/BlockExplorerManager.kt +++ b/feature_blockexplorer_api/src/main/java/jp/co/soramitsu/feature_blockexplorer_api/data/BlockExplorerManager.kt @@ -34,7 +34,6 @@ package jp.co.soramitsu.feature_blockexplorer_api.data import androidx.room.withTransaction import java.math.BigInteger -import java.util.Date import java.util.concurrent.TimeUnit import javax.inject.Inject import javax.inject.Singleton @@ -60,10 +59,6 @@ class BlockExplorerManager @Inject constructor( private val soraConfigManager: SoraConfigManager, ) { - companion object { - private val fiatChangeUpdatePeriod = TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS) - } - private val tempApy = mutableListOf() private var assetsInfo: List>? = null @@ -77,10 +72,23 @@ class BlockExplorerManager @Inject constructor( assetsInfo = it } - private suspend fun getAssetsInfoInternal(tokenIds: List): List> = - info.getAssetsInfo(tokenIds).map { - it.tokenId to BigInteger(it.liquidity) + private suspend fun getAssetsInfoInternal(tokenIds: List): List> { + val selected = soraConfigManager.getSelectedCurrency() + val tokens = db.assetDao().getFiatTokenPriceLocal(selected.code) + val yesterdayHour = yesterday() + val resultList = mutableListOf>() + val fiats = mutableListOf() + info.getAssetsInfo(tokenIds, yesterdayHour).forEach { assetInfo -> + val dbValue = tokens.find { it.tokenIdFiat == assetInfo.tokenId } + val delta = assetInfo.hourDelta + if (dbValue != null && delta != null) { + fiats.add(dbValue.copy(fiatPricePrevH = delta, fiatPricePrevHTime = yesterdayHour)) + } + resultList.add(assetInfo.tokenId to BigInteger(assetInfo.liquidity)) } + db.assetDao().insertFiatPrice(fiats) + return resultList + } suspend fun updatePoolsSbApy() { updateSbApyInternal() @@ -133,30 +141,38 @@ class BlockExplorerManager @Inject constructor( private suspend fun updateFiatPrices(fiatData: List) { val selected = soraConfigManager.getSelectedCurrency() val tokens = db.assetDao().getTokensWithFiatOfCurrency(selected.code) + val prices = fiatData.mapNotNull { apy -> val dbValue = tokens.find { it.token.id == apy.id } val apyRate = apy.priceUsd if (dbValue != null && apyRate != null) { - val change = fiatChange(dbValue.price?.fiatPricePrevD, apyRate) - val now = Date().time - val replace = dbValue.price?.let { price -> - now > price.fiatPricePrevHTime + fiatChangeUpdatePeriod - } ?: true - FiatTokenPriceLocal( - dbValue.token.id, - selected.code, - apyRate, - now, - if (replace) dbValue.price?.fiatPrice - ?: apyRate else dbValue.price?.fiatPricePrevH ?: apyRate, - if (replace) dbValue.price?.fiatPriceTime - ?: now else dbValue.price?.fiatPricePrevHTime ?: now, - if (replace) dbValue.price?.fiatPricePrevH - ?: apyRate else dbValue.price?.fiatPricePrevD ?: apyRate, - if (replace) dbValue.price?.fiatPricePrevHTime - ?: now else dbValue.price?.fiatPricePrevDTime ?: now, - change, - ) + val dbPrice = dbValue.price + if (dbPrice != null) { + val change = fiatChange(dbPrice.fiatPricePrevH, apyRate) + FiatTokenPriceLocal( + dbPrice.tokenIdFiat, + selected.code, + apyRate, + nowInSecond(), + dbPrice.fiatPricePrevH, + dbPrice.fiatPricePrevHTime, + dbPrice.fiatPricePrevD, + dbPrice.fiatPricePrevDTime, + change, + ) + } else { + FiatTokenPriceLocal( + tokenIdFiat = dbValue.token.id, + selected.code, + apyRate, + nowInSecond(), + 0.0, + 0, + 0.0, + 0, + null, + ) + } } else { null } @@ -164,5 +180,11 @@ class BlockExplorerManager @Inject constructor( db.assetDao().insertFiatPrice(prices) } + private fun nowInSecond() = + TimeUnit.SECONDS.convert(System.currentTimeMillis(), TimeUnit.MILLISECONDS) + + private fun yesterday() = + TimeUnit.SECONDS.convert(System.currentTimeMillis(), TimeUnit.MILLISECONDS) - 24 * 60 * 60 + private class FiatInfo(val id: String, val priceUsd: Double? = null) } diff --git a/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModel.kt b/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModel.kt index d84ca28ee..46c625350 100644 --- a/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModel.kt +++ b/feature_main_impl/src/main/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModel.kt @@ -114,6 +114,13 @@ class MainViewModel @Inject constructor( } } } + viewModelScope.launch { + withContext(coroutineManager.io) { + assetsInteractor.getTokensList().map { it.id }.also { tokens -> + blockExplorerManager.getTokensLiquidity(tokens) + } + } + } } fun showPinFragment() { diff --git a/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModelTest.kt b/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModelTest.kt index 05b1d3ad8..9a1644174 100644 --- a/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModelTest.kt +++ b/feature_main_impl/src/test/java/jp/co/soramitsu/feature_main_impl/presentation/MainViewModelTest.kt @@ -105,6 +105,8 @@ class MainViewModelTest { every { coroutineManager.io } returns this.coroutineContext[CoroutineDispatcher]!! coEvery { blockExplorerManager.updateFiat() } returns Unit coEvery { assetsInteractor.updateWhitelistBalances() } returns Unit + coEvery { assetsInteractor.getTokensList() } returns emptyList() + coEvery { blockExplorerManager.getTokensLiquidity(emptyList()) } returns emptyList() mockkObject(RepeatStrategyBuilder) every { RepeatStrategyBuilder.infinite() } returns object : RepeatStrategy { override suspend fun repeat(block: suspend () -> Unit) { From 57aaafd68820caa7e0677568bdea9a6841d1c698 Mon Sep 17 00:00:00 2001 From: arvifox Date: Thu, 7 Sep 2023 11:57:20 +0300 Subject: [PATCH 15/20] sca-92 card phone number --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d33b8ed03..1866f8a83 100644 --- a/build.gradle +++ b/build.gradle @@ -45,7 +45,7 @@ buildscript { composeCompiler : '1.4.6', composeConstraintLayout: '1.1.0-alpha05', uiCore : '0.1.2', - soraCard : '0.1.38', + soraCard : '0.1.39', lazySodium : '5.0.2', jna : '5.8.0', accompanist : '0.30.1', From 8a0c4544c11f9cbb0cd40d8c5795461c109b7b6d Mon Sep 17 00:00:00 2001 From: arvifox Date: Thu, 7 Sep 2023 21:23:22 +0300 Subject: [PATCH 16/20] sca-92 kyc request --- build.gradle | 2 +- .../co/soramitsu/common_wallet/domain/model/UserPoolData.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 1866f8a83..20b491894 100644 --- a/build.gradle +++ b/build.gradle @@ -45,7 +45,7 @@ buildscript { composeCompiler : '1.4.6', composeConstraintLayout: '1.1.0-alpha05', uiCore : '0.1.2', - soraCard : '0.1.39', + soraCard : '0.1.40', lazySodium : '5.0.2', jna : '5.8.0', accompanist : '0.30.1', diff --git a/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/domain/model/UserPoolData.kt b/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/domain/model/UserPoolData.kt index 7aea582f2..a839eedb5 100644 --- a/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/domain/model/UserPoolData.kt +++ b/common_wallet/src/main/java/jp/co/soramitsu/common_wallet/domain/model/UserPoolData.kt @@ -71,8 +71,8 @@ private fun printFiatInternal(basic: BasicPoolData, user: UserPoolData?): Pair Date: Fri, 8 Sep 2023 16:43:45 +0300 Subject: [PATCH 17/20] sn-2813 search toolbar improvements --- .../compose/scan/QrCodeScannerScreen.kt | 28 ++----- .../fullassetlist/FullAssetListFragment.kt | 44 ++++------- .../fullassetlist/FullAssetListViewModel.kt | 32 +++++--- .../FullAssetSettingsFragment.kt | 34 +++------ .../FullAssetSettingsViewModel.kt | 47 +++++++++--- .../screens/scan/QRCodeScannerActivity.kt | 6 +- .../AssetSettingsViewModelTest.kt | 32 ++++---- .../presentation/EcoSystemTokensState.kt | 4 - .../allcurrencies/AllCurrenciesScreen.kt | 40 ++-------- .../allcurrencies/AllCurrenciesViewModel.kt | 2 +- .../presentation/allpools/AllPoolsScreen.kt | 46 ++---------- .../allpools/AllPoolsViewModel.kt | 1 - .../presentation/explore/ExploreFragment.kt | 8 +- .../presentation/explore/ExploreViewModel.kt | 74 ++++++++++++++++++- .../presentation/start/StartScreen.kt | 2 - .../start/StartScreenViewModel.kt | 3 +- .../classic/PoolsManagementAdapter.kt | 2 +- .../fullpoollist/FullPoolListFragment.kt | 32 ++------ .../fullpoollist/FullPoolListViewModel.kt | 30 ++++++-- .../FullPoolSettingsFragment.kt | 34 +++------ .../FullPoolSettingsViewModel.kt | 41 ++++++++-- .../screens/swap/SwapViewModel.kt | 12 +++ .../presentation/states/PoolSettingsState.kt | 1 + 23 files changed, 293 insertions(+), 262 deletions(-) diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/scan/QrCodeScannerScreen.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/scan/QrCodeScannerScreen.kt index 3aa2e0236..db120028f 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/scan/QrCodeScannerScreen.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/components/compose/scan/QrCodeScannerScreen.kt @@ -49,14 +49,14 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.PathOperation import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp import androidx.constraintlayout.compose.ConstraintLayout import androidx.constraintlayout.compose.Dimension import jp.co.soramitsu.common.R import jp.co.soramitsu.common.presentation.compose.uikit.tokens.ScreenStatus import jp.co.soramitsu.common.presentation.compose.uikit.tokens.Text -import jp.co.soramitsu.common.presentation.compose.uikit.tokens.retrieveString import jp.co.soramitsu.ui_core.component.button.BleachedButton import jp.co.soramitsu.ui_core.component.button.FilledButton import jp.co.soramitsu.ui_core.component.button.properties.Order @@ -71,15 +71,6 @@ data class QRCodeScannerScreenState( val screenStatus: ScreenStatus, val throwable: Throwable? ) { - - val toolbarTitleText: Text = Text.StringRes(id = R.string.common_scan_qr) - - val uploadFromGalleryButtonText: Text = Text.StringRes(id = R.string.common_upload_from_library) - - val showMyQrButtonText: Text = Text.StringRes(id = R.string.scan_qr_show_my_qr) - - val isErrorTextVisible: Boolean = screenStatus === ScreenStatus.ERROR - val errorText: Text get() = throwable?.message?.let { Text.SimpleText(it) @@ -88,7 +79,6 @@ data class QRCodeScannerScreenState( @Composable fun QrCodeScannerScreen( - state: QRCodeScannerScreenState, onNavIconClick: () -> Unit, onUploadFromGalleryClick: () -> Unit, onShowUserQrClick: () -> Unit @@ -122,14 +112,14 @@ fun QrCodeScannerScreen( SoramitsuToolbar( state = SoramitsuToolbarState( basic = BasicToolbarState( - title = state.toolbarTitleText.retrieveString(), + title = R.string.common_scan_qr, navIcon = R.drawable.ic_close, ), type = SoramitsuToolbarType.SmallCentered() ), backgroundColor = blurCameraBackground, - elevation = Dp(0f), - onNavigate = onNavIconClick + elevation = 0.dp, + onNavigate = onNavIconClick, ) } @@ -262,7 +252,7 @@ fun QrCodeScannerScreen( ), size = Size.Large, order = Order.SECONDARY, - text = state.uploadFromGalleryButtonText.retrieveString(), + text = stringResource(id = R.string.common_upload_from_library), onClick = onUploadFromGalleryClick ) @@ -283,7 +273,7 @@ fun QrCodeScannerScreen( ), size = Size.Large, order = Order.SECONDARY, - text = state.showMyQrButtonText.retrieveString(), + text = stringResource(id = R.string.scan_qr_show_my_qr), onClick = onShowUserQrClick ) } @@ -301,10 +291,6 @@ private fun PreviewQrCodeScannerScreen() { contentDescription = "" ) QrCodeScannerScreen( - state = QRCodeScannerScreenState( - screenStatus = ScreenStatus.READY_TO_RENDER, - throwable = null - ), onNavIconClick = {}, onUploadFromGalleryClick = {}, onShowUserQrClick = {} diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetlist/FullAssetListFragment.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetlist/FullAssetListFragment.kt index b9e72f3aa..b5aac4c1e 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetlist/FullAssetListFragment.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetlist/FullAssetListFragment.kt @@ -55,13 +55,14 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material.Divider import androidx.compose.material.MaterialTheme import androidx.compose.material.Text +import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp import androidx.fragment.app.viewModels +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import com.google.accompanist.navigation.animation.composable @@ -72,10 +73,6 @@ import jp.co.soramitsu.common.base.theOnlyRoute import jp.co.soramitsu.common.domain.BottomBarController import jp.co.soramitsu.common_wallet.presentation.compose.components.AssetItem import jp.co.soramitsu.feature_assets_impl.presentation.components.compose.assetslist.CommonAssetsList -import jp.co.soramitsu.ui_core.component.toolbar.BasicToolbarState -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbar -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarState -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarType import jp.co.soramitsu.ui_core.resources.Dimens import jp.co.soramitsu.ui_core.theme.customColors import jp.co.soramitsu.ui_core.theme.customTypography @@ -86,6 +83,9 @@ class FullAssetListFragment : SoraBaseFragment() { override val viewModel: FullAssetListViewModel by viewModels() override fun backgroundColor(): Int = R.attr.baseBackgroundSecond + @Composable + override fun backgroundColorComposable() = MaterialTheme.customColors.bgSurface + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) (activity as BottomBarController).hideBottomBar() @@ -104,23 +104,7 @@ class FullAssetListFragment : SoraBaseFragment() { .background(MaterialTheme.customColors.bgSurface) .fillMaxSize() ) { - SoramitsuToolbar( - state = SoramitsuToolbarState( - basic = BasicToolbarState( - title = "", - navIcon = jp.co.soramitsu.ui_core.R.drawable.ic_cross_24, - actionLabel = R.string.common_edit, - searchValue = "", - ), - type = SoramitsuToolbarType.Small(), - ), - backgroundColor = MaterialTheme.customColors.bgSurface, - elevation = 0.dp, - onAction = viewModel::onAction, - onNavigate = viewModel::onNavIcon, - onSearch = viewModel::searchAssets, - ) - val state = viewModel.state + val state = viewModel.state.collectAsStateWithLifecycle() Row( modifier = Modifier .padding( @@ -142,7 +126,7 @@ class FullAssetListFragment : SoraBaseFragment() { ) Text( modifier = Modifier.weight(1f), - text = state.fiatSum, + text = state.value.fiatSum, textAlign = TextAlign.End, style = MaterialTheme.customTypography.headline2, color = MaterialTheme.customColors.fgPrimary, @@ -154,7 +138,7 @@ class FullAssetListFragment : SoraBaseFragment() { .fillMaxSize() ) { androidx.compose.animation.AnimatedVisibility( - visible = state.searchMode.not(), + visible = state.value.searchMode.not(), enter = fadeIn(), exit = fadeOut(), ) { @@ -164,24 +148,24 @@ class FullAssetListFragment : SoraBaseFragment() { .verticalScroll(scrollState), ) { CommonAssetsList( - state = state, + state = state.value, onAssetClick = viewModel::onAssetClick, ) } } androidx.compose.animation.AnimatedVisibility( - visible = state.searchMode, + visible = state.value.searchMode, enter = fadeIn(), exit = fadeOut(), ) { val listState = rememberLazyListState() LazyColumn(state = listState, modifier = Modifier.fillMaxSize()) { items( - count = state.topList.size + state.bottomList.size + 1, + count = state.value.topList.size + state.value.bottomList.size + 1, key = null, - contentType = { p -> if (p == state.topList.size) 0 else 1 }, + contentType = { p -> if (p == state.value.topList.size) 0 else 1 }, ) { position -> - if (position == state.topList.size) { + if (position == state.value.topList.size) { Text( text = stringResource(id = R.string.global_results).uppercase(), style = MaterialTheme.customTypography.headline4, @@ -189,7 +173,7 @@ class FullAssetListFragment : SoraBaseFragment() { ) } else { val item = - if (position < state.topList.size) state.topList[position] else state.bottomList[position - state.topList.size - 1] + if (position < state.value.topList.size) state.value.topList[position] else state.value.bottomList[position - state.value.topList.size - 1] AssetItem( assetState = item, testTag = "", diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetlist/FullAssetListViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetlist/FullAssetListViewModel.kt index 04663d8a0..6e2c01496 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetlist/FullAssetListViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetlist/FullAssetListViewModel.kt @@ -33,7 +33,6 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_assets_impl.presentation.screens.fullassetlist import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel @@ -49,7 +48,12 @@ import jp.co.soramitsu.common_wallet.presentation.compose.states.mapAssetsToCard import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_assets_impl.presentation.states.FullAssetListState +import jp.co.soramitsu.ui_core.R +import jp.co.soramitsu.ui_core.component.toolbar.BasicToolbarState +import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarState +import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarType import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.debounce @@ -68,10 +72,20 @@ class FullAssetListViewModel @Inject constructor( private val visAssets = mutableListOf() private val filter = MutableStateFlow("") - var state by mutableStateOf(FullAssetListState(false, "", emptyList(), emptyList())) - private set + private val _state = MutableStateFlow(FullAssetListState(false, "", emptyList(), emptyList())) + val state = _state.asStateFlow() init { + _toolbarState.value = SoramitsuToolbarState( + basic = BasicToolbarState( + title = "", + navIcon = R.drawable.ic_cross_24, + actionLabel = jp.co.soramitsu.common.R.string.common_edit, + searchValue = "", + searchEnabled = true, + ), + type = SoramitsuToolbarType.Small(), + ) viewModelScope.launch { allAssets.addAll(assetsInteractor.getWhitelistAssets()) launch { @@ -92,6 +106,10 @@ class FullAssetListViewModel @Inject constructor( } } + override fun onToolbarSearch(value: String) { + filter.value = value + } + private fun calcState(filter: String) { val idMap = visAssets.map { t -> t.token.id } val excluded = allAssets.filter { it.token.id !in idMap } @@ -101,7 +119,7 @@ class FullAssetListViewModel @Inject constructor( val group = visAssets.groupBy { (it.fiat ?: 0.0) >= thresholdBalance } - state = state.copy( + _state.value = _state.value.copy( searchMode = false, topList = mapAssetsToCardState( group[true] ?: emptyList(), @@ -122,7 +140,7 @@ class FullAssetListViewModel @Inject constructor( val bottomFilter = invisibleAssets.filter { it.token.isMatchFilter(filter) } val topSum = topFilter.fiatSum() val bottomSum = bottomFilter.fiatSum() - state = state.copy( + _state.value = _state.value.copy( searchMode = true, topList = mapAssetsToCardState(topFilter, numbersFormatter), bottomList = mapAssetsToCardState(bottomFilter, numbersFormatter), @@ -135,10 +153,6 @@ class FullAssetListViewModel @Inject constructor( } } - fun searchAssets(search: String) { - filter.value = search - } - override fun onAction() { assetsRouter.showFullAssetsSettings() } diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetsettings/FullAssetSettingsFragment.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetsettings/FullAssetSettingsFragment.kt index f2f385293..9b1d91592 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetsettings/FullAssetSettingsFragment.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetsettings/FullAssetSettingsFragment.kt @@ -43,13 +43,14 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material.MaterialTheme import androidx.compose.material.Text +import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.core.content.ContextCompat import androidx.fragment.app.viewModels +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import androidx.recyclerview.widget.DividerItemDecoration @@ -63,10 +64,6 @@ import jp.co.soramitsu.common.presentation.view.WrappedRecyclerView import jp.co.soramitsu.common.view.CustomItemTouchHelperCallback import jp.co.soramitsu.common_wallet.R as polkaswapR import jp.co.soramitsu.feature_assets_impl.presentation.components.classic.AssetsManagementAdapter -import jp.co.soramitsu.ui_core.component.toolbar.BasicToolbarState -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbar -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarState -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarType import jp.co.soramitsu.ui_core.resources.Dimens import jp.co.soramitsu.ui_core.theme.customColors import jp.co.soramitsu.ui_core.theme.customTypography @@ -77,6 +74,9 @@ class FullAssetSettingsFragment : SoraBaseFragment() override val viewModel: FullAssetSettingsViewModel by viewModels() override fun backgroundColor(): Int = R.attr.baseBackgroundSecond + @Composable + override fun backgroundColorComposable() = MaterialTheme.customColors.bgSurface + private val itemTouchHelperCallback = CustomItemTouchHelperCallback { from, to -> viewModel.assetPositionChanged(from, to) } @@ -95,25 +95,6 @@ class FullAssetSettingsFragment : SoraBaseFragment() .background(MaterialTheme.customColors.bgSurface) .fillMaxSize() ) { - SoramitsuToolbar( - state = SoramitsuToolbarState( - basic = BasicToolbarState( - title = "", - navIcon = jp.co.soramitsu.ui_core.R.drawable.ic_cross_24, - actionLabel = R.string.common_done, - searchValue = "", - ), - type = SoramitsuToolbarType.Small(), - ), - backgroundColor = MaterialTheme.customColors.bgSurface, - elevation = 0.dp, - onAction = viewModel::onCloseClick, - onNavigate = viewModel::onCloseClick, - onSearch = { - viewModel.searchAssets(it) - itemTouchHelperCallback.isDraggable = it.isBlank() - }, - ) Row( modifier = Modifier .padding( @@ -134,7 +115,7 @@ class FullAssetSettingsFragment : SoraBaseFragment() ) Text( modifier = Modifier, - text = viewModel.fiatSum, + text = viewModel.fiatSum.collectAsStateWithLifecycle().value, style = MaterialTheme.customTypography.headline2, color = MaterialTheme.customColors.fgPrimary, ) @@ -170,6 +151,9 @@ class FullAssetSettingsFragment : SoraBaseFragment() viewModel::onFavoriteClick, viewModel::onVisibilityClick, ) + viewModel.dragList.observe { + itemTouchHelperCallback.isDraggable = it + } viewModel.settingsState.observe { (view.list.adapter as AssetsManagementAdapter).submitList( buildList { diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetsettings/FullAssetSettingsViewModel.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetsettings/FullAssetSettingsViewModel.kt index 8c1591f65..36df9daa6 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetsettings/FullAssetSettingsViewModel.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/fullassetsettings/FullAssetSettingsViewModel.kt @@ -33,7 +33,6 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_assets_impl.presentation.screens.fullassetsettings import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData @@ -49,6 +48,12 @@ import jp.co.soramitsu.common.util.NumbersFormatter import jp.co.soramitsu.feature_assets_api.domain.AssetsInteractor import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_assets_impl.presentation.states.AssetSettingsState +import jp.co.soramitsu.ui_core.R +import jp.co.soramitsu.ui_core.component.toolbar.BasicToolbarState +import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarState +import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarType +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch @HiltViewModel @@ -61,15 +66,30 @@ class FullAssetSettingsViewModel @Inject constructor( private val _settingsState = MutableLiveData>() val settingsState: LiveData> = _settingsState + private val _dragList = MutableLiveData() + val dragList: LiveData = _dragList + private val curAssetList = mutableListOf() private var positions = mutableListOf() private var curFilter: String = "" private val tokensToMove = mutableListOf>() private var symbol: String = "" - internal var fiatSum by mutableStateOf("") + private val _fiatSum = MutableStateFlow("") + val fiatSum = _fiatSum.asStateFlow() init { + _toolbarState.value = SoramitsuToolbarState( + basic = BasicToolbarState( + title = "", + navIcon = R.drawable.ic_cross_24, + actionLabel = jp.co.soramitsu.common.R.string.common_done, + searchValue = "", + searchEnabled = true, + ), + type = SoramitsuToolbarType.Small(), + ) + viewModelScope.launch { curAssetList.clear() curAssetList.addAll( @@ -97,6 +117,20 @@ class FullAssetSettingsViewModel @Inject constructor( } } + override fun onToolbarSearch(value: String) { + _dragList.value = value.isBlank() + curFilter = value + filterAndUpdateAssetsList() + } + + override fun onAction() { + onCloseClick() + } + + override fun onNavIcon() { + onCloseClick() + } + private fun filterAndUpdateAssetsList() { val filter = curFilter.lowercase() val list = if (filter.isBlank()) { @@ -111,17 +145,12 @@ class FullAssetSettingsViewModel @Inject constructor( } } _settingsState.value = list - fiatSum = if (list.isNotEmpty()) + _fiatSum.value = if (list.isNotEmpty()) list.map { it.fiat ?: 0.0 }.reduce { acc, d -> acc + d }.let { formatFiatAmount(it, symbol, numbersFormatter) } else "" } - fun searchAssets(filter: String) { - curFilter = filter - filterAndUpdateAssetsList() - } - fun onFavoriteClick(asset: AssetSettingsState) { val checked = asset.favorite.not() val position = curAssetList.indexOfFirst { it.token.id == asset.token.id } @@ -176,7 +205,7 @@ class FullAssetSettingsViewModel @Inject constructor( } } - fun onCloseClick() { + private fun onCloseClick() { val unknownVisibleCount = curAssetList.count { it.favorite && !AssetHolder.isKnownAsset(it.token.id) } val position = AssetHolder.knownCount() + unknownVisibleCount diff --git a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/scan/QRCodeScannerActivity.kt b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/scan/QRCodeScannerActivity.kt index c37151b61..8fcf8aff6 100644 --- a/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/scan/QRCodeScannerActivity.kt +++ b/feature_assets_impl/src/main/java/jp/co/soramitsu/feature_assets_impl/presentation/screens/scan/QRCodeScannerActivity.kt @@ -53,6 +53,7 @@ import androidx.lifecycle.repeatOnLifecycle import com.google.zxing.client.android.Intents import com.journeyapps.barcodescanner.CaptureManager import dagger.hilt.android.AndroidEntryPoint +import jp.co.soramitsu.common.presentation.compose.uikit.tokens.ScreenStatus import jp.co.soramitsu.common.presentation.compose.uikit.tokens.retrieveString import jp.co.soramitsu.feature_assets_impl.databinding.QrCodeScannerLayoutBinding import jp.co.soramitsu.feature_assets_impl.presentation.components.compose.scan.QrCodeScannerScreen @@ -131,10 +132,9 @@ class QRCodeScannerActivity : AppCompatActivity() { setContent { MaterialTheme { QrCodeScannerScreen( - state = viewModel.qrCodeScannerScreenState, onNavIconClick = ::finish, onUploadFromGalleryClick = ::selectQrFromGallery, - onShowUserQrClick = ::finish + onShowUserQrClick = ::finish, ) } } @@ -158,7 +158,7 @@ class QRCodeScannerActivity : AppCompatActivity() { lifecycleScope.launch { repeatOnLifecycle(state = Lifecycle.State.STARTED) { snapshotFlow { viewModel.qrCodeScannerScreenState }.collectLatest { state -> - if (state.isErrorTextVisible) { + if (state.screenStatus == ScreenStatus.ERROR) { Toast.makeText( this@QRCodeScannerActivity, state.errorText.retrieveString( diff --git a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/assetsettings/AssetSettingsViewModelTest.kt b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/assetsettings/AssetSettingsViewModelTest.kt index d44a3d11f..a6fdbba3f 100644 --- a/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/assetsettings/AssetSettingsViewModelTest.kt +++ b/feature_assets_impl/src/test/java/jp/co/soramitsu/feature_assets_impl/presentation/assetsettings/AssetSettingsViewModelTest.kt @@ -146,7 +146,7 @@ class AssetSettingsViewModelTest { viewModel.onFavoriteClick(mappedModels[6]) advanceUntilIdle() verify(assetsInteractor).tokenFavoriteOn(listOf("token2_id")) - viewModel.onCloseClick() + viewModel.onAction() advanceUntilIdle() val map = list.map { it.token.id }.let { Collections.swap(it, 5, 6) @@ -168,7 +168,7 @@ class AssetSettingsViewModelTest { viewModel.onFavoriteClick(mappedModels[2]) advanceUntilIdle() verify(assetsInteractor).tokenFavoriteOn(listOf("0x0200050000000000000000000000000000000000000000000000000000000000")) - viewModel.onCloseClick() + viewModel.onAction() advanceUntilIdle() val map = list.map { it.token.id }.let { Collections.swap(it, 6, 7) @@ -193,7 +193,7 @@ class AssetSettingsViewModelTest { viewModel.onFavoriteClick(mappedModels[5]) advanceUntilIdle() verify(assetsInteractor).tokenFavoriteOff(listOf("token_id")) - viewModel.onCloseClick() + viewModel.onAction() advanceUntilIdle() val map = list.map { it.token.id }.let { Collections.swap(it, 5, 6) @@ -221,7 +221,7 @@ class AssetSettingsViewModelTest { viewModel.onFavoriteClick(mappedModels[8]) advanceUntilIdle() verify(assetsInteractor).tokenFavoriteOff(listOf("token4_id")) - viewModel.onCloseClick() + viewModel.onAction() advanceUntilIdle() val map = list.map { it.token.id }.let { Collections.swap(it, 6, 7) @@ -241,7 +241,7 @@ class AssetSettingsViewModelTest { viewModel.onFavoriteClick(mappedModels[8]) advanceUntilIdle() verify(assetsInteractor).tokenFavoriteOn(listOf("token4_id")) - viewModel.onCloseClick() + viewModel.onAction() advanceUntilIdle() val map = list.map { it.token.id }.let { Collections.swap(it, 5, 6) @@ -269,7 +269,7 @@ class AssetSettingsViewModelTest { viewModel.onFavoriteClick(mappedModels[8]) advanceUntilIdle() verify(assetsInteractor).tokenFavoriteOn(listOf("token4_id")) - viewModel.onCloseClick() + viewModel.onAction() advanceUntilIdle() val map = list.map { it.token.id }.mapIndexed { index, s -> s to index }.toMap() verify(assetsInteractor).updateAssetPositions(map) @@ -283,7 +283,7 @@ class AssetSettingsViewModelTest { viewModel.onFavoriteClick(mappedModels[6]) advanceUntilIdle() verify(assetsInteractor).tokenFavoriteOff(listOf("token2_id")) - viewModel.onCloseClick() + viewModel.onAction() advanceUntilIdle() val map = list.map { it.token.id }.let { Collections.swap(it, 6, 7) @@ -304,7 +304,7 @@ class AssetSettingsViewModelTest { viewModel.onFavoriteClick(mappedModels[7]) advanceUntilIdle() verify(assetsInteractor).tokenFavoriteOff(listOf("token3_id")) - viewModel.onCloseClick() + viewModel.onAction() advanceUntilIdle() val map = list.map { it.token.id }.let { Collections.swap(it, 7, 8) @@ -328,7 +328,7 @@ class AssetSettingsViewModelTest { viewModel.onFavoriteClick(mappedModels[7]) advanceUntilIdle() verify(assetsInteractor).tokenFavoriteOff(listOf("token3_id")) - viewModel.onCloseClick() + viewModel.onAction() advanceUntilIdle() val map = list.map { it.token.id }.let { Collections.swap(it, 7, 8) @@ -356,7 +356,7 @@ class AssetSettingsViewModelTest { viewModel.onFavoriteClick(mappedModels[8]) advanceUntilIdle() verify(assetsInteractor).tokenFavoriteOff(listOf("token4_id")) - viewModel.onCloseClick() + viewModel.onAction() advanceUntilIdle() val map = list.map { it.token.id }.mapIndexed { index, s -> s to index }.toMap() verify(assetsInteractor).updateAssetPositions(map) @@ -391,7 +391,7 @@ class AssetSettingsViewModelTest { viewModel.onFavoriteClick(mappedModels[8]) advanceUntilIdle() verify(assetsInteractor).tokenFavoriteOff(listOf("token4_id")) - viewModel.onCloseClick() + viewModel.onAction() advanceUntilIdle() val map = list.map { it.token.id }.mapIndexed { index, s -> s to index }.toMap() verify(assetsInteractor).updateAssetPositions(map) @@ -411,7 +411,7 @@ class AssetSettingsViewModelTest { viewModel.onFavoriteClick(mappedModels[6]) advanceUntilIdle() verify(assetsInteractor).tokenFavoriteOff(listOf("token2_id")) - viewModel.onCloseClick() + viewModel.onAction() advanceUntilIdle() val map = list.map { it.token.id }.let { Collections.swap(it, 7, 8) @@ -446,7 +446,7 @@ class AssetSettingsViewModelTest { @Test fun `click back`() = runTest { setUpStartList() - viewModel.onCloseClick() + viewModel.onAction() advanceUntilIdle() verify(router).popBackStackFragment() } @@ -454,7 +454,7 @@ class AssetSettingsViewModelTest { @Test fun `click done`() = runTest { setUpStartList() - viewModel.onCloseClick() + viewModel.onAction() advanceUntilIdle() verify(router).popBackStackFragment() } @@ -465,7 +465,7 @@ class AssetSettingsViewModelTest { val mappedModels = mapModels(list) viewModel.onFavoriteClick(mappedModels[0]) advanceUntilIdle() - viewModel.onCloseClick() + viewModel.onAction() advanceUntilIdle() verify(router).popBackStackFragment() } @@ -478,7 +478,7 @@ class AssetSettingsViewModelTest { advanceUntilIdle() viewModel.onFavoriteClick(mappedModels[1]) advanceUntilIdle() - viewModel.onCloseClick() + viewModel.onAction() advanceUntilIdle() verify(router).popBackStackFragment() } diff --git a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/EcoSystemTokensState.kt b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/EcoSystemTokensState.kt index 0f4c6e00b..afe997e93 100644 --- a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/EcoSystemTokensState.kt +++ b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/EcoSystemTokensState.kt @@ -39,20 +39,16 @@ import jp.co.soramitsu.common_wallet.presentation.compose.states.assetItemCardSt internal data class EcoSystemTokensState( val topTokens: List>, - val filter: String, ) internal val initialEcoSystemTokensState = EcoSystemTokensState( topTokens = List(5) { i -> (i + 1).toString() to assetItemCardStateEmpty }, - filter = "", ) internal data class EcoSystemPoolsState( val pools: List, - val filter: String, ) internal val initialEcoSystemPoolsState = EcoSystemPoolsState( pools = List(5) { i -> basicPoolListItemStateEmpty }, - filter = "", ) diff --git a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allcurrencies/AllCurrenciesScreen.kt b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allcurrencies/AllCurrenciesScreen.kt index 60ddbebd0..43aa31694 100644 --- a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allcurrencies/AllCurrenciesScreen.kt +++ b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allcurrencies/AllCurrenciesScreen.kt @@ -33,72 +33,50 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_ecosystem_impl.presentation.allcurrencies import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import jp.co.soramitsu.common.R import jp.co.soramitsu.common.presentation.compose.components.ContentCardEndless import jp.co.soramitsu.common_wallet.presentation.compose.components.AssetItemEnumerated import jp.co.soramitsu.common_wallet.presentation.compose.states.previewAssetItemCardStateList import jp.co.soramitsu.feature_ecosystem_impl.presentation.EcoSystemTokensState -import jp.co.soramitsu.ui_core.component.toolbar.BasicToolbarState -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbar -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarState -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarType import jp.co.soramitsu.ui_core.resources.Dimens @Composable internal fun AllCurrenciesScreen( + searchState: String, onTokenClicked: (String) -> Unit, - onNavClicked: () -> Unit, viewModel: AllCurrenciesViewModel = hiltViewModel(), ) { + LaunchedEffect(searchState) { + viewModel.onSearch(searchState) + } Column(modifier = Modifier.fillMaxSize()) { val state = viewModel.state.collectAsStateWithLifecycle().value AllCurrenciesInternal( state = state, - onNavIconClicked = onNavClicked, - onSearch = viewModel::onSearch, onTokenClicked = onTokenClicked, ) } } @Composable -private fun ColumnScope.AllCurrenciesInternal( +private fun AllCurrenciesInternal( state: EcoSystemTokensState, - onNavIconClicked: () -> Unit, - onSearch: (String) -> Unit, onTokenClicked: (String) -> Unit, ) { - SoramitsuToolbar( - state = SoramitsuToolbarState( - basic = BasicToolbarState( - title = R.string.common_currencies, - navIcon = jp.co.soramitsu.ui_core.R.drawable.ic_arrow_left, - searchValue = state.filter, - ), - type = SoramitsuToolbarType.Small(), - ), - elevation = 0.dp, - onNavigate = onNavIconClicked, - onSearch = onSearch, - ) ContentCardEndless( modifier = Modifier .padding(start = Dimens.x2, end = Dimens.x2, top = Dimens.x2) - .fillMaxWidth() - .weight(1f), + .fillMaxSize(), innerPadding = PaddingValues(all = Dimens.x2), ) { val listState = rememberLazyListState() @@ -127,9 +105,7 @@ private fun PreviewAllCurrenciesInternal() { previewAssetItemCardStateList.mapIndexed { q, w -> q.toString() to w }, - "", ), - {}, {}, {}, - ) + ) {} } } diff --git a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allcurrencies/AllCurrenciesViewModel.kt b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allcurrencies/AllCurrenciesViewModel.kt index 27e601b33..09bd13fa4 100644 --- a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allcurrencies/AllCurrenciesViewModel.kt +++ b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allcurrencies/AllCurrenciesViewModel.kt @@ -83,7 +83,7 @@ internal class AllCurrenciesViewModel @Inject constructor( val indexInAll = positions?.get(it.second.tokenId).orEmpty() indexInAll to it.second } - EcoSystemTokensState(mappedEnumerated, pair.second) + EcoSystemTokensState(mappedEnumerated) } .flowOn(coroutineManager.io) .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), initialEcoSystemTokensState) diff --git a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allpools/AllPoolsScreen.kt b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allpools/AllPoolsScreen.kt index 19e89c684..00e2e4c99 100644 --- a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allpools/AllPoolsScreen.kt +++ b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allpools/AllPoolsScreen.kt @@ -33,79 +33,51 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_ecosystem_impl.presentation.allpools import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import jp.co.soramitsu.common.R import jp.co.soramitsu.common.presentation.compose.components.ContentCardEndless import jp.co.soramitsu.common.util.StringPair import jp.co.soramitsu.common_wallet.presentation.compose.BasicPoolListItem import jp.co.soramitsu.common_wallet.presentation.compose.previewBasicPoolListItemState import jp.co.soramitsu.feature_ecosystem_impl.presentation.EcoSystemPoolsState -import jp.co.soramitsu.ui_core.component.toolbar.Action -import jp.co.soramitsu.ui_core.component.toolbar.BasicToolbarState -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbar -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarState -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarType import jp.co.soramitsu.ui_core.resources.Dimens @Composable internal fun AllPoolsScreen( + searchState: String, onPoolClicked: (StringPair) -> Unit, - onNavClicked: () -> Unit, - onPoolPlus: () -> Unit, viewModel: AllPoolsViewModel = hiltViewModel(), ) { + LaunchedEffect(searchState) { + viewModel.onSearch(searchState) + } Column(modifier = Modifier.fillMaxSize()) { val state = viewModel.poolsState.collectAsStateWithLifecycle().value AllPoolsInternal( state = state, - onNavIconClicked = onNavClicked, - onSearch = viewModel::onSearch, onPoolClicked = onPoolClicked, - onPoolPlus = onPoolPlus, ) } } @Composable -private fun ColumnScope.AllPoolsInternal( +private fun AllPoolsInternal( state: EcoSystemPoolsState, - onNavIconClicked: () -> Unit, - onSearch: (String) -> Unit, onPoolClicked: (StringPair) -> Unit, - onPoolPlus: () -> Unit, ) { - SoramitsuToolbar( - state = SoramitsuToolbarState( - basic = BasicToolbarState( - title = R.string.discovery_polkaswap_pools, - menu = listOf(Action.Plus()), - navIcon = jp.co.soramitsu.ui_core.R.drawable.ic_arrow_left, - searchValue = state.filter, - ), - type = SoramitsuToolbarType.Small(), - ), - elevation = 0.dp, - onNavigate = onNavIconClicked, - onSearch = onSearch, - onMenuItemClicked = { onPoolPlus.invoke() }, - ) ContentCardEndless( modifier = Modifier .padding(start = Dimens.x2, end = Dimens.x2, top = Dimens.x2) - .fillMaxWidth() - .weight(1f), + .fillMaxSize(), innerPadding = PaddingValues(all = Dimens.x2), ) { val listState = rememberLazyListState() @@ -130,12 +102,8 @@ private fun PreviewAllPoolsInternal() { AllPoolsInternal( state = EcoSystemPoolsState( pools = previewBasicPoolListItemState, - filter = "", ), - onNavIconClicked = {}, - onSearch = {}, onPoolClicked = {}, - onPoolPlus = {}, ) } } diff --git a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allpools/AllPoolsViewModel.kt b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allpools/AllPoolsViewModel.kt index 88846dd50..9ada953ed 100644 --- a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allpools/AllPoolsViewModel.kt +++ b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/allpools/AllPoolsViewModel.kt @@ -88,7 +88,6 @@ internal class AllPoolsViewModel @Inject constructor( } EcoSystemPoolsState( pools = mappedEnumerated, - filter = pair.second, ) } .flowOn(coroutineManager.io) diff --git a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/explore/ExploreFragment.kt b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/explore/ExploreFragment.kt index 9912dfb87..0cdd12399 100644 --- a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/explore/ExploreFragment.kt +++ b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/explore/ExploreFragment.kt @@ -35,6 +35,7 @@ package jp.co.soramitsu.feature_ecosystem_impl.presentation.explore import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.ScrollState import androidx.fragment.app.viewModels +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import com.google.accompanist.navigation.animation.composable @@ -86,18 +87,19 @@ class ExploreFragment : SoraBaseFragment() { composable( route = ExploreRoutes.ALL_CURRENCIES, ) { + val searchState = viewModel.searchState.collectAsStateWithLifecycle() AllCurrenciesScreen( + searchState = searchState.value, onTokenClicked = viewModel::onTokenClicked, - onNavClicked = { navController.popBackStack() }, ) } composable( route = ExploreRoutes.ALL_POOLS, ) { + val searchState = viewModel.searchState.collectAsStateWithLifecycle() AllPoolsScreen( + searchState = searchState.value, onPoolClicked = viewModel::onPoolClicked, - onNavClicked = { navController.popBackStack() }, - onPoolPlus = viewModel::onPoolPlus, ) } } diff --git a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/explore/ExploreViewModel.kt b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/explore/ExploreViewModel.kt index d1b1f4cdf..1ff8ace89 100644 --- a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/explore/ExploreViewModel.kt +++ b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/explore/ExploreViewModel.kt @@ -34,12 +34,19 @@ package jp.co.soramitsu.feature_ecosystem_impl.presentation.explore import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject +import jp.co.soramitsu.common.R import jp.co.soramitsu.common.presentation.viewmodel.BaseViewModel import jp.co.soramitsu.common.util.StringPair import jp.co.soramitsu.feature_assets_api.presentation.AssetsRouter import jp.co.soramitsu.feature_ecosystem_impl.presentation.ExploreRoutes import jp.co.soramitsu.feature_polkaswap_api.launcher.PolkaswapRouter import jp.co.soramitsu.sora.substrate.runtime.SubstrateOptionsProvider +import jp.co.soramitsu.ui_core.component.toolbar.Action +import jp.co.soramitsu.ui_core.component.toolbar.BasicToolbarState +import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarState +import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarType +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow @HiltViewModel class ExploreViewModel @Inject constructor( @@ -47,8 +54,73 @@ class ExploreViewModel @Inject constructor( private val assetsRouter: AssetsRouter, ) : BaseViewModel() { + private val _searchState = MutableStateFlow("") + val searchState = _searchState.asStateFlow() + + init { + _toolbarState.value = SoramitsuToolbarState( + type = SoramitsuToolbarType.Small(), + basic = BasicToolbarState( + title = "", + navIcon = jp.co.soramitsu.ui_core.R.drawable.ic_arrow_left, + visibility = false, + searchEnabled = false, + ), + ) + } + override fun startScreen(): String = ExploreRoutes.START + override fun onMenuItem(action: Action) { + when (action) { + is Action.Plus -> { + onPoolPlus() + } + else -> {} + } + } + + override fun onCurrentDestinationChanged(curDest: String) { + _toolbarState.value?.let { state -> + when (curDest) { + ExploreRoutes.ALL_POOLS -> { + _toolbarState.value = state.copy( + basic = state.basic.copy( + visibility = true, + title = R.string.discovery_polkaswap_pools, + searchEnabled = true, + searchValue = _searchState.value, + menu = listOf(Action.Plus()), + ) + ) + } + ExploreRoutes.ALL_CURRENCIES -> { + _toolbarState.value = state.copy( + basic = state.basic.copy( + visibility = true, + title = R.string.common_currencies, + searchEnabled = true, + searchValue = _searchState.value, + menu = emptyList(), + ) + ) + } + else -> { + _toolbarState.value = state.copy( + basic = state.basic.copy( + visibility = false, + searchEnabled = false, + ) + ) + } + } + } + } + + override fun onToolbarSearch(value: String) { + _searchState.value = value + } + fun onTokenClicked(tokenId: String) { assetsRouter.showAssetDetails(tokenId) } @@ -57,7 +129,7 @@ class ExploreViewModel @Inject constructor( polkaswapRouter.showPoolDetails(pool) } - fun onPoolPlus() { + private fun onPoolPlus() { polkaswapRouter.showAddLiquidity(SubstrateOptionsProvider.feeAssetId) } } diff --git a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/start/StartScreen.kt b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/start/StartScreen.kt index 89b9c0faa..d23b653fe 100644 --- a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/start/StartScreen.kt +++ b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/start/StartScreen.kt @@ -156,11 +156,9 @@ private fun DiscoverScreenPreview() { previewAssetItemCardStateList.mapIndexed { i, a -> i.toString() to a }, - "", ), EcoSystemPoolsState( previewBasicPoolListItemState, - "", ), {}, {}, {}, {}, ) diff --git a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/start/StartScreenViewModel.kt b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/start/StartScreenViewModel.kt index 2672a05c9..eb09f3137 100644 --- a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/start/StartScreenViewModel.kt +++ b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/start/StartScreenViewModel.kt @@ -80,7 +80,7 @@ internal class StartScreenViewModel @Inject constructor( ) } .map { - EcoSystemTokensState(ecoSystemMapper.mapEcoSystemTokens(it), "") + EcoSystemTokensState(ecoSystemMapper.mapEcoSystemTokens(it)) } .flowOn(coroutineManager.io) .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), initialEcoSystemTokensState) @@ -97,7 +97,6 @@ internal class StartScreenViewModel @Inject constructor( .map { EcoSystemPoolsState( pools = ecoSystemMapper.mapEcoSystemPools(it), - filter = "", ) } .flowOn(coroutineManager.io) diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/classic/PoolsManagementAdapter.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/classic/PoolsManagementAdapter.kt index b6cc18b32..3202f5d1b 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/classic/PoolsManagementAdapter.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/components/classic/PoolsManagementAdapter.kt @@ -85,7 +85,7 @@ class PoolViewHolder( fun bind(asset: PoolSettingsState) { assetIcon.load(asset.token1Icon) asset2Icon.load(asset.token2Icon) - title.text = asset.tokenName + title.text = asset.tokenSymbol amount.text = asset.assetAmount favoriteIcon.setImageResource(if (asset.favorite) R.drawable.ic_favorite_enabled else R.drawable.ic_favorite_disabled) diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoollist/FullPoolListFragment.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoollist/FullPoolListFragment.kt index a0dfd4c10..312e985e3 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoollist/FullPoolListFragment.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoollist/FullPoolListFragment.kt @@ -48,12 +48,13 @@ import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.verticalScroll import androidx.compose.material.MaterialTheme import androidx.compose.material.Text +import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp import androidx.fragment.app.viewModels +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import com.google.accompanist.navigation.animation.composable @@ -63,10 +64,6 @@ import jp.co.soramitsu.common.base.SoraBaseFragment import jp.co.soramitsu.common.base.theOnlyRoute import jp.co.soramitsu.common.domain.BottomBarController import jp.co.soramitsu.common_wallet.presentation.compose.components.PoolsList -import jp.co.soramitsu.ui_core.component.toolbar.BasicToolbarState -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbar -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarState -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarType import jp.co.soramitsu.ui_core.resources.Dimens import jp.co.soramitsu.ui_core.theme.customColors import jp.co.soramitsu.ui_core.theme.customTypography @@ -77,6 +74,9 @@ class FullPoolListFragment : SoraBaseFragment() { override val viewModel: FullPoolListViewModel by viewModels() override fun backgroundColor(): Int = R.attr.baseBackgroundSecond + @Composable + override fun backgroundColorComposable() = MaterialTheme.customColors.bgSurface + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) (activity as BottomBarController).hideBottomBar() @@ -95,23 +95,7 @@ class FullPoolListFragment : SoraBaseFragment() { .background(MaterialTheme.customColors.bgSurface) .fillMaxSize() ) { - SoramitsuToolbar( - state = SoramitsuToolbarState( - basic = BasicToolbarState( - title = "", - navIcon = jp.co.soramitsu.ui_core.R.drawable.ic_cross_24, - actionLabel = R.string.common_edit, - searchValue = "", - ), - type = SoramitsuToolbarType.Small(), - ), - backgroundColor = MaterialTheme.customColors.bgSurface, - elevation = 0.dp, - onAction = viewModel::onAction, - onNavigate = viewModel::onNavIcon, - onSearch = viewModel::searchAssets, - ) - val state = viewModel.state + val state = viewModel.state.collectAsStateWithLifecycle() Row( modifier = Modifier .padding( @@ -133,7 +117,7 @@ class FullPoolListFragment : SoraBaseFragment() { ) Text( modifier = Modifier.weight(1f), - text = state.fiatSum, + text = state.value.fiatSum, textAlign = TextAlign.End, style = MaterialTheme.customTypography.headline2, color = MaterialTheme.customColors.fgPrimary, @@ -145,7 +129,7 @@ class FullPoolListFragment : SoraBaseFragment() { .verticalScroll(scrollState) ) { PoolsList( - cardState = state.list, + cardState = state.value.list, onPoolClick = viewModel::onPoolClick, ) } diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoollist/FullPoolListViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoollist/FullPoolListViewModel.kt index ac163ce4c..60c5a6366 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoollist/FullPoolListViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoollist/FullPoolListViewModel.kt @@ -33,7 +33,6 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_polkaswap_impl.presentation.screens.fullpoollist import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel @@ -50,7 +49,12 @@ import jp.co.soramitsu.common_wallet.presentation.compose.states.mapPoolsData import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PoolsInteractor import jp.co.soramitsu.feature_polkaswap_api.launcher.PolkaswapRouter import jp.co.soramitsu.feature_polkaswap_impl.presentation.states.FullPoolListState +import jp.co.soramitsu.ui_core.R +import jp.co.soramitsu.ui_core.component.toolbar.BasicToolbarState +import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarState +import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarType import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.debounce @@ -66,15 +70,25 @@ class FullPoolListViewModel @Inject constructor( private val allPools = mutableListOf() private val filter = MutableStateFlow("") - internal var state by mutableStateOf( + private val _state = MutableStateFlow( FullPoolListState( "", PoolsListState(emptyList()) ) ) - private set + internal val state = _state.asStateFlow() init { + _toolbarState.value = SoramitsuToolbarState( + type = SoramitsuToolbarType.Small(), + basic = BasicToolbarState( + title = "", + navIcon = R.drawable.ic_cross_24, + visibility = true, + searchEnabled = true, + actionLabel = jp.co.soramitsu.common.R.string.common_edit, + ), + ) viewModelScope.launch { poolsInteractor.subscribePoolsCacheOfCurAccount() .catch { onError(it) } @@ -93,11 +107,15 @@ class FullPoolListViewModel @Inject constructor( } } + override fun onToolbarSearch(value: String) { + filter.value = value + } + private fun calcState(filter: String) { val filtered = if (filter.isBlank()) allPools else allPools.filter { it.basic.isFilterMatch(filter) } val data = mapPoolsData(filtered, numbersFormatter) - state = state.copy( + _state.value = _state.value.copy( list = data.first, fiatSum = formatFiatAmount( data.second, @@ -107,10 +125,6 @@ class FullPoolListViewModel @Inject constructor( ) } - fun searchAssets(search: String) { - filter.value = search - } - override fun onAction() { polkaswapRouter.showFullPoolsSettings() } diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoolsettings/FullPoolSettingsFragment.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoolsettings/FullPoolSettingsFragment.kt index 155caee54..b1dc5ef74 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoolsettings/FullPoolSettingsFragment.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoolsettings/FullPoolSettingsFragment.kt @@ -43,13 +43,14 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material.MaterialTheme import androidx.compose.material.Text +import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.core.content.ContextCompat import androidx.fragment.app.viewModels +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import androidx.recyclerview.widget.DividerItemDecoration @@ -63,10 +64,6 @@ import jp.co.soramitsu.common.presentation.view.WrappedRecyclerView import jp.co.soramitsu.common.view.CustomItemTouchHelperCallback import jp.co.soramitsu.common_wallet.R as polkaswapR import jp.co.soramitsu.feature_polkaswap_impl.presentation.components.classic.PoolsManagementAdapter -import jp.co.soramitsu.ui_core.component.toolbar.BasicToolbarState -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbar -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarState -import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarType import jp.co.soramitsu.ui_core.resources.Dimens import jp.co.soramitsu.ui_core.theme.customColors import jp.co.soramitsu.ui_core.theme.customTypography @@ -77,6 +74,9 @@ class FullPoolSettingsFragment : SoraBaseFragment() { override val viewModel: FullPoolSettingsViewModel by viewModels() override fun backgroundColor(): Int = R.attr.baseBackgroundSecond + @Composable + override fun backgroundColorComposable() = MaterialTheme.customColors.bgSurface + private val itemTouchHelperCallback = CustomItemTouchHelperCallback { from, to -> viewModel.assetPositionChanged(from, to) } @@ -95,25 +95,6 @@ class FullPoolSettingsFragment : SoraBaseFragment() { .background(MaterialTheme.customColors.bgSurface) .fillMaxSize() ) { - SoramitsuToolbar( - state = SoramitsuToolbarState( - basic = BasicToolbarState( - title = "", - navIcon = jp.co.soramitsu.ui_core.R.drawable.ic_cross_24, - actionLabel = R.string.common_done, - searchValue = "", - ), - type = SoramitsuToolbarType.Small(), - ), - backgroundColor = MaterialTheme.customColors.bgSurface, - elevation = 0.dp, - onAction = viewModel::onCloseClick, - onNavigate = viewModel::onCloseClick, - onSearch = { - viewModel.searchAssets(it) - itemTouchHelperCallback.isDraggable = it.isBlank() - }, - ) Row( modifier = Modifier .padding( @@ -134,7 +115,7 @@ class FullPoolSettingsFragment : SoraBaseFragment() { ) Text( modifier = Modifier, - text = viewModel.fiatSum, + text = viewModel.fiatSum.collectAsStateWithLifecycle().value, style = MaterialTheme.customTypography.headline2, color = MaterialTheme.customColors.fgPrimary, ) @@ -176,6 +157,9 @@ class FullPoolSettingsFragment : SoraBaseFragment() { } ) } + viewModel.dragList.observe { + itemTouchHelperCallback.isDraggable = it + } viewModel.assetPositions.observe { (view.list.adapter as PoolsManagementAdapter).notifyItemMoved( it.first, diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoolsettings/FullPoolSettingsViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoolsettings/FullPoolSettingsViewModel.kt index 5ab536a50..fd81977c7 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoolsettings/FullPoolSettingsViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/fullpoolsettings/FullPoolSettingsViewModel.kt @@ -33,7 +33,6 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_polkaswap_impl.presentation.screens.fullpoolsettings import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData @@ -51,6 +50,12 @@ import jp.co.soramitsu.common_wallet.domain.model.fiatSymbol import jp.co.soramitsu.feature_polkaswap_api.domain.interfaces.PoolsInteractor import jp.co.soramitsu.feature_polkaswap_impl.presentation.states.PoolSettingsState import jp.co.soramitsu.feature_wallet_api.launcher.WalletRouter +import jp.co.soramitsu.ui_core.R +import jp.co.soramitsu.ui_core.component.toolbar.BasicToolbarState +import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarState +import jp.co.soramitsu.ui_core.component.toolbar.SoramitsuToolbarType +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch @HiltViewModel @@ -66,14 +71,28 @@ class FullPoolSettingsViewModel @Inject constructor( private val _assetPositions = MutableLiveData>() val assetPositions: LiveData> = _assetPositions + private val _dragList = MutableLiveData() + val dragList: LiveData = _dragList + private val curPoolList = mutableListOf() private var positions = mutableListOf() private var curFilter: String = "" private var symbol: String = "" - internal var fiatSum by mutableStateOf("") + private val _fiatSum = MutableStateFlow("") + internal val fiatSum = _fiatSum.asStateFlow() init { + _toolbarState.value = SoramitsuToolbarState( + type = SoramitsuToolbarType.Small(), + basic = BasicToolbarState( + title = "", + navIcon = R.drawable.ic_cross_24, + visibility = true, + searchEnabled = true, + actionLabel = jp.co.soramitsu.common.R.string.common_done, + ), + ) viewModelScope.launch { val pools: List = poolsInteractor.getPoolsCacheOfCurAccount() @@ -85,6 +104,10 @@ class FullPoolSettingsViewModel @Inject constructor( token1Icon = poolData.basic.baseToken.iconUri(), token2Icon = poolData.basic.targetToken.iconUri(), tokenName = "%s-%s".format( + poolData.basic.baseToken.name, + poolData.basic.targetToken.name, + ), + tokenSymbol = "%s-%s".format( poolData.basic.baseToken.symbol, poolData.basic.targetToken.symbol, ), @@ -119,6 +142,7 @@ class FullPoolSettingsViewModel @Inject constructor( addAll( curPoolList.filter { it.tokenName.lowercase().contains(filter) || + it.tokenSymbol.lowercase().contains(filter) || it.assetAmount.lowercase().contains(filter) || it.id.first.lowercase().contains(filter) || it.id.second.lowercase().contains(filter) @@ -128,14 +152,15 @@ class FullPoolSettingsViewModel @Inject constructor( } _settingsState.value = list - fiatSum = if (list.isNotEmpty()) + _fiatSum.value = if (list.isNotEmpty()) list.map { it.fiat }.reduce { acc, d -> acc + d }.let { formatFiatAmount(it, symbol, numbersFormatter) } else "" } - fun searchAssets(filter: String) { - curFilter = filter + override fun onToolbarSearch(value: String) { + _dragList.value = value.isBlank() + curFilter = value filterAndUpdateAssetsList() } @@ -163,7 +188,11 @@ class FullPoolSettingsViewModel @Inject constructor( return true } - fun onCloseClick() { + override fun onAction() { + walletRouter.popBackStackFragment() + } + + override fun onNavIcon() { walletRouter.popBackStackFragment() } diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt index abb8e143e..230102682 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/screens/swap/SwapViewModel.kt @@ -422,6 +422,12 @@ class SwapViewModel @AssistedInject constructor( fun fromCardClicked() { if (assetsList.isNotEmpty()) { + val filtered = assetsList.filter { + it.token.id != _swapMainState.value.tokenToState?.token?.id.orEmpty() + } + _swapTokensFilter.value = _swapTokensFilter.value.copy( + tokenIds = filtered.map { it.token.id } + ) _swapMainState.value = _swapMainState.value.copy( tokenFromState = _swapMainState.value.tokenFromState?.copy( initialAmount = _swapMainState.value.tokenFromState?.amount?.nullZero(), @@ -435,6 +441,12 @@ class SwapViewModel @AssistedInject constructor( fun toCardClicked() { if (assetsList.isNotEmpty()) { + val filtered = assetsList.filter { + it.token.id != _swapMainState.value.tokenFromState?.token?.id.orEmpty() + } + _swapTokensFilter.value = _swapTokensFilter.value.copy( + tokenIds = filtered.map { it.token.id } + ) _swapMainState.value = _swapMainState.value.copy( tokenFromState = _swapMainState.value.tokenFromState?.copy( initialAmount = _swapMainState.value.tokenFromState?.amount?.nullZero(), diff --git a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/PoolSettingsState.kt b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/PoolSettingsState.kt index 75152fb7d..fd8b4032c 100644 --- a/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/PoolSettingsState.kt +++ b/feature_polkaswap_impl/src/main/java/jp/co/soramitsu/feature_polkaswap_impl/presentation/states/PoolSettingsState.kt @@ -40,6 +40,7 @@ data class PoolSettingsState( val token1Icon: Uri, val token2Icon: Uri, val tokenName: String, + val tokenSymbol: String, val assetAmount: String, val favorite: Boolean, val fiat: Double, From 9949f3bfaa64f4745f105115ef3781eaf1596e13 Mon Sep 17 00:00:00 2001 From: arvifox Date: Fri, 8 Sep 2023 17:35:15 +0300 Subject: [PATCH 18/20] soralution release v3.4.0.1 107 --- app/build.gradle | 2 +- build.gradle | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index f576dd966..0a22478ca 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -144,7 +144,7 @@ play { serviceAccountCredentials = file(System.env.CI_PLAY_KEY ?: "../key/fake.json") track = "internal" releaseStatus = ReleaseStatus.DRAFT - releaseName = "3.4.0.0 - Explore Ecosystem" + releaseName = "3.4.0.1 - Explore Ecosystem" } dependencies { diff --git a/build.gradle b/build.gradle index 20b491894..85d4e7be0 100644 --- a/build.gradle +++ b/build.gradle @@ -54,11 +54,11 @@ buildscript { ] ext { - // soralution 106 3.4.0.0 2023.08.25 + // soralution 107 3.4.0.1 2023.09.08 // sora dae 98 3.3.0.0 2023.08.18 // appVersionCode = Integer.valueOf(System.env.BUILD_NUMBER ?: 96) - appVersionCode = Integer.valueOf(System.env.CI_BUILD_ID ?: 106) - appVersionName = '3.4.0.0' + appVersionCode = Integer.valueOf(System.env.CI_BUILD_ID ?: 107) + appVersionName = '3.4.0.1' compileVersion = 33 minVersion = 24 From be154d5812fda8df707ece497116dfec7e6bca17 Mon Sep 17 00:00:00 2001 From: arvifox Date: Fri, 8 Sep 2023 22:57:15 +0300 Subject: [PATCH 19/20] sn-2888 banner card --- .../presentation/cardshub/BasicBannerCard.kt | 201 ++++++++++++++++++ .../presentation/cardshub/BuyXorCard.kt | 118 ++-------- .../presentation/cardshub/ReferralCard.kt | 123 +---------- 3 files changed, 221 insertions(+), 221 deletions(-) create mode 100644 feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/BasicBannerCard.kt diff --git a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/BasicBannerCard.kt b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/BasicBannerCard.kt new file mode 100644 index 000000000..95239644c --- /dev/null +++ b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/BasicBannerCard.kt @@ -0,0 +1,201 @@ +/* +This file is part of the SORA network and Polkaswap app. + +Copyright (c) 2020, 2021, Polka Biome Ltd. All rights reserved. +SPDX-License-Identifier: BSD-4-Clause + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list +of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this +list of conditions and the following disclaimer in the documentation and/or other +materials provided with the distribution. + +All advertising materials mentioning features or use of this software must display +the following acknowledgement: This product includes software developed by Polka Biome +Ltd., SORA, and Polkaswap. + +Neither the name of the Polka Biome Ltd. nor the names of its contributors may be used +to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY Polka Biome Ltd. AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Polka Biome Ltd. BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package jp.co.soramitsu.feature_wallet_impl.presentation.cardshub + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.layout.wrapContentWidth +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.constraintlayout.compose.ConstraintLayout +import androidx.constraintlayout.compose.Dimension +import jp.co.soramitsu.common.R +import jp.co.soramitsu.ui_core.component.button.BleachedButton +import jp.co.soramitsu.ui_core.component.button.FilledButton +import jp.co.soramitsu.ui_core.component.button.properties.Order +import jp.co.soramitsu.ui_core.component.button.properties.Size +import jp.co.soramitsu.ui_core.component.card.ContentCard +import jp.co.soramitsu.ui_core.resources.Dimens +import jp.co.soramitsu.ui_core.theme.customColors +import jp.co.soramitsu.ui_core.theme.customTypography + +@Composable +fun BasicBannerCard( + @DrawableRes imageContent: Int, + title: String, + description: String, + button: String, + onButtonClicked: () -> Unit, + onCloseCard: () -> Unit, +) { + ContentCard( + modifier = Modifier.fillMaxWidth(), + onClick = onButtonClicked, + ) { + Box( + modifier = Modifier + .fillMaxWidth() + ) { + ConstraintLayout( + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight(), + ) { + val (card, image) = createRefs() + val guideLine = createGuidelineFromStart(0.66f) + CardContent( + modifier = Modifier + .constrainAs(card) { + top.linkTo(parent.top) + start.linkTo(parent.start) + end.linkTo(guideLine) + width = Dimension.fillToConstraints + height = Dimension.wrapContent + }, + title = title, + description = description, + button = button, + onStartClicked = onButtonClicked, + ) + + Image( + modifier = Modifier.constrainAs(image) { + start.linkTo(guideLine) + top.linkTo(parent.top) + end.linkTo(parent.end) + bottom.linkTo(parent.bottom) + width = Dimension.fillToConstraints + height = Dimension.fillToConstraints + }, + contentScale = ContentScale.Fit, + alignment = Alignment.Center, + painter = painterResource(imageContent), + contentDescription = null, + ) + } + + BleachedButton( + modifier = Modifier + .wrapContentWidth() + .align(Alignment.TopEnd) + .padding(Dimens.x1), + size = Size.ExtraSmall, + order = Order.TERTIARY, + shape = CircleShape, + onClick = onCloseCard, + leftIcon = painterResource(R.drawable.ic_cross), + ) + } + } +} + +@Composable +private fun CardContent( + modifier: Modifier = Modifier, + title: String, + description: String, + button: String, + onStartClicked: () -> Unit, +) { + Column( + modifier = modifier + .padding( + start = Dimens.x3, + top = Dimens.x3, + bottom = Dimens.x2, + ), + verticalArrangement = Arrangement.SpaceEvenly, + ) { + Text( + text = title, + style = MaterialTheme.customTypography.headline2, + color = MaterialTheme.customColors.fgPrimary, + ) + + Text( + modifier = Modifier.padding(top = Dimens.x1), + text = description, + style = MaterialTheme.customTypography.paragraphXS, + color = MaterialTheme.customColors.fgPrimary, + ) + + FilledButton( + modifier = Modifier + .wrapContentWidth() + .padding(top = Dimens.x1_5), + text = button, + size = Size.ExtraSmall, + order = Order.PRIMARY, + onClick = onStartClicked, + ) + } +} + +@Preview +@Composable +private fun PreviewBasicBannerCard1() { + BasicBannerCard( + imageContent = R.drawable.image_friends, + title = "Some title of banner card, let it be longeeerr", + description = "Long description of banner card, The quick brown fox jumps over the lazy dog, The quick brown fox jumps over the lazy dog.And I, even I Artaxerxes the king, do make a decree to all the treasurers which are beyond the river, that whatsoever Ezra the priest, the scribe of the law of the God of heaven, shall require of you, it be done speedily", + button = "Just button title", + onCloseCard = {}, + onButtonClicked = {}, + ) +} + +@Preview +@Composable +private fun PreviewBasicBannerCard2() { + BasicBannerCard( + imageContent = R.drawable.ic_buy_xor_banner_sora, + title = "Title", + description = "Description", + button = "Button", + onCloseCard = {}, + onButtonClicked = {}, + ) +} diff --git a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/BuyXorCard.kt b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/BuyXorCard.kt index 69c9ccbe8..8f9c6fe75 100644 --- a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/BuyXorCard.kt +++ b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/BuyXorCard.kt @@ -32,125 +32,31 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_wallet_impl.presentation.cardshub -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentWidth -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import jp.co.soramitsu.common.R -import jp.co.soramitsu.ui_core.component.button.BleachedButton -import jp.co.soramitsu.ui_core.component.button.FilledButton -import jp.co.soramitsu.ui_core.component.button.properties.Order -import jp.co.soramitsu.ui_core.component.button.properties.Size -import jp.co.soramitsu.ui_core.component.card.ContentCard -import jp.co.soramitsu.ui_core.resources.Dimens -import jp.co.soramitsu.ui_core.theme.customColors -import jp.co.soramitsu.ui_core.theme.customTypography @Composable fun BuyXorCard( onCloseCard: () -> Unit, onBuyXorClicked: () -> Unit, ) { - ContentCard( - modifier = Modifier.fillMaxWidth(), - onClick = onBuyXorClicked, - ) { - Box( - modifier = Modifier - .fillMaxWidth() - ) { - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.Bottom, - horizontalArrangement = Arrangement.SpaceBetween - ) { - BuyXorContent(onBuyXorClicked = onBuyXorClicked) - - Image( - painter = painterResource(R.drawable.ic_buy_xor_banner_sora), - contentDescription = null - ) - } - - BleachedButton( - modifier = Modifier - .wrapContentWidth() - .align(Alignment.TopEnd) - .padding(Dimens.x1), - size = Size.ExtraSmall, - order = Order.TERTIARY, - shape = CircleShape, - onClick = onCloseCard, - leftIcon = painterResource(R.drawable.ic_cross), - ) - } - } -} - -@Composable -private fun BuyXorContent( - modifier: Modifier = Modifier, - onBuyXorClicked: () -> Unit -) { - Column( - modifier = modifier - .padding( - top = Dimens.x2, - bottom = Dimens.x3, - start = Dimens.x3, - end = Dimens.x3, - ) - ) { - Text( - text = stringResource(R.string.buy_crypto_buy_xor_banner_title), - style = MaterialTheme.customTypography.headline2, - color = MaterialTheme.customColors.fgPrimary - ) - - Text( - modifier = Modifier.padding(top = Dimens.x1), - text = stringResource(R.string.buy_crypto_buy_xor_with_fiat_subtitle), - style = MaterialTheme.customTypography.paragraphXS, - color = MaterialTheme.customColors.fgPrimary - ) - - FilledButton( - modifier = Modifier - .wrapContentWidth() - .padding(top = Dimens.x2), - text = stringResource(R.string.common_buy_xor), - size = Size.ExtraSmall, - order = Order.PRIMARY, - onClick = onBuyXorClicked, - ) - } + BasicBannerCard( + imageContent = R.drawable.ic_buy_xor_banner_sora, + title = stringResource(id = R.string.buy_crypto_buy_xor_banner_title), + description = stringResource(id = R.string.buy_crypto_buy_xor_with_fiat_subtitle), + button = stringResource(id = R.string.common_buy_xor), + onButtonClicked = onBuyXorClicked, + onCloseCard = onCloseCard, + ) } @Preview @Composable private fun PreviewBuyXorCard() { - Box( - modifier = Modifier - .fillMaxSize() - .padding(Dimens.x3) - ) { - BuyXorCard( - onCloseCard = {}, - onBuyXorClicked = {} - ) - } + BuyXorCard( + onCloseCard = {}, + onBuyXorClicked = {}, + ) } diff --git a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/ReferralCard.kt b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/ReferralCard.kt index 8b05d0427..9841b8d1d 100644 --- a/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/ReferralCard.kt +++ b/feature_wallet_impl/src/main/java/jp/co/soramitsu/feature_wallet_impl/presentation/cardshub/ReferralCard.kt @@ -32,131 +32,24 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package jp.co.soramitsu.feature_wallet_impl.presentation.cardshub -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.foundation.layout.wrapContentWidth -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview -import androidx.constraintlayout.compose.ConstraintLayout -import androidx.constraintlayout.compose.Dimension import jp.co.soramitsu.common.R -import jp.co.soramitsu.ui_core.component.button.BleachedButton -import jp.co.soramitsu.ui_core.component.button.FilledButton -import jp.co.soramitsu.ui_core.component.button.properties.Order -import jp.co.soramitsu.ui_core.component.button.properties.Size -import jp.co.soramitsu.ui_core.component.card.ContentCard -import jp.co.soramitsu.ui_core.resources.Dimens -import jp.co.soramitsu.ui_core.theme.customColors -import jp.co.soramitsu.ui_core.theme.customTypography @Composable fun ReferralCard( onStartClicked: () -> Unit, onCloseCard: () -> Unit, ) { - ContentCard( - modifier = Modifier.fillMaxWidth(), - onClick = onStartClicked, - ) { - Box( - modifier = Modifier - .fillMaxWidth() - ) { - ConstraintLayout( - modifier = Modifier - .fillMaxWidth() - .wrapContentHeight(), - ) { - val (ref, image) = createRefs() - ReferralContent( - modifier = Modifier - .constrainAs(ref) { - top.linkTo(parent.top) - start.linkTo(parent.start) - }, - onStartClicked = onStartClicked, - ) - - Image( - modifier = Modifier.constrainAs(image) { - start.linkTo(ref.end) - top.linkTo(parent.top) - end.linkTo(parent.end) - bottom.linkTo(ref.bottom) - width = Dimension.fillToConstraints - height = Dimension.fillToConstraints - }, - contentScale = ContentScale.Fit, - alignment = Alignment.CenterEnd, - painter = painterResource(R.drawable.image_friends), - contentDescription = null, - ) - } - - BleachedButton( - modifier = Modifier - .wrapContentWidth() - .align(Alignment.TopEnd) - .padding(Dimens.x1), - size = Size.ExtraSmall, - order = Order.TERTIARY, - shape = CircleShape, - onClick = onCloseCard, - leftIcon = painterResource(R.drawable.ic_cross), - ) - } - } -} - -@Composable -private fun ReferralContent( - modifier: Modifier = Modifier, - onStartClicked: () -> Unit, -) { - Column( - modifier = modifier - .padding( - top = Dimens.x2, - bottom = Dimens.x2, - start = Dimens.x3, - ) - .wrapContentHeight(), - ) { - Text( - text = stringResource(R.string.settings_invite_title), - style = MaterialTheme.customTypography.headline2, - color = MaterialTheme.customColors.fgPrimary, - ) - - Text( - modifier = Modifier.padding(top = Dimens.x1), - text = stringResource(R.string.referral_title), - style = MaterialTheme.customTypography.paragraphXS, - color = MaterialTheme.customColors.fgPrimary, - ) - - FilledButton( - modifier = Modifier - .wrapContentWidth() - .padding(top = Dimens.x1_5), - text = stringResource(R.string.referral_start_inviting), - size = Size.ExtraSmall, - order = Order.PRIMARY, - onClick = onStartClicked, - ) - } + BasicBannerCard( + imageContent = R.drawable.image_friends, + title = stringResource(id = R.string.settings_invite_title), + description = stringResource(id = R.string.referral_title), + button = stringResource(id = R.string.referral_start_inviting), + onButtonClicked = onStartClicked, + onCloseCard = onCloseCard, + ) } @Preview From 2a338c99e448755e336d91a88239411cf2c4abb8 Mon Sep 17 00:00:00 2001 From: arvifox Date: Fri, 8 Sep 2023 23:10:42 +0300 Subject: [PATCH 20/20] sora release v.3.3.0.2 100 --- build.gradle | 4 ++-- .../presentation/explore/ExploreViewModel.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 12236b97b..02f110430 100644 --- a/build.gradle +++ b/build.gradle @@ -55,9 +55,9 @@ buildscript { ext { // soralution 107 3.4.0.1 2023.09.08 - // sora dae 99 3.3.0.1 2023.08.28 + // sora dae 100 3.3.0.1 2023.09.08 // appVersionCode = Integer.valueOf(System.env.BUILD_NUMBER ?: 96) - appVersionCode = Integer.valueOf(System.env.CI_BUILD_ID ?: 107) + appVersionCode = Integer.valueOf(System.env.CI_BUILD_ID ?: 100) appVersionName = '3.3.0.2' compileVersion = 33 diff --git a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/explore/ExploreViewModel.kt b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/explore/ExploreViewModel.kt index 1ff8ace89..a36a4bba9 100644 --- a/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/explore/ExploreViewModel.kt +++ b/feature_ecosystem_impl/src/main/java/jp/co/soramitsu/feature_ecosystem_impl/presentation/explore/ExploreViewModel.kt @@ -129,7 +129,7 @@ class ExploreViewModel @Inject constructor( polkaswapRouter.showPoolDetails(pool) } - private fun onPoolPlus() { + fun onPoolPlus() { polkaswapRouter.showAddLiquidity(SubstrateOptionsProvider.feeAssetId) } }