Updated on 2026-08-14

This commit is contained in:
Tangem 2025-01-30 20:17:28 +05:00
parent fb05f7cf32
commit eadf1a17c8
9 changed files with 75 additions and 11 deletions

View file

@ -3,6 +3,7 @@ package com.tangem.common.ui.expressStatus
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
@ -19,7 +20,7 @@ import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
@Composable
fun ExpressHideButton(isTerminal: Boolean, isAutoDisposable: Boolean, onClick: () -> Unit) {
fun ColumnScope.ExpressHideButton(isTerminal: Boolean, isAutoDisposable: Boolean, onClick: () -> Unit) {
AnimatedVisibility(
visible = isTerminal && !isAutoDisposable,
label = "Hide button visibility animation",

View file

@ -59,6 +59,11 @@ fun OnrampStatusBottomSheetContent(state: ExpressTransactionStateUM.OnrampUM) {
SpacerH12()
ExpressStatusBlock(state = state.info.status)
ExpressStatusNotificationBlock(state = state.info.notification)
ExpressHideButton(
isTerminal = state.activeStatus.isTerminal,
isAutoDisposable = state.activeStatus.isAutoDisposable,
onClick = state.info.onDisposeExpressStatus,
)
SpacerH24()
}
}

View file

@ -49,6 +49,22 @@ data class OnrampStatus(
-> false
}
val isAutoDisposable: Boolean
get() = when (this) {
Finished,
-> true
Expired,
Failed,
Paused,
Created,
WaitingForPayment,
PaymentProcessing,
Verifying,
Paid,
Sending,
-> false
}
val isHidden: Boolean
get() = when (this) {
Created,

View file

@ -68,12 +68,12 @@ internal class OnrampStatusFactory @AssistedInject constructor(
}
}
suspend fun removeTransactionOnBottomSheetClosed() {
suspend fun removeTransactionOnBottomSheetClosed(isForceDispose: Boolean) {
val state = currentStateProvider()
val bottomSheetConfig = state.bottomSheetConfig?.content as? ExpressStatusBottomSheetConfig ?: return
val selectedTx = bottomSheetConfig.value as? ExpressTransactionStateUM.OnrampUM ?: return
if (selectedTx.activeStatus.isTerminal) {
if (selectedTx.activeStatus.isAutoDisposable || isForceDispose) {
onrampRemoveTransactionUseCase(externalTxId = selectedTx.info.txExternalId)
}
}

View file

@ -30,12 +30,12 @@ internal class OnrampStatusFactory @Inject constructor(
private val dispatchers: CoroutineDispatcherProvider,
) {
suspend fun removeTransactionOnBottomSheetClosed() {
suspend fun removeTransactionOnBottomSheetClosed(forceDispose: Boolean) {
val state = stateHolder.getSelectedWallet()
val bottomSheetConfig = state.bottomSheetConfig?.content as? ExpressStatusBottomSheetConfig ?: return
val selectedTx = bottomSheetConfig.value as? ExpressTransactionStateUM.OnrampUM ?: return
if (selectedTx.activeStatus.isTerminal) {
if (selectedTx.activeStatus.isAutoDisposable || forceDispose) {
onrampRemoveTransactionUseCase(externalTxId = selectedTx.info.txExternalId)
}
}

View file

@ -16,6 +16,8 @@ internal sealed interface WalletAlertState {
open val confirmButtonText: TextReference = resourceReference(id = R.string.common_ok)
open val isWarningConfirmButton: Boolean = false
abstract val onConfirmClick: (() -> Unit)?
open val cancelButtonText: TextReference? = null
open val onCancelClick: (() -> Unit)? = null
}
@Immutable
@ -107,4 +109,14 @@ internal sealed interface WalletAlertState {
override val onConfirmClick: (() -> Unit)? = null
}
data class ConfirmExpressStatusHide(
override val onConfirmClick: (() -> Unit),
override val onCancelClick: (() -> Unit),
) : Basic() {
override val title: TextReference = resourceReference(R.string.express_status_hide_dialog_title)
override val message: TextReference = resourceReference(R.string.express_status_hide_dialog_text)
override val confirmButtonText: TextReference = resourceReference(R.string.common_hide)
override val cancelButtonText: TextReference = resourceReference(R.string.common_cancel)
}
}

View file

@ -62,9 +62,7 @@ internal class SingleWalletOnrampTransactionConverter(
value.timestamp.toTimeFormat(),
),
),
toAmount = stringReference(
value.toAmount.format { crypto(currency) },
),
toAmount = stringReference(value.toAmount.format { crypto(currency) }),
toFiatAmount = stringReference(
status.fiatRate?.multiply(value.toAmount).format {
fiat(
@ -94,6 +92,7 @@ internal class SingleWalletOnrampTransactionConverter(
analyticsEventHandler.send(TokenOnrampAnalyticsEvent.GoToProvider)
clickIntents.onGoToProviderClick(it)
},
onDisposeExpressStatus = clickIntents::onConfirmDisposeExpressStatus,
onClick = {
val analyticEvent = TokenOnrampAnalyticsEvent.OnrampStatusOpened(
tokenSymbol = currency.symbol,

View file

@ -21,7 +21,7 @@ internal class WalletEventSender @Inject constructor(
stateHolder.update(transformer = SendEventTransformer(event = event, onConsume = ::onConsume))
}
private fun onConsume() {
fun onConsume() {
stateHolder.update {
it.copy(event = consumedEvent())
}

View file

@ -15,12 +15,14 @@ import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.feature.wallet.presentation.wallet.domain.OnrampStatusFactory
import com.tangem.feature.wallet.presentation.wallet.domain.unwrap
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
import com.tangem.feature.wallet.presentation.wallet.state.model.*
import com.tangem.feature.wallet.presentation.wallet.state.model.ActionsBottomSheetConfig
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletBottomSheetConfig
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
import com.tangem.feature.wallet.presentation.wallet.state.transformers.CloseBottomSheetTransformer
import com.tangem.feature.wallet.presentation.wallet.state.transformers.OpenBottomSheetTransformer
import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.MultiWalletCurrencyActionsConverter
import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.hilt.android.scopes.ViewModelScoped
import kotlinx.coroutines.flow.collectLatest
@ -54,6 +56,10 @@ internal interface WalletContentClickIntents {
fun onGoToProviderClick(externalTxId: String)
fun onExpressTransactionClick(txId: String)
fun onConfirmDisposeExpressStatus()
fun onDisposeExpressStatus()
}
@Suppress("LongParameterList")
@ -70,6 +76,7 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
private val shouldShowMarketsTooltipUseCase: ShouldShowMarketsTooltipUseCase,
private val dispatchers: CoroutineDispatcherProvider,
private val reduxStateHolder: ReduxStateHolder,
private val walletEventSender: WalletEventSender,
) : BaseWalletClickIntents(), WalletContentClickIntents {
override fun onBackClick() = router.popBackStack()
@ -185,7 +192,7 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
val userWalletId = stateHolder.getSelectedWalletId()
if (stateHolder.getSelectedWallet().bottomSheetConfig?.content is ExpressStatusBottomSheetConfig) {
viewModelScope.launch(dispatchers.main) {
onrampStatusFactory.removeTransactionOnBottomSheetClosed()
onrampStatusFactory.removeTransactionOnBottomSheetClosed(forceDispose = false)
}
}
stateHolder.update(CloseBottomSheetTransformer(userWalletId))
@ -211,4 +218,28 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
)
}
}
override fun onConfirmDisposeExpressStatus() {
walletEventSender.send(
WalletEvent.ShowAlert(
WalletAlertState.ConfirmExpressStatusHide(
onConfirmClick = {
walletEventSender.onConsume()
onDisposeExpressStatus()
},
onCancelClick = walletEventSender::onConsume,
),
),
)
}
override fun onDisposeExpressStatus() {
val userWalletId = stateHolder.getSelectedWalletId()
if (stateHolder.getSelectedWallet().bottomSheetConfig?.content is ExpressStatusBottomSheetConfig) {
viewModelScope.launch(dispatchers.main) {
onrampStatusFactory.removeTransactionOnBottomSheetClosed(forceDispose = true)
}
}
stateHolder.update(CloseBottomSheetTransformer(userWalletId))
}
}