Updated on 2026-08-14
This commit is contained in:
commit
b00a710ed0
17 changed files with 229 additions and 18 deletions
|
|
@ -127,7 +127,7 @@
|
|||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:host="onramp-success"
|
||||
android:host="*"
|
||||
android:scheme="tangem" />
|
||||
</intent-filter>
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import com.tangem.core.analytics.api.AnalyticsEventHandler
|
|||
import com.tangem.core.analytics.models.event.TechAnalyticsEvent
|
||||
import com.tangem.core.decompose.di.GlobalUiMessageSender
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.deeplink.DeepLinksRegistry
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.coil.ImagePreloader
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
|
|
@ -31,6 +32,7 @@ import com.tangem.domain.settings.usercountry.FetchUserCountryUseCase
|
|||
import com.tangem.domain.staking.FetchStakingTokensUseCase
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.feature.swap.analytics.StoriesEvents
|
||||
import com.tangem.features.onramp.deeplink.OnrampDeepLink
|
||||
import com.tangem.tap.common.extensions.setContext
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.BackupDialog
|
||||
|
|
@ -63,6 +65,8 @@ internal class MainViewModel @Inject constructor(
|
|||
private val imagePreloader: ImagePreloader,
|
||||
private val fetchHotCryptoUseCase: FetchHotCryptoUseCase,
|
||||
private val onboardingRepository: OnboardingRepository,
|
||||
private val deepLinksRegistry: DeepLinksRegistry,
|
||||
private val onrampDeepLinkFactory: OnrampDeepLink.Factory,
|
||||
getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
) : ViewModel() {
|
||||
|
||||
|
|
@ -97,6 +101,8 @@ internal class MainViewModel @Inject constructor(
|
|||
sendKeyboardIdentifierEvent()
|
||||
|
||||
preloadImages()
|
||||
|
||||
initializeDeepLinks()
|
||||
}
|
||||
|
||||
fun checkForUnfinishedBackup() {
|
||||
|
|
@ -333,4 +339,8 @@ internal class MainViewModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun initializeDeepLinks() {
|
||||
deepLinksRegistry.register(onrampDeepLinkFactory.create(viewModelScope))
|
||||
}
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@ interface OnrampApi {
|
|||
@GET("onramp-data")
|
||||
suspend fun getData(
|
||||
@Header("user-id") userWalletId: String,
|
||||
@Header("refcode") refCode: String,
|
||||
@Header("refcode") refCode: String?,
|
||||
@Query("fromCurrencyCode") fromCurrencyCode: String,
|
||||
@Query("fromPrecision") fromPrecision: Int,
|
||||
@Query("toContractAddress") toContractAddress: String,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.data.onramp
|
||||
|
||||
import android.net.Uri
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.blockchain.extensions.toBigDecimalOrDefault
|
||||
import com.tangem.data.common.api.safeApiCall
|
||||
|
|
@ -349,6 +350,7 @@ internal class DefaultOnrampRepository(
|
|||
val currency = requireNotNull(getDefaultCurrencySync()) { "Default currency must not be null" }
|
||||
val country = requireNotNull(getDefaultCountrySync()) { "Default country must not be null" }
|
||||
val requestId = UUID.randomUUID().toString()
|
||||
val redirectUrl = quote.provider.toRedirectUrl() ?: error("Invalid onramp redirect url")
|
||||
val data = safeApiCall(
|
||||
call = {
|
||||
onrampApi.getData(
|
||||
|
|
@ -362,7 +364,7 @@ internal class DefaultOnrampRepository(
|
|||
toDecimals = cryptoCurrency.decimals,
|
||||
providerId = quote.provider.id,
|
||||
toAddress = address,
|
||||
redirectUrl = "",
|
||||
redirectUrl = redirectUrl,
|
||||
language = null,
|
||||
theme = getTheme(isDarkTheme),
|
||||
requestId = requestId,
|
||||
|
|
@ -370,7 +372,7 @@ internal class DefaultOnrampRepository(
|
|||
refCode = ExpressUtils.getRefCode(
|
||||
userWallet = userWallet,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
),
|
||||
).takeUnless { it.isEmpty() },
|
||||
).bind()
|
||||
},
|
||||
onError = { e ->
|
||||
|
|
@ -544,6 +546,11 @@ internal class DefaultOnrampRepository(
|
|||
null
|
||||
}
|
||||
|
||||
private fun OnrampProvider.toRedirectUrl() = Uri.Builder()
|
||||
.path(REDIRECT_URL)
|
||||
.appendPath(id)
|
||||
.build().path
|
||||
|
||||
private companion object {
|
||||
const val PAYMENT_METHODS_KEY = "onramp_payment_methods"
|
||||
const val SELECTED_PAYMENT_METHOD_KEY = "onramp_selected_payment_method"
|
||||
|
|
@ -553,5 +560,7 @@ internal class DefaultOnrampRepository(
|
|||
const val CURRENCIES_KEY = "onramp_currencies"
|
||||
const val PROVIDER_THEME_DARK = "dark"
|
||||
const val PROVIDER_THEME_LIGHT = "light"
|
||||
|
||||
const val REDIRECT_URL = "https://tangem.com/onramp"
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.domain.onramp
|
|||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.onramp.model.OnrampProviderWithQuote
|
||||
import com.tangem.domain.onramp.model.cache.OnrampTransaction
|
||||
import com.tangem.domain.onramp.model.error.OnrampError
|
||||
import com.tangem.domain.onramp.repositories.OnrampErrorResolver
|
||||
import com.tangem.domain.onramp.repositories.OnrampRepository
|
||||
|
|
@ -20,7 +21,7 @@ class GetOnrampRedirectUrlUseCase(
|
|||
quote: OnrampProviderWithQuote.Data,
|
||||
cryptoCurrency: CryptoCurrency,
|
||||
isDarkTheme: Boolean,
|
||||
): Either<OnrampError, String> {
|
||||
): Either<OnrampError, OnrampTransaction> {
|
||||
return Either.catch {
|
||||
val transaction = repository.getOnrampData(
|
||||
userWallet = userWallet,
|
||||
|
|
@ -29,7 +30,7 @@ class GetOnrampRedirectUrlUseCase(
|
|||
isDarkTheme = isDarkTheme,
|
||||
)
|
||||
transactionRepository.storeTransaction(transaction)
|
||||
transaction.redirectUrl
|
||||
transaction
|
||||
}.mapLeft(errorResolver::resolve)
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ dependencies {
|
|||
/* Project - Core */
|
||||
implementation(projects.core.decompose)
|
||||
implementation(projects.core.ui)
|
||||
implementation(projects.core.deepLinks)
|
||||
|
||||
/* Project - Domain */
|
||||
implementation(projects.domain.onramp.models)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.features.onramp.deeplink
|
||||
|
||||
import com.tangem.core.deeplink.DeepLink
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
abstract class OnrampDeepLink : DeepLink() {
|
||||
override val uri = "tangem://onramp"
|
||||
|
||||
interface Factory {
|
||||
fun create(coroutineScope: CoroutineScope): OnrampDeepLink
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@ dependencies {
|
|||
implementation(projects.core.analytics)
|
||||
implementation(projects.core.configToggles)
|
||||
implementation(projects.core.decompose)
|
||||
implementation(projects.core.deepLinks)
|
||||
implementation(projects.core.navigation)
|
||||
implementation(projects.core.ui)
|
||||
implementation(projects.core.utils)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
package com.tangem.features.onramp.deeplink
|
||||
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.features.onramp.success.OnrampSuccessScreenTrigger
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
internal class DefaultOnrampDeepLink @AssistedInject constructor(
|
||||
private val appRouter: AppRouter,
|
||||
private val onrampSuccessScreenTrigger: OnrampSuccessScreenTrigger,
|
||||
@Assisted private val scope: CoroutineScope,
|
||||
) : OnrampDeepLink() {
|
||||
|
||||
override fun onReceive(params: Map<String, String>) {
|
||||
val txId = params[TX_ID_KEY]
|
||||
val result = OnrampRedirectResult.getResult(params[RESULT_KEY])
|
||||
|
||||
when {
|
||||
!txId.isNullOrEmpty() -> {
|
||||
// finish current onramp flow and show onramp success screen
|
||||
val replaceOnrampScreens = appRouter.stack
|
||||
.filterNot { it is AppRoute.Onramp }
|
||||
.toMutableList()
|
||||
replaceOnrampScreens.add(AppRoute.OnrampSuccess(txId))
|
||||
appRouter.replaceAll(*replaceOnrampScreens.toTypedArray())
|
||||
}
|
||||
result != OnrampRedirectResult.Unknown -> {
|
||||
scope.launch {
|
||||
onrampSuccessScreenTrigger.triggerOnrampSuccess(result == OnrampRedirectResult.Success)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : OnrampDeepLink.Factory {
|
||||
override fun create(coroutineScope: CoroutineScope): DefaultOnrampDeepLink
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val TX_ID_KEY = "tx_id"
|
||||
const val RESULT_KEY = "result"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.tangem.features.onramp.deeplink
|
||||
|
||||
enum class OnrampRedirectResult(val value: String) {
|
||||
Success("success"),
|
||||
Cancel("cancel"),
|
||||
Unknown(""),
|
||||
;
|
||||
|
||||
companion object {
|
||||
fun getResult(result: String?): OnrampRedirectResult {
|
||||
return entries.firstOrNull { it.value == result } ?: Unknown
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.tangem.features.onramp.deeplink.di
|
||||
|
||||
import com.tangem.features.onramp.deeplink.DefaultOnrampDeepLink
|
||||
import com.tangem.features.onramp.deeplink.OnrampDeepLink
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal interface OnrampDeeplinkModule {
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindFactory(impl: DefaultOnrampDeepLink.Factory): OnrampDeepLink.Factory
|
||||
}
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
package com.tangem.features.onramp.redirect.model
|
||||
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
||||
|
|
@ -13,14 +14,18 @@ import com.tangem.core.ui.extensions.stringReference
|
|||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.domain.onramp.GetOnrampRedirectUrlUseCase
|
||||
import com.tangem.domain.onramp.model.cache.OnrampTransaction
|
||||
import com.tangem.domain.onramp.model.error.OnrampError
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.redirect.OnrampRedirectComponent
|
||||
import com.tangem.features.onramp.redirect.entity.OnrampRedirectTopBarUM
|
||||
import com.tangem.features.onramp.redirect.entity.OnrampRedirectUM
|
||||
import com.tangem.features.onramp.success.OnrampSuccessScreenListener
|
||||
import com.tangem.features.onramp.utils.sendOnrampErrorEvent
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
|
@ -30,16 +35,19 @@ internal class OnrampRedirectModel @Inject constructor(
|
|||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val urlOpener: UrlOpener,
|
||||
private val getOnrampRedirectUrlUseCase: GetOnrampRedirectUrlUseCase,
|
||||
private val getWalletsUseCase: GetWalletsUseCase,
|
||||
private val messageSender: UiMessageSender,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
router: Router,
|
||||
private val onrampSuccessScreenListener: OnrampSuccessScreenListener,
|
||||
private val appRouter: AppRouter,
|
||||
paramsContainer: ParamsContainer,
|
||||
getWalletsUseCase: GetWalletsUseCase,
|
||||
) : Model() {
|
||||
|
||||
private val params: OnrampRedirectComponent.Params = paramsContainer.require()
|
||||
private val selectedUserWallet = getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId }
|
||||
|
||||
private var latestOnrampTransaction: OnrampTransaction? = null
|
||||
|
||||
val state = OnrampRedirectUM(
|
||||
topBarConfig = OnrampRedirectTopBarUM(
|
||||
title = combinedReference(
|
||||
|
|
@ -48,7 +56,7 @@ internal class OnrampRedirectModel @Inject constructor(
|
|||
),
|
||||
startButtonUM = TopAppBarButtonUM(
|
||||
iconRes = R.drawable.ic_close_24,
|
||||
onIconClicked = router::pop,
|
||||
onIconClicked = appRouter::pop,
|
||||
enabled = true,
|
||||
),
|
||||
),
|
||||
|
|
@ -63,6 +71,10 @@ internal class OnrampRedirectModel @Inject constructor(
|
|||
),
|
||||
)
|
||||
|
||||
init {
|
||||
subscribeToOnrampSuccessListener()
|
||||
}
|
||||
|
||||
fun getRedirectUrl(isDarkTheme: Boolean) {
|
||||
modelScope.launch {
|
||||
getOnrampRedirectUrlUseCase.invoke(
|
||||
|
|
@ -73,12 +85,31 @@ internal class OnrampRedirectModel @Inject constructor(
|
|||
)
|
||||
.onLeft(::handleError)
|
||||
.onRight {
|
||||
params.onBack()
|
||||
urlOpener.openUrl(it)
|
||||
latestOnrampTransaction = it
|
||||
urlOpener.openUrl(it.redirectUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun subscribeToOnrampSuccessListener() {
|
||||
onrampSuccessScreenListener.onrampSuccessTriggerFlow
|
||||
.onEach { result ->
|
||||
val latestTxId = latestOnrampTransaction?.txId
|
||||
if (latestTxId != null && result) {
|
||||
// Finish current onramp flow and show onramp success screen
|
||||
val replaceOnrampScreens = appRouter.stack
|
||||
.filterNot { it is AppRoute.Onramp }
|
||||
.toMutableList()
|
||||
replaceOnrampScreens.add(AppRoute.OnrampSuccess(latestTxId))
|
||||
appRouter.replaceAll(*replaceOnrampScreens.toTypedArray())
|
||||
} else {
|
||||
// Close redirect screen and show last onramp state
|
||||
params.onBack()
|
||||
}
|
||||
}
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun handleError(error: OnrampError) {
|
||||
Timber.e(error.toString())
|
||||
analyticsEventHandler.sendOnrampErrorEvent(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
package com.tangem.features.onramp.success
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
interface OnrampSuccessScreenListener {
|
||||
val onrampSuccessTriggerFlow: Flow<Boolean>
|
||||
}
|
||||
|
||||
interface OnrampSuccessScreenTrigger {
|
||||
suspend fun triggerOnrampSuccess(result: Boolean)
|
||||
}
|
||||
|
||||
@Singleton
|
||||
internal class DefaultOnrampSuccessScreenTrigger @Inject constructor() :
|
||||
OnrampSuccessScreenTrigger,
|
||||
OnrampSuccessScreenListener {
|
||||
|
||||
override val onrampSuccessTriggerFlow = MutableSharedFlow<Boolean>()
|
||||
|
||||
override suspend fun triggerOnrampSuccess(result: Boolean) {
|
||||
onrampSuccessTriggerFlow.emit(result)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,9 @@ package com.tangem.features.onramp.success.di
|
|||
|
||||
import com.tangem.features.onramp.component.OnrampSuccessComponent
|
||||
import com.tangem.features.onramp.success.DefaultOnrampSuccessComponent
|
||||
import com.tangem.features.onramp.success.DefaultOnrampSuccessScreenTrigger
|
||||
import com.tangem.features.onramp.success.OnrampSuccessScreenListener
|
||||
import com.tangem.features.onramp.success.OnrampSuccessScreenTrigger
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -16,4 +19,12 @@ internal interface OnrampSuccessComponentModule {
|
|||
fun bindOnrampSuccessComponentFactory(
|
||||
factory: DefaultOnrampSuccessComponent.Factory,
|
||||
): OnrampSuccessComponent.Factory
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindOnrampSuccessScreenTrigger(impl: DefaultOnrampSuccessScreenTrigger): OnrampSuccessScreenTrigger
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindOnrampSuccessScreenListener(impl: DefaultOnrampSuccessScreenTrigger): OnrampSuccessScreenListener
|
||||
}
|
||||
|
|
@ -2,4 +2,5 @@ package com.tangem.features.onramp.success.entity
|
|||
|
||||
interface OnrampSuccessClickIntents {
|
||||
fun goToProviderClick(providerLink: String)
|
||||
fun onCopyClick(copiedText: String)
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@ internal class SetOnrampSuccessContentConverter(
|
|||
private val cryptoCurrency: CryptoCurrency,
|
||||
private val transaction: OnrampTransaction,
|
||||
private val goToProviderClick: (String) -> Unit,
|
||||
private val onCopyClick: (String) -> Unit,
|
||||
) : Converter<OnrampStatus, OnrampSuccessComponentUM> {
|
||||
override fun convert(value: OnrampStatus): OnrampSuccessComponentUM {
|
||||
return OnrampSuccessComponentUM.Content(
|
||||
|
|
@ -46,8 +47,12 @@ internal class SetOnrampSuccessContentConverter(
|
|||
),
|
||||
providerName = stringReference(transaction.providerName),
|
||||
providerImageUrl = transaction.providerImageUrl,
|
||||
statusBlock = convertStatuses(value.status, value.externalTxUrl),
|
||||
notification = getNotification(value.status, value.externalTxUrl),
|
||||
statusBlock = convertStatuses(
|
||||
status = value.status,
|
||||
externalTxId = value.externalTxId,
|
||||
externalTxUrl = value.externalTxUrl,
|
||||
),
|
||||
notification = getNotification(status = value.status, externalTxUrl = value.externalTxUrl),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +78,11 @@ internal class SetOnrampSuccessContentConverter(
|
|||
null
|
||||
}
|
||||
|
||||
private fun convertStatuses(status: OnrampStatus.Status, externalTxUrl: String?): ExpressStatusUM {
|
||||
private fun convertStatuses(
|
||||
status: OnrampStatus.Status,
|
||||
externalTxId: String?,
|
||||
externalTxUrl: String?,
|
||||
): ExpressStatusUM {
|
||||
val statuses = with(status) {
|
||||
persistentListOf(
|
||||
getAwaitingDepositItem(),
|
||||
|
|
@ -85,7 +94,7 @@ internal class SetOnrampSuccessContentConverter(
|
|||
|
||||
return ExpressStatusUM(
|
||||
title = resourceReference(R.string.common_transaction_status),
|
||||
link = getStatusLink(status, externalTxUrl),
|
||||
link = getStatusLink(status = status, externalTxId = externalTxId, externalTxUrl = externalTxUrl),
|
||||
statuses = statuses,
|
||||
)
|
||||
}
|
||||
|
|
@ -183,7 +192,11 @@ internal class SetOnrampSuccessContentConverter(
|
|||
state = getStatusState(OnrampStatus.Status.Sending),
|
||||
)
|
||||
|
||||
private fun getStatusLink(status: OnrampStatus.Status, externalTxUrl: String?): ExpressLinkUM {
|
||||
private fun getStatusLink(
|
||||
status: OnrampStatus.Status,
|
||||
externalTxId: String?,
|
||||
externalTxUrl: String?,
|
||||
): ExpressLinkUM {
|
||||
if (externalTxUrl == null) return ExpressLinkUM.Empty
|
||||
return when (status) {
|
||||
OnrampStatus.Status.Verifying,
|
||||
|
|
@ -197,7 +210,15 @@ internal class SetOnrampSuccessContentConverter(
|
|||
},
|
||||
)
|
||||
}
|
||||
else -> ExpressLinkUM.Empty
|
||||
else -> if (externalTxId != null) {
|
||||
ExpressLinkUM.Content(
|
||||
icon = R.drawable.ic_copy_24,
|
||||
text = resourceReference(R.string.express_transaction_id, wrappedList(externalTxId)),
|
||||
onClick = { onCopyClick(externalTxId) },
|
||||
)
|
||||
} else {
|
||||
ExpressLinkUM.Empty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.tangem.core.decompose.model.ParamsContainer
|
|||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.core.ui.clipboard.ClipboardManager
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
|
|
@ -46,6 +47,7 @@ internal class OnrampSuccessComponentModel @Inject constructor(
|
|||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val messageSender: UiMessageSender,
|
||||
private val clipboardManager: ClipboardManager,
|
||||
private val router: Router,
|
||||
paramsContainer: ParamsContainer,
|
||||
) : Model(), OnrampSuccessClickIntents {
|
||||
|
|
@ -65,6 +67,10 @@ internal class OnrampSuccessComponentModel @Inject constructor(
|
|||
urlOpener.openUrl(providerLink)
|
||||
}
|
||||
|
||||
override fun onCopyClick(copiedText: String) {
|
||||
clipboardManager.setText(text = copiedText, isSensitive = false)
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
modelScope.launch {
|
||||
getOnrampTransactionUseCase(txId = params.txId)
|
||||
|
|
@ -124,6 +130,7 @@ internal class OnrampSuccessComponentModel @Inject constructor(
|
|||
cryptoCurrency = cryptoCurrency,
|
||||
transaction = transaction,
|
||||
goToProviderClick = ::goToProviderClick,
|
||||
onCopyClick = ::onCopyClick,
|
||||
).convert(status)
|
||||
}
|
||||
removeTransactionIfTerminalStatus(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue