Updated on 2026-08-14

This commit is contained in:
Tangem 2026-05-27 23:29:32 +04:00
parent 865d4a1ed5
commit 2071dd9e2d
6 changed files with 77 additions and 5 deletions

View file

@ -8,12 +8,15 @@ import com.tangem.core.analytics.models.AnalyticsParam.Key.ERROR_MESSAGE
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.AnalyticsParam.Key.FEE_TOKEN
import com.tangem.core.analytics.models.AnalyticsParam.Key.PROVIDER
import com.tangem.core.analytics.models.AnalyticsParam.Key.RECEIVE_BLOCKCHAIN
import com.tangem.core.analytics.models.AnalyticsParam.Key.RECEIVE_TOKEN
import com.tangem.core.analytics.models.AnalyticsParam.Key.SEND_BLOCKCHAIN
import com.tangem.core.analytics.models.AnalyticsParam.Key.SEND_TOKEN
import com.tangem.core.analytics.models.AppsFlyerIncludedEvent
import com.tangem.core.analytics.models.getReferralParams
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.feature.swap.domain.models.domain.SwapProvider
import com.tangem.feature.swap.domain.models.domain.SwapUIMode
import com.tangem.feature.swap.domain.models.ui.FeeBucket
private const val SWAP_CATEGORY = "Swap"
@ -37,6 +40,39 @@ sealed class SwapEvents(
),
), AppsFlyerIncludedEvent
class SwapType(val mode: SwapUIMode) : SwapEvents(
event = "Swap type simple/detailed",
params = mapOf("Swap type" to mode.key),
)
class SwapTypeSelect(
val provider: SwapProvider?,
val sendToken: String,
val sendBlockchain: String,
val receiveToken: String?,
val receiveBlockchain: String?,
) : SwapEvents(
event = "Button - Swap type menu",
params = buildMap {
provider?.let { put(PROVIDER, it.name) }
put(SEND_TOKEN, sendToken)
put(SEND_BLOCKCHAIN, sendBlockchain)
receiveToken?.let { put(RECEIVE_TOKEN, it) }
receiveBlockchain?.let { put(RECEIVE_BLOCKCHAIN, it) }
},
)
class SwapTypeReSelection(
val typeFrom: SwapUIMode,
val typeTo: SwapUIMode,
) : SwapEvents(
event = "Swap type re-selection",
params = mapOf(
"Type from" to typeFrom.key,
"Type to" to typeTo.key,
),
)
class SendTokenBalanceClicked : SwapEvents(event = "Send Token Balance Clicked")
class ChooseTokenScreenResult(
@ -75,9 +111,17 @@ sealed class SwapEvents(
),
)
class ButtonSwapClicked(val sendToken: String, val receiveToken: String) : SwapEvents(
class ButtonSwapClicked(
val sendToken: String,
val receiveToken: String,
val swapUIMode: SwapUIMode,
) : SwapEvents(
event = "Button - Swap",
params = mapOf("Send Token" to sendToken, "Receive Token" to receiveToken),
params = mapOf(
"Send Token" to sendToken,
"Receive Token" to receiveToken,
"Swap type" to swapUIMode.key,
),
)
class ButtonGivePermissionClicked(

View file

@ -302,7 +302,9 @@ internal class SwapModel @Inject constructor(
}.launchIn(modelScope)
modelScope.launch {
uiState = uiState.copy(swapUIMode = getSwapUiModeUseCase())
val swapUIMode = getSwapUiModeUseCase()
uiState = uiState.copy(swapUIMode = swapUIMode)
analyticsEventHandler.send(SwapEvents.SwapType(swapUIMode))
}
}
@ -1662,6 +1664,7 @@ internal class SwapModel @Inject constructor(
SwapEvents.ButtonSwapClicked(
sendToken = sendTokenSymbol,
receiveToken = receiveTokenSymbol,
swapUIMode = uiState.swapUIMode,
),
)
}
@ -1765,15 +1768,34 @@ internal class SwapModel @Inject constructor(
router.replaceAll(SwapRoute.Success)
},
onSwapUIModeChange = ::onSwapUIModeChange,
onSwapTypeMenuOpened = ::onSwapTypeMenuOpened,
)
}
private fun onSwapUIModeChange(mode: SwapUIMode) {
if (uiState.swapUIMode == mode) return
val currentMode = uiState.swapUIMode
if (currentMode == mode) return
analyticsEventHandler.send(
SwapEvents.SwapTypeReSelection(typeFrom = currentMode, typeTo = mode),
)
uiState = uiState.copy(swapUIMode = mode)
modelScope.launch { setSwapUiModeUseCase(mode) }
}
private fun onSwapTypeMenuOpened() {
val fromCurrency = dataState.fromSwapCurrencyStatus?.currency
val toCurrency = dataState.toSwapCurrencyStatus?.currency
analyticsEventHandler.send(
SwapEvents.SwapTypeSelect(
provider = dataState.selectedProvider,
sendToken = fromCurrency?.symbol.orEmpty(),
sendBlockchain = fromCurrency?.network?.name.orEmpty(),
receiveToken = toCurrency?.symbol,
receiveBlockchain = toCurrency?.network?.name,
),
)
}
private fun selectWalletInSelector(
fromSwapCurrencyStatus: SwapCurrencyStatus?,
toSwapCurrencyStatus: SwapCurrencyStatus?,

View file

@ -46,6 +46,7 @@ internal data class SwapStateHolder(
val onPredefinedPercentSelected: ((PredefinedPercentAmount) -> Unit)? = null,
val onShowPermissionBottomSheet: () -> Unit = {},
val onSwapUIModeChange: (SwapUIMode) -> Unit = {},
val onSwapTypeMenuOpened: () -> Unit = {},
)
@Immutable

View file

@ -30,4 +30,5 @@ internal data class UiActions(
val onLinkClick: (String) -> Unit,
val onReceiveCardWarningClick: () -> Unit,
val onSwapUIModeChange: (SwapUIMode) -> Unit,
val onSwapTypeMenuOpened: () -> Unit,
)

View file

@ -108,6 +108,7 @@ internal class StateBuilder(
isInsufficientFunds = false,
swapUIMode = swapUIMode,
onSwapUIModeChange = actions.onSwapUIModeChange,
onSwapTypeMenuOpened = actions.onSwapTypeMenuOpened,
shouldShowAbMenu = swapFeatureToggles.isSwapAbEnabled,
isPredefinedButtonsEnabled = swapFeatureToggles.isSwapPredefinedButtonsEnabled,
)

View file

@ -87,7 +87,10 @@ private fun SwapTopBar(stateHolder: SwapStateHolder) {
backIconRes = R.drawable.ic_close_24,
iconRes = if (stateHolder.shouldShowAbMenu) R.drawable.ic_more_vertical_24 else null,
onIconClick = if (stateHolder.shouldShowAbMenu) {
{ shouldShowModeMenu = true }
{
stateHolder.onSwapTypeMenuOpened()
shouldShowModeMenu = true
}
} else {
null
},