diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c48f118fe4..383bdf1b24 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -207,6 +207,8 @@ dependencies { implementation(projects.features.nft.impl) implementation(projects.features.walletconnect.api) implementation(projects.features.walletconnect.impl) + implementation(projects.features.feeSelector.api) + implementation(projects.features.feeSelector.impl) /** AndroidX libraries */ implementation(deps.androidx.core.ktx) diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/fields/AmountTextField.kt b/core/ui/src/main/java/com/tangem/core/ui/components/fields/AmountTextField.kt index c985d43cfc..017523fbbc 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/fields/AmountTextField.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/fields/AmountTextField.kt @@ -59,6 +59,7 @@ fun AmountTextField( textStyle: TextStyle, modifier: Modifier = Modifier, color: Color = TangemTheme.colors.text.primary1, + backgroundColor: Color = TangemTheme.colors.background.action, visualTransformation: VisualTransformation = AmountVisualTransformation(decimals), keyboardOptions: KeyboardOptions = KeyboardOptions( keyboardType = KeyboardType.Number, @@ -117,7 +118,7 @@ fun AmountTextField( singleLine = true, readOnly = !isEnabled, visualTransformation = visualTransformation, - modifier = Modifier.background(TangemTheme.colors.background.action), + modifier = Modifier.background(backgroundColor), ) } } diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnterInfoAmount.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnterInfoAmount.kt index bf0e7bb5ed..5a92d21899 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnterInfoAmount.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnterInfoAmount.kt @@ -1,16 +1,17 @@ package com.tangem.core.ui.components.inputrow -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.* import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import com.tangem.core.ui.R import com.tangem.core.ui.components.fields.AmountTextField import com.tangem.core.ui.components.fields.visualtransformations.AmountVisualTransformation import com.tangem.core.ui.components.inputrow.inner.DividerContainer @@ -105,4 +106,77 @@ fun InputRowEnterInfoAmount( } } } +} + +@Composable +fun InputRowEnterInfoAmountV2( + title: TextReference, + text: String, + decimals: Int, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + symbol: String? = null, + info: TextReference? = null, + titleColor: Color = TangemTheme.colors.text.secondary, + textColor: Color = TangemTheme.colors.text.primary1, + infoColor: Color = TangemTheme.colors.text.tertiary, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, + showDivider: Boolean = false, + isReadOnly: Boolean = false, +) { + DividerContainer( + modifier = modifier, + showDivider = showDivider, + paddingValues = PaddingValues(horizontal = 12.dp), + ) { + Column( + modifier = Modifier.fillMaxWidth().padding(16.dp), + ) { + Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(2.dp)) { + Text( + text = title.resolveReference(), + style = TangemTheme.typography.subtitle2, + color = titleColor, + ) + Icon( + modifier = Modifier.size(16.dp), + painter = painterResource(R.drawable.ic_union_16), + tint = TangemTheme.colors.icon.informative, + contentDescription = null, + ) + } + Row { + AmountTextField( + value = text, + decimals = decimals, + visualTransformation = AmountVisualTransformation( + decimals = decimals, + symbol = symbol, + decimalFormat = rememberDecimalFormat(), + ), + onValueChange = onValueChange, + color = textColor, + isEnabled = !isReadOnly, + textStyle = TangemTheme.typography.body2, + keyboardOptions = keyboardOptions, + keyboardActions = keyboardActions, + backgroundColor = Color.Transparent, + modifier = Modifier + .padding(top = TangemTheme.dimens.spacing8) + .weight(1f), + ) + info?.let { + Text( + text = it.resolveReference(), + style = TangemTheme.typography.body2, + color = infoColor, + modifier = Modifier + .padding(start = TangemTheme.dimens.spacing8) + .align(Alignment.Bottom), + ) + } + } + } + } } \ No newline at end of file diff --git a/core/ui/src/main/res/drawable/ic_edit_v2_24.xml b/core/ui/src/main/res/drawable/ic_edit_v2_24.xml new file mode 100644 index 0000000000..5cdd16423c --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_edit_v2_24.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/core/ui/src/main/res/drawable/ic_star_mini_24.xml b/core/ui/src/main/res/drawable/ic_star_mini_24.xml new file mode 100644 index 0000000000..99a400477c --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_star_mini_24.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/core/ui/src/main/res/drawable/ic_union_16.xml b/core/ui/src/main/res/drawable/ic_union_16.xml new file mode 100644 index 0000000000..3281f5e0ff --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_union_16.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/features/fee-selector/api/.gitignore b/features/fee-selector/api/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/features/fee-selector/api/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/features/fee-selector/api/build.gradle.kts b/features/fee-selector/api/build.gradle.kts new file mode 100644 index 0000000000..f224bf5622 --- /dev/null +++ b/features/fee-selector/api/build.gradle.kts @@ -0,0 +1,27 @@ +plugins { + alias(deps.plugins.android.library) + alias(deps.plugins.kotlin.android) + id("configuration") +} + +android { + namespace = "com.tangem.features.feeselector.api" +} + +dependencies { + /** Project - Core */ + implementation(projects.core.ui) + implementation(projects.core.decompose) + + /** Domain models */ + // api(projects.domain.models) + implementation(projects.domain.appCurrency.models) + // implementation(projects.domain.wallets.models) + + /** Compose */ + implementation(deps.compose.runtime) + implementation(deps.compose.foundation) + + /** Other */ + implementation(deps.kotlin.immutable.collections) +} \ No newline at end of file diff --git a/features/fee-selector/api/src/main/kotlin/com/tangem/features/feeselector/api/component/FeeSelectorComponent.kt b/features/fee-selector/api/src/main/kotlin/com/tangem/features/feeselector/api/component/FeeSelectorComponent.kt new file mode 100644 index 0000000000..726aab533a --- /dev/null +++ b/features/fee-selector/api/src/main/kotlin/com/tangem/features/feeselector/api/component/FeeSelectorComponent.kt @@ -0,0 +1,12 @@ +package com.tangem.features.feeselector.api.component + +import com.tangem.core.decompose.factory.ComponentFactory +import com.tangem.core.ui.decompose.ComposableBottomSheetComponent +import com.tangem.core.ui.decompose.ComposableContentComponent +import com.tangem.domain.appcurrency.model.AppCurrency + +interface FeeSelectorComponent : ComposableContentComponent, ComposableBottomSheetComponent { + data class Params(val appCurrency: AppCurrency) + + interface Factory : ComponentFactory +} \ No newline at end of file diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/ui/state/CustomFeeFieldUM.kt b/features/fee-selector/api/src/main/kotlin/com/tangem/features/feeselector/api/entity/CustomFeeFieldUM.kt similarity index 84% rename from features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/ui/state/CustomFeeFieldUM.kt rename to features/fee-selector/api/src/main/kotlin/com/tangem/features/feeselector/api/entity/CustomFeeFieldUM.kt index 5b52d2c6b8..cc823ad6d6 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/ui/state/CustomFeeFieldUM.kt +++ b/features/fee-selector/api/src/main/kotlin/com/tangem/features/feeselector/api/entity/CustomFeeFieldUM.kt @@ -1,4 +1,4 @@ -package com.tangem.features.send.v2.subcomponents.fee.ui.state +package com.tangem.features.feeselector.api.entity import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions @@ -6,7 +6,7 @@ import androidx.compose.runtime.Immutable import com.tangem.core.ui.extensions.TextReference @Immutable -internal data class CustomFeeFieldUM( +data class CustomFeeFieldUM( val value: String, val onValueChange: (String) -> Unit, val keyboardOptions: KeyboardOptions, diff --git a/features/fee-selector/impl/.gitignore b/features/fee-selector/impl/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/features/fee-selector/impl/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/features/fee-selector/impl/build.gradle.kts b/features/fee-selector/impl/build.gradle.kts new file mode 100644 index 0000000000..90c8927b9b --- /dev/null +++ b/features/fee-selector/impl/build.gradle.kts @@ -0,0 +1,57 @@ +plugins { + alias(deps.plugins.android.library) + alias(deps.plugins.kotlin.android) + alias(deps.plugins.kotlin.serialization) + alias(deps.plugins.kotlin.kapt) + alias(deps.plugins.hilt.android) + id("configuration") +} + +android { + namespace = "com.tangem.features.feeselector.impl" +} + +dependencies { + /** Project - API */ + implementation(projects.features.feeSelector.api) + + /** Project - Core */ + implementation(projects.common.ui) + implementation(projects.common.routing) + implementation(projects.core.decompose) + implementation(projects.core.ui) + implementation(projects.core.pagination) + implementation(projects.core.navigation) + + /** Project - Domain */ + implementation(projects.domain.appCurrency.models) + implementation(projects.domain.models) + implementation(projects.domain.tokens) + implementation(projects.domain.tokens.models) + implementation(projects.domain.wallets) + implementation(projects.domain.wallets.models) + + /** AndroidX */ + implementation(deps.androidx.activity.compose) + implementation(deps.lifecycle.compose) + + /** Compose */ + implementation(deps.compose.ui) + implementation(deps.compose.ui.tooling) + implementation(deps.compose.foundation) + implementation(deps.compose.material3) + implementation(deps.compose.shimmer) + + /*** Tangem SDK */ + implementation(tangemDeps.blockchain) + + /** DI */ + implementation(deps.hilt.android) + kapt(deps.hilt.kapt) + + /** Other */ + implementation(deps.arrow.core) + implementation(deps.kotlin.immutable.collections) + implementation(deps.decompose.ext.compose) + implementation(deps.timber) +} \ No newline at end of file diff --git a/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/component/DefaultFeeSelectorComponent.kt b/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/component/DefaultFeeSelectorComponent.kt new file mode 100644 index 0000000000..0fda871e10 --- /dev/null +++ b/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/component/DefaultFeeSelectorComponent.kt @@ -0,0 +1,45 @@ +package com.tangem.features.feeselector.impl.component + +import androidx.activity.compose.BackHandler +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.tangem.core.decompose.context.AppComponentContext +import com.tangem.core.decompose.model.getOrCreateModel +import com.tangem.features.feeselector.api.component.FeeSelectorComponent +import com.tangem.features.feeselector.impl.model.FeeSelectorModel +import com.tangem.features.feeselector.impl.ui.FeeSelectorModalBottomSheet +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject + +internal class DefaultFeeSelectorComponent @AssistedInject constructor( + @Assisted appComponentContext: AppComponentContext, + @Assisted private val params: FeeSelectorComponent.Params, +) : FeeSelectorComponent, AppComponentContext by appComponentContext { + + private val model: FeeSelectorModel = getOrCreateModel(params = params) + + override fun dismiss() { + model.dismiss() + } + + @Composable + override fun BottomSheet() { + FeeSelectorModalBottomSheet(onDismiss = ::dismiss, state = TODO()) + } + + // Temporary workaround, to use test this component + @Composable + override fun Content(modifier: Modifier) { + BackHandler(onBack = router::pop) + FeeSelectorModalBottomSheet(onDismiss = ::dismiss, state = TODO()) + } + + @AssistedFactory + interface Factory : FeeSelectorComponent.Factory { + override fun create( + context: AppComponentContext, + params: FeeSelectorComponent.Params, + ): DefaultFeeSelectorComponent + } +} \ No newline at end of file diff --git a/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/di/FeeSelectorFeatureModule.kt b/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/di/FeeSelectorFeatureModule.kt new file mode 100644 index 0000000000..d47efb12e3 --- /dev/null +++ b/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/di/FeeSelectorFeatureModule.kt @@ -0,0 +1,18 @@ +package com.tangem.features.feeselector.impl.di + +import com.tangem.features.feeselector.api.component.FeeSelectorComponent +import com.tangem.features.feeselector.impl.component.DefaultFeeSelectorComponent +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +internal interface FeeSelectorFeatureModule { + + @Binds + @Singleton + fun bindComponentFactory(factory: DefaultFeeSelectorComponent.Factory): FeeSelectorComponent.Factory +} \ No newline at end of file diff --git a/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/di/FeeSelectorModelModule.kt b/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/di/FeeSelectorModelModule.kt new file mode 100644 index 0000000000..2144133681 --- /dev/null +++ b/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/di/FeeSelectorModelModule.kt @@ -0,0 +1,19 @@ +package com.tangem.features.feeselector.impl.di + +import com.tangem.core.decompose.di.ModelComponent +import com.tangem.core.decompose.model.Model +import com.tangem.features.feeselector.impl.model.FeeSelectorModel +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.multibindings.ClassKey +import dagger.multibindings.IntoMap + +@Module +@InstallIn(ModelComponent::class) +internal interface FeeSelectorModelModule { + @Binds + @IntoMap + @ClassKey(FeeSelectorModel::class) + fun bindModel(model: FeeSelectorModel): Model +} \ No newline at end of file diff --git a/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/entity/FeeSelectorUM.kt b/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/entity/FeeSelectorUM.kt new file mode 100644 index 0000000000..9fba9272a5 --- /dev/null +++ b/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/entity/FeeSelectorUM.kt @@ -0,0 +1,40 @@ +package com.tangem.features.feeselector.impl.entity + +import androidx.compose.runtime.Immutable +import com.tangem.blockchain.common.Amount +import com.tangem.core.ui.extensions.TextReference +import com.tangem.domain.appcurrency.model.AppCurrency +import com.tangem.features.feeselector.api.entity.CustomFeeFieldUM +import kotlinx.collections.immutable.ImmutableList +import java.math.BigDecimal + +@Immutable +internal sealed class FeeSelectorUM { + + data object Loading : FeeSelectorUM() + + data class Content( + val isDoneEnabled: Boolean, + val feeItems: ImmutableList, + val selectedFeeItem: FeeItem, + val isFeeApproximate: Boolean, + val feeFiatRateDataHolder: FeeFiatRateDataHolder?, + ) : FeeSelectorUM() +} + +@Immutable +data class FeeFiatRateDataHolder( + val rate: BigDecimal, + val appCurrency: AppCurrency, +) + +@Immutable +internal sealed class FeeItem { + abstract val onSelect: () -> Unit + + 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, override val onSelect: () -> Unit) : FeeItem() +} \ No newline at end of file diff --git a/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/model/FeeSelectorModel.kt b/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/model/FeeSelectorModel.kt new file mode 100644 index 0000000000..ea2ae3c857 --- /dev/null +++ b/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/model/FeeSelectorModel.kt @@ -0,0 +1,31 @@ +package com.tangem.features.feeselector.impl.model + +import androidx.compose.runtime.Stable +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.feeselector.api.component.FeeSelectorComponent +import com.tangem.features.feeselector.impl.entity.FeeSelectorUM +import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import javax.inject.Inject + +@Stable +@ModelScoped +internal class FeeSelectorModel @Inject constructor( + paramsContainer: ParamsContainer, + private val router: Router, + override val dispatchers: CoroutineDispatcherProvider, +) : Model() { + + @Suppress("UnusedPrivateMember") + private val params = paramsContainer.require() + val uiState: StateFlow + field = MutableStateFlow(FeeSelectorUM.Loading) + + fun dismiss() { + router.pop() + } +} \ No newline at end of file diff --git a/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/ui/FeeSelectorModalBottomSheet.kt b/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/ui/FeeSelectorModalBottomSheet.kt new file mode 100644 index 0000000000..4b6215a295 --- /dev/null +++ b/features/fee-selector/impl/src/main/kotlin/com/tangem/features/feeselector/impl/ui/FeeSelectorModalBottomSheet.kt @@ -0,0 +1,510 @@ +package com.tangem.features.feeselector.impl.ui + +import android.content.res.Configuration +import androidx.annotation.DrawableRes +import androidx.compose.animation.* +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.HorizontalDivider +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 +import androidx.compose.ui.graphics.Color +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.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider +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.common.ui.amountScreen.utils.getFiatReference +import com.tangem.core.ui.components.PrimaryButton +import com.tangem.core.ui.components.atoms.text.EllipsisText +import com.tangem.core.ui.components.atoms.text.TextEllipsis +import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig +import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent +import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle +import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetWithFooter +import com.tangem.core.ui.components.inputrow.InputRowEnterInfoAmountV2 +import com.tangem.core.ui.extensions.* +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.feeselector.api.entity.CustomFeeFieldUM +import com.tangem.features.feeselector.impl.R +import com.tangem.features.feeselector.impl.entity.FeeFiatRateDataHolder +import com.tangem.features.feeselector.impl.entity.FeeItem +import com.tangem.features.feeselector.impl.entity.FeeSelectorUM +import com.tangem.utils.StringsSigns +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf +import java.math.BigDecimal + +@Composable +internal fun FeeSelectorModalBottomSheet(state: FeeSelectorUM.Content, onDismiss: () -> Unit) { + TangemModalBottomSheetWithFooter( + config = TangemBottomSheetConfig( + isShown = true, + onDismissRequest = onDismiss, + content = TangemBottomSheetConfigContent.Empty, + ), + containerColor = TangemTheme.colors.background.primary, + title = { + TangemModalBottomSheetTitle( + title = resourceReference(R.string.common_network_fee_title), + startIconRes = R.drawable.ic_back_24, + onStartClick = onDismiss, + ) + }, + content = { + FeeSelectorItems(state = state, modifier = Modifier.padding(vertical = 4.dp, horizontal = 16.dp)) + }, + footer = { + PrimaryButton( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + text = stringResourceSafe(R.string.common_done), + onClick = onDismiss, + enabled = state.isDoneEnabled, + ) + }, + ) +} + +@Suppress("LongMethod", "CyclomaticComplexMethod") +@Composable +private fun FeeSelectorItems(state: FeeSelectorUM.Content, modifier: Modifier = Modifier) { + Column(modifier = modifier) { + state.feeItems.fastForEachIndexed { index, item -> + val isSelected = item == 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, + label = "Fee selector icon tint change", + ) + val iconBackgroundColor by animateColorAsState( + targetValue = if (isSelected) { + TangemTheme.colors.icon.accent.copy(alpha = 0.1F) + } else { + TangemTheme.colors.background.secondary + }, + label = "Fee selector icon background change", + ) + val onSelect by rememberUpdatedState(item.onSelect) + val itemModifier = Modifier + .fillMaxWidth() + .background(TangemTheme.colors.background.primary) + .then( + if (isSelected) { + Modifier + .border( + width = 2.5.dp, + color = iconTint.copy(alpha = 0.2F), + shape = RoundedCornerShape(16.dp), + ) + .padding(2.5.dp) + .border(width = 1.dp, color = iconTint, shape = RoundedCornerShape(14.dp)) + .clip(RoundedCornerShape(14.dp)) + } else { + Modifier + }, + ) + .clickableSingle(onClick = onSelect) + when (item) { + is FeeItem.Suggested -> RegularFeeItemContent( + modifier = itemModifier, + title = item.title, + iconRes = R.drawable.ic_star_mini_24, + iconBackgroundColor = iconBackgroundColor, + iconTint = iconTint, + preDot = stringReference( + item.amount.value.format { + crypto( + symbol = item.amount.currencySymbol, + decimals = item.amount.decimals, + ).fee(canBeLower = state.isFeeApproximate) + }, + ), + postDot = if (state.feeFiatRateDataHolder != null) { + getFiatReference( + value = item.amount.value, + rate = state.feeFiatRateDataHolder.rate, + appCurrency = state.feeFiatRateDataHolder.appCurrency, + ) + } else { + null + }, + ellipsizeOffset = item.amount.currencySymbol.length, + showDivider = !isSelected && !lastItem, + ) + is FeeItem.Slow -> RegularFeeItemContent( + modifier = itemModifier, + title = resourceReference(R.string.common_fee_selector_option_slow), + iconRes = R.drawable.ic_tortoise_24, + iconBackgroundColor = iconBackgroundColor, + iconTint = iconTint, + preDot = stringReference( + item.amount.value.format { + crypto( + symbol = item.amount.currencySymbol, + decimals = item.amount.decimals, + ).fee(canBeLower = state.isFeeApproximate) + }, + ), + postDot = if (state.feeFiatRateDataHolder != null) { + getFiatReference( + value = item.amount.value, + rate = state.feeFiatRateDataHolder.rate, + appCurrency = state.feeFiatRateDataHolder.appCurrency, + ) + } else { + null + }, + ellipsizeOffset = item.amount.currencySymbol.length, + showDivider = !isSelected && !lastItem, + ) + is FeeItem.Market -> RegularFeeItemContent( + modifier = itemModifier, + title = resourceReference(R.string.common_fee_selector_option_market), + iconRes = R.drawable.ic_bird_24, + iconBackgroundColor = iconBackgroundColor, + iconTint = iconTint, + preDot = stringReference( + item.amount.value.format { + crypto( + symbol = item.amount.currencySymbol, + decimals = item.amount.decimals, + ).fee(canBeLower = state.isFeeApproximate) + }, + ), + postDot = if (state.feeFiatRateDataHolder != null) { + getFiatReference( + value = item.amount.value, + rate = state.feeFiatRateDataHolder.rate, + appCurrency = state.feeFiatRateDataHolder.appCurrency, + ) + } else { + null + }, + ellipsizeOffset = item.amount.currencySymbol.length, + showDivider = !isSelected && !lastItem, + ) + is FeeItem.Fast -> RegularFeeItemContent( + modifier = itemModifier, + title = resourceReference(R.string.common_fee_selector_option_fast), + iconRes = R.drawable.ic_hare_24, + iconBackgroundColor = iconBackgroundColor, + iconTint = iconTint, + preDot = stringReference( + item.amount.value.format { + crypto( + symbol = item.amount.currencySymbol, + decimals = item.amount.decimals, + ).fee(canBeLower = state.isFeeApproximate) + }, + ), + postDot = if (state.feeFiatRateDataHolder != null) { + getFiatReference( + value = item.amount.value, + rate = state.feeFiatRateDataHolder.rate, + appCurrency = state.feeFiatRateDataHolder.appCurrency, + ) + } else { + null + }, + ellipsizeOffset = item.amount.currencySymbol.length, + showDivider = !isSelected && !lastItem, + ) + is FeeItem.Custom -> CustomFeeBlock( + modifier = itemModifier, + customFee = item, + isSelected = isSelected, + iconBackgroundColor = iconBackgroundColor, + iconTint = iconTint, + ) + } + } + } +} + +@Composable +private fun CustomFeeBlock( + customFee: FeeItem.Custom, + isSelected: Boolean, + iconBackgroundColor: Color, + iconTint: Color, + modifier: Modifier = Modifier, +) { + Column(modifier = modifier) { + Row( + modifier = Modifier.padding(all = 12.dp), + horizontalArrangement = Arrangement.spacedBy(12.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + modifier = Modifier + .size(36.dp) + .background(color = iconBackgroundColor, shape = CircleShape) + .padding(6.dp), + painter = painterResource(R.drawable.ic_edit_v2_24), + tint = iconTint, + contentDescription = null, + ) + Text( + text = stringResourceSafe(R.string.common_custom), + color = TangemTheme.colors.text.primary1, + style = TangemTheme.typography.subtitle2, + ) + } + AnimatedVisibility( + visible = isSelected, + label = "Custom Fee Selected Animation", + enter = expandVertically().plus(fadeIn()), + exit = shrinkVertically().plus(fadeOut()), + ) { + ExpandedCustomFeeItems(customFeeFields = customFee.customValues, onValueChange = { _, _ -> }) + } + } +} + +@Composable +private fun ExpandedCustomFeeItems( + customFeeFields: ImmutableList, + onValueChange: (Int, String) -> Unit, + modifier: Modifier = Modifier, +) { + Column(modifier = modifier) { + customFeeFields.fastForEachIndexed { index, field -> + val showDivider = index != customFeeFields.size - 1 + if (field.label != null) { + InputRowEnterInfoAmountV2( + text = field.value, + decimals = field.decimals, + symbol = field.symbol, + title = field.title, + titleColor = TangemTheme.colors.text.tertiary, + info = field.label, + keyboardOptions = field.keyboardOptions, + keyboardActions = field.keyboardActions, + onValueChange = { onValueChange(index, it) }, + showDivider = showDivider, + isReadOnly = field.isReadonly, + ) + } else { + InputRowEnterInfoAmountV2( + text = field.value, + decimals = field.decimals, + title = field.title, + titleColor = TangemTheme.colors.text.tertiary, + symbol = field.symbol, + onValueChange = { onValueChange(index, it) }, + keyboardOptions = field.keyboardOptions, + keyboardActions = field.keyboardActions, + showDivider = showDivider, + ) + } + } + } +} + +@Composable +private fun RegularFeeItemContent( + title: TextReference, + @DrawableRes iconRes: Int, + iconBackgroundColor: Color, + iconTint: Color, + modifier: Modifier = Modifier, + preDot: TextReference? = null, + postDot: TextReference? = null, + ellipsizeOffset: Int? = null, + showDivider: Boolean = true, +) { + Column(modifier = modifier) { + Row( + modifier = Modifier.padding(all = 12.dp), + horizontalArrangement = Arrangement.spacedBy(12.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + modifier = Modifier + .size(36.dp) + .background(color = iconBackgroundColor, shape = CircleShape) + .padding(6.dp), + painter = painterResource(iconRes), + tint = iconTint, + contentDescription = null, + ) + FeeDescription( + title = title, + preDot = preDot, + postDot = postDot, + ellipsizeOffset = ellipsizeOffset, + ) + } + if (showDivider) { + HorizontalDivider( + modifier = Modifier.padding(start = 60.dp, end = 12.dp), + color = TangemTheme.colors.stroke.primary, + thickness = 0.5.dp, + ) + } + } +} + +@Composable +private fun FeeDescription( + title: TextReference, + modifier: Modifier = Modifier, + preDot: TextReference? = null, + postDot: TextReference? = null, + ellipsizeOffset: Int? = null, +) { + Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(2.dp)) { + Text( + text = title.resolveReference(), + color = TangemTheme.colors.text.primary1, + style = TangemTheme.typography.subtitle2, + ) + if (preDot != null) { + FeeValueContent(preDot = preDot, postDot = postDot, ellipsizeOffset = ellipsizeOffset) + } + } +} + +@Composable +private fun FeeValueContent(preDot: TextReference, postDot: TextReference?, ellipsizeOffset: Int? = null) { + val ellipsis = if (ellipsizeOffset == null) { + TextEllipsis.End + } else { + TextEllipsis.OffsetEnd(ellipsizeOffset) + } + val textColor = TangemTheme.colors.text.tertiary + val textStyle = TangemTheme.typography.caption1 + Row { + EllipsisText( + text = preDot.resolveReference(), + style = textStyle, + color = textColor, + textAlign = TextAlign.End, + ellipsis = ellipsis, + ) + if (postDot != null) { + Text( + text = StringsSigns.DOT, + style = textStyle, + color = textColor, + textAlign = TextAlign.Center, + modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing4), + ) + Text(text = postDot.resolveReference(), style = textStyle, color = textColor) + } + } +} + +@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 FeeSelectorBS_Preview( + @PreviewParameter(FeeSelectorUMContentProvider::class) + state: FeeSelectorUM.Content, +) { + TangemThemePreview { + FeeSelectorModalBottomSheet(onDismiss = {}, state = state) + } +} + +private class FeeSelectorUMContentProvider : CollectionPreviewParameterProvider( + collection = listOf( + FeeSelectorUM.Content( + isDoneEnabled = false, + feeItems = persistentListOf( + FeeItem.Suggested( + title = stringReference("Suggested by Tangem"), + amount = Amount(value = BigDecimal("0.1"), blockchain = Blockchain.Ethereum), + onSelect = onSelectStub, + ), + 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), + ), + // selectedFeeItem = FeeItem.Market( + // amount = Amount(value = BigDecimal("0.02"), blockchain = Blockchain.Ethereum), + // onSelect = onSelectStub + // ), + selectedFeeItem = FeeItem.Custom(customValues = customFeeFields, onSelect = onSelectStub), + isFeeApproximate = true, + feeFiatRateDataHolder = FeeFiatRateDataHolder( + rate = BigDecimal.TEN, + appCurrency = AppCurrency.Default, + ), + ), + ), +) + +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, + ), +) \ No newline at end of file diff --git a/features/send-v2/impl/build.gradle.kts b/features/send-v2/impl/build.gradle.kts index edc948f7c6..15d1d01b0b 100644 --- a/features/send-v2/impl/build.gradle.kts +++ b/features/send-v2/impl/build.gradle.kts @@ -16,6 +16,7 @@ dependencies { implementation(projects.features.sendV2.api) implementation(projects.features.txhistory.api) implementation(projects.features.nft.api) + implementation(projects.features.feeSelector.api) /** Libs */ implementation(projects.libs.crypto) diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/FeeConverter.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/FeeConverter.kt index 2a5863ed1d..b8c9fecfcf 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/FeeConverter.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/FeeConverter.kt @@ -4,8 +4,8 @@ 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.feeselector.api.entity.CustomFeeFieldUM 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.subcomponents.fee.ui.state.FeeType import com.tangem.utils.converter.Converter import kotlinx.collections.immutable.ImmutableList diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/SendFeeCustomFieldConverter.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/SendFeeCustomFieldConverter.kt index 78304904a5..26603db4d2 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/SendFeeCustomFieldConverter.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/SendFeeCustomFieldConverter.kt @@ -5,11 +5,11 @@ 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.feeselector.api.entity.CustomFeeFieldUM 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.subcomponents.fee.ui.state.FeeSelectorUM import com.tangem.utils.converter.TwoWayConverter import kotlinx.collections.immutable.ImmutableList diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/CustomFeeConverter.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/CustomFeeConverter.kt index 4250d48580..19645e440b 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/CustomFeeConverter.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/CustomFeeConverter.kt @@ -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.feeselector.api.entity.CustomFeeFieldUM import com.tangem.utils.converter.Converter import kotlinx.collections.immutable.ImmutableList diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/bitcoin/BitcoinCustomFeeConverter.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/bitcoin/BitcoinCustomFeeConverter.kt index a2f5349672..548887f56d 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/bitcoin/BitcoinCustomFeeConverter.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/bitcoin/BitcoinCustomFeeConverter.kt @@ -11,11 +11,11 @@ import com.tangem.core.ui.utils.parseBigDecimal 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.feeselector.api.entity.CustomFeeFieldUM 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 import com.tangem.lib.crypto.BlockchainUtils import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/ethereum/BaseEthereumCustomFeeConverter.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/ethereum/BaseEthereumCustomFeeConverter.kt index c0828d3d60..fbdd94c589 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/ethereum/BaseEthereumCustomFeeConverter.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/ethereum/BaseEthereumCustomFeeConverter.kt @@ -1,8 +1,8 @@ package com.tangem.features.send.v2.subcomponents.fee.model.converters.custom.ethereum import com.tangem.blockchain.common.transaction.Fee +import com.tangem.features.feeselector.api.entity.CustomFeeFieldUM 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 /** diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/ethereum/EthereumCustomFeeConverter.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/ethereum/EthereumCustomFeeConverter.kt index ce2ba52261..f083aaa40c 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/ethereum/EthereumCustomFeeConverter.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/ethereum/EthereumCustomFeeConverter.kt @@ -10,10 +10,10 @@ import com.tangem.core.ui.extensions.resourceReference 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.feeselector.api.entity.CustomFeeFieldUM 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 diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/ethereum/EthereumEIPCustomFeeConverter.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/ethereum/EthereumEIPCustomFeeConverter.kt index 2a7d389e13..4a40819826 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/ethereum/EthereumEIPCustomFeeConverter.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/ethereum/EthereumEIPCustomFeeConverter.kt @@ -11,6 +11,7 @@ import com.tangem.core.ui.utils.parseBigDecimal 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.feeselector.api.entity.CustomFeeFieldUM 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 @@ -19,7 +20,6 @@ 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 kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/ethereum/EthereumLegacyCustomFeeConverter.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/ethereum/EthereumLegacyCustomFeeConverter.kt index 8b2f86beb7..fe9af7c37b 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/ethereum/EthereumLegacyCustomFeeConverter.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/ethereum/EthereumLegacyCustomFeeConverter.kt @@ -11,6 +11,7 @@ import com.tangem.core.ui.utils.parseBigDecimal 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.feeselector.api.entity.CustomFeeFieldUM 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 @@ -19,7 +20,6 @@ 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 kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/kaspa/KaspaCustomFeeConverter.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/kaspa/KaspaCustomFeeConverter.kt index 2714e7d9f6..af0c7a97b4 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/kaspa/KaspaCustomFeeConverter.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/model/converters/custom/kaspa/KaspaCustomFeeConverter.kt @@ -11,10 +11,10 @@ import com.tangem.core.ui.utils.parseBigDecimal 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.feeselector.api.entity.CustomFeeFieldUM 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 import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/ui/SendCustomFee.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/ui/SendCustomFee.kt index cf31789446..d597bdd4b3 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/ui/SendCustomFee.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/ui/SendCustomFee.kt @@ -12,7 +12,7 @@ import com.tangem.core.ui.components.containers.FooterContainer import com.tangem.core.ui.components.inputrow.InputRowEnterAmount import com.tangem.core.ui.components.inputrow.InputRowEnterInfoAmount import com.tangem.core.ui.res.TangemTheme -import com.tangem.features.send.v2.subcomponents.fee.ui.state.CustomFeeFieldUM +import com.tangem.features.feeselector.api.entity.CustomFeeFieldUM import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeType import kotlinx.collections.immutable.ImmutableList diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/ui/state/FeeSelectorUM.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/ui/state/FeeSelectorUM.kt index a9f5aae1b4..ee4677b452 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/ui/state/FeeSelectorUM.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/ui/state/FeeSelectorUM.kt @@ -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.feeselector.api.entity.CustomFeeFieldUM import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/ui/state/FeeUM.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/ui/state/FeeUM.kt index 6bf499e1c4..e310e424af 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/ui/state/FeeUM.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/fee/ui/state/FeeUM.kt @@ -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.feeselector.api.entity.CustomFeeFieldUM import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import java.math.BigDecimal diff --git a/settings.gradle.kts b/settings.gradle.kts index d096b06988..f34d536ed8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -239,6 +239,9 @@ include(":features:nft:impl") include(":features:walletconnect:api") include(":features:walletconnect:impl") + +include(":features:fee-selector:api") +include(":features:fee-selector:impl") // endregion Feature modules // region Domain modules