Updated on 2026-08-14
This commit is contained in:
commit
d4bafed03c
7 changed files with 73 additions and 41 deletions
|
|
@ -83,9 +83,7 @@ internal class DefaultOnrampRepository(
|
|||
private val onrampErrorAdapter = moshi.adapter(ExpressErrorResponse::class.java)
|
||||
private val onrampErrorConverter = OnrampErrorConverter(onrampErrorAdapter)
|
||||
|
||||
override suspend fun getCurrencies(): Flow<List<OnrampCurrency>> = withContext(dispatchers.io) {
|
||||
currenciesStore.get(CURRENCIES_KEY)
|
||||
}
|
||||
override fun getCurrencies(): Flow<List<OnrampCurrency>> = currenciesStore.get(CURRENCIES_KEY)
|
||||
|
||||
override suspend fun fetchCurrencies() = withContext(dispatchers.io) {
|
||||
if (!currenciesStore.getSyncOrNull(CURRENCIES_KEY).isNullOrEmpty()) return@withContext
|
||||
|
|
@ -97,9 +95,7 @@ internal class DefaultOnrampRepository(
|
|||
currenciesStore.store(CURRENCIES_KEY, result)
|
||||
}
|
||||
|
||||
override suspend fun getCountries(): Flow<List<OnrampCountry>> = withContext(dispatchers.io) {
|
||||
countriesStore.get(COUNTRIES_KEY)
|
||||
}
|
||||
override fun getCountries(): Flow<List<OnrampCountry>> = countriesStore.get(COUNTRIES_KEY)
|
||||
|
||||
override suspend fun getCountriesSync(): List<OnrampCountry>? {
|
||||
return countriesStore.getSyncOrNull(COUNTRIES_KEY)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class GetOnrampCurrenciesUseCase(
|
|||
private val errorResolver: OnrampErrorResolver,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(): EitherFlow<OnrampError, OnrampCurrencies> {
|
||||
operator fun invoke(): EitherFlow<OnrampError, OnrampCurrencies> {
|
||||
return onrampRepository.getCurrencies().map { currenciesList ->
|
||||
Either.catch {
|
||||
val (populars, others) = currenciesList.toSet()
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ import kotlinx.coroutines.flow.Flow
|
|||
@Suppress("TooManyFunctions")
|
||||
interface OnrampRepository {
|
||||
// api
|
||||
suspend fun getCurrencies(): Flow<List<OnrampCurrency>>
|
||||
suspend fun getCountries(): Flow<List<OnrampCountry>>
|
||||
fun getCurrencies(): Flow<List<OnrampCurrency>>
|
||||
fun getCountries(): Flow<List<OnrampCountry>>
|
||||
suspend fun getCountriesSync(): List<OnrampCountry>?
|
||||
suspend fun getCountryByIp(): OnrampCountry
|
||||
suspend fun getStatus(txId: String): OnrampStatus
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.features.onramp.selectcountry.entity.transformer
|
||||
|
||||
import com.tangem.features.onramp.selectcountry.entity.CountryListUM
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
||||
internal class UpdateCountryItemsErrorTransformer(
|
||||
private val onRetry: () -> Unit,
|
||||
) : Transformer<CountryListUM> {
|
||||
override fun transform(prevState: CountryListUM): CountryListUM {
|
||||
return CountryListUM.Error(
|
||||
searchBarUM = prevState.searchBarUM,
|
||||
onRetry = onRetry,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ import com.tangem.features.onramp.selectcountry.SelectCountryComponent
|
|||
import com.tangem.features.onramp.selectcountry.entity.CountryItemState
|
||||
import com.tangem.features.onramp.selectcountry.entity.CountryListUM
|
||||
import com.tangem.features.onramp.selectcountry.entity.CountryListUMController
|
||||
import com.tangem.features.onramp.selectcountry.entity.transformer.UpdateCountryItemsErrorTransformer
|
||||
import com.tangem.features.onramp.selectcountry.entity.transformer.UpdateCountryItemsLoadingTransformer
|
||||
import com.tangem.features.onramp.selectcountry.entity.transformer.UpdateCountryItemsTransformer
|
||||
import com.tangem.features.onramp.utils.InputManager
|
||||
|
|
@ -26,8 +27,10 @@ import com.tangem.features.onramp.utils.sendOnrampErrorEvent
|
|||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -44,13 +47,12 @@ internal class OnrampSelectCountryModel @Inject constructor(
|
|||
paramsContainer: ParamsContainer,
|
||||
) : Model() {
|
||||
|
||||
val state: StateFlow<CountryListUM> get() = countryListUMController.state
|
||||
val state: StateFlow<CountryListUM> get() = controller.state
|
||||
private val params: SelectCountryComponent.Params = paramsContainer.require()
|
||||
private val countryListUMController = CountryListUMController(
|
||||
private val controller = CountryListUMController(
|
||||
searchBarUM = createSearchBarUM(),
|
||||
loadingItems = loadingItems,
|
||||
)
|
||||
private val refreshTrigger = MutableSharedFlow<Unit>()
|
||||
|
||||
init {
|
||||
analyticsEventHandler.send(OnrampAnalyticsEvent.SelectResidenceOpened)
|
||||
|
|
@ -58,20 +60,13 @@ internal class OnrampSelectCountryModel @Inject constructor(
|
|||
modelScope.launch { subscribeOnUpdateState() }
|
||||
}
|
||||
|
||||
private fun updateCountriesList() {
|
||||
modelScope.launch {
|
||||
fetchOnrampCountriesUseCase()
|
||||
}
|
||||
}
|
||||
|
||||
fun dismiss() {
|
||||
params.onDismiss()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
private suspend fun subscribeOnUpdateState() {
|
||||
combine(
|
||||
flow = refreshTrigger.onStart { emit(Unit) }.flatMapLatest { getOnrampCountriesUseCase() },
|
||||
flow = getOnrampCountriesUseCase(),
|
||||
flow2 = getOnrampCountryUseCase(),
|
||||
flow3 = searchManager.query,
|
||||
) { maybeCountries, maybeCountry, query ->
|
||||
|
|
@ -89,7 +84,7 @@ internal class OnrampSelectCountryModel @Inject constructor(
|
|||
onCountryClick = ::saveCountry,
|
||||
)
|
||||
}
|
||||
.onEach(countryListUMController::update)
|
||||
.onEach(controller::update)
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
|
|
@ -102,23 +97,31 @@ internal class OnrampSelectCountryModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun onRetry() {
|
||||
modelScope.launch { refreshTrigger.emit(Unit) }
|
||||
countryListUMController.update(UpdateCountryItemsLoadingTransformer(loadingItems))
|
||||
controller.update(UpdateCountryItemsLoadingTransformer(loadingItems))
|
||||
updateCountriesList()
|
||||
}
|
||||
|
||||
private fun updateCountriesList() {
|
||||
modelScope.launch {
|
||||
fetchOnrampCountriesUseCase().onLeft {
|
||||
controller.update(UpdateCountryItemsErrorTransformer(onRetry = ::onRetry))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onSearchQueryChange(newQuery: String) {
|
||||
val searchBarUM = countryListUMController.state.value.searchBarUM
|
||||
val searchBarUM = controller.state.value.searchBarUM
|
||||
if (searchBarUM.query == newQuery) return
|
||||
|
||||
modelScope.launch {
|
||||
countryListUMController.update(transformer = UpdateSearchQueryTransformer(newQuery))
|
||||
controller.update(transformer = UpdateSearchQueryTransformer(newQuery))
|
||||
|
||||
searchManager.update(newQuery)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onSearchBarActiveChange(isActive: Boolean) {
|
||||
countryListUMController.update(
|
||||
controller.update(
|
||||
transformer = UpdateSearchBarActiveStateTransformer(
|
||||
isActive = isActive,
|
||||
placeHolder = resourceReference(id = R.string.common_search),
|
||||
|
|
@ -137,7 +140,7 @@ internal class OnrampSelectCountryModel @Inject constructor(
|
|||
}
|
||||
|
||||
private companion object {
|
||||
private const val LOADING_ITEMS_COUNT = 5
|
||||
const val LOADING_ITEMS_COUNT = 5
|
||||
val loadingItems: ImmutableList<CountryItemState.Loading> = MutableList(LOADING_ITEMS_COUNT) {
|
||||
CountryItemState.Loading("Loading #$it")
|
||||
}.toImmutableList()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.features.onramp.selectcurrency.entity.transformer
|
||||
|
||||
import com.tangem.features.onramp.selectcurrency.entity.CurrenciesListUM
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
||||
internal class UpdateCurrencyItemsErrorTransformer(
|
||||
private val onRetry: () -> Unit,
|
||||
) : Transformer<CurrenciesListUM> {
|
||||
override fun transform(prevState: CurrenciesListUM): CurrenciesListUM {
|
||||
return CurrenciesListUM.Error(
|
||||
searchBarUM = prevState.searchBarUM,
|
||||
onRetry = onRetry,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ import com.tangem.features.onramp.selectcurrency.entity.CurrenciesListUM
|
|||
import com.tangem.features.onramp.selectcurrency.entity.CurrenciesSection
|
||||
import com.tangem.features.onramp.selectcurrency.entity.CurrencyItemState
|
||||
import com.tangem.features.onramp.selectcurrency.entity.CurrencyListController
|
||||
import com.tangem.features.onramp.selectcurrency.entity.transformer.UpdateCurrencyItemsErrorTransformer
|
||||
import com.tangem.features.onramp.selectcurrency.entity.transformer.UpdateCurrencyItemsLoadingTransformer
|
||||
import com.tangem.features.onramp.selectcurrency.entity.transformer.UpdateCurrencyItemsTransformer
|
||||
import com.tangem.features.onramp.utils.InputManager
|
||||
|
|
@ -27,8 +28,10 @@ import com.tangem.features.onramp.utils.sendOnrampErrorEvent
|
|||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -51,23 +54,15 @@ internal class OnrampSelectCurrencyModel @Inject constructor(
|
|||
currencySearchBarUM = createSearchBarUM(),
|
||||
loadingSections = loadingSections,
|
||||
)
|
||||
private val refreshTrigger = MutableSharedFlow<Unit>()
|
||||
|
||||
init {
|
||||
updateCurrenciesList()
|
||||
subscribeOnUpdateState()
|
||||
}
|
||||
|
||||
private fun updateCurrenciesList() {
|
||||
modelScope.launch {
|
||||
fetchOnrampCurrenciesUseCase()
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
private fun subscribeOnUpdateState() {
|
||||
combine(
|
||||
flow = refreshTrigger.onStart { emit(Unit) }.flatMapLatest { getOnrampCurrenciesUseCase() },
|
||||
flow = getOnrampCurrenciesUseCase(),
|
||||
flow2 = searchManager.query,
|
||||
) { maybeCurrencies, query ->
|
||||
maybeCurrencies.onLeft {
|
||||
|
|
@ -97,8 +92,16 @@ internal class OnrampSelectCurrencyModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun onRetry() {
|
||||
modelScope.launch { refreshTrigger.emit(Unit) }
|
||||
controller.update(UpdateCurrencyItemsLoadingTransformer(loadingSections))
|
||||
updateCurrenciesList()
|
||||
}
|
||||
|
||||
private fun updateCurrenciesList() {
|
||||
modelScope.launch {
|
||||
fetchOnrampCurrenciesUseCase().onLeft {
|
||||
controller.update(UpdateCurrencyItemsErrorTransformer(onRetry = ::onRetry))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onSearchQueryChange(newQuery: String) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue