Updated on 2026-08-14

This commit is contained in:
Tangem 2026-04-27 10:36:30 +02:00
parent 99acc9718b
commit 4fa5989289
3 changed files with 48 additions and 0 deletions

View file

@ -105,6 +105,10 @@ dependencies {
implementation(deps.kotlin.serialization)
implementation(deps.kotlin.immutable.collections)
implementation(deps.decompose.ext.compose)
implementation(deps.firebase.perf) {
exclude(group = "com.google.firebase", module = "protolite-well-known-types")
exclude(group = "com.google.protobuf", module = "protobuf-javalite")
}
/** Tangem libs */
implementation(tangemDeps.blockchain)

View file

@ -0,0 +1,36 @@
package com.tangem.feature.swap.analytics
import com.google.firebase.perf.FirebasePerformance
import com.google.firebase.perf.metrics.Trace
internal class SwapQuotePerformanceTracker {
private var trace: Trace? = null
fun onLoadingStarted(providersCount: Int) {
trace?.stop()
trace = FirebasePerformance.getInstance().newTrace(SWAP_QUOTES_LOADED_TRACE_NAME).apply {
putAttribute(PROVIDERS_COUNT, providersCount.toString())
start()
}
}
fun onLoadingFinished(hasError: Boolean) {
trace?.apply {
putAttribute(HAS_ERROR, if (hasError) "Yes" else "No")
stop()
}
trace = null
}
fun onDestroy() {
trace?.stop()
trace = null
}
private companion object {
const val SWAP_QUOTES_LOADED_TRACE_NAME = "Swap_quotes_loaded"
const val PROVIDERS_COUNT = "providers_count"
const val HAS_ERROR = "has_error"
}
}

View file

@ -68,6 +68,7 @@ import com.tangem.domain.transaction.models.TransactionFeeExtended
import com.tangem.domain.transaction.usecase.gasless.IsGaslessFeeSupportedForNetwork
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
import com.tangem.feature.swap.analytics.SwapEvents
import com.tangem.feature.swap.analytics.SwapQuotePerformanceTracker
import com.tangem.feature.swap.choosetoken.api.ChooseTokenAnalyticsPayload
import com.tangem.feature.swap.choosetoken.api.ChooseTokenBridge
import com.tangem.feature.swap.choosetoken.api.ChooseTokenResult
@ -192,6 +193,7 @@ internal class SwapModel @Inject constructor(
private val amountDebouncer = Debouncer()
private val singleTaskScheduler = SingleTaskScheduler<Map<SwapProvider, SwapState>>()
private val performanceTracker = SwapQuotePerformanceTracker()
val dataStateStateFlow = MutableStateFlow(SwapProcessDataState())
var dataState
@ -295,6 +297,7 @@ internal class SwapModel @Inject constructor(
override fun onDestroy() {
singleTaskScheduler.cancelTask()
performanceTracker.onDestroy()
super.onDestroy()
}
@ -605,6 +608,7 @@ internal class SwapModel @Inject constructor(
uiStateHolder = uiState,
)
feeSelectorRepository.state.value = FeeSelectorUM.Loading
performanceTracker.onLoadingStarted(toProvidersList.size)
}
singleTaskScheduler.scheduleTask(
modelScope,
@ -686,6 +690,9 @@ internal class SwapModel @Inject constructor(
}
},
onSuccess = { providersState ->
performanceTracker.onLoadingFinished(
hasError = providersState.values.none { it is SwapState.QuotesLoadedState },
)
if (providersState.isNotEmpty()) {
val (provider, state) = updateLoadedQuotes(providersState)
setupLoadedState(
@ -715,6 +722,7 @@ internal class SwapModel @Inject constructor(
},
onError = { error ->
TangemLogger.e("Error when loading quotes: $error")
performanceTracker.onLoadingFinished(hasError = true)
feeSelectorRepository.state.value = FeeSelectorUM.Error(GetFeeError.UnknownError, isHidden = true)
uiState = stateBuilder.addNotification(uiState, null) { startLoadingQuotesFromLastState() }
},