Updated on 2026-08-14

This commit is contained in:
Tangem 2025-07-01 13:39:08 +05:00
parent 566c06095d
commit 8aa6ce0100
43 changed files with 274 additions and 146 deletions

View file

@ -33,17 +33,18 @@ 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.entity.FeeFiatRateUM
import com.tangem.features.send.v2.api.entity.FeeItem
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
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 kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import java.math.BigDecimal
internal class DefaultFeeSelectorBlockComponent @AssistedInject constructor(
@ -53,6 +54,16 @@ internal class DefaultFeeSelectorBlockComponent @AssistedInject constructor(
private val model: FeeSelectorModel = getOrCreateModel(params = params)
init {
model.uiState
.onEach(params.callback::onFeeResult)
.launchIn(componentScope)
}
override fun updateState(feeSelectorUM: FeeSelectorUM) {
model.updateState(feeSelectorUM)
}
@Composable
override fun Content(modifier: Modifier) {
val state by model.uiState.collectAsStateWithLifecycle()
@ -125,12 +136,13 @@ private fun RowScope.FeeLoading() {
@Composable
private fun RowScope.FeeContent(state: FeeSelectorUM.Content) {
val fiatRate = state.feeFiatRateUM
EllipsisText(
text = if (state.feeFiatRateUM != null) {
text = if (fiatRate != null) {
getFiatString(
value = state.selectedFeeItem.fee.amount.value,
rate = state.feeFiatRateUM.rate,
appCurrency = state.feeFiatRateUM.appCurrency,
rate = fiatRate.rate,
appCurrency = fiatRate.appCurrency,
approximate = state.isFeeApproximate,
)
} else {
@ -167,9 +179,7 @@ private fun FeeSelectorBlockContent_Preview() {
FeeSelectorBlockContent(
modifier = Modifier.fillMaxWidth(),
state = FeeSelectorUM.Content(
doneButtonConfig = PrimaryButtonConfig(enabled = true, onClick = {}),
feeItems = persistentListOf(feeItem),
onFeeSelected = {},
selectedFeeItem = feeItem,
isFeeApproximate = false,
feeFiatRateUM = FeeFiatRateUM(

View file

@ -1,13 +1,12 @@
package com.tangem.features.send.v2.feeselector
import androidx.activity.compose.BackHandler
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.features.send.v2.api.FeeSelectorComponent
import com.tangem.features.send.v2.api.params.FeeSelectorParams
import com.tangem.features.send.v2.feeselector.model.FeeSelectorModel
import com.tangem.features.send.v2.feeselector.ui.FeeSelectorModalBottomSheet
import dagger.assisted.Assisted
@ -16,7 +15,7 @@ import dagger.assisted.AssistedInject
internal class DefaultFeeSelectorComponent @AssistedInject constructor(
@Assisted appComponentContext: AppComponentContext,
@Assisted private val params: FeeSelectorComponent.Params,
@Assisted private val params: FeeSelectorParams.FeeSelectorDetailsParams,
) : FeeSelectorComponent, AppComponentContext by appComponentContext {
private val model: FeeSelectorModel = getOrCreateModel(params = params)
@ -27,22 +26,15 @@ internal class DefaultFeeSelectorComponent @AssistedInject constructor(
@Composable
override fun BottomSheet() {
FeeSelectorModalBottomSheet(onDismiss = ::dismiss, state = TODO())
}
// Temporary workaround, to use test this component
@Composable
override fun Content(modifier: Modifier) {
val state by model.uiState.collectAsStateWithLifecycle()
BackHandler(onBack = router::pop)
FeeSelectorModalBottomSheet(onDismiss = ::dismiss, state = state)
FeeSelectorModalBottomSheet(onDismiss = ::dismiss, state = state, feeSelectorIntents = model)
}
@AssistedFactory
interface Factory : FeeSelectorComponent.Factory {
override fun create(
context: AppComponentContext,
params: FeeSelectorComponent.Params,
params: FeeSelectorParams.FeeSelectorDetailsParams,
): DefaultFeeSelectorComponent
}
}

View file

@ -1,56 +0,0 @@
package com.tangem.features.send.v2.feeselector.entity
import androidx.compose.runtime.Immutable
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
import java.math.BigInteger
@Immutable
internal sealed class 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(
override val doneButtonConfig: PrimaryButtonConfig,
val feeItems: ImmutableList<FeeItem>,
val onFeeSelected: (FeeItem) -> Unit,
val selectedFeeItem: FeeItem,
val isFeeApproximate: Boolean,
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
internal data class FeeFiatRateUM(
val rate: BigDecimal,
val appCurrency: AppCurrency,
)
@Immutable
internal sealed class FeeItem {
abstract val fee: Fee
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()
}

View file

@ -0,0 +1,17 @@
package com.tangem.features.send.v2.feeselector.model
import com.tangem.features.send.v2.api.entity.FeeItem
internal interface FeeSelectorIntents {
fun onFeeItemSelected(feeItem: FeeItem)
fun onCustomFeeValueChange(index: Int, value: String)
fun onCustomFeeNextClick()
fun onDoneClick()
}
internal class StubFeeSelectorIntents : FeeSelectorIntents {
override fun onFeeItemSelected(feeItem: FeeItem) {}
override fun onCustomFeeValueChange(index: Int, value: String) {}
override fun onCustomFeeNextClick() {}
override fun onDoneClick() {}
}

View file

@ -10,9 +10,9 @@ import com.tangem.core.decompose.navigation.Router
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.entity.FeeItem
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
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
@ -31,19 +31,23 @@ internal class FeeSelectorModel @Inject constructor(
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val router: Router,
override val dispatchers: CoroutineDispatcherProvider,
) : Model() {
) : Model(), FeeSelectorIntents {
private val params = paramsContainer.require<FeeSelectorParams.FeeSelectorBlockParams>()
private val params = paramsContainer.require<FeeSelectorParams>()
private var appCurrency: AppCurrency = AppCurrency.Default
val uiState: StateFlow<FeeSelectorUM>
field = MutableStateFlow<FeeSelectorUM>(FeeSelectorUM.Loading(onDone = ::onDone))
field = MutableStateFlow<FeeSelectorUM>(params.state)
init {
initAppCurrency()
loadFee()
}
fun updateState(feeSelectorUM: FeeSelectorUM) {
uiState.value = feeSelectorUM
}
fun dismiss() {
router.pop()
}
@ -58,18 +62,16 @@ internal class FeeSelectorModel @Inject constructor(
modelScope.launch {
params.onLoadFee()
.fold(
ifLeft = { uiState.update(FeeSelectorErrorTransformer(it)) },
ifRight = {
ifLeft = { error -> uiState.update(FeeSelectorErrorTransformer(error)) },
ifRight = { fee ->
uiState.update(
FeeSelectorLoadedTransformer(
cryptoCurrencyStatus = params.cryptoCurrencyStatus,
appCurrency = appCurrency,
fees = it,
fees = fee,
suggestedFeeState = params.suggestedFeeState,
isFeeApproximate = isFeeApproximate(it.normal.amount.type),
onFeeSelected = ::onFeeItemSelected,
onCustomFeeValueChange = ::onCustomFeeValueChange,
onNextClick = ::onNextClick,
isFeeApproximate = isFeeApproximate(fee.normal.amount.type),
feeSelectorIntents = this@FeeSelectorModel,
),
)
},
@ -78,24 +80,24 @@ internal class FeeSelectorModel @Inject constructor(
}
private fun isFeeApproximate(amountType: AmountType): Boolean {
val networkId = params.network.id
val networkId = params.cryptoCurrencyStatus.currency.network.id
return isFeeApproximateUseCase(networkId = networkId, amountType = amountType)
}
private fun onFeeItemSelected(feeItem: FeeItem) {
override fun onFeeItemSelected(feeItem: FeeItem) {
uiState.update(FeeItemSelectedTransformer(feeItem))
}
@Suppress("UnusedPrivateMember")
private fun onCustomFeeValueChange(index: Int, value: String) {
override fun onCustomFeeValueChange(index: Int, value: String) {
// TODO: [REDACTED_JIRA]
}
private fun onNextClick() {
override fun onCustomFeeNextClick() {
// TODO: [REDACTED_JIRA]
}
private fun onDone() {
// TODO: [REDACTED_JIRA]
override fun onDoneClick() {
params.callback.onFeeResult(uiState.value)
dismiss()
}
}

View file

@ -5,7 +5,8 @@ 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.features.send.v2.api.entity.FeeItem
import com.tangem.features.send.v2.feeselector.model.FeeSelectorIntents
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
@ -13,15 +14,13 @@ 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 feeSelectorIntents: FeeSelectorIntents,
private val appCurrency: AppCurrency,
cryptoCurrencyStatus: CryptoCurrencyStatus,
) : Converter<TransactionFee, ImmutableList<FeeItem>> {
private val customFeeFieldConverter = FeeSelectorCustomFieldConverter(
onCustomFeeValueChange = onCustomFeeValueChange,
onNextClick = onNextClick,
feeSelectorIntents = feeSelectorIntents,
appCurrency = appCurrency,
feeCryptoCurrencyStatus = cryptoCurrencyStatus,
normalFee = normalFee,

View file

@ -1,7 +1,7 @@
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.features.send.v2.api.entity.FeeItem
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.utils.transformer.Transformer
internal class FeeItemSelectedTransformer(private val selectedFeeItem: FeeItem) : Transformer<FeeSelectorUM> {

View file

@ -8,15 +8,15 @@ 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.api.entity.CustomFeeFieldUM
import com.tangem.features.send.v2.feeselector.model.FeeSelectorIntents
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 feeSelectorIntents: FeeSelectorIntents,
private val appCurrency: AppCurrency,
private val feeCryptoCurrencyStatus: CryptoCurrencyStatus,
private val normalFee: Fee,
@ -24,8 +24,8 @@ internal class FeeSelectorCustomFieldConverter(
private val ethereumCustomFeeConverter by lazy(LazyThreadSafetyMode.NONE) {
EthereumCustomFeeConverter(
onCustomFeeValueChange = onCustomFeeValueChange,
onNextClick = onNextClick,
onCustomFeeValueChange = feeSelectorIntents::onCustomFeeValueChange,
onNextClick = feeSelectorIntents::onCustomFeeNextClick,
appCurrency = appCurrency,
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
)
@ -33,8 +33,8 @@ internal class FeeSelectorCustomFieldConverter(
private val bitcoinCustomFeeConverter by lazy(LazyThreadSafetyMode.NONE) {
BitcoinCustomFeeConverter(
onCustomFeeValueChange = onCustomFeeValueChange,
onNextClick = onNextClick,
onCustomFeeValueChange = feeSelectorIntents::onCustomFeeValueChange,
onNextClick = feeSelectorIntents::onCustomFeeNextClick,
appCurrency = appCurrency,
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
)
@ -42,7 +42,7 @@ internal class FeeSelectorCustomFieldConverter(
private val kaspaCustomFeeConverter by lazy(LazyThreadSafetyMode.NONE) {
KaspaCustomFeeConverter(
onCustomFeeValueChange = onCustomFeeValueChange,
onCustomFeeValueChange = feeSelectorIntents::onCustomFeeValueChange,
appCurrency = appCurrency,
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
)

View file

@ -1,12 +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.features.send.v2.api.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)
return FeeSelectorUM.Error(error = error)
}
}

View file

@ -3,10 +3,11 @@ 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.entity.FeeFiatRateUM
import com.tangem.features.send.v2.api.entity.FeeItem
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
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.model.FeeSelectorIntents
import com.tangem.utils.transformer.Transformer
import kotlinx.collections.immutable.ImmutableList
@ -17,29 +18,31 @@ internal class FeeSelectorLoadedTransformer(
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,
private val feeSelectorIntents: FeeSelectorIntents,
) : Transformer<FeeSelectorUM> {
private val feeItemsConverter = FeeItemConverter(
suggestedFeeState = suggestedFeeState,
normalFee = fees.normal,
onCustomFeeValueChange = onCustomFeeValueChange,
onNextClick = onNextClick,
feeSelectorIntents = feeSelectorIntents,
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 }
val selectedFee = when (prevState) {
is FeeSelectorUM.Content -> feeItems.first { it.isSame(prevState.selectedFeeItem) }
is FeeSelectorUM.Error,
FeeSelectorUM.Loading,
-> 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,

View file

@ -15,7 +15,6 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@ -48,12 +47,13 @@ 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.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.api.entity.CustomFeeFieldUM
import com.tangem.features.send.v2.api.entity.FeeFiatRateUM
import com.tangem.features.send.v2.api.entity.FeeItem
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.v2.feeselector.model.FeeSelectorIntents
import com.tangem.features.send.v2.feeselector.model.StubFeeSelectorIntents
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.subcomponents.fee.ui.state.CustomFeeFieldUM
import com.tangem.utils.StringsSigns
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@ -61,7 +61,11 @@ import java.math.BigDecimal
import java.math.BigInteger
@Composable
internal fun FeeSelectorModalBottomSheet(state: FeeSelectorUM, onDismiss: () -> Unit) {
internal fun FeeSelectorModalBottomSheet(
state: FeeSelectorUM,
feeSelectorIntents: FeeSelectorIntents,
onDismiss: () -> Unit,
) {
if (state !is FeeSelectorUM.Content) return
TangemModalBottomSheetWithFooter<TangemBottomSheetConfigContent.Empty>(
@ -81,6 +85,7 @@ internal fun FeeSelectorModalBottomSheet(state: FeeSelectorUM, onDismiss: () ->
content = {
FeeSelectorItems(
state = state,
feeSelectorIntents = feeSelectorIntents,
modifier = Modifier.padding(vertical = 4.dp, horizontal = 16.dp),
)
},
@ -90,8 +95,7 @@ internal fun FeeSelectorModalBottomSheet(state: FeeSelectorUM, onDismiss: () ->
.fillMaxWidth()
.padding(16.dp),
text = stringResourceSafe(R.string.common_done),
onClick = state.doneButtonConfig.onClick,
enabled = state.doneButtonConfig.enabled,
onClick = feeSelectorIntents::onDoneClick,
)
},
)
@ -99,10 +103,15 @@ internal fun FeeSelectorModalBottomSheet(state: FeeSelectorUM, onDismiss: () ->
@Suppress("LongMethod", "CyclomaticComplexMethod")
@Composable
private fun FeeSelectorItems(state: FeeSelectorUM.Content, modifier: Modifier = Modifier) {
private fun FeeSelectorItems(
state: FeeSelectorUM.Content,
feeSelectorIntents: FeeSelectorIntents,
modifier: Modifier = Modifier,
) {
Column(modifier = modifier) {
val feeFiatRateUM = state.feeFiatRateUM
state.feeItems.fastForEachIndexed { index, item ->
val isSelected = item == state.selectedFeeItem
val isSelected = item.isSame(state.selectedFeeItem)
val lastItem = index == state.feeItems.size - 1
val iconTint by animateColorAsState(
targetValue = if (isSelected) TangemTheme.colors.icon.accent else TangemTheme.colors.text.tertiary,
@ -116,7 +125,6 @@ private fun FeeSelectorItems(state: FeeSelectorUM.Content, modifier: Modifier =
},
label = "Fee selector icon background change",
)
val onSelect by rememberUpdatedState(state.onFeeSelected)
val itemModifier = Modifier
.fillMaxWidth()
.background(TangemTheme.colors.background.primary)
@ -135,7 +143,7 @@ private fun FeeSelectorItems(state: FeeSelectorUM.Content, modifier: Modifier =
Modifier
},
)
.clickableSingle(onClick = { onSelect(item) })
.clickableSingle(onClick = { feeSelectorIntents.onFeeItemSelected(item) })
when (item) {
is FeeItem.Suggested -> RegularFeeItemContent(
modifier = itemModifier,
@ -151,11 +159,11 @@ private fun FeeSelectorItems(state: FeeSelectorUM.Content, modifier: Modifier =
).fee(canBeLower = state.isFeeApproximate)
},
),
postDot = if (state.feeFiatRateUM != null) {
postDot = if (feeFiatRateUM != null) {
getFiatReference(
value = item.fee.amount.value,
rate = state.feeFiatRateUM.rate,
appCurrency = state.feeFiatRateUM.appCurrency,
rate = feeFiatRateUM.rate,
appCurrency = feeFiatRateUM.appCurrency,
)
} else {
null
@ -177,11 +185,11 @@ private fun FeeSelectorItems(state: FeeSelectorUM.Content, modifier: Modifier =
).fee(canBeLower = state.isFeeApproximate)
},
),
postDot = if (state.feeFiatRateUM != null) {
postDot = if (feeFiatRateUM != null) {
getFiatReference(
value = item.fee.amount.value,
rate = state.feeFiatRateUM.rate,
appCurrency = state.feeFiatRateUM.appCurrency,
rate = feeFiatRateUM.rate,
appCurrency = feeFiatRateUM.appCurrency,
)
} else {
null
@ -203,11 +211,11 @@ private fun FeeSelectorItems(state: FeeSelectorUM.Content, modifier: Modifier =
).fee(canBeLower = state.isFeeApproximate)
},
),
postDot = if (state.feeFiatRateUM != null) {
postDot = if (feeFiatRateUM != null) {
getFiatReference(
value = item.fee.amount.value,
rate = state.feeFiatRateUM.rate,
appCurrency = state.feeFiatRateUM.appCurrency,
rate = feeFiatRateUM.rate,
appCurrency = feeFiatRateUM.appCurrency,
)
} else {
null
@ -229,11 +237,11 @@ private fun FeeSelectorItems(state: FeeSelectorUM.Content, modifier: Modifier =
).fee(canBeLower = state.isFeeApproximate)
},
),
postDot = if (state.feeFiatRateUM != null) {
postDot = if (feeFiatRateUM != null) {
getFiatReference(
value = item.fee.amount.value,
rate = state.feeFiatRateUM.rate,
appCurrency = state.feeFiatRateUM.appCurrency,
rate = feeFiatRateUM.rate,
appCurrency = feeFiatRateUM.appCurrency,
)
} else {
null
@ -466,14 +474,13 @@ private fun FeeSelectorBS_Preview(
state: FeeSelectorUM.Content,
) {
TangemThemePreview {
FeeSelectorModalBottomSheet(onDismiss = {}, state = state)
FeeSelectorModalBottomSheet(onDismiss = {}, state = state, feeSelectorIntents = StubFeeSelectorIntents())
}
}
private class FeeSelectorUMContentProvider : CollectionPreviewParameterProvider<FeeSelectorUM.Content>(
collection = listOf(
FeeSelectorUM.Content(
doneButtonConfig = PrimaryButtonConfig(enabled = true, onClick = {}),
feeItems = persistentListOf(
FeeItem.Suggested(
title = stringReference("Suggested by Tangem"),
@ -484,7 +491,6 @@ private class FeeSelectorUMContentProvider : CollectionPreviewParameterProvider<
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),
// ),

View file

@ -5,7 +5,7 @@ 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.subcomponents.fee.model.SendFeeClickIntents
import com.tangem.features.send.v2.subcomponents.fee.ui.state.CustomFeeFieldUM
import com.tangem.features.send.v2.api.entity.CustomFeeFieldUM
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeType
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.ImmutableList

View file

@ -9,7 +9,7 @@ import com.tangem.features.send.v2.subcomponents.fee.model.SendFeeClickIntents
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.api.entity.CustomFeeFieldUM
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM
import com.tangem.utils.converter.TwoWayConverter
import kotlinx.collections.immutable.ImmutableList

View file

@ -1,7 +1,7 @@
package com.tangem.features.send.v2.subcomponents.fee.model.converters.custom
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.features.send.v2.subcomponents.fee.ui.state.CustomFeeFieldUM
import com.tangem.features.send.v2.api.entity.CustomFeeFieldUM
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.ImmutableList

View file

@ -14,7 +14,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.send.v2.impl.R
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
import com.tangem.features.send.v2.api.entity.CustomFeeFieldUM
import com.tangem.lib.crypto.BlockchainUtils
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf

View file

@ -2,7 +2,7 @@ package com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.et
import com.tangem.blockchain.common.transaction.Fee
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.CustomFeeConverter
import com.tangem.features.send.v2.subcomponents.fee.ui.state.CustomFeeFieldUM
import com.tangem.features.send.v2.api.entity.CustomFeeFieldUM
import kotlinx.collections.immutable.ImmutableList
/**

View file

@ -12,7 +12,7 @@ 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.checkExceedBalance
import com.tangem.features.send.v2.subcomponents.fee.ui.state.CustomFeeFieldUM
import com.tangem.features.send.v2.api.entity.CustomFeeFieldUM
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList

View file

@ -18,7 +18,7 @@ import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.eth
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.ethereum.EthereumCustomFeeConverter.Companion.GAS_DECIMALS
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.ethereum.EthereumCustomFeeConverter.Companion.GIGA_DECIMALS
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.setEmpty
import com.tangem.features.send.v2.subcomponents.fee.ui.state.CustomFeeFieldUM
import com.tangem.features.send.v2.api.entity.CustomFeeFieldUM
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList

View file

@ -18,7 +18,7 @@ import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.eth
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.ethereum.EthereumCustomFeeConverter.Companion.GAS_DECIMALS
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.ethereum.EthereumCustomFeeConverter.Companion.GIGA_DECIMALS
import com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.setEmpty
import com.tangem.features.send.v2.subcomponents.fee.ui.state.CustomFeeFieldUM
import com.tangem.features.send.v2.api.entity.CustomFeeFieldUM
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList

View file

@ -13,7 +13,7 @@ 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.converters.custom.CustomFeeConverter
import com.tangem.features.send.v2.subcomponents.fee.ui.state.CustomFeeFieldUM
import com.tangem.features.send.v2.api.entity.CustomFeeFieldUM
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList

View file

@ -17,7 +17,7 @@ import com.tangem.core.ui.components.inputrow.InputRowEnterInfoAmount
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.subcomponents.fee.ui.state.CustomFeeFieldUM
import com.tangem.features.send.v2.api.entity.CustomFeeFieldUM
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeType
import kotlinx.collections.immutable.ImmutableList

View file

@ -1,20 +0,0 @@
package com.tangem.features.send.v2.subcomponents.fee.ui.state
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.extensions.TextReference
@Immutable
data class CustomFeeFieldUM(
val value: String,
val onValueChange: (String) -> Unit,
val keyboardOptions: KeyboardOptions,
val keyboardActions: KeyboardActions,
val symbol: String?,
val decimals: Int,
val title: TextReference,
val footer: TextReference,
val label: TextReference? = null,
val isReadonly: Boolean = false,
)

View file

@ -5,6 +5,7 @@ import com.tangem.blockchain.common.transaction.Fee
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.domain.transaction.error.GetFeeError
import com.tangem.features.send.v2.api.entity.CustomFeeFieldUM
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import java.math.BigInteger

View file

@ -3,6 +3,7 @@ package com.tangem.features.send.v2.subcomponents.fee.ui.state
import androidx.compose.runtime.Stable
import com.tangem.common.ui.notifications.NotificationUM
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.features.send.v2.api.entity.CustomFeeFieldUM
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import java.math.BigDecimal