Updated on 2026-08-14

This commit is contained in:
Tangem 2025-05-15 11:39:28 +03:00
parent a72837204d
commit 96b4a46462
8 changed files with 30 additions and 24 deletions

View file

@ -11,3 +11,12 @@ fun <T : Any, R : Any> ApiResponse<T>.fold(onSuccess: (T) -> R, onError: (ApiRes
is ApiResponse.Success -> onSuccess(data) is ApiResponse.Success -> onSuccess(data)
} }
} }
inline fun <T> catchApiResponseError(onError: (ApiResponseError) -> Unit, block: () -> T): T {
return try {
block()
} catch (e: ApiResponseError) {
onError(e)
throw e
}
}

View file

@ -55,11 +55,11 @@ interface TangemTechApi {
/** Returns referral status by [walletId] */ /** Returns referral status by [walletId] */
@GET("referral/{walletId}") @GET("referral/{walletId}")
suspend fun getReferralStatus(@Path("walletId") walletId: String): ReferralResponse suspend fun getReferralStatus(@Path("walletId") walletId: String): ApiResponse<ReferralResponse>
/** Make user referral, requires [StartReferralBody] */ /** Make user referral, requires [StartReferralBody] */
@POST("referral") @POST("referral")
suspend fun startReferral(@Body startReferralBody: StartReferralBody): ReferralResponse suspend fun startReferral(@Body startReferralBody: StartReferralBody): ApiResponse<ReferralResponse>
@GET("quotes") @GET("quotes")
suspend fun getQuotes( suspend fun getQuotes(

View file

@ -113,7 +113,7 @@ internal class DefaultMarketsTokenRepository(
tangemTechApi = tangemTechApi, tangemTechApi = tangemTechApi,
marketsApi = marketsApi, marketsApi = marketsApi,
analyticsEventHandler = analyticsEventHandler, analyticsEventHandler = analyticsEventHandler,
onApiError = { onApiResponseError = {
analyticsEventHandler.send(createListErrorEvent(it).toEvent()) analyticsEventHandler.send(createListErrorEvent(it).toEvent())
}, },
) )

View file

@ -7,6 +7,7 @@ import com.tangem.data.markets.converters.TokenMarketChartsConverter
import com.tangem.data.markets.converters.TokenQuotesShortConverter import com.tangem.data.markets.converters.TokenQuotesShortConverter
import com.tangem.data.markets.converters.toRequestParam import com.tangem.data.markets.converters.toRequestParam
import com.tangem.datasource.api.common.response.ApiResponseError import com.tangem.datasource.api.common.response.ApiResponseError
import com.tangem.datasource.api.common.response.catchApiResponseError
import com.tangem.datasource.api.common.response.getOrThrow import com.tangem.datasource.api.common.response.getOrThrow
import com.tangem.datasource.api.markets.TangemTechMarketsApi import com.tangem.datasource.api.markets.TangemTechMarketsApi
import com.tangem.datasource.api.markets.models.response.TokenMarketChartListResponse import com.tangem.datasource.api.markets.models.response.TokenMarketChartListResponse
@ -25,7 +26,7 @@ internal class MarketsBatchUpdateFetcher(
private val marketsApi: TangemTechMarketsApi, private val marketsApi: TangemTechMarketsApi,
private val tangemTechApi: TangemTechApi, private val tangemTechApi: TangemTechApi,
private val analyticsEventHandler: AnalyticsEventHandler, private val analyticsEventHandler: AnalyticsEventHandler,
private val onApiError: (ApiResponseError) -> Unit, private val onApiResponseError: (ApiResponseError) -> Unit,
) : BatchUpdateFetcher<Int, List<TokenMarket>, TokenMarketUpdateRequest> { ) : BatchUpdateFetcher<Int, List<TokenMarket>, TokenMarketUpdateRequest> {
override suspend fun BatchUpdateFetcher.UpdateContext<Int, List<TokenMarket>>.fetchUpdateAsync( override suspend fun BatchUpdateFetcher.UpdateContext<Int, List<TokenMarket>>.fetchUpdateAsync(
@ -41,7 +42,7 @@ internal class MarketsBatchUpdateFetcher(
val updateTasks = idsToUpdate.map { batchIds -> val updateTasks = idsToUpdate.map { batchIds ->
async { async {
retryOnError { retryOnError {
catchApiError(onApiError) { catchApiResponseError(onApiResponseError) {
marketsApi.getCoinsListCharts( marketsApi.getCoinsListCharts(
coinIds = batchIds.second.joinToString(separator = ","), coinIds = batchIds.second.joinToString(separator = ","),
interval = updateRequest.interval.toRequestParam(), interval = updateRequest.interval.toRequestParam(),
@ -71,7 +72,7 @@ internal class MarketsBatchUpdateFetcher(
} }
is TokenMarketUpdateRequest.UpdateQuotes -> { is TokenMarketUpdateRequest.UpdateQuotes -> {
val quotesRes = retryOnError { val quotesRes = retryOnError {
catchApiError(onApiError) { catchApiResponseError(onApiResponseError) {
tangemTechApi.getQuotes( tangemTechApi.getQuotes(
currencyId = updateRequest.currencyId, currencyId = updateRequest.currencyId,
coinIds = idsToUpdate.map { it.second }.flatten().joinToString(separator = ","), coinIds = idsToUpdate.map { it.second }.flatten().joinToString(separator = ","),
@ -133,13 +134,4 @@ internal class MarketsBatchUpdateFetcher(
} }
} }
} }
private inline fun <T> catchApiError(onError: (ApiResponseError) -> Unit, block: () -> T): T {
return try {
block()
} catch (e: ApiResponseError) {
onError(e)
throw e
}
}
} }

View file

@ -5,6 +5,7 @@ import com.tangem.blockchain.common.Token
import com.tangem.blockchainsdk.utils.ExcludedBlockchains import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.blockchainsdk.utils.fromNetworkId import com.tangem.blockchainsdk.utils.fromNetworkId
import com.tangem.data.common.currency.CryptoCurrencyFactory import com.tangem.data.common.currency.CryptoCurrencyFactory
import com.tangem.datasource.api.common.response.getOrThrow
import com.tangem.datasource.api.tangemTech.TangemTechApi import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.api.tangemTech.models.StartReferralBody import com.tangem.datasource.api.tangemTech.models.StartReferralBody
import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.datasource.local.userwallet.UserWalletsStore
@ -38,7 +39,7 @@ internal class ReferralRepositoryImpl @Inject constructor(
val referralData = referralConverter.convert( val referralData = referralConverter.convert(
referralApi.getReferralStatus( referralApi.getReferralStatus(
walletId = walletId, walletId = walletId,
), ).getOrThrow(),
) )
referralStatus[walletId] = referralData referralStatus[walletId] = referralData
@ -66,7 +67,7 @@ internal class ReferralRepositoryImpl @Inject constructor(
tokenId = tokenId, tokenId = tokenId,
address = address, address = address,
), ),
), ).getOrThrow(),
) )
referralStatus[walletId] = referralData referralStatus[walletId] = referralData
referralData referralData

View file

@ -4,11 +4,12 @@ import com.tangem.core.analytics.models.AnalyticsEvent
sealed class ReferralEvents(event: String) : AnalyticsEvent(REFERRAL_PROGRAM_CATEGORY, event) { sealed class ReferralEvents(event: String) : AnalyticsEvent(REFERRAL_PROGRAM_CATEGORY, event) {
object ReferralScreenOpened : ReferralEvents(event = "Referral Screen Opened") data object ReferralScreenOpened : ReferralEvents(event = "Referral Screen Opened")
object ClickParticipate : ReferralEvents(event = "Button - Participate") data object ClickParticipate : ReferralEvents(event = "Button - Participate")
object ClickCopy : ReferralEvents(event = "Button - Copy") data object ClickCopy : ReferralEvents(event = "Button - Copy")
object ClickShare : ReferralEvents(event = "Button - Share") data object ClickShare : ReferralEvents(event = "Button - Share")
object ClickTaC : ReferralEvents(event = "Link - TaC") data object ClickTaC : ReferralEvents(event = "Link - TaC")
data object ParticipateSuccessful : ReferralEvents(event = "Participate Successful")
} }
private const val REFERRAL_PROGRAM_CATEGORY = "Referral Program" private const val REFERRAL_PROGRAM_CATEGORY = "Referral Program"

View file

@ -91,7 +91,10 @@ internal class ReferralModel @Inject constructor(
uiState = uiState.copy(referralInfoState = ReferralInfoState.Loading) uiState = uiState.copy(referralInfoState = ReferralInfoState.Loading)
modelScope.launch { modelScope.launch {
runCatching { referralInteractor.startReferral(params.userWalletId) } runCatching { referralInteractor.startReferral(params.userWalletId) }
.onSuccess(::showContent) .onSuccess {
analyticsEventHandler.send(ReferralEvents.ParticipateSuccessful)
showContent(it)
}
.onFailure { throwable -> .onFailure { throwable ->
if (throwable is ReferralError.UserCancelledException) { if (throwable is ReferralError.UserCancelledException) {
lastReferralData?.let { referralData -> lastReferralData?.let { referralData ->

View file

@ -39,7 +39,7 @@ internal data class ReferralStateHolder(
val onParticipateClicked: () -> Unit, val onParticipateClicked: () -> Unit,
) : ReferralInfoState, ReferralInfoContentState ) : ReferralInfoState, ReferralInfoContentState
object Loading : ReferralInfoState data object Loading : ReferralInfoState
} }
data class ErrorSnackbar( data class ErrorSnackbar(