Updated on 2026-08-14

This commit is contained in:
Tangem 2025-07-21 12:22:10 +05:00
parent 68fbe17731
commit b7dc46ae64
7 changed files with 111 additions and 0 deletions

View file

@ -0,0 +1,13 @@
package com.tangem.features.send.v2.api.feeselector
import kotlinx.coroutines.flow.Flow
data class FeeSelectorReloadData(val removeSuggestedFee: Boolean = false)
interface FeeSelectorReloadTrigger {
suspend fun triggerUpdate(data: FeeSelectorReloadData = FeeSelectorReloadData())
}
interface FeeSelectorReloadListener {
val reloadTriggerFlow: Flow<FeeSelectorReloadData>
}

View file

@ -0,0 +1,20 @@
package com.tangem.features.send.v2.feeselector
import com.tangem.features.send.v2.api.feeselector.FeeSelectorReloadData
import com.tangem.features.send.v2.api.feeselector.FeeSelectorReloadListener
import com.tangem.features.send.v2.api.feeselector.FeeSelectorReloadTrigger
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
internal class DefaultFeeSelectorReload @Inject constructor() : FeeSelectorReloadListener, FeeSelectorReloadTrigger {
private val _reloadTriggerFlow = MutableSharedFlow<FeeSelectorReloadData>()
override val reloadTriggerFlow: Flow<FeeSelectorReloadData> = _reloadTriggerFlow.asSharedFlow()
override suspend fun triggerUpdate(data: FeeSelectorReloadData) {
_reloadTriggerFlow.emit(data)
}
}

View file

@ -2,8 +2,11 @@ package com.tangem.features.send.v2.feeselector.di
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
import com.tangem.features.send.v2.api.FeeSelectorComponent
import com.tangem.features.send.v2.api.feeselector.FeeSelectorReloadListener
import com.tangem.features.send.v2.api.feeselector.FeeSelectorReloadTrigger
import com.tangem.features.send.v2.feeselector.DefaultFeeSelectorBlockComponent
import com.tangem.features.send.v2.feeselector.DefaultFeeSelectorComponent
import com.tangem.features.send.v2.feeselector.DefaultFeeSelectorReload
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
@ -21,4 +24,12 @@ internal interface FeeSelectorFeatureModule {
@Binds
@Singleton
fun bindBlockComponentFactory(factory: DefaultFeeSelectorBlockComponent.Factory): FeeSelectorBlockComponent.Factory
@Binds
@Singleton
fun provideFeeSelectorReloadTrigger(impl: DefaultFeeSelectorReload): FeeSelectorReloadTrigger
@Binds
@Singleton
fun provideFeeSelectorReloadListener(impl: DefaultFeeSelectorReload): FeeSelectorReloadListener
}

View file

@ -14,12 +14,15 @@ import com.tangem.domain.transaction.usecase.IsFeeApproximateUseCase
import com.tangem.features.send.v2.api.callbacks.FeeSelectorModelCallback
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.feeselector.FeeSelectorReloadListener
import com.tangem.features.send.v2.api.params.FeeSelectorParams
import com.tangem.features.send.v2.feeselector.model.transformers.*
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.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import javax.inject.Inject
@ -27,6 +30,7 @@ import javax.inject.Inject
@ModelScoped
internal class FeeSelectorModel @Inject constructor(
paramsContainer: ParamsContainer,
private val feeSelectorReloadListener: FeeSelectorReloadListener,
private val isFeeApproximateUseCase: IsFeeApproximateUseCase,
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
override val dispatchers: CoroutineDispatcherProvider,
@ -43,12 +47,24 @@ internal class FeeSelectorModel @Inject constructor(
init {
initAppCurrency()
loadFee()
listenReloadTrigger()
}
fun updateState(feeSelectorUM: FeeSelectorUM) {
uiState.value = feeSelectorUM
}
private fun listenReloadTrigger() {
feeSelectorReloadListener.reloadTriggerFlow
.onEach { data ->
if (data.removeSuggestedFee) {
uiState.update(FeeSelectorRemoveSuggestedTransformer)
}
loadFee()
}
.launchIn(modelScope)
}
private fun initAppCurrency() {
modelScope.launch {
appCurrency = getSelectedAppCurrencyUseCase.invokeSync().getOrElse { AppCurrency.Default }
@ -56,6 +72,7 @@ internal class FeeSelectorModel @Inject constructor(
}
private fun loadFee() {
uiState.update(FeeSelectorLoadingTransformers)
modelScope.launch {
params.onLoadFee()
.fold(

View file

@ -0,0 +1,11 @@
package com.tangem.features.send.v2.feeselector.model.transformers
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.utils.transformer.Transformer
internal object FeeSelectorLoadingTransformers : Transformer<FeeSelectorUM> {
override fun transform(prevState: FeeSelectorUM): FeeSelectorUM {
return FeeSelectorUM.Loading
}
}

View file

@ -0,0 +1,24 @@
package com.tangem.features.send.v2.feeselector.model.transformers
import com.tangem.features.send.v2.api.entity.FeeItem
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.utils.transformer.Transformer
import kotlinx.collections.immutable.toImmutableList
internal object FeeSelectorRemoveSuggestedTransformer : Transformer<FeeSelectorUM> {
override fun transform(prevState: FeeSelectorUM): FeeSelectorUM {
val state = prevState as? FeeSelectorUM.Content ?: return prevState
val newFeeItems = state.feeItems.filterNot { item -> item is FeeItem.Suggested }
val newSelectedFee = if (state.selectedFeeItem is FeeItem.Suggested) {
state.feeItems.first { item -> item is FeeItem.Market }
} else {
state.selectedFeeItem
}
return state.copy(
feeItems = newFeeItems.toImmutableList(),
selectedFeeItem = newSelectedFee,
)
}
}

View file

@ -30,6 +30,8 @@ import com.tangem.domain.walletconnect.usecase.method.*
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.features.send.v2.api.callbacks.FeeSelectorModelCallback
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.v2.api.feeselector.FeeSelectorReloadData
import com.tangem.features.send.v2.api.feeselector.FeeSelectorReloadTrigger
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
@ -53,6 +55,7 @@ import kotlin.properties.Delegates
internal class WcSendTransactionModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,
private val feeSelectorReloadTrigger: FeeSelectorReloadTrigger,
private val router: Router,
private val clipboardManager: ClipboardManager,
private val useCaseFactory: WcRequestUseCaseFactory,
@ -76,6 +79,7 @@ internal class WcSendTransactionModel @Inject constructor(
private var signState: WcSignState<*> by Delegates.notNull()
private var wcApproval: WcApproval? = null
private var sign: () -> Unit = {}
private val feeReloadState = MutableStateFlow(false)
init {
@Suppress("UnusedPrivateMember")
@ -116,6 +120,9 @@ internal class WcSendTransactionModel @Inject constructor(
wcApproval = useCase as? WcApproval
sign = { useCase.sign() }
buildUiState(securityCheck, useCase, signState, isApprovalMethod)
if (feeReloadState.value) {
triggerFeeReload()
}
}
}
else -> unknownMethodRunnable()
@ -123,6 +130,13 @@ internal class WcSendTransactionModel @Inject constructor(
}
}
private fun triggerFeeReload() {
feeReloadState.value = false
modelScope.launch {
feeSelectorReloadTrigger.triggerUpdate(data = FeeSelectorReloadData(removeSuggestedFee = true))
}
}
/**
* Handles callback with updated [feeSelectorUM] from click FeeSelectorComponent.
* We need to trigger navigation to dismiss fee selector component
@ -242,6 +256,7 @@ internal class WcSendTransactionModel @Inject constructor(
wcApproval?.getAmount()?.let { currentAmount ->
wcApproval?.updateAmount(currentAmount.copy(amount = currentAmount.amount?.copy(value = newValue)))
}
feeReloadState.value = true
}
fun onClickAllowToSpend() {