Updated on 2026-08-14
This commit is contained in:
parent
5f6e5e328f
commit
ccaaab6ffe
11 changed files with 35 additions and 98 deletions
|
|
@ -42,8 +42,8 @@ internal data class SwapStateHolder(
|
|||
val onRefresh: () -> Unit,
|
||||
val onBackClicked: () -> Unit,
|
||||
val onChangeCardsClicked: () -> Unit,
|
||||
val onSelectTokenClick: (() -> Unit)? = null,
|
||||
val onSuccess: (() -> Unit)? = null,
|
||||
val onSelectTokenClick: (() -> Unit),
|
||||
val onSuccess: (() -> Unit),
|
||||
val onMaxAmountSelected: (() -> Unit)? = null,
|
||||
val onShowPermissionBottomSheet: () -> Unit = {},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ data class UiActions(
|
|||
val onProviderClick: (String) -> Unit,
|
||||
val onProviderSelect: (String) -> Unit,
|
||||
val onBuyClick: (CryptoCurrency) -> Unit,
|
||||
val onPolicyClick: (String) -> Unit,
|
||||
val onTosClick: (String) -> Unit,
|
||||
val onSelectTokenClick: () -> Unit,
|
||||
val onSuccess: () -> Unit,
|
||||
val onLinkClick: (String) -> Unit,
|
||||
val onReceiveCardWarningClick: () -> Unit,
|
||||
val onFeeReadMoreClick: (String) -> Unit,
|
||||
)
|
||||
|
|
@ -6,20 +6,16 @@ import androidx.compose.foundation.background
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.tangem.common.routing.AppRouter
|
||||
|
||||
import com.tangem.core.ui.UiDependencies
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.screen.ComposeFragment
|
||||
import com.tangem.feature.swap.router.CustomTabsManager
|
||||
import com.tangem.feature.swap.router.SwapNavScreen
|
||||
import com.tangem.feature.swap.router.SwapRouter
|
||||
import com.tangem.feature.swap.ui.SwapScreen
|
||||
import com.tangem.feature.swap.ui.SwapSelectTokenScreen
|
||||
import com.tangem.feature.swap.ui.SwapSuccessScreen
|
||||
import com.tangem.feature.swap.viewmodels.SwapViewModel
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import java.lang.ref.WeakReference
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
|
|
@ -28,20 +24,11 @@ class SwapFragment : ComposeFragment() {
|
|||
@Inject
|
||||
override lateinit var uiDependencies: UiDependencies
|
||||
|
||||
@Inject
|
||||
lateinit var appRouter: AppRouter
|
||||
|
||||
private val viewModel by viewModels<SwapViewModel>()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
lifecycle.addObserver(viewModel)
|
||||
viewModel.setRouter(
|
||||
SwapRouter(
|
||||
customTabsManager = CustomTabsManager(WeakReference(context)),
|
||||
router = appRouter,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
package com.tangem.feature.swap.router
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import androidx.browser.customtabs.CustomTabColorSchemeParams
|
||||
import androidx.browser.customtabs.CustomTabsIntent
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
@Deprecated("Replace with CustomTabsUrlOpener")
|
||||
class CustomTabsManager(private val context: WeakReference<Context>) {
|
||||
|
||||
fun openUrl(url: String) {
|
||||
val mContext = context.get() ?: return
|
||||
val browserIntent = Intent()
|
||||
.setAction(Intent.ACTION_VIEW)
|
||||
.addCategory(Intent.CATEGORY_BROWSABLE)
|
||||
.setDataAndType(Uri.fromParts("http", "", null), "text/plain")
|
||||
var possibleBrowsers =
|
||||
mContext.packageManager.queryIntentActivities(browserIntent, PackageManager.MATCH_DEFAULT_ONLY)
|
||||
if (possibleBrowsers.isEmpty()) {
|
||||
possibleBrowsers =
|
||||
mContext.packageManager.queryIntentActivities(browserIntent, PackageManager.MATCH_ALL)
|
||||
}
|
||||
if (possibleBrowsers.isNotEmpty()) {
|
||||
val customTabsIntent = CustomTabsIntent.Builder()
|
||||
.setDefaultColorSchemeParams(
|
||||
CustomTabColorSchemeParams.Builder().build(),
|
||||
)
|
||||
.build()
|
||||
customTabsIntent.intent.setPackage(possibleBrowsers[0].activityInfo.packageName)
|
||||
context.get()?.let { customTabsIntent.launchUrl(it, Uri.parse(url)) }
|
||||
} else {
|
||||
val browserIntent2 = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
mContext.startActivity(browserIntent2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,6 @@ import com.tangem.domain.tokens.model.CryptoCurrency
|
|||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
internal class SwapRouter(
|
||||
private val customTabsManager: CustomTabsManager,
|
||||
private val router: AppRouter,
|
||||
) {
|
||||
|
||||
|
|
@ -45,10 +44,6 @@ internal class SwapRouter(
|
|||
}
|
||||
}
|
||||
|
||||
fun openUrl(url: String) {
|
||||
customTabsManager.openUrl(url)
|
||||
}
|
||||
|
||||
fun openTokenDetails(userWalletId: UserWalletId, currency: CryptoCurrency) {
|
||||
val route = AppRoute.CurrencyDetails(
|
||||
userWalletId = userWalletId,
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ internal class StateBuilder(
|
|||
onMaxAmountSelected = actions.onMaxAmountSelected,
|
||||
changeCardsButtonState = ChangeCardsButtonState.UPDATE_IN_PROGRESS,
|
||||
onShowPermissionBottomSheet = actions.openPermissionBottomSheet,
|
||||
onSelectTokenClick = actions.onSelectTokenClick,
|
||||
onSuccess = actions.onSuccess,
|
||||
providerState = ProviderState.Empty(),
|
||||
shouldShowMaxAmount = false,
|
||||
priceImpact = PriceImpact.Empty(),
|
||||
|
|
@ -352,14 +354,14 @@ internal class StateBuilder(
|
|||
LegalState(
|
||||
title = resourceReference(R.string.common_terms_of_use),
|
||||
link = it,
|
||||
onClick = actions.onTosClick,
|
||||
onClick = actions.onLinkClick,
|
||||
)
|
||||
},
|
||||
policyLink = swapProvider.privacyPolicy?.let {
|
||||
LegalState(
|
||||
title = resourceReference(R.string.common_privacy_policy),
|
||||
link = it,
|
||||
onClick = actions.onPolicyClick,
|
||||
onClick = actions.onLinkClick,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
@ -1039,7 +1041,7 @@ internal class StateBuilder(
|
|||
readMoreUrl = buildReadMoreUrl(),
|
||||
feeItems = txFeeState.toFeeItemState(),
|
||||
readMore = resourceReference(R.string.common_read_more),
|
||||
onReadMoreClick = actions.onFeeReadMoreClick,
|
||||
onReadMoreClick = actions.onLinkClick,
|
||||
)
|
||||
return uiState.copy(
|
||||
bottomSheetConfig = TangemBottomSheetConfig(
|
||||
|
|
|
|||
|
|
@ -444,6 +444,8 @@ private val state = SwapStateHolder(
|
|||
priceImpact = PriceImpact.Empty(),
|
||||
shouldShowMaxAmount = true,
|
||||
isInsufficientFunds = false,
|
||||
onSuccess = {},
|
||||
onSelectTokenClick = {},
|
||||
tosState = TosState(
|
||||
tosLink = LegalState(
|
||||
title = stringReference("Terms of Use"),
|
||||
|
|
|
|||
|
|
@ -8,12 +8,14 @@ import androidx.lifecycle.*
|
|||
import arrow.core.Either
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.common.routing.bundle.unbundle
|
||||
import com.tangem.common.ui.bottomsheet.permission.state.ApproveType
|
||||
import com.tangem.common.ui.bottomsheet.permission.state.GiveTxPermissionState.InProgress.getApproveTypeOrNull
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.utils.InputNumberFormatter
|
||||
|
|
@ -86,6 +88,8 @@ internal class SwapViewModel @Inject constructor(
|
|||
private val getMinimumTransactionAmountSyncUseCase: GetMinimumTransactionAmountSyncUseCase,
|
||||
swapInteractorFactory: SwapInteractor.Factory,
|
||||
private val savedStateHandle: SavedStateHandle,
|
||||
private val urlOpener: UrlOpener,
|
||||
router: AppRouter,
|
||||
) : ViewModel(), DefaultLifecycleObserver {
|
||||
|
||||
private val initialCurrencyFrom: CryptoCurrency
|
||||
|
|
@ -141,7 +145,7 @@ internal class SwapViewModel @Inject constructor(
|
|||
private var isOrderReversed = false
|
||||
private val lastAmount = mutableStateOf(INITIAL_AMOUNT)
|
||||
private val lastReducedBalanceBy = mutableStateOf(BigDecimal.ZERO)
|
||||
private var swapRouter: SwapRouter by Delegates.notNull()
|
||||
private var swapRouter: SwapRouter = SwapRouter(router = router)
|
||||
|
||||
private val isUserResolvableError: (SwapState) -> Boolean = {
|
||||
it is SwapState.SwapError &&
|
||||
|
|
@ -201,19 +205,6 @@ internal class SwapViewModel @Inject constructor(
|
|||
analyticsEventHandler.send(SwapEvents.SwapScreenOpened(initialCurrencyFrom.symbol))
|
||||
}
|
||||
|
||||
fun setRouter(router: SwapRouter) {
|
||||
swapRouter = router
|
||||
uiState = uiState.copy(
|
||||
onSelectTokenClick = {
|
||||
router.openScreen(SwapNavScreen.SelectToken)
|
||||
sendSelectTokenScreenOpenedEvent()
|
||||
},
|
||||
onSuccess = {
|
||||
router.openScreen(SwapNavScreen.Success)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun sendSelectTokenScreenOpenedEvent() {
|
||||
val isAnyAvailableTokensTo = dataState.tokensDataState?.toGroup?.available?.isNotEmpty() ?: false
|
||||
val isAnyAvailableTokensFrom = dataState.tokensDataState?.fromGroup?.available?.isNotEmpty() ?: false
|
||||
|
|
@ -609,7 +600,7 @@ internal class SwapViewModel @Inject constructor(
|
|||
txUrl = url,
|
||||
onExploreClick = {
|
||||
if (it.txHash.isNotEmpty()) {
|
||||
swapRouter.openUrl(url)
|
||||
urlOpener.openUrl(url)
|
||||
}
|
||||
analyticsEventHandler.send(
|
||||
event = SwapEvents.ButtonExplore(initialCurrencyFrom.symbol),
|
||||
|
|
@ -618,7 +609,7 @@ internal class SwapViewModel @Inject constructor(
|
|||
onStatusClick = {
|
||||
val txExternalUrl = it.txExternalUrl
|
||||
if (!txExternalUrl.isNullOrBlank()) {
|
||||
swapRouter.openUrl(txExternalUrl)
|
||||
urlOpener.openUrl(txExternalUrl)
|
||||
analyticsEventHandler.send(
|
||||
event = SwapEvents.ButtonStatus(initialCurrencyFrom.symbol),
|
||||
)
|
||||
|
|
@ -1103,12 +1094,6 @@ internal class SwapViewModel @Inject constructor(
|
|||
onRetryClick = {
|
||||
startLoadingQuotesFromLastState()
|
||||
},
|
||||
onPolicyClick = {
|
||||
swapRouter.openUrl(it)
|
||||
},
|
||||
onTosClick = {
|
||||
swapRouter.openUrl(it)
|
||||
},
|
||||
onReceiveCardWarningClick = {
|
||||
val selectedProvider = dataState.selectedProvider ?: return@UiActions
|
||||
val currencySymbol = dataState.toCryptoCurrency?.currency?.symbol ?: return@UiActions
|
||||
|
|
@ -1122,8 +1107,13 @@ internal class SwapViewModel @Inject constructor(
|
|||
uiState = stateBuilder.clearAlert(uiState)
|
||||
}
|
||||
},
|
||||
onFeeReadMoreClick = {
|
||||
swapRouter.openUrl(it)
|
||||
onLinkClick = urlOpener::openUrl,
|
||||
onSelectTokenClick = {
|
||||
swapRouter.openScreen(SwapNavScreen.SelectToken)
|
||||
sendSelectTokenScreenOpenedEvent()
|
||||
},
|
||||
onSuccess = {
|
||||
swapRouter.openScreen(SwapNavScreen.Success)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue