Updated on 2026-08-14
This commit is contained in:
parent
c024ba2836
commit
96784ebd43
8 changed files with 53 additions and 21 deletions
|
|
@ -552,6 +552,7 @@
|
|||
<string name="feedback_subject_support_tangem">Tangemへのフィードバック</string>
|
||||
<string name="feedback_subject_tx_failed">取引を送信できません</string>
|
||||
<string name="feedback_token_description_error">コインの説明エラー</string>
|
||||
<string name="gasless_transaction_fee">ガス代不要の取引手数料</string>
|
||||
<string name="generic_error">エラーが発生しました</string>
|
||||
<string name="generic_error_code">エラーが発生しました。コード: %s 。</string>
|
||||
<string name="generic_requires_memo_error">メモが必要</string>
|
||||
|
|
@ -973,6 +974,7 @@
|
|||
<string name="onboarding_wallet_info_title_fourth">アクセスコードの復元</string>
|
||||
<string name="onboarding_wallet_info_title_second">同一のカード</string>
|
||||
<string name="onboarding_wallet_info_title_third">アクセスコード</string>
|
||||
<string name="only_one_mobile_wallet_explanation">同時に利用できるのは、モバイルウォレットまたはハードウェアウォレットのいずれか一方のみです。Tangemのコールドウォレットを使用するには、ウォレットをアップグレードするか、アプリから削除してください。</string>
|
||||
<string name="onramp_all_offers_button_title">すべてのオファー</string>
|
||||
<string name="onramp_avaiable_with_payment_methods">%sで利用可能</string>
|
||||
<string name="onramp_choose_provider_title_hint">プロバイダーが取引を促進します</string>
|
||||
|
|
|
|||
|
|
@ -560,6 +560,7 @@
|
|||
<string name="feedback_subject_support_tangem">Tangem feedback</string>
|
||||
<string name="feedback_subject_tx_failed">Can\'t send a transaction</string>
|
||||
<string name="feedback_token_description_error">Coin description error</string>
|
||||
<string name="gasless_not_enough_funds_to_cover_token_fee">Not enough funds</string>
|
||||
<string name="gasless_transaction_fee">Gasless transaction fee</string>
|
||||
<string name="generic_error">An error occurred</string>
|
||||
<string name="generic_error_code">An error occurred. Code: %s.</string>
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ data class FeeExtraInfo(
|
|||
val feeCryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
val availableFeeCurrencies: ImmutableList<CryptoCurrencyStatus>? = null,
|
||||
val transactionFeeExtended: TransactionFeeExtended? = null,
|
||||
val isNotEnoughFunds: Boolean = false,
|
||||
)
|
||||
|
||||
sealed class FeeNonce {
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ fun FeeExtendedSelectorContent(state: FeeExtendedSelectorUM, modifier: Modifier
|
|||
},
|
||||
ellipsizeOffset = fee.amount.currencySymbol.length,
|
||||
showSelectorIcon = isChooseSpeedAvailable,
|
||||
isNotEnoughFunds = state.parent.feeExtraInfo.isNotEnoughFunds,
|
||||
isLoading = state.fee.isLoading(),
|
||||
)
|
||||
}
|
||||
|
|
@ -168,6 +169,7 @@ private fun Preview() {
|
|||
isFeeConvertibleToFiat = true,
|
||||
isTronToken = false,
|
||||
feeCryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
isNotEnoughFunds = true,
|
||||
),
|
||||
feeNonce = FeeNonce.None,
|
||||
feeFiatRateUM = FeeFiatRateUM(
|
||||
|
|
|
|||
|
|
@ -328,6 +328,7 @@ internal fun RegularFeeItemContent(
|
|||
ellipsizeOffset: Int? = null,
|
||||
showSelectorIcon: Boolean = false,
|
||||
isLoading: Boolean = false,
|
||||
isNotEnoughFunds: Boolean = false,
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
Row(
|
||||
|
|
@ -353,6 +354,7 @@ internal fun RegularFeeItemContent(
|
|||
postDot = postDot,
|
||||
ellipsizeOffset = ellipsizeOffset,
|
||||
isLoading = isLoading,
|
||||
isNotEnoughFunds = isNotEnoughFunds,
|
||||
)
|
||||
|
||||
if (showSelectorIcon) {
|
||||
|
|
@ -376,6 +378,7 @@ private fun FeeDescription(
|
|||
postDot: TextReference? = null,
|
||||
ellipsizeOffset: Int? = null,
|
||||
isLoading: Boolean = false,
|
||||
isNotEnoughFunds: Boolean = false,
|
||||
) {
|
||||
Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(2.dp)) {
|
||||
Text(
|
||||
|
|
@ -385,6 +388,11 @@ private fun FeeDescription(
|
|||
modifier = Modifier.testTag(SendSelectNetworkFeeBottomSheetTestTags.REGULAR_ITEM_TITLE),
|
||||
)
|
||||
when {
|
||||
isNotEnoughFunds -> Text(
|
||||
text = stringResourceSafe(R.string.gasless_not_enough_funds_to_cover_token_fee),
|
||||
color = TangemTheme.colors.text.warning,
|
||||
style = TangemTheme.typography.caption1,
|
||||
)
|
||||
isLoading -> TextShimmer(
|
||||
modifier = Modifier.width(122.dp),
|
||||
style = TangemTheme.typography.caption1,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.features.send.v2.feeselector.model
|
|||
import arrow.core.Either
|
||||
import arrow.core.flatMap
|
||||
import arrow.core.getOrElse
|
||||
import arrow.core.left
|
||||
import arrow.core.raise.either
|
||||
import com.tangem.blockchain.common.AmountType
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
|
|
@ -228,10 +229,13 @@ internal class FeeSelectorLogic @AssistedInject constructor(
|
|||
|
||||
return extended(selectedTokenOrNull).fold(
|
||||
ifLeft = { error ->
|
||||
if (error is GetFeeError.GaslessError) {
|
||||
params.onLoadFee().map { LoadedFeeResult.Basic(it) }
|
||||
} else {
|
||||
Either.Left(error)
|
||||
when (error) {
|
||||
is GetFeeError.GaslessError.NotEnoughFunds -> error.left()
|
||||
is GetFeeError.GaslessError -> {
|
||||
// Something wrong with gasless fee, fallback to basic fee
|
||||
params.onLoadFee().map { LoadedFeeResult.Basic(it) }
|
||||
}
|
||||
else -> error.left()
|
||||
}
|
||||
},
|
||||
ifRight = { fee ->
|
||||
|
|
@ -243,32 +247,38 @@ internal class FeeSelectorLogic @AssistedInject constructor(
|
|||
private suspend fun populateExtendedFee(
|
||||
fee: TransactionFeeExtended,
|
||||
): Either<GetFeeError, LoadedFeeResult.Extended> = either {
|
||||
val selectedToken = if (params.feeCryptoCurrencyStatus.currency.id != fee.feeTokenId) {
|
||||
getSingleCryptoCurrencyStatusUseCase
|
||||
.invokeMultiWalletSync(
|
||||
userWalletId = params.userWalletId,
|
||||
cryptoCurrencyId = fee.feeTokenId,
|
||||
).getOrElse {
|
||||
raise(GetFeeError.DataError(IllegalStateException("No token found for id: ${fee.feeTokenId}")))
|
||||
}
|
||||
} else {
|
||||
params.feeCryptoCurrencyStatus
|
||||
LoadedFeeResult.Extended(
|
||||
fee = fee,
|
||||
selectedToken = getSelectedTokenStatus(fee.feeTokenId).bind(),
|
||||
availableTokens = getAvailableFeeTokens().bind(),
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun getSelectedTokenStatus(tokenId: CryptoCurrency.ID): Either<GetFeeError, CryptoCurrencyStatus> =
|
||||
either {
|
||||
val feeTokenId = tokenId
|
||||
if (params.feeCryptoCurrencyStatus.currency.id != feeTokenId) {
|
||||
getSingleCryptoCurrencyStatusUseCase
|
||||
.invokeMultiWalletSync(
|
||||
userWalletId = params.userWalletId,
|
||||
cryptoCurrencyId = feeTokenId,
|
||||
).getOrElse {
|
||||
raise(GetFeeError.DataError(IllegalStateException("No token found for id: $tokenId")))
|
||||
}
|
||||
} else {
|
||||
params.feeCryptoCurrencyStatus
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getAvailableFeeTokens(): Either<GetFeeError, List<CryptoCurrencyStatus>> = either {
|
||||
val userWallet = getUserWalletUseCase(params.userWalletId).mapLeft {
|
||||
GetFeeError.DataError(IllegalStateException("No wallet found for id: ${params.userWalletId}"))
|
||||
}.bind()
|
||||
|
||||
val availableTokens = getAvailableFeeTokensUseCase.invoke(
|
||||
getAvailableFeeTokensUseCase.invoke(
|
||||
userWallet = userWallet,
|
||||
network = params.cryptoCurrencyStatus.currency.network,
|
||||
).bind()
|
||||
|
||||
LoadedFeeResult.Extended(
|
||||
fee = fee,
|
||||
selectedToken = selectedToken,
|
||||
availableTokens = availableTokens,
|
||||
)
|
||||
}
|
||||
|
||||
sealed class LoadedFeeResult {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,13 @@ import com.tangem.utils.transformer.Transformer
|
|||
internal class FeeSelectorErrorTransformer(private val error: GetFeeError) : Transformer<FeeSelectorUM> {
|
||||
|
||||
override fun transform(prevState: FeeSelectorUM): FeeSelectorUM {
|
||||
if (prevState is FeeSelectorUM.Content && error is GetFeeError.GaslessError.NotEnoughFunds) {
|
||||
return prevState.copy(
|
||||
isPrimaryButtonEnabled = false,
|
||||
feeExtraInfo = prevState.feeExtraInfo.copy(isNotEnoughFunds = true),
|
||||
)
|
||||
}
|
||||
|
||||
return FeeSelectorUM.Error(error = error)
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ class FeeSelectorTokenSelectedTransformer(
|
|||
feeItems = persistentListOf(FeeItem.Loading),
|
||||
feeExtraInfo = prevState.feeExtraInfo.copy(
|
||||
feeCryptoCurrencyStatus = selectedToken,
|
||||
isNotEnoughFunds = false,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue