Updated on 2026-08-14
This commit is contained in:
parent
bcc6331bb8
commit
816d8532de
5 changed files with 49 additions and 34 deletions
|
|
@ -10,19 +10,21 @@ import com.tangem.domain.express.ExpressRepository
|
||||||
import com.tangem.domain.express.models.ExpressProvider
|
import com.tangem.domain.express.models.ExpressProvider
|
||||||
import com.tangem.domain.express.models.ExpressProviderType
|
import com.tangem.domain.express.models.ExpressProviderType
|
||||||
import com.tangem.domain.models.wallet.UserWallet
|
import com.tangem.domain.models.wallet.UserWallet
|
||||||
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import com.tangem.utils.extensions.filterIf
|
import com.tangem.utils.extensions.filterIf
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
internal class DefaultExpressRepository(
|
internal class DefaultExpressRepository(
|
||||||
private val tangemExpressApi: TangemExpressApi,
|
private val tangemExpressApi: TangemExpressApi,
|
||||||
private val appPreferencesStore: AppPreferencesStore,
|
private val appPreferencesStore: AppPreferencesStore,
|
||||||
|
private val dispatchers: CoroutineDispatcherProvider,
|
||||||
) : ExpressRepository {
|
) : ExpressRepository {
|
||||||
|
|
||||||
override suspend fun getProviders(
|
override suspend fun getProviders(
|
||||||
userWallet: UserWallet,
|
userWallet: UserWallet,
|
||||||
filterProviderTypes: List<ExpressProviderType>,
|
filterProviderTypes: List<ExpressProviderType>,
|
||||||
): List<ExpressProvider> {
|
): List<ExpressProvider> = with(dispatchers.io) {
|
||||||
return safeApiCall(
|
safeApiCall(
|
||||||
call = {
|
call = {
|
||||||
tangemExpressApi.getProviders(
|
tangemExpressApi.getProviders(
|
||||||
userWalletId = userWallet.walletId.stringValue,
|
userWalletId = userWallet.walletId.stringValue,
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import com.tangem.datasource.di.NetworkMoshi
|
||||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
import com.tangem.domain.express.ExpressErrorResolver
|
import com.tangem.domain.express.ExpressErrorResolver
|
||||||
import com.tangem.domain.express.ExpressRepository
|
import com.tangem.domain.express.ExpressRepository
|
||||||
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
|
|
@ -34,10 +35,12 @@ internal object ExpressDataModule {
|
||||||
fun provideExpressRepository(
|
fun provideExpressRepository(
|
||||||
tangemExpressApi: TangemExpressApi,
|
tangemExpressApi: TangemExpressApi,
|
||||||
appPreferencesStore: AppPreferencesStore,
|
appPreferencesStore: AppPreferencesStore,
|
||||||
|
dispatchers: CoroutineDispatcherProvider,
|
||||||
): ExpressRepository {
|
): ExpressRepository {
|
||||||
return DefaultExpressRepository(
|
return DefaultExpressRepository(
|
||||||
tangemExpressApi = tangemExpressApi,
|
tangemExpressApi = tangemExpressApi,
|
||||||
appPreferencesStore = appPreferencesStore,
|
appPreferencesStore = appPreferencesStore,
|
||||||
|
dispatchers = dispatchers,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -7,10 +7,7 @@ import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
|
||||||
import kotlinx.coroutines.flow.flowOn
|
|
||||||
import kotlinx.coroutines.flow.mapNotNull
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of [SingleQuoteStatusProducer]
|
* Default implementation of [SingleQuoteStatusProducer]
|
||||||
|
|
@ -28,7 +25,7 @@ internal class DefaultSingleQuoteStatusProducer @AssistedInject constructor(
|
||||||
|
|
||||||
override fun produce(): Flow<QuoteStatus> {
|
override fun produce(): Flow<QuoteStatus> {
|
||||||
return quotesStatusesStore.get()
|
return quotesStatusesStore.get()
|
||||||
.mapNotNull { quotes -> quotes.firstOrNull { it.rawCurrencyId == params.rawCurrencyId } }
|
.mapNotNull { quotes -> quotes.firstOrNull { it.rawCurrencyId == params.rawCurrencyId } ?: fallback }
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.flowOn(dispatchers.default)
|
.flowOn(dispatchers.default)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import com.tangem.domain.express.models.ExpressRateType
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||||
import com.tangem.domain.models.network.NetworkStatus
|
import com.tangem.domain.models.network.NetworkStatus
|
||||||
|
import com.tangem.domain.models.quote.QuoteStatus
|
||||||
import com.tangem.domain.models.wallet.UserWallet
|
import com.tangem.domain.models.wallet.UserWallet
|
||||||
import com.tangem.domain.quotes.single.SingleQuoteStatusFetcher
|
import com.tangem.domain.quotes.single.SingleQuoteStatusFetcher
|
||||||
import com.tangem.domain.quotes.single.SingleQuoteStatusProducer
|
import com.tangem.domain.quotes.single.SingleQuoteStatusProducer
|
||||||
|
|
@ -65,7 +66,7 @@ internal class DefaultSwapRepositoryV2 @Inject constructor(
|
||||||
initialCurrency: CryptoCurrency,
|
initialCurrency: CryptoCurrency,
|
||||||
cryptoCurrencyStatusList: List<CryptoCurrencyStatus>,
|
cryptoCurrencyStatusList: List<CryptoCurrencyStatus>,
|
||||||
filterProviderTypes: List<ExpressProviderType>,
|
filterProviderTypes: List<ExpressProviderType>,
|
||||||
): List<SwapPairModel> = withContext(coroutineDispatcher.io) {
|
): List<SwapPairModel> = withContext(coroutineDispatcher.default) {
|
||||||
val cryptoCurrencyList = cryptoCurrencyStatusList.map { it.currency }
|
val cryptoCurrencyList = cryptoCurrencyStatusList.map { it.currency }
|
||||||
|
|
||||||
val allPairs = getPairsInternal(
|
val allPairs = getPairsInternal(
|
||||||
|
|
@ -113,7 +114,7 @@ internal class DefaultSwapRepositoryV2 @Inject constructor(
|
||||||
initialCurrency: CryptoCurrency,
|
initialCurrency: CryptoCurrency,
|
||||||
cryptoCurrencyList: List<CryptoCurrency>,
|
cryptoCurrencyList: List<CryptoCurrency>,
|
||||||
filterProviderTypes: List<ExpressProviderType>,
|
filterProviderTypes: List<ExpressProviderType>,
|
||||||
): List<SwapPairModel> = withContext(coroutineDispatcher.io) {
|
): List<SwapPairModel> = withContext(coroutineDispatcher.default) {
|
||||||
val allPairs = getPairsInternal(
|
val allPairs = getPairsInternal(
|
||||||
userWallet = userWallet,
|
userWallet = userWallet,
|
||||||
initialCurrency = initialCurrency,
|
initialCurrency = initialCurrency,
|
||||||
|
|
@ -330,25 +331,27 @@ internal class DefaultSwapRepositoryV2 @Inject constructor(
|
||||||
userWallet: UserWallet,
|
userWallet: UserWallet,
|
||||||
from: List<CryptoCurrency>,
|
from: List<CryptoCurrency>,
|
||||||
to: List<CryptoCurrency>,
|
to: List<CryptoCurrency>,
|
||||||
) = safeApiCall(
|
) = withContext(coroutineDispatcher.io) {
|
||||||
call = {
|
safeApiCall(
|
||||||
tangemExpressApi.getPairs(
|
call = {
|
||||||
userWalletId = userWallet.walletId.stringValue,
|
tangemExpressApi.getPairs(
|
||||||
refCode = ExpressUtils.getRefCode(
|
userWalletId = userWallet.walletId.stringValue,
|
||||||
userWallet = userWallet,
|
refCode = ExpressUtils.getRefCode(
|
||||||
appPreferencesStore = appPreferencesStore,
|
userWallet = userWallet,
|
||||||
),
|
appPreferencesStore = appPreferencesStore,
|
||||||
body = PairsRequestBody(
|
),
|
||||||
from = tokenInfoConverter.convertList(from),
|
body = PairsRequestBody(
|
||||||
to = tokenInfoConverter.convertList(to),
|
from = tokenInfoConverter.convertList(from),
|
||||||
),
|
to = tokenInfoConverter.convertList(to),
|
||||||
).getOrThrow()
|
),
|
||||||
},
|
).getOrThrow()
|
||||||
onError = {
|
},
|
||||||
Timber.w(it, "Unable to get pairs")
|
onError = {
|
||||||
throw it
|
Timber.w(it, "Unable to get pairs")
|
||||||
},
|
throw it
|
||||||
)
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send with swap specific currency status creation
|
* Send with swap specific currency status creation
|
||||||
|
|
@ -360,9 +363,9 @@ internal class DefaultSwapRepositoryV2 @Inject constructor(
|
||||||
|
|
||||||
val quote = singleQuoteStatusSupplier.getSyncOrNull(
|
val quote = singleQuoteStatusSupplier.getSyncOrNull(
|
||||||
params = SingleQuoteStatusProducer.Params(rawCurrencyId = rawCurrencyId),
|
params = SingleQuoteStatusProducer.Params(rawCurrencyId = rawCurrencyId),
|
||||||
)?.right()
|
)
|
||||||
|
|
||||||
if (quote == null) {
|
if (quote == null || quote.value is QuoteStatus.Empty) {
|
||||||
singleQuoteStatusFetcher.invoke(
|
singleQuoteStatusFetcher.invoke(
|
||||||
params = SingleQuoteStatusFetcher.Params(
|
params = SingleQuoteStatusFetcher.Params(
|
||||||
rawCurrencyId = rawCurrencyId,
|
rawCurrencyId = rawCurrencyId,
|
||||||
|
|
@ -373,7 +376,7 @@ internal class DefaultSwapRepositoryV2 @Inject constructor(
|
||||||
|
|
||||||
return currencyStatusProxyCreator.createCurrencyStatus(
|
return currencyStatusProxyCreator.createCurrencyStatus(
|
||||||
currency = cryptoCurrency,
|
currency = cryptoCurrency,
|
||||||
maybeQuoteStatus = quote ?: singleQuoteStatusSupplier.getSyncOrNull(
|
maybeQuoteStatus = quote?.right() ?: singleQuoteStatusSupplier.getSyncOrNull(
|
||||||
params = SingleQuoteStatusProducer.Params(rawCurrencyId = rawCurrencyId),
|
params = SingleQuoteStatusProducer.Params(rawCurrencyId = rawCurrencyId),
|
||||||
).right(),
|
).right(),
|
||||||
maybeNetworkStatus = NetworkStatus(
|
maybeNetworkStatus = NetworkStatus(
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,13 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.util.fastForEach
|
import androidx.compose.ui.util.fastForEachIndexed
|
||||||
import com.tangem.core.ui.components.SpacerWMax
|
import com.tangem.core.ui.components.SpacerWMax
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||||
import com.tangem.core.ui.components.bottomsheets.message.*
|
import com.tangem.core.ui.components.bottomsheets.message.*
|
||||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
||||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
||||||
|
import com.tangem.core.ui.decorations.roundedShapeItemDecoration
|
||||||
import com.tangem.core.ui.extensions.*
|
import com.tangem.core.ui.extensions.*
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
import com.tangem.core.ui.res.TangemThemePreview
|
||||||
|
|
@ -94,13 +95,22 @@ internal fun SwapChooseTokenNetworkContent(state: SwapChooseTokenNetworkContentU
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun SwapChooseTokenNetworkContentList(swapNetworks: ImmutableList<SwapChooseNetworkUM>) {
|
private fun SwapChooseTokenNetworkContentList(swapNetworks: ImmutableList<SwapChooseNetworkUM>) {
|
||||||
Column {
|
Column(
|
||||||
swapNetworks.fastForEach { network ->
|
modifier = Modifier
|
||||||
|
.padding(top = 8.dp)
|
||||||
|
.padding(16.dp),
|
||||||
|
) {
|
||||||
|
swapNetworks.fastForEachIndexed { index, network ->
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
.roundedShapeItemDecoration(
|
||||||
|
currentIndex = index,
|
||||||
|
lastIndex = swapNetworks.lastIndex,
|
||||||
|
addDefaultPadding = false,
|
||||||
|
)
|
||||||
.clickable(
|
.clickable(
|
||||||
interactionSource = remember { MutableInteractionSource() },
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
indication = ripple(),
|
indication = ripple(),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue