Updated on 2026-08-14
This commit is contained in:
parent
058a6ab4d5
commit
451fdc5e0b
37 changed files with 748 additions and 226 deletions
|
|
@ -13,12 +13,18 @@ fun getFiatReference(value: BigDecimal?, rate: BigDecimal?, appCurrency: AppCurr
|
|||
return stringReference(formattedFiat)
|
||||
}
|
||||
|
||||
fun getFiatString(value: BigDecimal?, rate: BigDecimal?, appCurrency: AppCurrency): String {
|
||||
fun getFiatString(
|
||||
value: BigDecimal?,
|
||||
rate: BigDecimal?,
|
||||
appCurrency: AppCurrency,
|
||||
approximate: Boolean = false,
|
||||
): String {
|
||||
if (value == null || rate == null) return EMPTY_BALANCE_SIGN
|
||||
val feeValue = value.multiply(rate)
|
||||
return BigDecimalFormatter.formatFiatAmount(
|
||||
fiatAmount = feeValue,
|
||||
fiatCurrencyCode = appCurrency.code,
|
||||
fiatCurrencySymbol = appCurrency.symbol,
|
||||
withApproximateSign = approximate,
|
||||
)
|
||||
}
|
||||
|
|
@ -102,7 +102,7 @@ internal class WcEthSendTransactionUseCase @AssistedInject constructor(
|
|||
emit(newState)
|
||||
}
|
||||
|
||||
override suspend fun dAppFee(): Fee.Ethereum.Legacy? {
|
||||
override fun dAppFee(): Fee.Ethereum.Legacy? {
|
||||
return dAppFee
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ internal class WcEthSignTransactionUseCase @AssistedInject constructor(
|
|||
emitAll(delegate.invoke(transactionData))
|
||||
}
|
||||
|
||||
override suspend fun dAppFee(): Fee.Ethereum.Legacy? {
|
||||
override fun dAppFee(): Fee.Ethereum.Legacy? {
|
||||
return dAppFee
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ interface WcListTransactionUseCase :
|
|||
* [updateFee] triggered a new [TransactionData] emit
|
||||
*/
|
||||
interface WcMutableFee {
|
||||
suspend fun dAppFee(): Fee?
|
||||
fun dAppFee(): Fee?
|
||||
fun updateFee(fee: Fee)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,10 +16,17 @@ dependencies {
|
|||
/** Domain models */
|
||||
api(projects.domain.models)
|
||||
implementation(projects.domain.appCurrency.models)
|
||||
implementation(projects.domain.wallets.models)
|
||||
implementation(projects.domain.tokens.models)
|
||||
implementation(projects.domain.nft.models)
|
||||
implementation(projects.domain.tokens.models)
|
||||
implementation(projects.domain.transaction.models)
|
||||
implementation(projects.domain.wallets.models)
|
||||
|
||||
/* Compose */
|
||||
/** Compose */
|
||||
implementation(deps.compose.runtime)
|
||||
|
||||
/** Tangem */
|
||||
implementation(tangemDeps.blockchain)
|
||||
|
||||
/** Other */
|
||||
implementation(deps.arrow.core)
|
||||
}
|
||||
|
|
@ -2,8 +2,9 @@ package com.tangem.features.send.v2.api
|
|||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.features.send.v2.api.params.FeeSelectorParams
|
||||
|
||||
interface FeeSelectorBlockComponent : ComposableContentComponent {
|
||||
|
||||
interface Factory : ComponentFactory<Unit, FeeSelectorBlockComponent>
|
||||
interface Factory : ComponentFactory<FeeSelectorParams.FeeSelectorBlockParams, FeeSelectorBlockComponent>
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.tangem.features.send.v2.api.params
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
|
||||
sealed class FeeSelectorParams {
|
||||
abstract val onLoadFee: suspend () -> Either<GetFeeError, TransactionFee>
|
||||
abstract val network: Network
|
||||
abstract val cryptoCurrencyStatus: CryptoCurrencyStatus
|
||||
|
||||
data class FeeSelectorBlockParams(
|
||||
override val onLoadFee: suspend () -> Either<GetFeeError, TransactionFee>,
|
||||
override val network: Network,
|
||||
override val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
val suggestedFeeState: SuggestedFeeState,
|
||||
) : FeeSelectorParams()
|
||||
|
||||
sealed class SuggestedFeeState {
|
||||
data object None : SuggestedFeeState()
|
||||
data class Suggestion(val title: TextReference, val fee: Fee) : SuggestedFeeState()
|
||||
}
|
||||
}
|
||||
|
|
@ -6,41 +6,70 @@ import androidx.compose.foundation.layout.*
|
|||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.common.ui.amountScreen.utils.getFiatString
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.components.SpacerWMax
|
||||
import com.tangem.core.ui.components.TextShimmer
|
||||
import com.tangem.core.ui.components.atoms.text.EllipsisText
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.format.bigdecimal.BigDecimalFormatConstants.EMPTY_BALANCE_SIGN
|
||||
import com.tangem.core.ui.format.bigdecimal.crypto
|
||||
import com.tangem.core.ui.format.bigdecimal.fee
|
||||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
|
||||
import com.tangem.features.send.v2.api.params.FeeSelectorParams
|
||||
import com.tangem.features.send.v2.feeselector.entity.FeeFiatRateUM
|
||||
import com.tangem.features.send.v2.feeselector.entity.FeeItem
|
||||
import com.tangem.features.send.v2.feeselector.entity.FeeSelectorUM
|
||||
import com.tangem.features.send.v2.feeselector.entity.PrimaryButtonConfig
|
||||
import com.tangem.features.send.v2.feeselector.model.FeeSelectorModel
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import java.math.BigDecimal
|
||||
|
||||
@Suppress("UnusedPrivateMember")
|
||||
internal class DefaultFeeSelectorBlockComponent @AssistedInject constructor(
|
||||
@Assisted appComponentContext: AppComponentContext,
|
||||
@Assisted params: Unit,
|
||||
@Assisted params: FeeSelectorParams.FeeSelectorBlockParams,
|
||||
) : FeeSelectorBlockComponent, AppComponentContext by appComponentContext {
|
||||
|
||||
private val model: FeeSelectorModel = getOrCreateModel(params = params)
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
FeeSelectorBlockContent(modifier = modifier)
|
||||
val state by model.uiState.collectAsStateWithLifecycle()
|
||||
FeeSelectorBlockContent(modifier = modifier, state = state)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : FeeSelectorBlockComponent.Factory {
|
||||
override fun create(context: AppComponentContext, params: Unit): DefaultFeeSelectorBlockComponent
|
||||
override fun create(
|
||||
context: AppComponentContext,
|
||||
params: FeeSelectorParams.FeeSelectorBlockParams,
|
||||
): DefaultFeeSelectorBlockComponent
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun FeeSelectorBlockContent(modifier: Modifier = Modifier) {
|
||||
private fun FeeSelectorBlockContent(state: FeeSelectorUM, modifier: Modifier = Modifier) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.background(TangemTheme.colors.background.action)
|
||||
|
|
@ -67,26 +96,90 @@ private fun FeeSelectorBlockContent(modifier: Modifier = Modifier) {
|
|||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.informative,
|
||||
)
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Text(
|
||||
text = "~ 0.25 \$",
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
Icon(
|
||||
modifier = Modifier.size(width = 18.dp, height = 24.dp),
|
||||
painter = painterResource(id = R.drawable.ic_select_18_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.informative,
|
||||
)
|
||||
SpacerWMax()
|
||||
when (state) {
|
||||
is FeeSelectorUM.Content -> FeeContent(state)
|
||||
is FeeSelectorUM.Loading -> FeeLoading()
|
||||
is FeeSelectorUM.Error -> FeeError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RowScope.FeeError() {
|
||||
Text(
|
||||
text = EMPTY_BALANCE_SIGN,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
style = TangemTheme.typography.body2,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RowScope.FeeLoading() {
|
||||
TextShimmer(
|
||||
radius = TangemTheme.dimens.radius3,
|
||||
style = TangemTheme.typography.body1,
|
||||
modifier = Modifier.width(width = TangemTheme.dimens.size90),
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RowScope.FeeContent(state: FeeSelectorUM.Content) {
|
||||
EllipsisText(
|
||||
text = if (state.feeFiatRateUM != null) {
|
||||
getFiatString(
|
||||
value = state.selectedFeeItem.fee.amount.value,
|
||||
rate = state.feeFiatRateUM.rate,
|
||||
appCurrency = state.feeFiatRateUM.appCurrency,
|
||||
approximate = state.isFeeApproximate,
|
||||
)
|
||||
} else {
|
||||
state.selectedFeeItem.fee.amount.value.format {
|
||||
crypto(
|
||||
symbol = state.selectedFeeItem.fee.amount.currencySymbol,
|
||||
decimals = state.selectedFeeItem.fee.amount.decimals,
|
||||
).fee(canBeLower = state.isFeeApproximate)
|
||||
}
|
||||
},
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
textAlign = TextAlign.End,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(start = TangemTheme.dimens.spacing4),
|
||||
)
|
||||
Icon(
|
||||
modifier = Modifier.size(width = 18.dp, height = 24.dp),
|
||||
painter = painterResource(id = R.drawable.ic_select_18_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.informative,
|
||||
)
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO)
|
||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun FeeSelectorBlockContent_Preview() {
|
||||
TangemThemePreview {
|
||||
FeeSelectorBlockContent(modifier = Modifier.fillMaxWidth())
|
||||
val feeItem = FeeItem.Market(
|
||||
Fee.Common(amount = Amount(value = BigDecimal("0.0002876"), blockchain = Blockchain.Ethereum)),
|
||||
)
|
||||
FeeSelectorBlockContent(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
state = FeeSelectorUM.Content(
|
||||
doneButtonConfig = PrimaryButtonConfig(enabled = true, onClick = {}),
|
||||
feeItems = persistentListOf(feeItem),
|
||||
onFeeSelected = {},
|
||||
selectedFeeItem = feeItem,
|
||||
isFeeApproximate = false,
|
||||
feeFiatRateUM = FeeFiatRateUM(
|
||||
rate = BigDecimal("2500"),
|
||||
appCurrency = AppCurrency.Default,
|
||||
),
|
||||
displayNonceInput = false,
|
||||
nonce = null,
|
||||
onNonceChange = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
package com.tangem.features.send.v2.feeselector.entity
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.features.send.v2.subcomponents.fee.ui.state.CustomFeeFieldUM
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import java.math.BigDecimal
|
||||
|
|
@ -12,33 +13,44 @@ import java.math.BigInteger
|
|||
@Immutable
|
||||
internal sealed class FeeSelectorUM {
|
||||
|
||||
data object Loading : FeeSelectorUM()
|
||||
abstract val doneButtonConfig: PrimaryButtonConfig
|
||||
|
||||
data class Loading(private val onDone: () -> Unit) : FeeSelectorUM() {
|
||||
override val doneButtonConfig = PrimaryButtonConfig(enabled = false, onClick = onDone)
|
||||
}
|
||||
|
||||
data class Error(val error: GetFeeError, private val onDone: () -> Unit) : FeeSelectorUM() {
|
||||
override val doneButtonConfig = PrimaryButtonConfig(enabled = false, onClick = onDone)
|
||||
}
|
||||
|
||||
data class Content(
|
||||
val isDoneEnabled: Boolean,
|
||||
override val doneButtonConfig: PrimaryButtonConfig,
|
||||
val feeItems: ImmutableList<FeeItem>,
|
||||
val onFeeSelected: (FeeItem) -> Unit,
|
||||
val selectedFeeItem: FeeItem,
|
||||
val isFeeApproximate: Boolean,
|
||||
val feeFiatRateDataHolder: FeeFiatRateDataHolder?,
|
||||
val feeFiatRateUM: FeeFiatRateUM?,
|
||||
val displayNonceInput: Boolean,
|
||||
val nonce: BigInteger?,
|
||||
val onNonceChange: (String) -> Unit,
|
||||
) : FeeSelectorUM()
|
||||
}
|
||||
|
||||
internal data class PrimaryButtonConfig(val enabled: Boolean, val onClick: () -> Unit)
|
||||
|
||||
@Immutable
|
||||
data class FeeFiatRateDataHolder(
|
||||
internal data class FeeFiatRateUM(
|
||||
val rate: BigDecimal,
|
||||
val appCurrency: AppCurrency,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
internal sealed class FeeItem {
|
||||
abstract val onSelect: () -> Unit
|
||||
abstract val fee: Fee
|
||||
|
||||
data class Suggested(val title: TextReference, val amount: Amount, override val onSelect: () -> Unit) : FeeItem()
|
||||
data class Slow(val amount: Amount, override val onSelect: () -> Unit) : FeeItem()
|
||||
data class Market(val amount: Amount, override val onSelect: () -> Unit) : FeeItem()
|
||||
data class Fast(val amount: Amount, override val onSelect: () -> Unit) : FeeItem()
|
||||
data class Custom(val customValues: ImmutableList<CustomFeeFieldUM>, override val onSelect: () -> Unit) : FeeItem()
|
||||
data class Suggested(val title: TextReference, override val fee: Fee) : FeeItem()
|
||||
data class Slow(override val fee: Fee) : FeeItem()
|
||||
data class Market(override val fee: Fee) : FeeItem()
|
||||
data class Fast(override val fee: Fee) : FeeItem()
|
||||
data class Custom(override val fee: Fee, val customValues: ImmutableList<CustomFeeFieldUM>) : FeeItem()
|
||||
}
|
||||
|
|
@ -1,31 +1,101 @@
|
|||
package com.tangem.features.send.v2.feeselector.model
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.blockchain.common.AmountType
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.features.send.v2.api.FeeSelectorComponent
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.transaction.usecase.IsFeeApproximateUseCase
|
||||
import com.tangem.features.send.v2.api.params.FeeSelectorParams
|
||||
import com.tangem.features.send.v2.feeselector.entity.FeeItem
|
||||
import com.tangem.features.send.v2.feeselector.entity.FeeSelectorUM
|
||||
import com.tangem.features.send.v2.feeselector.model.transformers.FeeItemSelectedTransformer
|
||||
import com.tangem.features.send.v2.feeselector.model.transformers.FeeSelectorErrorTransformer
|
||||
import com.tangem.features.send.v2.feeselector.model.transformers.FeeSelectorLoadedTransformer
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.transformer.update
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@Stable
|
||||
@ModelScoped
|
||||
internal class FeeSelectorModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
private val isFeeApproximateUseCase: IsFeeApproximateUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val router: Router,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
) : Model() {
|
||||
|
||||
@Suppress("UnusedPrivateMember")
|
||||
private val params = paramsContainer.require<FeeSelectorComponent.Params>()
|
||||
private val params = paramsContainer.require<FeeSelectorParams.FeeSelectorBlockParams>()
|
||||
private var appCurrency: AppCurrency = AppCurrency.Default
|
||||
|
||||
val uiState: StateFlow<FeeSelectorUM>
|
||||
field = MutableStateFlow<FeeSelectorUM>(FeeSelectorUM.Loading)
|
||||
field = MutableStateFlow<FeeSelectorUM>(FeeSelectorUM.Loading(onDone = ::onDone))
|
||||
|
||||
init {
|
||||
initAppCurrency()
|
||||
loadFee()
|
||||
}
|
||||
|
||||
fun dismiss() {
|
||||
router.pop()
|
||||
}
|
||||
|
||||
private fun initAppCurrency() {
|
||||
modelScope.launch {
|
||||
appCurrency = getSelectedAppCurrencyUseCase.invokeSync().getOrElse { AppCurrency.Default }
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadFee() {
|
||||
modelScope.launch {
|
||||
params.onLoadFee()
|
||||
.fold(
|
||||
ifLeft = { uiState.update(FeeSelectorErrorTransformer(it)) },
|
||||
ifRight = {
|
||||
uiState.update(
|
||||
FeeSelectorLoadedTransformer(
|
||||
cryptoCurrencyStatus = params.cryptoCurrencyStatus,
|
||||
appCurrency = appCurrency,
|
||||
fees = it,
|
||||
suggestedFeeState = params.suggestedFeeState,
|
||||
isFeeApproximate = isFeeApproximate(it.normal.amount.type),
|
||||
onFeeSelected = ::onFeeItemSelected,
|
||||
onCustomFeeValueChange = ::onCustomFeeValueChange,
|
||||
onNextClick = ::onNextClick,
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isFeeApproximate(amountType: AmountType): Boolean {
|
||||
val networkId = params.network.id
|
||||
return isFeeApproximateUseCase(networkId = networkId, amountType = amountType)
|
||||
}
|
||||
|
||||
private fun onFeeItemSelected(feeItem: FeeItem) {
|
||||
uiState.update(FeeItemSelectedTransformer(feeItem))
|
||||
}
|
||||
|
||||
@Suppress("UnusedPrivateMember")
|
||||
private fun onCustomFeeValueChange(index: Int, value: String) {
|
||||
// TODO: [REDACTED_JIRA]
|
||||
}
|
||||
|
||||
private fun onNextClick() {
|
||||
// TODO: [REDACTED_JIRA]
|
||||
}
|
||||
|
||||
private fun onDone() {
|
||||
// TODO: [REDACTED_JIRA]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package com.tangem.features.send.v2.feeselector.model.transformers
|
||||
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.send.v2.api.params.FeeSelectorParams
|
||||
import com.tangem.features.send.v2.feeselector.entity.FeeItem
|
||||
import com.tangem.utils.converter.Converter
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
internal class FeeItemConverter(
|
||||
private val suggestedFeeState: FeeSelectorParams.SuggestedFeeState,
|
||||
private val normalFee: Fee,
|
||||
private val onCustomFeeValueChange: (Int, String) -> Unit,
|
||||
private val onNextClick: () -> Unit,
|
||||
private val appCurrency: AppCurrency,
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
) : Converter<TransactionFee, ImmutableList<FeeItem>> {
|
||||
|
||||
private val customFeeFieldConverter = FeeSelectorCustomFieldConverter(
|
||||
onCustomFeeValueChange = onCustomFeeValueChange,
|
||||
onNextClick = onNextClick,
|
||||
appCurrency = appCurrency,
|
||||
feeCryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
normalFee = normalFee,
|
||||
)
|
||||
|
||||
override fun convert(value: TransactionFee): ImmutableList<FeeItem> {
|
||||
val fees = mutableListOf<FeeItem>()
|
||||
|
||||
when (suggestedFeeState) {
|
||||
FeeSelectorParams.SuggestedFeeState.None -> Unit
|
||||
is FeeSelectorParams.SuggestedFeeState.Suggestion -> fees.add(
|
||||
FeeItem.Suggested(
|
||||
title = suggestedFeeState.title,
|
||||
fee = suggestedFeeState.fee,
|
||||
),
|
||||
)
|
||||
}
|
||||
when (value) {
|
||||
is TransactionFee.Choosable -> {
|
||||
fees.add(FeeItem.Slow(fee = value.minimum))
|
||||
fees.add(FeeItem.Market(fee = value.normal))
|
||||
fees.add(FeeItem.Fast(fee = value.priority))
|
||||
}
|
||||
is TransactionFee.Single -> {
|
||||
fees.add(FeeItem.Market(fee = value.normal))
|
||||
}
|
||||
}
|
||||
val customFeeFields = customFeeFieldConverter.convert(normalFee)
|
||||
if (customFeeFields.isNotEmpty()) {
|
||||
fees.add(
|
||||
FeeItem.Custom(
|
||||
fee = customFeeFieldConverter.convertBack(customFeeFields),
|
||||
customValues = customFeeFields,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
return fees.toImmutableList()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.tangem.features.send.v2.feeselector.model.transformers
|
||||
|
||||
import com.tangem.features.send.v2.feeselector.entity.FeeItem
|
||||
import com.tangem.features.send.v2.feeselector.entity.FeeSelectorUM
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
||||
internal class FeeItemSelectedTransformer(private val selectedFeeItem: FeeItem) : Transformer<FeeSelectorUM> {
|
||||
override fun transform(prevState: FeeSelectorUM): FeeSelectorUM {
|
||||
prevState as? FeeSelectorUM.Content ?: return prevState
|
||||
|
||||
return prevState.copy(selectedFeeItem = selectedFeeItem)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
package com.tangem.features.send.v2.feeselector.model.transformers
|
||||
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.core.ui.utils.parseToBigDecimal
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.bitcoin.BitcoinCustomFeeConverter
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.ethereum.EthereumCustomFeeConverter
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.kaspa.KaspaCustomFeeConverter
|
||||
import com.tangem.features.send.v2.subcomponents.fee.ui.state.CustomFeeFieldUM
|
||||
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM
|
||||
import com.tangem.utils.converter.TwoWayConverter
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
internal class FeeSelectorCustomFieldConverter(
|
||||
private val onCustomFeeValueChange: (Int, String) -> Unit,
|
||||
private val onNextClick: () -> Unit,
|
||||
private val appCurrency: AppCurrency,
|
||||
private val feeCryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
private val normalFee: Fee,
|
||||
) : TwoWayConverter<Fee, ImmutableList<CustomFeeFieldUM>> {
|
||||
|
||||
private val ethereumCustomFeeConverter by lazy(LazyThreadSafetyMode.NONE) {
|
||||
EthereumCustomFeeConverter(
|
||||
onCustomFeeValueChange = onCustomFeeValueChange,
|
||||
onNextClick = onNextClick,
|
||||
appCurrency = appCurrency,
|
||||
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
|
||||
)
|
||||
}
|
||||
|
||||
private val bitcoinCustomFeeConverter by lazy(LazyThreadSafetyMode.NONE) {
|
||||
BitcoinCustomFeeConverter(
|
||||
onCustomFeeValueChange = onCustomFeeValueChange,
|
||||
onNextClick = onNextClick,
|
||||
appCurrency = appCurrency,
|
||||
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
|
||||
)
|
||||
}
|
||||
|
||||
private val kaspaCustomFeeConverter by lazy(LazyThreadSafetyMode.NONE) {
|
||||
KaspaCustomFeeConverter(
|
||||
onCustomFeeValueChange = onCustomFeeValueChange,
|
||||
appCurrency = appCurrency,
|
||||
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
|
||||
)
|
||||
}
|
||||
|
||||
override fun convert(value: Fee): ImmutableList<CustomFeeFieldUM> {
|
||||
return when (value) {
|
||||
is Fee.Ethereum -> ethereumCustomFeeConverter.convert(value)
|
||||
is Fee.Bitcoin -> bitcoinCustomFeeConverter.convert(value)
|
||||
is Fee.Kaspa -> kaspaCustomFeeConverter.convert(value)
|
||||
else -> persistentListOf()
|
||||
}
|
||||
}
|
||||
|
||||
override fun convertBack(value: ImmutableList<CustomFeeFieldUM>): Fee {
|
||||
return if (value.isEmpty()) {
|
||||
normalFee
|
||||
} else {
|
||||
when (normalFee) {
|
||||
is Fee.Ethereum -> ethereumCustomFeeConverter.convertBack(normalFee = normalFee, value = value)
|
||||
is Fee.Bitcoin -> bitcoinCustomFeeConverter.convertBack(normalFee = normalFee, value = value)
|
||||
is Fee.Kaspa -> kaspaCustomFeeConverter.convertBack(normalFee = normalFee, value = value)
|
||||
else -> {
|
||||
val customFee = value.firstOrNull()
|
||||
Fee.Common(
|
||||
normalFee.amount.copy(
|
||||
value = customFee?.value?.parseToBigDecimal(customFee.decimals),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onValueChange(feeSelectorState: FeeSelectorUM.Content, index: Int, value: String) =
|
||||
when (val fee = feeSelectorState.fees.normal) {
|
||||
is Fee.Ethereum -> ethereumCustomFeeConverter.onValueChange(
|
||||
feeValue = fee,
|
||||
customValues = feeSelectorState.customValues,
|
||||
index = index,
|
||||
value = value,
|
||||
)
|
||||
is Fee.Bitcoin -> bitcoinCustomFeeConverter.onValueChange(
|
||||
customValues = feeSelectorState.customValues,
|
||||
index = index,
|
||||
value = value,
|
||||
txSize = fee.txSize,
|
||||
)
|
||||
is Fee.Kaspa -> kaspaCustomFeeConverter.onValueChange(
|
||||
customValues = feeSelectorState.customValues,
|
||||
index = index,
|
||||
value = value,
|
||||
)
|
||||
else -> feeSelectorState.customValues
|
||||
}
|
||||
|
||||
fun tryAutoFixValue(feeSelectorState: FeeSelectorUM.Content) = when (feeSelectorState.fees) {
|
||||
is TransactionFee.Choosable -> feeSelectorState.fees.minimum
|
||||
is TransactionFee.Single -> feeSelectorState.fees.normal
|
||||
}.let {
|
||||
when (it) {
|
||||
is Fee.Kaspa -> kaspaCustomFeeConverter.tryAutoFixValue(
|
||||
minimumFee = it,
|
||||
customValues = feeSelectorState.customValues,
|
||||
)
|
||||
else -> feeSelectorState.customValues
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.features.send.v2.feeselector.model.transformers
|
||||
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.features.send.v2.feeselector.entity.FeeSelectorUM
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
||||
internal class FeeSelectorErrorTransformer(private val error: GetFeeError) : Transformer<FeeSelectorUM> {
|
||||
|
||||
override fun transform(prevState: FeeSelectorUM): FeeSelectorUM {
|
||||
return FeeSelectorUM.Error(error = error, onDone = prevState.doneButtonConfig.onClick)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package com.tangem.features.send.v2.feeselector.model.transformers
|
||||
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.send.v2.api.params.FeeSelectorParams
|
||||
import com.tangem.features.send.v2.feeselector.entity.FeeFiatRateUM
|
||||
import com.tangem.features.send.v2.feeselector.entity.FeeItem
|
||||
import com.tangem.features.send.v2.feeselector.entity.FeeSelectorUM
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class FeeSelectorLoadedTransformer(
|
||||
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
private val appCurrency: AppCurrency,
|
||||
private val fees: TransactionFee,
|
||||
private val suggestedFeeState: FeeSelectorParams.SuggestedFeeState,
|
||||
private val isFeeApproximate: Boolean,
|
||||
private val onFeeSelected: (FeeItem) -> Unit,
|
||||
private val onCustomFeeValueChange: (Int, String) -> Unit,
|
||||
private val onNextClick: () -> Unit,
|
||||
) : Transformer<FeeSelectorUM> {
|
||||
|
||||
private val feeItemsConverter = FeeItemConverter(
|
||||
suggestedFeeState = suggestedFeeState,
|
||||
normalFee = fees.normal,
|
||||
onCustomFeeValueChange = onCustomFeeValueChange,
|
||||
onNextClick = onNextClick,
|
||||
appCurrency = appCurrency,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
)
|
||||
|
||||
override fun transform(prevState: FeeSelectorUM): FeeSelectorUM {
|
||||
val feeItems: ImmutableList<FeeItem> = feeItemsConverter.convert(fees)
|
||||
val selectedFee = feeItems.find { it is FeeItem.Suggested } ?: feeItems.first { it is FeeItem.Market }
|
||||
return FeeSelectorUM.Content(
|
||||
doneButtonConfig = prevState.doneButtonConfig.copy(enabled = true),
|
||||
feeItems = feeItems,
|
||||
selectedFeeItem = selectedFee,
|
||||
isFeeApproximate = isFeeApproximate,
|
||||
onFeeSelected = onFeeSelected,
|
||||
feeFiatRateUM = cryptoCurrencyStatus.value.fiatRate?.let { rate ->
|
||||
FeeFiatRateUM(
|
||||
rate = rate,
|
||||
appCurrency = appCurrency,
|
||||
)
|
||||
},
|
||||
displayNonceInput = false,
|
||||
nonce = null,
|
||||
onNonceChange = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -31,6 +31,7 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.compose.ui.util.fastForEachIndexed
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.common.ui.amountScreen.utils.getFiatReference
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.atoms.text.EllipsisText
|
||||
|
|
@ -47,9 +48,10 @@ import com.tangem.core.ui.format.bigdecimal.format
|
|||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.features.send.v2.feeselector.entity.FeeFiatRateDataHolder
|
||||
import com.tangem.features.send.v2.feeselector.entity.FeeFiatRateUM
|
||||
import com.tangem.features.send.v2.feeselector.entity.FeeItem
|
||||
import com.tangem.features.send.v2.feeselector.entity.FeeSelectorUM
|
||||
import com.tangem.features.send.v2.feeselector.entity.PrimaryButtonConfig
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.subcomponents.fee.ui.state.CustomFeeFieldUM
|
||||
import com.tangem.utils.StringsSigns
|
||||
|
|
@ -88,8 +90,8 @@ internal fun FeeSelectorModalBottomSheet(state: FeeSelectorUM, onDismiss: () ->
|
|||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
text = stringResourceSafe(R.string.common_done),
|
||||
onClick = onDismiss,
|
||||
enabled = state.isDoneEnabled,
|
||||
onClick = state.doneButtonConfig.onClick,
|
||||
enabled = state.doneButtonConfig.enabled,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
@ -114,7 +116,7 @@ private fun FeeSelectorItems(state: FeeSelectorUM.Content, modifier: Modifier =
|
|||
},
|
||||
label = "Fee selector icon background change",
|
||||
)
|
||||
val onSelect by rememberUpdatedState(item.onSelect)
|
||||
val onSelect by rememberUpdatedState(state.onFeeSelected)
|
||||
val itemModifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(TangemTheme.colors.background.primary)
|
||||
|
|
@ -133,7 +135,7 @@ private fun FeeSelectorItems(state: FeeSelectorUM.Content, modifier: Modifier =
|
|||
Modifier
|
||||
},
|
||||
)
|
||||
.clickableSingle(onClick = onSelect)
|
||||
.clickableSingle(onClick = { onSelect(item) })
|
||||
when (item) {
|
||||
is FeeItem.Suggested -> RegularFeeItemContent(
|
||||
modifier = itemModifier,
|
||||
|
|
@ -142,23 +144,23 @@ private fun FeeSelectorItems(state: FeeSelectorUM.Content, modifier: Modifier =
|
|||
iconBackgroundColor = iconBackgroundColor,
|
||||
iconTint = iconTint,
|
||||
preDot = stringReference(
|
||||
item.amount.value.format {
|
||||
item.fee.amount.value.format {
|
||||
crypto(
|
||||
symbol = item.amount.currencySymbol,
|
||||
decimals = item.amount.decimals,
|
||||
symbol = item.fee.amount.currencySymbol,
|
||||
decimals = item.fee.amount.decimals,
|
||||
).fee(canBeLower = state.isFeeApproximate)
|
||||
},
|
||||
),
|
||||
postDot = if (state.feeFiatRateDataHolder != null) {
|
||||
postDot = if (state.feeFiatRateUM != null) {
|
||||
getFiatReference(
|
||||
value = item.amount.value,
|
||||
rate = state.feeFiatRateDataHolder.rate,
|
||||
appCurrency = state.feeFiatRateDataHolder.appCurrency,
|
||||
value = item.fee.amount.value,
|
||||
rate = state.feeFiatRateUM.rate,
|
||||
appCurrency = state.feeFiatRateUM.appCurrency,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
ellipsizeOffset = item.amount.currencySymbol.length,
|
||||
ellipsizeOffset = item.fee.amount.currencySymbol.length,
|
||||
showDivider = !isSelected && !lastItem,
|
||||
)
|
||||
is FeeItem.Slow -> RegularFeeItemContent(
|
||||
|
|
@ -168,23 +170,23 @@ private fun FeeSelectorItems(state: FeeSelectorUM.Content, modifier: Modifier =
|
|||
iconBackgroundColor = iconBackgroundColor,
|
||||
iconTint = iconTint,
|
||||
preDot = stringReference(
|
||||
item.amount.value.format {
|
||||
item.fee.amount.value.format {
|
||||
crypto(
|
||||
symbol = item.amount.currencySymbol,
|
||||
decimals = item.amount.decimals,
|
||||
symbol = item.fee.amount.currencySymbol,
|
||||
decimals = item.fee.amount.decimals,
|
||||
).fee(canBeLower = state.isFeeApproximate)
|
||||
},
|
||||
),
|
||||
postDot = if (state.feeFiatRateDataHolder != null) {
|
||||
postDot = if (state.feeFiatRateUM != null) {
|
||||
getFiatReference(
|
||||
value = item.amount.value,
|
||||
rate = state.feeFiatRateDataHolder.rate,
|
||||
appCurrency = state.feeFiatRateDataHolder.appCurrency,
|
||||
value = item.fee.amount.value,
|
||||
rate = state.feeFiatRateUM.rate,
|
||||
appCurrency = state.feeFiatRateUM.appCurrency,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
ellipsizeOffset = item.amount.currencySymbol.length,
|
||||
ellipsizeOffset = item.fee.amount.currencySymbol.length,
|
||||
showDivider = !isSelected && !lastItem,
|
||||
)
|
||||
is FeeItem.Market -> RegularFeeItemContent(
|
||||
|
|
@ -194,23 +196,23 @@ private fun FeeSelectorItems(state: FeeSelectorUM.Content, modifier: Modifier =
|
|||
iconBackgroundColor = iconBackgroundColor,
|
||||
iconTint = iconTint,
|
||||
preDot = stringReference(
|
||||
item.amount.value.format {
|
||||
item.fee.amount.value.format {
|
||||
crypto(
|
||||
symbol = item.amount.currencySymbol,
|
||||
decimals = item.amount.decimals,
|
||||
symbol = item.fee.amount.currencySymbol,
|
||||
decimals = item.fee.amount.decimals,
|
||||
).fee(canBeLower = state.isFeeApproximate)
|
||||
},
|
||||
),
|
||||
postDot = if (state.feeFiatRateDataHolder != null) {
|
||||
postDot = if (state.feeFiatRateUM != null) {
|
||||
getFiatReference(
|
||||
value = item.amount.value,
|
||||
rate = state.feeFiatRateDataHolder.rate,
|
||||
appCurrency = state.feeFiatRateDataHolder.appCurrency,
|
||||
value = item.fee.amount.value,
|
||||
rate = state.feeFiatRateUM.rate,
|
||||
appCurrency = state.feeFiatRateUM.appCurrency,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
ellipsizeOffset = item.amount.currencySymbol.length,
|
||||
ellipsizeOffset = item.fee.amount.currencySymbol.length,
|
||||
showDivider = !isSelected && !lastItem,
|
||||
)
|
||||
is FeeItem.Fast -> RegularFeeItemContent(
|
||||
|
|
@ -220,23 +222,23 @@ private fun FeeSelectorItems(state: FeeSelectorUM.Content, modifier: Modifier =
|
|||
iconBackgroundColor = iconBackgroundColor,
|
||||
iconTint = iconTint,
|
||||
preDot = stringReference(
|
||||
item.amount.value.format {
|
||||
item.fee.amount.value.format {
|
||||
crypto(
|
||||
symbol = item.amount.currencySymbol,
|
||||
decimals = item.amount.decimals,
|
||||
symbol = item.fee.amount.currencySymbol,
|
||||
decimals = item.fee.amount.decimals,
|
||||
).fee(canBeLower = state.isFeeApproximate)
|
||||
},
|
||||
),
|
||||
postDot = if (state.feeFiatRateDataHolder != null) {
|
||||
postDot = if (state.feeFiatRateUM != null) {
|
||||
getFiatReference(
|
||||
value = item.amount.value,
|
||||
rate = state.feeFiatRateDataHolder.rate,
|
||||
appCurrency = state.feeFiatRateDataHolder.appCurrency,
|
||||
value = item.fee.amount.value,
|
||||
rate = state.feeFiatRateUM.rate,
|
||||
appCurrency = state.feeFiatRateUM.appCurrency,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
ellipsizeOffset = item.amount.currencySymbol.length,
|
||||
ellipsizeOffset = item.fee.amount.currencySymbol.length,
|
||||
showDivider = !isSelected && !lastItem,
|
||||
)
|
||||
is FeeItem.Custom -> CustomFeeBlock(
|
||||
|
|
@ -471,34 +473,24 @@ private fun FeeSelectorBS_Preview(
|
|||
private class FeeSelectorUMContentProvider : CollectionPreviewParameterProvider<FeeSelectorUM.Content>(
|
||||
collection = listOf(
|
||||
FeeSelectorUM.Content(
|
||||
isDoneEnabled = false,
|
||||
doneButtonConfig = PrimaryButtonConfig(enabled = true, onClick = {}),
|
||||
feeItems = persistentListOf(
|
||||
FeeItem.Suggested(
|
||||
title = stringReference("Suggested by Tangem"),
|
||||
amount = Amount(value = BigDecimal("0.1"), blockchain = Blockchain.Ethereum),
|
||||
onSelect = onSelectStub,
|
||||
fee = Fee.Common(Amount(value = BigDecimal("0.1"), blockchain = Blockchain.Ethereum)),
|
||||
),
|
||||
FeeItem.Slow(
|
||||
amount = Amount(value = BigDecimal("0.01"), blockchain = Blockchain.Ethereum),
|
||||
onSelect = onSelectStub,
|
||||
),
|
||||
FeeItem.Market(
|
||||
amount = Amount(value = BigDecimal("0.02"), blockchain = Blockchain.Ethereum),
|
||||
onSelect = onSelectStub,
|
||||
),
|
||||
FeeItem.Fast(
|
||||
amount = Amount(value = BigDecimal("0.3"), blockchain = Blockchain.Ethereum),
|
||||
onSelect = onSelectStub,
|
||||
),
|
||||
FeeItem.Custom(customValues = customFeeFields, onSelect = onSelectStub),
|
||||
FeeItem.Slow(fee = Fee.Common(Amount(value = BigDecimal("0.01"), blockchain = Blockchain.Ethereum))),
|
||||
FeeItem.Market(fee = Fee.Common(Amount(value = BigDecimal("0.02"), blockchain = Blockchain.Ethereum))),
|
||||
FeeItem.Fast(fee = Fee.Common(Amount(value = BigDecimal("0.03"), blockchain = Blockchain.Ethereum))),
|
||||
customFeeItem,
|
||||
),
|
||||
onFeeSelected = {},
|
||||
// selectedFeeItem = FeeItem.Market(
|
||||
// amount = Amount(value = BigDecimal("0.02"), blockchain = Blockchain.Ethereum),
|
||||
// onSelect = onSelectStub
|
||||
// ),
|
||||
selectedFeeItem = FeeItem.Custom(customValues = customFeeFields, onSelect = onSelectStub),
|
||||
selectedFeeItem = customFeeItem,
|
||||
isFeeApproximate = true,
|
||||
feeFiatRateDataHolder = FeeFiatRateDataHolder(
|
||||
feeFiatRateUM = FeeFiatRateUM(
|
||||
rate = BigDecimal.TEN,
|
||||
appCurrency = AppCurrency.Default,
|
||||
),
|
||||
|
|
@ -509,43 +501,44 @@ private class FeeSelectorUMContentProvider : CollectionPreviewParameterProvider<
|
|||
),
|
||||
)
|
||||
|
||||
private val onSelectStub: () -> Unit = {}
|
||||
|
||||
private val customFeeFields = persistentListOf(
|
||||
CustomFeeFieldUM(
|
||||
value = "0.119806",
|
||||
onValueChange = {},
|
||||
keyboardOptions = KeyboardOptions(),
|
||||
keyboardActions = KeyboardActions(),
|
||||
symbol = "ETH",
|
||||
decimals = 8,
|
||||
title = resourceReference(R.string.send_max_fee),
|
||||
footer = resourceReference(R.string.send_custom_amount_fee_footer),
|
||||
label = stringReference("~ 0,03 \$"),
|
||||
isReadonly = false,
|
||||
),
|
||||
CustomFeeFieldUM(
|
||||
value = "40000",
|
||||
onValueChange = {},
|
||||
keyboardOptions = KeyboardOptions(),
|
||||
keyboardActions = KeyboardActions(),
|
||||
symbol = "GWEI",
|
||||
decimals = 8,
|
||||
title = resourceReference(R.string.send_gas_price),
|
||||
footer = resourceReference(R.string.send_gas_price_footer),
|
||||
label = null,
|
||||
isReadonly = false,
|
||||
),
|
||||
CustomFeeFieldUM(
|
||||
value = "31400",
|
||||
onValueChange = {},
|
||||
keyboardOptions = KeyboardOptions(),
|
||||
keyboardActions = KeyboardActions(),
|
||||
symbol = null,
|
||||
decimals = 8,
|
||||
title = resourceReference(R.string.send_gas_limit),
|
||||
footer = resourceReference(R.string.send_gas_limit_footer),
|
||||
label = null,
|
||||
isReadonly = false,
|
||||
private val customFeeItem = FeeItem.Custom(
|
||||
fee = Fee.Common(Amount(value = BigDecimal("0.05"), blockchain = Blockchain.Ethereum)),
|
||||
customValues = persistentListOf(
|
||||
CustomFeeFieldUM(
|
||||
value = "0.119806",
|
||||
onValueChange = {},
|
||||
keyboardOptions = KeyboardOptions(),
|
||||
keyboardActions = KeyboardActions(),
|
||||
symbol = "ETH",
|
||||
decimals = 8,
|
||||
title = resourceReference(R.string.send_max_fee),
|
||||
footer = resourceReference(R.string.send_custom_amount_fee_footer),
|
||||
label = stringReference("~ 0,03 \$"),
|
||||
isReadonly = false,
|
||||
),
|
||||
CustomFeeFieldUM(
|
||||
value = "40000",
|
||||
onValueChange = {},
|
||||
keyboardOptions = KeyboardOptions(),
|
||||
keyboardActions = KeyboardActions(),
|
||||
symbol = "GWEI",
|
||||
decimals = 8,
|
||||
title = resourceReference(R.string.send_gas_price),
|
||||
footer = resourceReference(R.string.send_gas_price_footer),
|
||||
label = null,
|
||||
isReadonly = false,
|
||||
),
|
||||
CustomFeeFieldUM(
|
||||
value = "31400",
|
||||
onValueChange = {},
|
||||
keyboardOptions = KeyboardOptions(),
|
||||
keyboardActions = KeyboardActions(),
|
||||
symbol = null,
|
||||
decimals = 8,
|
||||
title = resourceReference(R.string.send_gas_limit),
|
||||
footer = resourceReference(R.string.send_gas_limit_footer),
|
||||
label = null,
|
||||
isReadonly = false,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -24,7 +24,8 @@ internal class SendFeeCustomFieldConverter(
|
|||
|
||||
private val ethereumCustomFeeConverter by lazy(LazyThreadSafetyMode.NONE) {
|
||||
EthereumCustomFeeConverter(
|
||||
clickIntents = clickIntents,
|
||||
onCustomFeeValueChange = clickIntents::onCustomFeeValueChange,
|
||||
onNextClick = clickIntents::onNextClick,
|
||||
appCurrency = appCurrency,
|
||||
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
|
||||
)
|
||||
|
|
@ -32,7 +33,8 @@ internal class SendFeeCustomFieldConverter(
|
|||
|
||||
private val bitcoinCustomFeeConverter by lazy(LazyThreadSafetyMode.NONE) {
|
||||
BitcoinCustomFeeConverter(
|
||||
clickIntents = clickIntents,
|
||||
onCustomFeeValueChange = clickIntents::onCustomFeeValueChange,
|
||||
onNextClick = clickIntents::onNextClick,
|
||||
appCurrency = appCurrency,
|
||||
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
|
||||
)
|
||||
|
|
@ -40,7 +42,7 @@ internal class SendFeeCustomFieldConverter(
|
|||
|
||||
private val kaspaCustomFeeConverter by lazy(LazyThreadSafetyMode.NONE) {
|
||||
KaspaCustomFeeConverter(
|
||||
clickIntents = clickIntents,
|
||||
onCustomFeeValueChange = clickIntents::onCustomFeeValueChange,
|
||||
appCurrency = appCurrency,
|
||||
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import com.tangem.core.ui.utils.parseToBigDecimal
|
|||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.SendFeeClickIntents
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.checkExceedBalance
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.CustomFeeConverter
|
||||
import com.tangem.features.send.v2.subcomponents.fee.ui.state.CustomFeeFieldUM
|
||||
|
|
@ -24,7 +23,8 @@ import java.math.BigDecimal
|
|||
import java.math.RoundingMode
|
||||
|
||||
internal class BitcoinCustomFeeConverter(
|
||||
private val clickIntents: SendFeeClickIntents,
|
||||
private val onCustomFeeValueChange: (Int, String) -> Unit,
|
||||
private val onNextClick: () -> Unit,
|
||||
private val appCurrency: AppCurrency,
|
||||
private val feeCryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
) : CustomFeeConverter<Fee.Bitcoin> {
|
||||
|
|
@ -40,7 +40,7 @@ internal class BitcoinCustomFeeConverter(
|
|||
value = feeValue?.parseBigDecimal(value.amount.decimals).orEmpty(),
|
||||
decimals = value.amount.decimals,
|
||||
symbol = value.amount.currencySymbol,
|
||||
onValueChange = { clickIntents.onCustomFeeValueChange(FEE_AMOUNT_INDEX, it) },
|
||||
onValueChange = { onCustomFeeValueChange(FEE_AMOUNT_INDEX, it) },
|
||||
keyboardOptions = KeyboardOptions(
|
||||
imeAction = ImeAction.Companion.Next,
|
||||
keyboardType = KeyboardType.Companion.Number,
|
||||
|
|
@ -65,7 +65,7 @@ internal class BitcoinCustomFeeConverter(
|
|||
symbol = "",
|
||||
title = resourceReference(R.string.send_satoshi_per_byte_title),
|
||||
footer = resourceReference(R.string.send_satoshi_per_byte_text),
|
||||
onValueChange = { clickIntents.onCustomFeeValueChange(FEE_SATOSHI_INDEX, it) },
|
||||
onValueChange = { onCustomFeeValueChange(FEE_SATOSHI_INDEX, it) },
|
||||
keyboardOptions = KeyboardOptions(
|
||||
imeAction = if (checkExceedBalance(
|
||||
feeBalance = currencyStatus.amount,
|
||||
|
|
@ -78,9 +78,7 @@ internal class BitcoinCustomFeeConverter(
|
|||
},
|
||||
keyboardType = KeyboardType.Companion.Number,
|
||||
),
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = { clickIntents.onNextClick() },
|
||||
),
|
||||
keyboardActions = KeyboardActions(onDone = { onNextClick() }),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -11,14 +11,14 @@ import com.tangem.core.ui.utils.parseBigDecimal
|
|||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.SendFeeClickIntents
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.checkExceedBalance
|
||||
import com.tangem.features.send.v2.subcomponents.fee.ui.state.CustomFeeFieldUM
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
internal class EthereumCustomFeeConverter(
|
||||
private val clickIntents: SendFeeClickIntents,
|
||||
private val onCustomFeeValueChange: (Int, String) -> Unit,
|
||||
private val onNextClick: () -> Unit,
|
||||
private val appCurrency: AppCurrency,
|
||||
feeCryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
) : BaseEthereumCustomFeeConverter<Fee.Ethereum> {
|
||||
|
|
@ -26,13 +26,13 @@ internal class EthereumCustomFeeConverter(
|
|||
private val currencyStatus = feeCryptoCurrencyStatus.value
|
||||
|
||||
private val legacyFeeConverter = EthereumLegacyCustomFeeConverter(
|
||||
clickIntents = clickIntents,
|
||||
onCustomFeeValueChange = onCustomFeeValueChange,
|
||||
appCurrency = appCurrency,
|
||||
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
|
||||
)
|
||||
|
||||
private val eipFeeConverter = EthereumEIPCustomFeeConverter(
|
||||
clickIntents = clickIntents,
|
||||
onCustomFeeValueChange = onCustomFeeValueChange,
|
||||
appCurrency = appCurrency,
|
||||
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
|
||||
)
|
||||
|
|
@ -84,7 +84,7 @@ internal class EthereumCustomFeeConverter(
|
|||
value = feeValue?.parseBigDecimal(value.amount.decimals).orEmpty(),
|
||||
decimals = value.amount.decimals,
|
||||
symbol = value.amount.currencySymbol,
|
||||
onValueChange = { clickIntents.onCustomFeeValueChange(FEE_AMOUNT, it) },
|
||||
onValueChange = { onCustomFeeValueChange(FEE_AMOUNT, it) },
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next, keyboardType = KeyboardType.Number),
|
||||
title = resourceReference(R.string.send_max_fee),
|
||||
footer = resourceReference(R.string.send_custom_amount_fee_footer),
|
||||
|
|
@ -106,13 +106,13 @@ internal class EthereumCustomFeeConverter(
|
|||
symbol = "",
|
||||
title = resourceReference(R.string.send_gas_limit),
|
||||
footer = resourceReference(R.string.send_gas_limit_footer),
|
||||
onValueChange = { clickIntents.onCustomFeeValueChange(getGasLimitIndex(value), it) },
|
||||
onValueChange = { onCustomFeeValueChange(getGasLimitIndex(value), it) },
|
||||
keyboardOptions = KeyboardOptions(
|
||||
imeAction = if (isExceedBalance) ImeAction.None else ImeAction.Done,
|
||||
keyboardType = KeyboardType.Number,
|
||||
),
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = { clickIntents.onNextClick() },
|
||||
onDone = { onNextClick() },
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import com.tangem.core.ui.utils.parseToBigDecimal
|
|||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.SendFeeClickIntents
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.checkExceedBalance
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.ethereum.EthereumCustomFeeConverter.Companion.ETHEREUM_GAS_UNIT
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.ethereum.EthereumCustomFeeConverter.Companion.FEE_AMOUNT
|
||||
|
|
@ -26,7 +25,7 @@ import kotlinx.collections.immutable.toImmutableList
|
|||
import java.math.RoundingMode
|
||||
|
||||
internal class EthereumEIPCustomFeeConverter(
|
||||
private val clickIntents: SendFeeClickIntents,
|
||||
private val onCustomFeeValueChange: (Int, String) -> Unit,
|
||||
private val appCurrency: AppCurrency,
|
||||
private val feeCryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
) : BaseEthereumCustomFeeConverter<Fee.Ethereum.EIP1559> {
|
||||
|
|
@ -41,7 +40,7 @@ internal class EthereumEIPCustomFeeConverter(
|
|||
symbol = ETHEREUM_GAS_UNIT,
|
||||
title = resourceReference(R.string.send_custom_evm_max_fee),
|
||||
footer = resourceReference(R.string.send_custom_evm_max_fee_footer),
|
||||
onValueChange = { clickIntents.onCustomFeeValueChange(MAX_FEE, it) },
|
||||
onValueChange = { onCustomFeeValueChange(MAX_FEE, it) },
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next, keyboardType = KeyboardType.Number),
|
||||
keyboardActions = KeyboardActions(),
|
||||
),
|
||||
|
|
@ -51,7 +50,7 @@ internal class EthereumEIPCustomFeeConverter(
|
|||
symbol = ETHEREUM_GAS_UNIT,
|
||||
title = resourceReference(R.string.send_custom_evm_priority_fee),
|
||||
footer = resourceReference(R.string.send_custom_evm_priority_fee_footer),
|
||||
onValueChange = { clickIntents.onCustomFeeValueChange(PRIORITY_FEE, it) },
|
||||
onValueChange = { onCustomFeeValueChange(PRIORITY_FEE, it) },
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next, keyboardType = KeyboardType.Number),
|
||||
keyboardActions = KeyboardActions(),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import com.tangem.core.ui.utils.parseToBigDecimal
|
|||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.SendFeeClickIntents
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.checkExceedBalance
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.ethereum.EthereumCustomFeeConverter.Companion.ETHEREUM_GAS_UNIT
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.ethereum.EthereumCustomFeeConverter.Companion.FEE_AMOUNT
|
||||
|
|
@ -26,7 +25,7 @@ import kotlinx.collections.immutable.toImmutableList
|
|||
import java.math.RoundingMode
|
||||
|
||||
internal class EthereumLegacyCustomFeeConverter(
|
||||
private val clickIntents: SendFeeClickIntents,
|
||||
private val onCustomFeeValueChange: (Int, String) -> Unit,
|
||||
private val appCurrency: AppCurrency,
|
||||
feeCryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
) : BaseEthereumCustomFeeConverter<Fee.Ethereum.Legacy> {
|
||||
|
|
@ -41,7 +40,7 @@ internal class EthereumLegacyCustomFeeConverter(
|
|||
symbol = ETHEREUM_GAS_UNIT,
|
||||
title = resourceReference(R.string.send_gas_price),
|
||||
footer = resourceReference(R.string.send_gas_price_footer),
|
||||
onValueChange = { clickIntents.onCustomFeeValueChange(GAS_PRICE, it) },
|
||||
onValueChange = { onCustomFeeValueChange(GAS_PRICE, it) },
|
||||
keyboardOptions = KeyboardOptions(
|
||||
imeAction = ImeAction.Next,
|
||||
keyboardType = KeyboardType.Number,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import com.tangem.core.ui.utils.parseToBigDecimal
|
|||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.SendFeeClickIntents
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.CustomFeeConverter
|
||||
import com.tangem.features.send.v2.subcomponents.fee.ui.state.CustomFeeFieldUM
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
|
@ -21,7 +20,7 @@ import kotlinx.collections.immutable.toImmutableList
|
|||
import java.math.RoundingMode
|
||||
|
||||
internal class KaspaCustomFeeConverter(
|
||||
private val clickIntents: SendFeeClickIntents,
|
||||
private val onCustomFeeValueChange: (Int, String) -> Unit,
|
||||
private val appCurrency: AppCurrency,
|
||||
feeCryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
) : CustomFeeConverter<Fee.Kaspa> {
|
||||
|
|
@ -35,7 +34,7 @@ internal class KaspaCustomFeeConverter(
|
|||
value = feeValue?.parseBigDecimal(value.amount.decimals).orEmpty(),
|
||||
decimals = value.amount.decimals,
|
||||
symbol = value.amount.currencySymbol,
|
||||
onValueChange = { clickIntents.onCustomFeeValueChange(FEE_AMOUNT_INDEX, it) },
|
||||
onValueChange = { onCustomFeeValueChange(FEE_AMOUNT_INDEX, it) },
|
||||
keyboardOptions = KeyboardOptions(
|
||||
imeAction = ImeAction.Companion.Next,
|
||||
keyboardType = KeyboardType.Companion.Number,
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ dependencies {
|
|||
implementation(projects.domain.models)
|
||||
implementation(projects.domain.qrScanning.models)
|
||||
implementation(projects.domain.tokens.models)
|
||||
implementation(projects.domain.transaction.models)
|
||||
implementation(projects.domain.wallets.models)
|
||||
implementation(projects.domain.walletConnect)
|
||||
implementation(projects.domain.walletConnect.models)
|
||||
|
|
@ -37,8 +38,10 @@ dependencies {
|
|||
/** Domain */
|
||||
implementation(projects.domain.appCurrency)
|
||||
implementation(projects.domain.balanceHiding)
|
||||
implementation(projects.domain.legacy)
|
||||
implementation(projects.domain.qrScanning)
|
||||
implementation(projects.domain.tokens)
|
||||
implementation(projects.domain.transaction)
|
||||
implementation(projects.domain.wallets)
|
||||
|
||||
/** DI */
|
||||
|
|
|
|||
|
|
@ -64,12 +64,10 @@ internal class DefaultWcRoutingComponent @AssistedInject constructor(
|
|||
is WcInnerRoute.SignMessage -> WcSignTransactionContainerComponent(
|
||||
appComponentContext = childContext,
|
||||
params = WcTransactionModelParams(config.rawRequest),
|
||||
feeSelectorBlockComponentFactory = feeSelectorBlockComponentFactory,
|
||||
)
|
||||
is WcInnerRoute.AddNetwork -> WcAddNetworkContainerComponent(
|
||||
appComponentContext = childContext,
|
||||
params = WcTransactionModelParams(config.rawRequest),
|
||||
feeSelectorBlockComponentFactory = feeSelectorBlockComponentFactory,
|
||||
)
|
||||
is WcInnerRoute.Send -> WcSendTransactionContainerComponent(
|
||||
appComponentContext = childContext,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import com.tangem.core.decompose.context.AppComponentContext
|
|||
import com.tangem.core.decompose.context.childByContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
|
||||
import com.tangem.features.walletconnect.transaction.components.common.WcCommonTransactionComponentDelegate
|
||||
import com.tangem.features.walletconnect.transaction.components.common.WcTransactionModelParams
|
||||
import com.tangem.features.walletconnect.transaction.components.common.getWcCommonScreen
|
||||
|
|
@ -15,8 +14,7 @@ import com.tangem.features.walletconnect.transaction.routes.WcTransactionRoutes
|
|||
internal class WcAddNetworkContainerComponent(
|
||||
appComponentContext: AppComponentContext,
|
||||
params: WcTransactionModelParams,
|
||||
feeSelectorBlockComponentFactory: FeeSelectorBlockComponent.Factory,
|
||||
) : WcCommonTransactionComponentDelegate(appComponentContext, feeSelectorBlockComponentFactory) {
|
||||
) : WcCommonTransactionComponentDelegate(appComponentContext) {
|
||||
|
||||
private val model: WcAddNetworkModel = getOrCreateModel(params = params)
|
||||
|
||||
|
|
|
|||
|
|
@ -15,12 +15,10 @@ import com.tangem.core.decompose.context.AppComponentContext
|
|||
import com.tangem.core.decompose.navigation.inner.InnerRouter
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
|
||||
import com.tangem.features.walletconnect.transaction.routes.WcTransactionRoutes
|
||||
|
||||
internal abstract class WcCommonTransactionComponentDelegate(
|
||||
private val appComponentContext: AppComponentContext,
|
||||
private val feeSelectorBlockComponentFactory: FeeSelectorBlockComponent.Factory,
|
||||
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
||||
|
||||
private var stackNavigation: StackNavigation<WcTransactionRoutes>? = null
|
||||
|
|
@ -31,10 +29,6 @@ internal abstract class WcCommonTransactionComponentDelegate(
|
|||
InnerRouter<WcTransactionRoutes>(stackNavigation = it, popCallback = { onChildBack() })
|
||||
}
|
||||
}
|
||||
protected val feeSelectorBlockComponent = feeSelectorBlockComponentFactory.create(
|
||||
context = appComponentContext,
|
||||
params = Unit,
|
||||
)
|
||||
|
||||
protected fun init(
|
||||
navigation: StackNavigation<WcTransactionRoutes>,
|
||||
|
|
|
|||
|
|
@ -6,15 +6,28 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
|
||||
import com.tangem.features.send.v2.api.params.FeeSelectorParams
|
||||
import com.tangem.features.walletconnect.transaction.model.WcSendTransactionModel
|
||||
import com.tangem.features.walletconnect.transaction.ui.send.WcSendTransactionModalBottomSheet
|
||||
|
||||
internal class WcSendTransactionComponent(
|
||||
private val appComponentContext: AppComponentContext,
|
||||
private val model: WcSendTransactionModel,
|
||||
private val feeSelectorBlockComponent: FeeSelectorBlockComponent,
|
||||
private val feeSelectorBlockComponentFactory: FeeSelectorBlockComponent.Factory,
|
||||
) : AppComponentContext by appComponentContext, ComposableBottomSheetComponent {
|
||||
|
||||
private val feeSelectorBlockComponent by lazy {
|
||||
feeSelectorBlockComponentFactory.create(
|
||||
context = appComponentContext,
|
||||
params = FeeSelectorParams.FeeSelectorBlockParams(
|
||||
onLoadFee = model::loadFee,
|
||||
network = model.useCase.network,
|
||||
cryptoCurrencyStatus = model.cryptoCurrencyStatus,
|
||||
suggestedFeeState = model.suggestedFeeState,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
override fun dismiss() {
|
||||
model.dismiss()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ import com.tangem.features.walletconnect.transaction.routes.WcTransactionRoutes
|
|||
internal class WcSendTransactionContainerComponent(
|
||||
appComponentContext: AppComponentContext,
|
||||
params: WcTransactionModelParams,
|
||||
feeSelectorBlockComponentFactory: FeeSelectorBlockComponent.Factory,
|
||||
) : WcCommonTransactionComponentDelegate(appComponentContext, feeSelectorBlockComponentFactory) {
|
||||
private val feeSelectorBlockComponentFactory: FeeSelectorBlockComponent.Factory,
|
||||
) : WcCommonTransactionComponentDelegate(appComponentContext) {
|
||||
|
||||
private val model: WcSendTransactionModel = getOrCreateModel(params = params)
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ internal class WcSendTransactionContainerComponent(
|
|||
return WcSendTransactionComponent(
|
||||
appComponentContext = appComponentContext,
|
||||
model = model,
|
||||
feeSelectorBlockComponent = feeSelectorBlockComponent,
|
||||
feeSelectorBlockComponentFactory = feeSelectorBlockComponentFactory,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -5,14 +5,12 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
|
||||
import com.tangem.features.walletconnect.transaction.model.WcSignTransactionModel
|
||||
import com.tangem.features.walletconnect.transaction.ui.sign.WcSignTransactionModalBottomSheetContent
|
||||
|
||||
internal class WcSignTransactionComponent(
|
||||
private val appComponentContext: AppComponentContext,
|
||||
private val model: WcSignTransactionModel,
|
||||
private val feeSelectorBlockComponent: FeeSelectorBlockComponent,
|
||||
) : AppComponentContext by appComponentContext, ComposableBottomSheetComponent {
|
||||
|
||||
override fun dismiss() {
|
||||
|
|
@ -26,7 +24,6 @@ internal class WcSignTransactionComponent(
|
|||
if (content != null) {
|
||||
WcSignTransactionModalBottomSheetContent(
|
||||
state = content!!.transaction,
|
||||
feeSelectorBlockComponent = feeSelectorBlockComponent,
|
||||
onClickTransactionRequest = model::showTransactionRequest,
|
||||
onBack = router::pop,
|
||||
onDismiss = ::dismiss,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import com.tangem.core.decompose.context.AppComponentContext
|
|||
import com.tangem.core.decompose.context.childByContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
|
||||
import com.tangem.features.walletconnect.transaction.components.common.WcCommonTransactionComponentDelegate
|
||||
import com.tangem.features.walletconnect.transaction.components.common.WcTransactionModelParams
|
||||
import com.tangem.features.walletconnect.transaction.components.common.getWcCommonScreen
|
||||
|
|
@ -15,8 +14,7 @@ import com.tangem.features.walletconnect.transaction.routes.WcTransactionRoutes
|
|||
internal class WcSignTransactionContainerComponent(
|
||||
appComponentContext: AppComponentContext,
|
||||
params: WcTransactionModelParams,
|
||||
feeSelectorBlockComponentFactory: FeeSelectorBlockComponent.Factory,
|
||||
) : WcCommonTransactionComponentDelegate(appComponentContext, feeSelectorBlockComponentFactory) {
|
||||
) : WcCommonTransactionComponentDelegate(appComponentContext) {
|
||||
|
||||
private val model: WcSignTransactionModel = getOrCreateModel(params = params)
|
||||
|
||||
|
|
@ -45,7 +43,6 @@ internal class WcSignTransactionContainerComponent(
|
|||
return WcSignTransactionComponent(
|
||||
appComponentContext = appComponentContext,
|
||||
model = model,
|
||||
feeSelectorBlockComponent = feeSelectorBlockComponent,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,15 +3,13 @@ package com.tangem.features.walletconnect.transaction.converter
|
|||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.domain.walletconnect.model.WcEthMethod
|
||||
import com.tangem.domain.walletconnect.model.WcSolanaMethod
|
||||
import com.tangem.domain.walletconnect.usecase.method.WcMutableFee
|
||||
import com.tangem.domain.walletconnect.usecase.method.WcSignState
|
||||
import com.tangem.domain.walletconnect.usecase.method.WcSignStep
|
||||
import com.tangem.domain.walletconnect.usecase.method.WcTransactionUseCase
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
import com.tangem.features.walletconnect.transaction.entity.blockaid.WcSendReceiveTransactionCheckResultsUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionActionsUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestBlockUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestInfoItemUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestInfoUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.*
|
||||
import com.tangem.features.walletconnect.transaction.entity.send.WcSendTransactionItemUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.send.WcSendTransactionUM
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
|
@ -39,6 +37,7 @@ internal class WcSendTransactionUMConverter @Inject constructor(
|
|||
onShowVerifiedAlert = value.actions.onShowVerifiedAlert,
|
||||
),
|
||||
),
|
||||
feeState = constructFeeState(useCase = value.useCase),
|
||||
walletName = value.useCase.session.wallet.name,
|
||||
networkInfo = networkInfoUMConverter.convert(value.useCase.network),
|
||||
address = value.useCase.walletAddress.toShortAddressText(),
|
||||
|
|
@ -81,6 +80,12 @@ internal class WcSendTransactionUMConverter @Inject constructor(
|
|||
else -> null
|
||||
}
|
||||
|
||||
private fun constructFeeState(useCase: WcTransactionUseCase): WcTransactionFeeState {
|
||||
val mutableFee = useCase as? WcMutableFee ?: return WcTransactionFeeState.None
|
||||
val dAppFee = mutableFee.dAppFee()
|
||||
return if (dAppFee != null) WcTransactionFeeState.Success(dAppFee) else WcTransactionFeeState.Loading
|
||||
}
|
||||
|
||||
data class Input(
|
||||
val useCase: WcTransactionUseCase,
|
||||
val signState: WcSignState<*>,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
package com.tangem.features.walletconnect.transaction.entity.common
|
||||
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
|
||||
internal sealed class WcTransactionFeeState {
|
||||
object Loading : WcTransactionFeeState()
|
||||
data class Success(val fee: Fee) : WcTransactionFeeState()
|
||||
data object None : WcTransactionFeeState()
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import com.tangem.features.walletconnect.transaction.entity.blockaid.WcSendRecei
|
|||
import com.tangem.features.walletconnect.transaction.entity.common.WcCommonTransactionUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcNetworkInfoUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionAppInfoContentUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionFeeState
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestInfoUM
|
||||
|
||||
internal data class WcSendTransactionUM(
|
||||
|
|
@ -15,13 +16,13 @@ internal data class WcSendTransactionUM(
|
|||
) : WcCommonTransactionUM
|
||||
|
||||
internal data class WcSendTransactionItemUM(
|
||||
val feeState: WcTransactionFeeState,
|
||||
val onDismiss: () -> Unit,
|
||||
val onSend: () -> Unit,
|
||||
val appInfo: WcTransactionAppInfoContentUM,
|
||||
val estimatedWalletChanges: WcSendReceiveTransactionCheckResultsUM?,
|
||||
val walletName: String,
|
||||
val networkInfo: WcNetworkInfoUM,
|
||||
val networkFee: String? = null,
|
||||
val address: String? = null,
|
||||
val isLoading: Boolean = false,
|
||||
) : TangemBottomSheetConfigContent
|
||||
|
|
@ -7,14 +7,25 @@ import com.arkivanov.decompose.router.stack.pop
|
|||
import com.arkivanov.decompose.router.stack.pushNew
|
||||
import com.domain.blockaid.models.transaction.ValidationResult
|
||||
import com.tangem.blockchain.common.TransactionData
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.ui.clipboard.ClipboardManager
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.core.lce.Lce
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.tokens.GetNetworkCoinStatusUseCase
|
||||
import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.domain.transaction.usecase.GetFeeUseCase
|
||||
import com.tangem.domain.walletconnect.WcRequestUseCaseFactory
|
||||
import com.tangem.domain.walletconnect.usecase.method.*
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.features.send.v2.api.params.FeeSelectorParams
|
||||
import com.tangem.features.walletconnect.connections.routing.WcInnerRoute
|
||||
import com.tangem.features.walletconnect.transaction.components.common.WcTransactionModelParams
|
||||
import com.tangem.features.walletconnect.transaction.converter.WcCommonTransactionUMConverter
|
||||
|
|
@ -29,6 +40,7 @@ import kotlinx.coroutines.flow.*
|
|||
import kotlinx.coroutines.launch
|
||||
import java.math.BigDecimal
|
||||
import javax.inject.Inject
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Stable
|
||||
|
|
@ -41,6 +53,8 @@ internal class WcSendTransactionModel @Inject constructor(
|
|||
private val useCaseFactory: WcRequestUseCaseFactory,
|
||||
private val converter: WcCommonTransactionUMConverter,
|
||||
private val blockAidUiConverter: WcSendAndReceiveBlockAidUiConverter,
|
||||
private val getFeeUseCase: GetFeeUseCase,
|
||||
private val getNetworkCoinUseCase: GetNetworkCoinStatusUseCase,
|
||||
) : Model(), WcCommonTransactionModel {
|
||||
|
||||
private val params = paramsContainer.require<WcTransactionModelParams>()
|
||||
|
|
@ -50,6 +64,10 @@ internal class WcSendTransactionModel @Inject constructor(
|
|||
|
||||
val stackNavigation = StackNavigation<WcTransactionRoutes>()
|
||||
|
||||
internal var useCase: WcSignUseCase<*> by Delegates.notNull()
|
||||
internal var cryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull()
|
||||
internal var suggestedFeeState: FeeSelectorParams.SuggestedFeeState = FeeSelectorParams.SuggestedFeeState.None
|
||||
private var signState: WcSignState<*> by Delegates.notNull()
|
||||
private var wcApproval: WcApproval? = null
|
||||
private var sign: () -> Unit = {}
|
||||
|
||||
|
|
@ -63,36 +81,65 @@ internal class WcSendTransactionModel @Inject constructor(
|
|||
when (useCase) {
|
||||
is WcListTransactionUseCase,
|
||||
is WcTransactionUseCase,
|
||||
-> combine(
|
||||
useCase.invoke(),
|
||||
useCase.securityStatus,
|
||||
) { signState, securityCheck -> signState to securityCheck }
|
||||
.distinctUntilChanged()
|
||||
.collectLatest {
|
||||
val (signState, securityCheck) = it
|
||||
if (signingIsDone(signState, useCase)) return@collectLatest
|
||||
val signModel: Any = signState.signModel
|
||||
val isMutableFee = useCase is WcMutableFee
|
||||
val dAppFee = if (isMutableFee) useCase.dAppFee() else null
|
||||
val selectedFee = when (signModel) {
|
||||
is TransactionData.Compiled -> signModel.fee
|
||||
is TransactionData.Uncompiled -> signModel.fee
|
||||
else -> null
|
||||
-> {
|
||||
this@WcSendTransactionModel.cryptoCurrencyStatus =
|
||||
getCryptoCurrencyStatus(userWallet = useCase.wallet, network = useCase.network)
|
||||
.onLeft { unknownMethodRunnable() }
|
||||
.getOrNull() ?: return@launch
|
||||
this@WcSendTransactionModel.useCase = useCase
|
||||
(useCase as? WcMutableFee)
|
||||
?.dAppFee()
|
||||
?.let { dAppFee ->
|
||||
suggestedFeeState = FeeSelectorParams.SuggestedFeeState.Suggestion(
|
||||
title = stringReference(useCase.session.sdkModel.appMetaData.name),
|
||||
fee = dAppFee,
|
||||
)
|
||||
}
|
||||
val isDAppFeeSelected = dAppFee != null && dAppFee == selectedFee
|
||||
combine(
|
||||
useCase.invoke(),
|
||||
useCase.securityStatus,
|
||||
) { signState, securityCheck -> signState to securityCheck }
|
||||
.distinctUntilChanged()
|
||||
.collectLatest { (signState, securityCheck) ->
|
||||
if (signingIsDone(signState, useCase)) return@collectLatest
|
||||
|
||||
val isSecurityCheckContent = securityCheck is Lce.Content
|
||||
var isApprovalMethod = isSecurityCheckContent &&
|
||||
securityCheck.content is BlockAidTransactionCheck.Result.Approval
|
||||
wcApproval = useCase as? WcApproval
|
||||
sign = { useCase.sign() }
|
||||
buildUiState(securityCheck, useCase, signState)
|
||||
}
|
||||
this@WcSendTransactionModel.signState = signState
|
||||
val isSecurityCheckContent = securityCheck is Lce.Content
|
||||
var isApprovalMethod = isSecurityCheckContent &&
|
||||
securityCheck.content is BlockAidTransactionCheck.Result.Approval
|
||||
wcApproval = useCase as? WcApproval
|
||||
sign = { useCase.sign() }
|
||||
buildUiState(securityCheck, useCase, signState)
|
||||
}
|
||||
}
|
||||
else -> unknownMethodRunnable()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun loadFee(): Either<GetFeeError, TransactionFee> {
|
||||
val signModel = signState.signModel
|
||||
val transactionData = signModel as? TransactionData.Uncompiled ?: error("TransactionData must be Uncompiled")
|
||||
return getFeeUseCase.invoke(
|
||||
userWallet = useCase.wallet,
|
||||
network = useCase.network,
|
||||
transactionData = transactionData,
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun getCryptoCurrencyStatus(
|
||||
userWallet: UserWallet,
|
||||
network: Network,
|
||||
): Either<CurrencyStatusError, CryptoCurrencyStatus> {
|
||||
return getNetworkCoinUseCase.invokeSync(
|
||||
userWalletId = userWallet.walletId,
|
||||
networkId = network.id,
|
||||
derivationPath = network.derivationPath,
|
||||
isSingleWalletWithTokens = userWallet is UserWallet.Cold &&
|
||||
userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(),
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun buildUiState(
|
||||
securityCheck: Lce<Throwable, BlockAidTransactionCheck.Result>,
|
||||
useCase: WcSignUseCase<*>,
|
||||
|
|
|
|||
|
|
@ -14,11 +14,13 @@ import com.tangem.core.ui.components.divider.DividerWithPadding
|
|||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcNetworkInfoUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionFeeState
|
||||
|
||||
@Composable
|
||||
internal fun WcSendTransactionItems(
|
||||
walletName: String,
|
||||
networkInfo: WcNetworkInfoUM,
|
||||
feeState: WcTransactionFeeState,
|
||||
feeSelectorBlockComponent: FeeSelectorBlockComponent,
|
||||
modifier: Modifier = Modifier,
|
||||
address: String? = null,
|
||||
|
|
@ -52,6 +54,8 @@ internal fun WcSendTransactionItems(
|
|||
)
|
||||
}
|
||||
DividerWithPadding(start = 40.dp, end = 12.dp)
|
||||
feeSelectorBlockComponent.Content(Modifier)
|
||||
if (feeState != WcTransactionFeeState.None) {
|
||||
feeSelectorBlockComponent.Content(Modifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -34,6 +34,7 @@ import com.tangem.features.walletconnect.transaction.entity.blockaid.WcEstimated
|
|||
import com.tangem.features.walletconnect.transaction.entity.blockaid.WcSendReceiveTransactionCheckResultsUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcNetworkInfoUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionAppInfoContentUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionFeeState
|
||||
import com.tangem.features.walletconnect.transaction.entity.send.WcSendTransactionItemUM
|
||||
import com.tangem.features.walletconnect.transaction.ui.blockaid.TransactionCheckResultsItem
|
||||
import com.tangem.features.walletconnect.transaction.ui.common.WcSendTransactionItems
|
||||
|
|
@ -42,7 +43,7 @@ import com.tangem.features.walletconnect.transaction.ui.common.WcTransactionRequ
|
|||
import com.tangem.features.walletconnect.transaction.ui.common.WcTransactionRequestItem
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Suppress("LongParameterList", "LongMethod")
|
||||
@Composable
|
||||
internal fun WcSendTransactionModalBottomSheet(
|
||||
state: WcSendTransactionItemUM,
|
||||
|
|
@ -103,6 +104,7 @@ internal fun WcSendTransactionModalBottomSheet(
|
|||
WcSendTransactionItems(
|
||||
walletName = state.walletName,
|
||||
networkInfo = state.networkInfo,
|
||||
feeState = state.feeState,
|
||||
feeSelectorBlockComponent = feeSelectorBlockComponent,
|
||||
address = state.address,
|
||||
)
|
||||
|
|
@ -192,7 +194,7 @@ private class WcSendTransactionStateProvider : CollectionPreviewParameterProvide
|
|||
),
|
||||
walletName = "Tangem 2.0",
|
||||
networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22),
|
||||
networkFee = "~ 0.22 $",
|
||||
feeState = WcTransactionFeeState.Loading,
|
||||
address = "0x345FF...34FA",
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -25,11 +25,9 @@ import com.tangem.core.ui.components.divider.DividerWithPadding
|
|||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
|
||||
import com.tangem.features.walletconnect.connections.entity.VerifiedDAppState
|
||||
import com.tangem.features.walletconnect.connections.ui.WcAppInfoItem
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
import com.tangem.features.walletconnect.transaction.components.PreviewFeeSelectorBlockComponent
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcNetworkInfoUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionAppInfoContentUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.sign.WcSignTransactionItemUM
|
||||
|
|
@ -38,7 +36,6 @@ import com.tangem.features.walletconnect.transaction.ui.common.*
|
|||
@Composable
|
||||
internal fun WcSignTransactionModalBottomSheetContent(
|
||||
state: WcSignTransactionItemUM,
|
||||
feeSelectorBlockComponent: FeeSelectorBlockComponent,
|
||||
onClickTransactionRequest: () -> Unit,
|
||||
onBack: () -> Unit,
|
||||
onDismiss: () -> Unit,
|
||||
|
|
@ -87,7 +84,7 @@ internal fun WcSignTransactionModalBottomSheetContent(
|
|||
)
|
||||
}
|
||||
Column(modifier = Modifier.padding(top = 16.dp)) {
|
||||
WcSignTransactionItems(state, feeSelectorBlockComponent)
|
||||
WcSignTransactionItems(state)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -104,11 +101,7 @@ internal fun WcSignTransactionModalBottomSheetContent(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun WcSignTransactionItems(
|
||||
state: WcSignTransactionItemUM,
|
||||
feeSelectorBlockComponent: FeeSelectorBlockComponent,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
private fun WcSignTransactionItems(state: WcSignTransactionItemUM, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.clip(RoundedCornerShape(14.dp))
|
||||
|
|
@ -138,7 +131,6 @@ private fun WcSignTransactionItems(
|
|||
)
|
||||
}
|
||||
DividerWithPadding(start = 40.dp, end = 12.dp)
|
||||
feeSelectorBlockComponent.Content(modifier = Modifier)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -168,7 +160,6 @@ private fun WcSignTransactionBottomSheetPreview(
|
|||
content = {
|
||||
WcSignTransactionModalBottomSheetContent(
|
||||
state = state,
|
||||
feeSelectorBlockComponent = PreviewFeeSelectorBlockComponent(),
|
||||
onClickTransactionRequest = {},
|
||||
onBack = {},
|
||||
onDismiss = {},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue