Updated on 2026-08-14
This commit is contained in:
parent
c4bbacd9c3
commit
d293f60a6d
14 changed files with 60 additions and 13 deletions
|
|
@ -10,10 +10,15 @@ package com.tangem.core.ui.components.bottomsheets
|
|||
data class TangemBottomSheetConfig(
|
||||
val isShown: Boolean,
|
||||
val onDismissRequest: () -> Unit,
|
||||
val dismissOnClickOutside: () -> Boolean = { true },
|
||||
val content: TangemBottomSheetConfigContent,
|
||||
) {
|
||||
|
||||
companion object {
|
||||
val Empty = TangemBottomSheetConfig(false, {}, TangemBottomSheetConfigContent.Empty)
|
||||
val Empty = TangemBottomSheetConfig(
|
||||
isShown = false,
|
||||
onDismissRequest = {},
|
||||
content = TangemBottomSheetConfigContent.Empty,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -88,7 +88,17 @@ inline fun <reified T : TangemBottomSheetConfigContent> DefaultModalBottomSheetW
|
|||
noinline footer: @Composable (BoxScope.(T) -> Unit)?,
|
||||
) {
|
||||
var isVisible by remember { mutableStateOf(value = config.isShown) }
|
||||
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = skipPartiallyExpanded)
|
||||
val sheetState = rememberModalBottomSheetState(
|
||||
skipPartiallyExpanded = skipPartiallyExpanded,
|
||||
confirmValueChange = { sheetValue ->
|
||||
if (config.dismissOnClickOutside().not()) {
|
||||
// Ignore transitions to hidden (prevents dismiss on outside click/back press)
|
||||
sheetValue != SheetValue.Hidden
|
||||
} else {
|
||||
true
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
if (isVisible && config.content is T) {
|
||||
BasicModalBottomSheetWithFooter<T>(
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import java.math.BigInteger
|
|||
import java.math.RoundingMode
|
||||
|
||||
private val HUNDRED_PERCENT = 100.toBigInteger() // base 100%
|
||||
val INCREASE_GAS_LIMIT_FOR_SUPPLY = 112.toBigInteger() // 12% increase
|
||||
val INCREASE_GAS_LIMIT_FOR_SUPPLY = 120.toBigInteger() // 20% increase
|
||||
|
||||
fun Fee.fixFee(cryptoCurrency: CryptoCurrency, gasLimit: BigInteger): Fee = when (this) {
|
||||
is Fee.Ethereum.Legacy -> copy(
|
||||
|
|
|
|||
|
|
@ -314,9 +314,9 @@ class YieldSupplyEstimateEnterFeeUseCaseTest {
|
|||
val deployFee = txs.first().fee as Fee.Ethereum.EIP1559
|
||||
val approveFee = txs[1].fee as Fee.Ethereum.EIP1559
|
||||
val enterFee = txs.last().fee as Fee.Ethereum.EIP1559
|
||||
Truth.assertThat(deployFee.gasLimit).isEqualTo(BigInteger.valueOf(1_120))
|
||||
Truth.assertThat(approveFee.gasLimit).isEqualTo(BigInteger.valueOf(2_240))
|
||||
Truth.assertThat(enterFee.gasLimit).isEqualTo(BigInteger.valueOf(3_360))
|
||||
Truth.assertThat(deployFee.gasLimit).isEqualTo(BigInteger.valueOf(1_200))
|
||||
Truth.assertThat(approveFee.gasLimit).isEqualTo(BigInteger.valueOf(2_400))
|
||||
Truth.assertThat(enterFee.gasLimit).isEqualTo(BigInteger.valueOf(3_600))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -353,9 +353,9 @@ class YieldSupplyEstimateEnterFeeUseCaseTest {
|
|||
val deployFee = txs.first().fee as Fee.Ethereum.Legacy
|
||||
val approveFee = txs[1].fee as Fee.Ethereum.Legacy
|
||||
val enterFee = txs.last().fee as Fee.Ethereum.Legacy
|
||||
Truth.assertThat(deployFee.gasLimit).isEqualTo(BigInteger.valueOf(1_120))
|
||||
Truth.assertThat(approveFee.gasLimit).isEqualTo(BigInteger.valueOf(2_240))
|
||||
Truth.assertThat(enterFee.gasLimit).isEqualTo(BigInteger.valueOf(3_360))
|
||||
Truth.assertThat(deployFee.gasLimit).isEqualTo(BigInteger.valueOf(1_200))
|
||||
Truth.assertThat(approveFee.gasLimit).isEqualTo(BigInteger.valueOf(2_400))
|
||||
Truth.assertThat(enterFee.gasLimit).isEqualTo(BigInteger.valueOf(3_600))
|
||||
}
|
||||
|
||||
private fun getDeployTx() = uncompiled(
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.features.yield.supply.impl.subcomponents.active
|
|||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.arkivanov.decompose.extensions.compose.subscribeAsState
|
||||
import com.arkivanov.decompose.router.stack.StackNavigation
|
||||
import com.arkivanov.decompose.router.stack.childStack
|
||||
|
|
@ -59,9 +60,10 @@ internal class YieldSupplyActiveEntryComponent(
|
|||
@Composable
|
||||
override fun BottomSheet() {
|
||||
val stackState by innerStack.subscribeAsState()
|
||||
|
||||
val isTransactionInProgress by model.isTransactionInProgressFlow.collectAsStateWithLifecycle()
|
||||
YieldSupplyActiveEntryBottomSheet(
|
||||
stackState = stackState,
|
||||
dismissOnClickOutside = { !isTransactionInProgress },
|
||||
onDismiss = ::dismiss,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ import com.tangem.features.yield.supply.impl.subcomponents.approve.YieldSupplyAp
|
|||
import com.tangem.features.yield.supply.impl.subcomponents.stopearning.YieldSupplyStopEarningComponent
|
||||
import com.tangem.utils.TangemBlogUrlBuilder
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import javax.inject.Inject
|
||||
|
||||
@ModelScoped
|
||||
|
|
@ -25,15 +28,25 @@ internal class YieldSupplyActiveEntryModel @Inject constructor(
|
|||
|
||||
private val params = paramsContainer.require<YieldSupplyActiveEntryComponent.Params>()
|
||||
|
||||
val isTransactionInProgressFlow: StateFlow<Boolean>
|
||||
field = MutableStateFlow(false)
|
||||
|
||||
override fun onStopEarning() {
|
||||
router.push(YieldSupplyActiveRoute.Exit)
|
||||
}
|
||||
|
||||
override fun onBackClick() {
|
||||
router.pop()
|
||||
if (!isTransactionInProgressFlow.value) {
|
||||
router.pop()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTransactionProgress(inProgress: Boolean) {
|
||||
isTransactionInProgressFlow.update { inProgress }
|
||||
}
|
||||
|
||||
override fun onTransactionSent() {
|
||||
isTransactionInProgressFlow.update { false }
|
||||
params.onDismiss()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,12 +14,14 @@ import com.tangem.features.yield.supply.impl.subcomponents.active.model.YieldSup
|
|||
@Composable
|
||||
internal fun YieldSupplyActiveEntryBottomSheet(
|
||||
stackState: ChildStack<YieldSupplyActiveRoute, ComposableModularContentComponent>,
|
||||
dismissOnClickOutside: () -> Boolean,
|
||||
onDismiss: () -> Unit,
|
||||
) {
|
||||
TangemModalBottomSheetWithFooter<TangemBottomSheetConfigContent.Empty>(
|
||||
config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = onDismiss,
|
||||
dismissOnClickOutside = dismissOnClickOutside,
|
||||
content = TangemBottomSheetConfigContent.Empty,
|
||||
),
|
||||
containerColor = TangemTheme.colors.background.tertiary,
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ internal class YieldSupplyApproveComponent(
|
|||
|
||||
interface ModelCallback {
|
||||
fun onBackClick()
|
||||
fun onTransactionProgress(inProgress: Boolean)
|
||||
fun onTransactionSent()
|
||||
}
|
||||
}
|
||||
|
|
@ -117,6 +117,8 @@ internal class YieldSupplyApproveModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun onClick() {
|
||||
params.callback.onTransactionProgress(true)
|
||||
|
||||
val yieldSupplyFeeUM = uiState.value.yieldSupplyFeeUM as? YieldSupplyFeeUM.Content ?: return
|
||||
uiState.update(YieldSupplyTransactionInProgressTransformer)
|
||||
|
||||
|
|
@ -153,6 +155,7 @@ internal class YieldSupplyApproveModel @Inject constructor(
|
|||
}
|
||||
},
|
||||
)
|
||||
params.callback.onTransactionProgress(false)
|
||||
},
|
||||
ifRight = {
|
||||
val event = AnalyticsParam.TxSentFrom.Earning(
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.features.yield.supply.impl.subcomponents.startearning
|
|||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.arkivanov.decompose.extensions.compose.subscribeAsState
|
||||
import com.arkivanov.decompose.router.stack.StackNavigation
|
||||
import com.arkivanov.decompose.router.stack.childStack
|
||||
|
|
@ -56,9 +57,11 @@ internal class YieldSupplyStartEarningEntryComponent(
|
|||
@Composable
|
||||
override fun BottomSheet() {
|
||||
val stackState by innerStack.subscribeAsState()
|
||||
val uiState by model.uiState.collectAsStateWithLifecycle()
|
||||
|
||||
YieldSupplyStartEarningBottomSheet(
|
||||
stackState = stackState,
|
||||
dismissOnClickOutside = { !uiState.isTransactionSending },
|
||||
onDismiss = ::dismiss,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import com.tangem.core.decompose.navigation.Router
|
|||
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.features.yield.supply.impl.R
|
||||
import com.tangem.features.yield.supply.api.analytics.YieldSupplyAnalytics
|
||||
import com.tangem.features.yield.supply.impl.R
|
||||
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyActionUM
|
||||
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyFeeUM
|
||||
import com.tangem.features.yield.supply.impl.subcomponents.feepolicy.YieldSupplyFeePolicyComponent
|
||||
|
|
@ -54,7 +54,9 @@ internal class YieldSupplyStartEarningEntryModel @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onBackClick() {
|
||||
router.pop()
|
||||
if (!uiState.value.isTransactionSending) {
|
||||
router.pop()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFeePolicyClick() {
|
||||
|
|
|
|||
|
|
@ -14,12 +14,14 @@ import com.tangem.features.yield.supply.impl.subcomponents.startearning.YieldSup
|
|||
@Composable
|
||||
internal fun YieldSupplyStartEarningBottomSheet(
|
||||
stackState: ChildStack<YieldSupplyStartEarningRoute, ComposableModularContentComponent>,
|
||||
dismissOnClickOutside: () -> Boolean,
|
||||
onDismiss: () -> Unit,
|
||||
) {
|
||||
TangemModalBottomSheetWithFooter<TangemBottomSheetConfigContent.Empty>(
|
||||
config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = onDismiss,
|
||||
dismissOnClickOutside = dismissOnClickOutside,
|
||||
content = TangemBottomSheetConfigContent.Empty,
|
||||
),
|
||||
containerColor = TangemTheme.colors.background.tertiary,
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ internal class YieldSupplyStopEarningComponent(
|
|||
|
||||
interface ModelCallback {
|
||||
fun onBackClick()
|
||||
fun onTransactionProgress(inProgress: Boolean)
|
||||
fun onTransactionSent()
|
||||
}
|
||||
}
|
||||
|
|
@ -126,6 +126,8 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun onClick() {
|
||||
params.callback.onTransactionProgress(true)
|
||||
|
||||
val yieldSupplyFeeUM = uiState.value.yieldSupplyFeeUM as? YieldSupplyFeeUM.Content ?: return
|
||||
analytics.send(
|
||||
YieldSupplyAnalytics.ButtonStopEarning(
|
||||
|
|
@ -163,6 +165,7 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
|
|||
}
|
||||
},
|
||||
)
|
||||
params.callback.onTransactionProgress(false)
|
||||
},
|
||||
ifRight = {
|
||||
onStopEarningTransactionSuccess()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue