Updated on 2026-08-14

This commit is contained in:
Tangem 2024-09-25 10:47:47 +05:00
parent ebe91678c7
commit 36f2b71d03
10 changed files with 38 additions and 96 deletions

View file

@ -8,7 +8,7 @@ import com.tangem.core.ui.extensions.wrappedList
import com.tangem.domain.transaction.error.SendTransactionError
import com.tangem.utils.converter.Converter
class SendTransactionAlertConverter(
class TransactionErrorAlertConverter(
private val popBackStack: () -> Unit,
private val onFailedTxEmailClick: (String) -> Unit,
) : Converter<SendTransactionError, AlertUM?> {

View file

@ -9,7 +9,7 @@ data class AlertTransactionErrorUM(
val code: String,
val cause: String?,
val causeTextReference: TextReference? = null,
override val onConfirmClick: (() -> Unit)? = null,
override val onConfirmClick: () -> Unit,
) : AlertUM {
override val title: TextReference = resourceReference(id = R.string.send_alert_transaction_failed_title)
override val message: TextReference = resourceReference(

View file

@ -8,5 +8,5 @@ interface AlertUM {
val title: TextReference?
val message: TextReference
val confirmButtonText: TextReference
val onConfirmClick: (() -> Unit)?
val onConfirmClick: () -> Unit
}

View file

@ -137,6 +137,14 @@ class SendTransactionUseCase(
is BlockchainSdkError.WrappedTangemError -> {
parseWrappedError(tangemError) // todo remove when sdk errors are revised
}
is BlockchainSdkError.WrappedThrowable -> {
val causeError = tangemError.cause
if (causeError is BlockchainSdkError) {
SendTransactionError.BlockchainSdkError(causeError.code, causeError.customMessage)
} else {
SendTransactionError.BlockchainSdkError(tangemError.code, tangemError.customMessage)
}
}
else -> {
SendTransactionError.BlockchainSdkError(error.code, tangemError.customMessage)
}

View file

@ -1,58 +1,35 @@
package com.tangem.features.send.impl.presentation.state
import androidx.compose.runtime.Immutable
import com.tangem.common.ui.alerts.models.AlertUM
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.features.send.impl.R
@Immutable
internal sealed class SendAlertState {
abstract val title: TextReference?
abstract val message: TextReference
open val confirmButtonText: TextReference = resourceReference(id = R.string.common_ok)
open val onConfirmClick: (() -> Unit)? = null
internal sealed class SendAlertUM : AlertUM {
data class GenericError(
override val title: TextReference? = resourceReference(id = R.string.send_alert_transaction_failed_title),
override val onConfirmClick: (() -> Unit),
) : SendAlertState() {
) : SendAlertUM() {
override val message: TextReference = resourceReference(R.string.common_unknown_error)
override val confirmButtonText: TextReference =
resourceReference(id = R.string.common_support)
}
data class TransactionError(
val code: String,
val cause: String?,
val causeTextReference: TextReference? = null,
override val onConfirmClick: (() -> Unit),
) : SendAlertState() {
override val title: TextReference = resourceReference(id = R.string.send_alert_transaction_failed_title)
override val message: TextReference = resourceReference(
id = R.string.send_alert_transaction_failed_text,
formatArgs = wrappedList(causeTextReference ?: cause.orEmpty(), code),
)
override val confirmButtonText: TextReference =
resourceReference(id = R.string.common_support)
}
data class DemoMode(
data class FeeIncreased(
override val onConfirmClick: () -> Unit,
) : SendAlertState() {
override val title: TextReference = resourceReference(id = R.string.warning_demo_mode_title)
override val message: TextReference = resourceReference(id = R.string.warning_demo_mode_message)
}
data object FeeIncreased : SendAlertState() {
) : SendAlertUM() {
override val title: TextReference? = null
override val message: TextReference = resourceReference(id = R.string.send_notification_high_fee_title)
override val confirmButtonText: TextReference = resourceReference(id = R.string.common_ok)
}
data class FeeTooLow(
override val onConfirmClick: () -> Unit,
) : SendAlertState() {
) : SendAlertUM() {
override val title: TextReference? = null
override val message: TextReference = resourceReference(id = R.string.send_alert_fee_too_low_text)
override val confirmButtonText: TextReference = resourceReference(R.string.common_continue)
@ -61,7 +38,7 @@ internal sealed class SendAlertState {
data class FeeTooHigh(
val times: String,
override val onConfirmClick: () -> Unit,
) : SendAlertState() {
) : SendAlertUM() {
override val title: TextReference? = null
override val message: TextReference =
resourceReference(id = R.string.send_alert_fee_too_high_text, wrappedList(times))
@ -70,7 +47,7 @@ internal sealed class SendAlertState {
data class FeeUnreachableError(
override val onConfirmClick: (() -> Unit),
) : SendAlertState() {
) : SendAlertUM() {
override val title: TextReference = resourceReference(R.string.send_fee_unreachable_error_title)
override val message: TextReference = resourceReference(R.string.send_fee_unreachable_error_text)
override val confirmButtonText = resourceReference(R.string.warning_button_refresh)

View file

@ -1,6 +1,7 @@
package com.tangem.features.send.impl.presentation.state
import androidx.compose.runtime.Immutable
import com.tangem.common.ui.alerts.models.AlertUM
import com.tangem.core.ui.extensions.TextReference
@Immutable
@ -8,5 +9,5 @@ internal sealed class SendEvent {
data class ShowSnackBar(val text: TextReference) : SendEvent()
data class ShowAlert(val alert: SendAlertState) : SendEvent()
data class ShowAlert(val alert: AlertUM) : SendEvent()
}

View file

@ -1,6 +1,7 @@
package com.tangem.features.send.impl.presentation.state
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.common.ui.alerts.TransactionErrorAlertConverter
import com.tangem.core.ui.event.consumedEvent
import com.tangem.core.ui.event.triggeredEvent
import com.tangem.domain.transaction.error.SendTransactionError
@ -24,9 +25,10 @@ internal class SendEventStateFactory(
private val clickIntents: SendClickIntents,
private val feeStateFactory: FeeStateFactory,
) {
private val sendTransactionErrorConverter by lazy(LazyThreadSafetyMode.NONE) {
SendTransactionAlertConverter(
clickIntents = clickIntents,
private val transactionErrorAlertConverter by lazy(LazyThreadSafetyMode.NONE) {
TransactionErrorAlertConverter(
popBackStack = clickIntents::popBackStack,
onFailedTxEmailClick = clickIntents::onFailedTxEmailClick,
)
}
@ -37,7 +39,7 @@ internal class SendEventStateFactory(
fun getSendTransactionErrorState(error: SendTransactionError?, onConsume: () -> Unit): SendUiState {
val state = currentStateProvider()
val event = error?.let {
sendTransactionErrorConverter.convert(error)?.let {
transactionErrorAlertConverter.convert(error)?.let {
triggeredEvent<SendEvent>(SendEvent.ShowAlert(it), onConsume)
}
}
@ -68,7 +70,7 @@ internal class SendEventStateFactory(
return if (newFeeValue > oldFeeValue) {
updateFeeState.copy(
event = triggeredEvent(
data = SendEvent.ShowAlert(SendAlertState.FeeIncreased),
data = SendEvent.ShowAlert(SendAlertUM.FeeIncreased(onConsume)),
onConsume = onConsume,
),
)
@ -83,7 +85,7 @@ internal class SendEventStateFactory(
return state.copy(
event = triggeredEvent(
data = SendEvent.ShowAlert(
SendAlertState.FeeTooLow(
SendAlertUM.FeeTooLow(
onConfirmClick = clickIntents::showSend,
),
),
@ -96,7 +98,7 @@ internal class SendEventStateFactory(
return currentStateProvider().copy(
event = triggeredEvent(
data = SendEvent.ShowAlert(
SendAlertState.FeeTooHigh(
SendAlertUM.FeeTooHigh(
onConfirmClick = clickIntents::showSend,
times = diff,
),
@ -111,7 +113,7 @@ internal class SendEventStateFactory(
return state.copy(
event = triggeredEvent(
data = SendEvent.ShowAlert(
SendAlertState.GenericError(
SendAlertUM.GenericError(
onConfirmClick = { clickIntents.onFailedTxEmailClick(error?.localizedMessage.orEmpty()) },
),
),
@ -125,7 +127,7 @@ internal class SendEventStateFactory(
return state.copy(
event = triggeredEvent(
data = SendEvent.ShowAlert(
SendAlertState.FeeUnreachableError(onConfirmClick = clickIntents::feeReload),
SendAlertUM.FeeUnreachableError(onConfirmClick = clickIntents::feeReload),
),
onConsume = onConsume,
),

View file

@ -1,46 +0,0 @@
package com.tangem.features.send.impl.presentation.state
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.domain.transaction.error.SendTransactionError
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.utils.converter.Converter
internal class SendTransactionAlertConverter(
private val clickIntents: SendClickIntents,
) : Converter<SendTransactionError, SendAlertState?> {
override fun convert(value: SendTransactionError): SendAlertState? {
return when (value) {
SendTransactionError.DemoCardError -> SendAlertState.DemoMode(
onConfirmClick = { clickIntents.popBackStack() },
)
is SendTransactionError.TangemSdkError -> SendAlertState.TransactionError(
code = value.code.toString(),
cause = null,
causeTextReference = resourceReference(value.messageRes, wrappedList(value.args)),
onConfirmClick = { clickIntents.onFailedTxEmailClick(value.code.toString()) },
)
is SendTransactionError.BlockchainSdkError -> SendAlertState.TransactionError(
code = value.code.toString(),
cause = value.message,
onConfirmClick = { clickIntents.onFailedTxEmailClick("${value.code}: ${value.message.orEmpty()}") },
)
is SendTransactionError.DataError -> SendAlertState.TransactionError(
code = "",
cause = value.message,
onConfirmClick = { clickIntents.onFailedTxEmailClick(value.message.orEmpty()) },
)
is SendTransactionError.NetworkError -> SendAlertState.TransactionError(
code = value.code.orEmpty(),
cause = value.message.orEmpty(),
onConfirmClick = { clickIntents.onFailedTxEmailClick(value.message.orEmpty()) },
)
is SendTransactionError.UnknownError -> SendAlertState.TransactionError(
code = "",
cause = value.ex?.localizedMessage,
onConfirmClick = { clickIntents.onFailedTxEmailClick(value.ex?.localizedMessage.orEmpty()) },
)
else -> null
}
}
}

View file

@ -5,19 +5,19 @@ import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import com.tangem.common.ui.alerts.models.AlertUM
import com.tangem.core.ui.components.BasicDialog
import com.tangem.core.ui.components.DialogButtonUM
import com.tangem.core.ui.event.EventEffect
import com.tangem.core.ui.event.StateEvent
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.features.send.impl.R
import com.tangem.features.send.impl.presentation.state.SendAlertState
import com.tangem.features.send.impl.presentation.state.SendEvent
@Composable
internal fun SendEventEffect(event: StateEvent<SendEvent>, snackbarHostState: SnackbarHostState) {
val resources = LocalContext.current.resources
var alertConfig by remember { mutableStateOf<SendAlertState?>(value = null) }
var alertConfig by remember { mutableStateOf<AlertUM?>(value = null) }
val keyboardController = LocalSoftwareKeyboardController.current
LaunchedEffect(key1 = alertConfig) {
@ -44,7 +44,7 @@ internal fun SendEventEffect(event: StateEvent<SendEvent>, snackbarHostState: Sn
}
@Composable
internal fun SendAlert(state: SendAlertState, onDismiss: () -> Unit) {
internal fun SendAlert(state: AlertUM, onDismiss: () -> Unit) {
val confirmButton: DialogButtonUM
val dismissButton: DialogButtonUM?

View file

@ -1,6 +1,6 @@
package com.tangem.features.staking.impl.presentation.state.events
import com.tangem.common.ui.alerts.SendTransactionAlertConverter
import com.tangem.common.ui.alerts.TransactionErrorAlertConverter
import com.tangem.domain.staking.model.stakekit.StakingError
import com.tangem.domain.transaction.error.SendTransactionError
import com.tangem.features.staking.impl.presentation.state.StakingStateController
@ -22,7 +22,7 @@ internal class StakingEventFactory(
fun createSendTransactionErrorAlert(error: SendTransactionError?) {
val alert = error?.let {
SendTransactionAlertConverter(
TransactionErrorAlertConverter(
popBackStack = popBackStack,
onFailedTxEmailClick = onFailedTxEmailClick,
).convert(error)