diff --git a/common/ui/src/main/java/com/tangem/common/ui/expressStatus/ExpressHideButton.kt b/common/ui/src/main/java/com/tangem/common/ui/expressStatus/ExpressHideButton.kt
new file mode 100644
index 0000000000..16a1484d52
--- /dev/null
+++ b/common/ui/src/main/java/com/tangem/common/ui/expressStatus/ExpressHideButton.kt
@@ -0,0 +1,45 @@
+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
+import androidx.compose.material3.Text
+import androidx.compose.material3.ripple
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.dp
+import com.tangem.core.ui.R
+import com.tangem.core.ui.extensions.stringResourceSafe
+import com.tangem.core.ui.res.TangemTheme
+
+@Composable
+fun ColumnScope.ExpressHideButton(isTerminal: Boolean, isAutoDisposable: Boolean, onClick: () -> Unit) {
+ AnimatedVisibility(
+ visible = isTerminal && !isAutoDisposable,
+ label = "Hide button visibility animation",
+ ) {
+ Text(
+ text = stringResourceSafe(R.string.express_status_hide_button_text),
+ color = TangemTheme.colors.text.tertiary,
+ style = TangemTheme.typography.button,
+ textAlign = TextAlign.Center,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(start = 12.dp, end = 12.dp, top = 14.dp)
+ .clip(RoundedCornerShape(12.dp))
+ .clickable(
+ interactionSource = remember { MutableInteractionSource() },
+ indication = ripple(bounded = false),
+ onClick = onClick,
+ )
+ .padding(vertical = 10.dp),
+ )
+ }
+}
\ No newline at end of file
diff --git a/common/ui/src/main/java/com/tangem/common/ui/expressStatus/OnrampStatusBottomSheetContent.kt b/common/ui/src/main/java/com/tangem/common/ui/expressStatus/OnrampStatusBottomSheetContent.kt
index 35905de8f7..fc888d6c64 100644
--- a/common/ui/src/main/java/com/tangem/common/ui/expressStatus/OnrampStatusBottomSheetContent.kt
+++ b/common/ui/src/main/java/com/tangem/common/ui/expressStatus/OnrampStatusBottomSheetContent.kt
@@ -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()
}
}
\ No newline at end of file
diff --git a/common/ui/src/main/java/com/tangem/common/ui/expressStatus/state/ExpressTransactionStateUM.kt b/common/ui/src/main/java/com/tangem/common/ui/expressStatus/state/ExpressTransactionStateUM.kt
index 45138854f8..fb2489e331 100644
--- a/common/ui/src/main/java/com/tangem/common/ui/expressStatus/state/ExpressTransactionStateUM.kt
+++ b/common/ui/src/main/java/com/tangem/common/ui/expressStatus/state/ExpressTransactionStateUM.kt
@@ -30,6 +30,7 @@ data class ExpressTransactionStateInfoUM(
val timestampFormatted: TextReference,
val onGoToProviderClick: (String) -> Unit,
val onClick: () -> Unit,
+ val onDisposeExpressStatus: () -> Unit,
val iconState: ExpressTransactionStateIconUM,
val toAmount: TextReference,
val toFiatAmount: TextReference?,
diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml
index ae312288dd..8a48bdcc9f 100644
--- a/core/res/src/main/res/values-de/strings.xml
+++ b/core/res/src/main/res/values-de/strings.xml
@@ -314,6 +314,9 @@
Gekauft %s
Kauf %s
Kauf %s…
+ Diese Transaktion ausblenden
+ Sobald dieser Bildschirm ausgeblendet wurde, kann er nicht mehr aufgerufen werden.
+ Bist Du sicher, dass Du die Transaktionsdetails ausblenden willst?
Keine Token gefunden. Bitte versuche eine andere Anfrage
ID: %s
Transaktions-ID kopiert
@@ -790,6 +793,8 @@
Migrieren
Natives Staking
Derzeit sind keine aktiven Validatoren für das Staking verfügbar. Bitte versuchen Sie es später erneut.
+ Beim Staking im Cardano Netzwerk wird das gesamte Guthaben genutzt. Zusätzlich werden 2 ADA reserviert und nach dem Unstaking zurückgegeben. Deine ADA sind während des Stakings nicht gesperrt.
+ Einzelheiten zum ADA-Staking
Verdiente Belohnungen werden an Deine Wallet gesendet und stehen Dir sofort zur Verfügung
Stake sicher und verdienen Belohnungen
Sicher staken und tägliche Belohnungen verdienen.
@@ -803,6 +808,8 @@
Verdiene Staking-Belohnungen
Dein verbleibender Stakingbetrag ist zu niedrig, um den Einsatz aufzuheben. Du musst mehr Staken, um den Mindestbetrag zum Aufheben des Einsatzes zu erreichen.
Niedriges Stakingguthaben
+ Für erneutes Staking sind mindestens %1$s %2$s erforderlich. Bitte lade Dein Guthaben auf.
+ Nicht genug %s
Aufgrund von Netzwerkproblemen ist Staking derzeit nicht verfügbar. Bitte versuche es später erneut.
Beim Staking im %1$s -Netzwerk mit einem neuen Validator werden alle zuvor eingesetzten Kryptos automatisch an diesen Validator übertragen
Reinvestiert Deine verdienten Prämien in Deinen Einsatzbetrag und erhöht so den potenziellen Gewinn.
diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml
index 287efe4ff4..d7232f22fd 100644
--- a/core/res/src/main/res/values-ja/strings.xml
+++ b/core/res/src/main/res/values-ja/strings.xml
@@ -648,7 +648,7 @@
工場出荷時設定にリセットすると、選択したカードやリングからウォレットが完全に削除されます。現在のウォレットを復元したり、カードやリングを使用してアクセスコードを復元することはできません。
工場出荷時の状態にリセットすると、選択したカードやリングからウォレットが完全に削除され、アプリから削除されます。現在のウォレットを復元することはできません。
Tangem Ringユーザーは、11/15日までChangelly経由でスワップを3回手数料ゼロで行えます!
- 今すぐ手数料0%でスワップしましょう!
+ 今すぐ手数料0% でスワップしましょう!
アプリにログインして、カードまたはリングをスキャンせずに残高を確認できます
アプリにアクセスする
生体認証の使用を許可する
@@ -780,6 +780,8 @@
移行
ネイティブステーキング
現在、ステーキングに使用できるアクティブなバリデータは見つかりません。しばらくしてからもう一度お試しください。
+ Cardanoネットワークでステーキングする場合、残高全体が使用されます。追加の2ADAが予約され、ステーキング解除後に返却されます。ステーキング中はADAはロックされません。
+ ADAステーキングの詳細
獲得した報酬はあなたのアドレスに直接送られ、すぐ使用可能です。
安全にステーキングして報酬を獲得しましょう
安全にステーキングして、報酬を毎日獲得しましょう
@@ -988,7 +990,7 @@
%sネットワーク
アドレスがクリップボードにコピーされました
インターネット接続がありません
- 今すぐ10 %オフで購入
+ 今すぐ10 % オフで購入
1.3万種類以上の暗号資産にアクセス。ワンタップで買付、売却、スワップ、ステーキングが可能です。\nバックアップ用に最大3枚のカードを連携できます。
Tangemウォレットを見る
ウォレット設定
diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index 145dac2a4c..aa9e27fb7d 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -142,6 +142,7 @@
Synchronize addresses
Go to provider
Go to token
+ Hide
hour
Import
In progress
@@ -314,6 +315,9 @@
Bought %s
Buying %s
Buying %s...
+ Hide this transaction
+ Once hidden, the transaction status cannot be viewed again. You can simply swipe to dismiss instead.
+ Hide Transaction Status?
No tokens found. Please try another request
ID: %s
Transaction ID copied
@@ -792,6 +796,8 @@
Migrate
Native staking
No active validators available for staking at the moment. Please try again later.
+ When staking in the Cardano network, the entire balance is used. An additional 2 ADA will be reserved and returned after unstaking. Your ADA is not locked while staking.
+ ADA Staking Details
Earned rewards will be sent to your wallet and available for use immediately
Stake securely and start earning your rewards
Stake securely and start earning daily rewards
@@ -805,6 +811,8 @@
Earn staking rewards
Your remaining staked balance will be too low to unstake. You’ll need to stake more to meet the minimum unstake amount.
Low staked balance
+ A minimum of %1$s %2$s is required for restaking. Please top up your balance.
+ Not enough %s
Staking is currently unavailable due to network conditions. Please try again later.
Staking in the %1$s network with a new validator will automatically transfer all previously staked funds to this validator
Reinvests your earned rewards in your staked amount, increasing potential earnings.
diff --git a/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampStatus.kt b/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampStatus.kt
index 64aa740a5e..e116c0c085 100644
--- a/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampStatus.kt
+++ b/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampStatus.kt
@@ -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,
diff --git a/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapTransactionRepository.kt b/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapTransactionRepository.kt
index ed7aa550c5..082f1b8ec9 100644
--- a/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapTransactionRepository.kt
+++ b/features/swap/data/src/main/java/com/tangem/feature/swap/DefaultSwapTransactionRepository.kt
@@ -1,6 +1,7 @@
package com.tangem.feature.swap
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
+import com.tangem.data.common.currency.UserTokensResponseFactory
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.preferences.PreferencesKeys
import com.tangem.datasource.local.preferences.utils.getObjectList
@@ -26,6 +27,7 @@ internal class DefaultSwapTransactionRepository(
) : SwapTransactionRepository {
private val converter = SavedSwapTransactionListConverter(excludedBlockchains)
+ private val userTokensResponseFactory = UserTokensResponseFactory()
override suspend fun storeTransaction(
userWalletId: UserWalletId,
@@ -33,7 +35,13 @@ internal class DefaultSwapTransactionRepository(
toCryptoCurrency: CryptoCurrency,
transaction: SavedSwapTransactionModel,
) {
- transaction.status?.let { storeTransactionState(transaction.txId, it) }
+ transaction.status?.let {
+ storeTransactionState(
+ txId = transaction.txId,
+ status = it,
+ refundTokenCurrency = null,
+ )
+ }
appPreferencesStore.editData { mutablePreferences ->
val savedTransactions: List? = mutablePreferences.getObjectList(
key = PreferencesKeys.SWAP_TRANSACTIONS_KEY,
@@ -154,14 +162,22 @@ internal class DefaultSwapTransactionRepository(
}
}
- override suspend fun storeTransactionState(txId: String, status: ExchangeStatusModel) {
+ override suspend fun storeTransactionState(
+ txId: String,
+ status: ExchangeStatusModel,
+ refundTokenCurrency: CryptoCurrency?,
+ ) {
appPreferencesStore.editData { mutablePreferences ->
val savedMap = mutablePreferences.getObjectMap(
key = PreferencesKeys.SWAP_TRANSACTIONS_STATUSES_KEY,
)
val updatesMap = savedMap.toMutableMap()
- updatesMap[txId] = status
+ updatesMap[txId] = status.copy(
+ refundTokensResponse = refundTokenCurrency?.let {
+ userTokensResponseFactory.createResponseToken(refundTokenCurrency)
+ },
+ )
mutablePreferences.setObjectMap(
key = PreferencesKeys.SWAP_TRANSACTIONS_STATUSES_KEY,
diff --git a/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SavedSwapTransactionListConverter.kt b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SavedSwapTransactionListConverter.kt
index d3d6093b01..ed4ce2cf2e 100644
--- a/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SavedSwapTransactionListConverter.kt
+++ b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SavedSwapTransactionListConverter.kt
@@ -53,7 +53,15 @@ internal class SavedSwapTransactionListConverter(
return SavedSwapTransactionListModel(
transactions = value.transactions.map { tx ->
- tx.copy(status = txStatuses[tx.txId])
+ val status = txStatuses[tx.txId]
+ val refundCurrency = status?.refundTokensResponse?.let { id ->
+ responseCryptoCurrenciesFactory.createCurrency(
+ responseToken = id,
+ scanResponse = scanResponse,
+ )
+ }
+ val statusWithRefundCurrency = status?.copy(refundCurrency = refundCurrency)
+ tx.copy(status = statusWithRefundCurrency)
},
userWalletId = value.userWalletId,
fromCryptoCurrencyId = value.fromCryptoCurrencyId,
diff --git a/features/swap/domain/build.gradle.kts b/features/swap/domain/build.gradle.kts
index bbf66619e0..ed5fe567e7 100644
--- a/features/swap/domain/build.gradle.kts
+++ b/features/swap/domain/build.gradle.kts
@@ -42,6 +42,7 @@ dependencies {
/** Core modules */
implementation(projects.core.utils)
implementation(projects.core.ui)
+ implementation(projects.core.datasource)
/** Feature Apis */
implementation(projects.features.wallet.api)
diff --git a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/ExchangeStatus.kt b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/ExchangeStatus.kt
index 161326f0bb..bd5e63b506 100644
--- a/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/ExchangeStatus.kt
+++ b/features/swap/domain/models/src/main/java/com/tangem/feature/swap/domain/models/domain/ExchangeStatus.kt
@@ -2,6 +2,8 @@ package com.tangem.feature.swap.domain.models.domain
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
+import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
+import com.tangem.domain.tokens.model.CryptoCurrency
@JsonClass(generateAdapter = true)
data class ExchangeStatusModel(
@@ -19,6 +21,10 @@ data class ExchangeStatusModel(
val refundNetwork: String? = null,
@Json(name = "refundContractAddress")
val refundContractAddress: String? = null,
+ @Json(name = "refundTokensResponse")
+ val refundTokensResponse: UserTokensResponse.Token? = null,
+ @Json(ignore = true)
+ val refundCurrency: CryptoCurrency? = null,
)
@JsonClass(generateAdapter = false)
@@ -64,4 +70,16 @@ enum class ExchangeStatus {
@Json(name = "Paused")
Paused,
+
+ ;
+
+ val isTerminal: Boolean
+ get() = this == Refunded ||
+ this == Finished ||
+ this == Cancelled ||
+ this == TxFailed ||
+ this == Unknown
+
+ val isAutoDisposable: Boolean
+ get() = this == Finished
}
\ No newline at end of file
diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapTransactionRepository.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapTransactionRepository.kt
index f02a93f2ab..812499d47f 100644
--- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapTransactionRepository.kt
+++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/SwapTransactionRepository.kt
@@ -30,7 +30,7 @@ interface SwapTransactionRepository {
txId: String,
)
- suspend fun storeTransactionState(txId: String, status: ExchangeStatusModel)
+ suspend fun storeTransactionState(txId: String, status: ExchangeStatusModel, refundTokenCurrency: CryptoCurrency?)
suspend fun storeLastSwappedCryptoCurrencyId(userWalletId: UserWalletId, cryptoCurrencyId: CryptoCurrency.ID)
diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsDialogConfig.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsDialogConfig.kt
index ce5a9f3d49..7df750dad1 100644
--- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsDialogConfig.kt
+++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsDialogConfig.kt
@@ -1,6 +1,7 @@
package com.tangem.feature.tokendetails.presentation.tokendetails.state.components
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.tokendetails.impl.R
@@ -133,5 +134,22 @@ internal data class TokenDetailsDialogConfig(
onClick = onConfirmClick,
)
}
+
+ data class ConfirmExpressStatusHideDialogConfig(
+ val onConfirmClick: () -> Unit,
+ val onCancelClick: () -> Unit,
+ ) : DialogContentConfig() {
+ 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 confirmButtonConfig: ButtonConfig = ButtonConfig(
+ text = resourceReference(R.string.common_hide),
+ onClick = onConfirmClick,
+ )
+
+ override val cancelButtonConfig: ButtonConfig = ButtonConfig(
+ text = resourceReference(R.string.common_cancel),
+ onClick = onCancelClick,
+ )
+ }
}
}
\ No newline at end of file
diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/express/ExchangeUM.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/express/ExchangeUM.kt
index 4420f4be4a..ac23c537eb 100644
--- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/express/ExchangeUM.kt
+++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/express/ExchangeUM.kt
@@ -15,7 +15,6 @@ internal data class ExchangeUM(
val statuses: ImmutableList,
val notification: ExchangeStatusNotifications? = null,
val showProviderLink: Boolean,
- val isRefundTerminalStatus: Boolean,
val fromCryptoCurrency: CryptoCurrency,
val toCryptoCurrency: CryptoCurrency,
) : ExpressTransactionStateUM
\ No newline at end of file
diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsOnrampTransactionStateConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsOnrampTransactionStateConverter.kt
index 3b8d00da73..ec6b983685 100644
--- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsOnrampTransactionStateConverter.kt
+++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsOnrampTransactionStateConverter.kt
@@ -94,6 +94,7 @@ internal class TokenDetailsOnrampTransactionStateConverter(
clickIntents.onGoToProviderClick(it)
},
onClick = { clickIntents.onExpressTransactionClick(value.txId) },
+ onDisposeExpressStatus = clickIntents::onConfirmDisposeExpressStatus,
),
providerName = value.providerName,
providerImageUrl = value.providerImageUrl,
diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt
index d93b495c65..e88c1cc061 100644
--- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt
+++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt
@@ -340,6 +340,22 @@ internal class TokenDetailsStateFactory(
return balanceSelectStateConverter.convert(buttonConfig)
}
+ fun getStateWithConfirmHideExpressStatus(): TokenDetailsState {
+ return currentStateProvider().copy(
+ dialogConfig = TokenDetailsDialogConfig(
+ isShow = true,
+ onDismissRequest = clickIntents::onDismissDialog,
+ content = TokenDetailsDialogConfig.DialogContentConfig.ConfirmExpressStatusHideDialogConfig(
+ onConfirmClick = {
+ clickIntents.onDisposeExpressStatus()
+ clickIntents.onDismissDialog()
+ },
+ onCancelClick = clickIntents::onDismissDialog,
+ ),
+ ),
+ )
+ }
+
private fun TokenDetailsAppBarMenuConfig.updateMenu(
cardTypesResolver: CardTypesResolver,
hasDerivations: Boolean,
diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSwapTransactionsStateConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSwapTransactionsStateConverter.kt
index 18fe759bac..ba05cd229d 100644
--- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSwapTransactionsStateConverter.kt
+++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSwapTransactionsStateConverter.kt
@@ -80,17 +80,20 @@ internal class TokenDetailsSwapTransactionsStateConverter(
fromFiatAmount = quote.fiatRate.multiply(fromAmount)
}
}
- val notifications =
- getNotification(transaction.status?.status, transaction.status?.txExternalUrl, null)
+ val statusModel = transaction.status
+ val notifications = getNotification(
+ status = statusModel?.status,
+ txUrl = statusModel?.txExternalUrl,
+ refundToken = statusModel?.refundCurrency,
+ )
val showProviderLink = getShowProviderLink(notifications, transaction.status)
result.add(
ExchangeUM(
provider = transaction.provider,
- statuses = getStatuses(transaction.status?.status),
+ statuses = getStatuses(statusModel?.status),
notification = notifications,
- activeStatus = transaction.status?.status,
+ activeStatus = statusModel?.status,
showProviderLink = showProviderLink,
- isRefundTerminalStatus = true,
fromCryptoCurrency = fromCryptoCurrency,
toCryptoCurrency = toCryptoCurrency,
info = createStateInfo(
@@ -107,25 +110,19 @@ internal class TokenDetailsSwapTransactionsStateConverter(
return result.toPersistentList()
}
- fun updateTxStatus(
- tx: ExchangeUM,
- statusModel: ExchangeStatusModel?,
- refundToken: CryptoCurrency?,
- isRefundTerminalStatus: Boolean,
- ): ExchangeUM {
+ fun updateTxStatus(tx: ExchangeUM, statusModel: ExchangeStatusModel?): ExchangeUM {
if (statusModel == null || tx.activeStatus == statusModel.status) {
Timber.e("UpdateTxStatus isn't required. Current status isn't changed")
return tx
}
val hasFailed = statusModel.status == ExchangeStatus.Failed
- val notifications = getNotification(statusModel.status, statusModel.txExternalUrl, refundToken)
+ val notifications = getNotification(statusModel.status, statusModel.txExternalUrl, statusModel.refundCurrency)
val showProviderLink = getShowProviderLink(notifications, statusModel)
return tx.copy(
activeStatus = statusModel.status,
notification = notifications,
statuses = getStatuses(statusModel.status, hasFailed),
showProviderLink = showProviderLink,
- isRefundTerminalStatus = isRefundTerminalStatus,
info = tx.info.copy(txExternalUrl = statusModel.txExternalUrl),
)
}
@@ -164,7 +161,8 @@ internal class TokenDetailsSwapTransactionsStateConverter(
},
iconState = getIconState(transaction.status?.status),
status = getStatusState(),
- notification = null, // fixme [REDACTED_JIRA]
+ notification = null, // fixme [REDACTED_JIRA],
+ onDisposeExpressStatus = clickIntents::onConfirmDisposeExpressStatus,
)
}
diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExchangeStatusFactory.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExchangeStatusFactory.kt
index b63aad6b70..3bf62b35de 100644
--- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExchangeStatusFactory.kt
+++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExchangeStatusFactory.kt
@@ -79,13 +79,13 @@ internal class ExchangeStatusFactory @AssistedInject constructor(
}
}
- suspend fun removeTransactionOnBottomSheetClosed(isForceTerminal: Boolean = false) {
+ suspend fun removeTransactionOnBottomSheetClosed(isForceDispose: Boolean = false) {
val state = currentStateProvider()
val bottomSheetConfig = state.bottomSheetConfig?.content as? ExpressStatusBottomSheetConfig ?: return
val selectedTx = bottomSheetConfig.value as? ExchangeUM ?: return
- val shouldTerminate = selectedTx.activeStatus.isTerminal(selectedTx.isRefundTerminalStatus) || isForceTerminal
- if (shouldTerminate) {
+ val shouldDispose = selectedTx.activeStatus?.isAutoDisposable == true || isForceDispose
+ if (shouldDispose) {
swapTransactionRepository.removeTransaction(
userWalletId = userWalletId,
fromCryptoCurrency = selectedTx.fromCryptoCurrency,
@@ -96,20 +96,14 @@ internal class ExchangeStatusFactory @AssistedInject constructor(
}
suspend fun updateSwapTxStatus(swapTx: ExchangeUM): ExchangeUM {
- return if (swapTx.activeStatus.isTerminal(swapTx.isRefundTerminalStatus)) {
+ return if (swapTx.activeStatus?.isTerminal == true) {
swapTx
} else {
val statusModel = getExchangeStatus(swapTx.info.txId, swapTx.provider)
- val isRefundTerminalStatus = statusModel?.refundNetwork == null &&
- statusModel?.refundContractAddress == null &&
- swapTx.provider.type != ExchangeProviderType.DEX_BRIDGE
- val addedRefundToken = addRefundCurrencyIfNeeded(statusModel, swapTx.provider.type)
swapTransactionsStateConverter.updateTxStatus(
tx = swapTx,
statusModel = statusModel,
- refundToken = addedRefundToken,
- isRefundTerminalStatus = isRefundTerminalStatus,
)
}
}
@@ -120,8 +114,11 @@ internal class ExchangeStatusFactory @AssistedInject constructor(
ifLeft = { null },
ifRight = { statusModel ->
sendStatusUpdateAnalytics(statusModel, provider)
- swapTransactionRepository.storeTransactionState(txId, statusModel)
- statusModel
+
+ val refundTokenCurrency = addRefundCurrencyIfNeeded(statusModel, provider.type)
+
+ swapTransactionRepository.storeTransactionState(txId, statusModel, refundTokenCurrency)
+ statusModel.copy(refundCurrency = refundTokenCurrency)
},
)
}
@@ -174,15 +171,6 @@ internal class ExchangeStatusFactory @AssistedInject constructor(
)
}
- private fun ExchangeStatus?.isTerminal(isRefundTerminal: Boolean): Boolean {
- val needTerminalRefund = this == ExchangeStatus.Refunded && isRefundTerminal
- return needTerminalRefund ||
- this == ExchangeStatus.Finished ||
- this == ExchangeStatus.Cancelled ||
- this == ExchangeStatus.TxFailed ||
- this == ExchangeStatus.Unknown
- }
-
private fun toAnalyticStatus(status: ExchangeStatus?): ExpressAnalyticsStatus? {
return when (status) {
ExchangeStatus.New,
diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExpressStatusFactory.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExpressStatusFactory.kt
index 3c1633c710..5f1c18949f 100644
--- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExpressStatusFactory.kt
+++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/ExpressStatusFactory.kt
@@ -157,11 +157,13 @@ internal class ExpressStatusFactory @AssistedInject constructor(
suspend fun removeTransactionOnBottomSheetClosed(
expressState: ExpressTransactionStateUM,
- isForceTerminal: Boolean = false,
+ isForceDispose: Boolean = false,
) {
when (expressState) {
- is ExchangeUM -> exchangeStatusFactory.removeTransactionOnBottomSheetClosed(isForceTerminal)
- is ExpressTransactionStateUM.OnrampUM -> onrampStatusFactory.removeTransactionOnBottomSheetClosed()
+ is ExchangeUM -> exchangeStatusFactory.removeTransactionOnBottomSheetClosed(isForceDispose)
+ is ExpressTransactionStateUM.OnrampUM -> onrampStatusFactory.removeTransactionOnBottomSheetClosed(
+ isForceDispose,
+ )
}
}
diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/OnrampStatusFactory.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/OnrampStatusFactory.kt
index 7ca14864da..79328454af 100644
--- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/OnrampStatusFactory.kt
+++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/express/OnrampStatusFactory.kt
@@ -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)
}
}
diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/express/exchange/ExchangeStatusBottomSheetContent.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/express/exchange/ExchangeStatusBottomSheetContent.kt
index 3c969fa8d2..f547861942 100644
--- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/express/exchange/ExchangeStatusBottomSheetContent.kt
+++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/express/exchange/ExchangeStatusBottomSheetContent.kt
@@ -9,6 +9,7 @@ import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import com.tangem.common.ui.expressStatus.ExpressEstimate
+import com.tangem.common.ui.expressStatus.ExpressHideButton
import com.tangem.common.ui.expressStatus.ExpressProvider
import com.tangem.core.ui.R
import com.tangem.core.ui.components.SpacerH10
@@ -70,6 +71,11 @@ internal fun ExchangeStatusBottomSheetContent(state: ExchangeUM) {
if (state.notification != null) {
Notification(state = state.notification, activeStatus = state.activeStatus)
}
+ ExpressHideButton(
+ isTerminal = state.activeStatus?.isTerminal == true,
+ isAutoDisposable = state.activeStatus?.isAutoDisposable == true,
+ onClick = state.info.onDisposeExpressStatus,
+ )
SpacerH24()
}
}
diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsClickIntents.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsClickIntents.kt
index e4439079b5..8806affc45 100644
--- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsClickIntents.kt
+++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsClickIntents.kt
@@ -72,4 +72,8 @@ interface TokenDetailsClickIntents {
fun onGoToRefundedTokenClick(cryptoCurrency: CryptoCurrency)
fun onOpenUrlClick(url: String)
+
+ fun onConfirmDisposeExpressStatus()
+
+ fun onDisposeExpressStatus()
}
\ No newline at end of file
diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt
index cb86b9d766..744218305e 100644
--- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt
+++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt
@@ -784,16 +784,6 @@ internal class TokenDetailsViewModel @Inject constructor(
}
override fun onGoToRefundedTokenClick(cryptoCurrency: CryptoCurrency) {
- val bottomSheetState = internalUiState.value.bottomSheetConfig?.content
- if (bottomSheetState is ExpressStatusBottomSheetConfig) {
- viewModelScope.launch {
- expressStatusFactory.removeTransactionOnBottomSheetClosed(
- expressState = bottomSheetState.value,
- isForceTerminal = true,
- )
- }
- }
- internalUiState.value = stateFactory.getStateWithClosedBottomSheet()
router.openTokenDetails(userWalletId, cryptoCurrency)
}
@@ -950,6 +940,23 @@ internal class TokenDetailsViewModel @Inject constructor(
internalUiState.value = stateFactory.getStateWithUpdatedBalanceSegmentedButtonConfig(config)
}
+ override fun onConfirmDisposeExpressStatus() {
+ internalUiState.value = stateFactory.getStateWithConfirmHideExpressStatus()
+ }
+
+ override fun onDisposeExpressStatus() {
+ val bottomSheetState = internalUiState.value.bottomSheetConfig?.content
+ if (bottomSheetState is ExpressStatusBottomSheetConfig) {
+ viewModelScope.launch {
+ expressStatusFactory.removeTransactionOnBottomSheetClosed(
+ expressState = bottomSheetState.value,
+ isForceDispose = true,
+ )
+ }
+ }
+ internalUiState.value = stateFactory.getStateWithClosedBottomSheet()
+ }
+
private fun handleUnavailabilityReason(
unavailabilityReason: ScenarioUnavailabilityReason,
tokenSymbol: String,
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/OnrampStatusFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/OnrampStatusFactory.kt
index 7686df2258..32450b5201 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/OnrampStatusFactory.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/OnrampStatusFactory.kt
@@ -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)
}
}
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletAlertState.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletAlertState.kt
index a55311e803..7d8fe9b661 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletAlertState.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletAlertState.kt
@@ -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
@@ -108,4 +110,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)
+ }
}
\ No newline at end of file
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletOnrampTransactionConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletOnrampTransactionConverter.kt
index 606d0ed064..a5a0ee99b1 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletOnrampTransactionConverter.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/SingleWalletOnrampTransactionConverter.kt
@@ -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,
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletEventSender.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletEventSender.kt
index 34859d54d9..710e54acde 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletEventSender.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletEventSender.kt
@@ -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())
}
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletContentClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletContentClickIntents.kt
index 0b20b60c75..3d00a7564b 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletContentClickIntents.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletContentClickIntents.kt
@@ -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))
+ }
}
\ No newline at end of file