Updated on 2026-08-14

This commit is contained in:
Tangem 2023-11-21 11:05:15 +03:00
commit 6e20ef6027
57 changed files with 360 additions and 864 deletions

View file

@ -23,12 +23,15 @@ dependencies {
/** Project - Utils */
implementation(projects.core.utils)
/** AndroidX */
implementation(deps.androidx.datastore)
/** DI */
implementation(deps.hilt.core)
kapt(deps.hilt.kapt)
/** Other */
implementation(deps.jodatime)
implementation(deps.kotlin.coroutines)
implementation(deps.timber)
implementation(deps.jodatime)
}

View file

@ -6,12 +6,16 @@ import com.tangem.data.common.cache.CacheRegistry
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.api.tangemTech.models.CurrenciesResponse
import com.tangem.datasource.local.appcurrency.AvailableAppCurrenciesStore
import com.tangem.datasource.local.appcurrency.SelectedAppCurrencyStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.preferences.PreferencesKeys
import com.tangem.datasource.local.preferences.utils.getObject
import com.tangem.datasource.local.preferences.utils.storeObject
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -19,23 +23,25 @@ import org.joda.time.Duration
internal class DefaultAppCurrencyRepository(
private val tangemTechApi: TangemTechApi,
private val appPreferencesStore: AppPreferencesStore,
private val availableAppCurrenciesStore: AvailableAppCurrenciesStore,
private val selectedAppCurrencyStore: SelectedAppCurrencyStore,
private val cacheRegistry: CacheRegistry,
private val dispatchers: CoroutineDispatcherProvider,
) : AppCurrencyRepository {
private val appCurrencyConverter = AppCurrencyConverter()
override fun getSelectedAppCurrency(): Flow<AppCurrency> = channelFlow {
launch(dispatchers.io) {
selectedAppCurrencyStore.get()
.map(appCurrencyConverter::convert)
.collect(::send)
}
override fun getSelectedAppCurrency(): Flow<AppCurrency> {
return channelFlow {
launch {
appPreferencesStore
.getObject<CurrenciesResponse.Currency>(key = PreferencesKeys.SELECTED_APP_CURRENCY_KEY)
.filterNotNull()
.map(appCurrencyConverter::convert)
.collect(::send)
}
withContext(dispatchers.io) {
if (selectedAppCurrencyStore.isEmpty()) {
withContext(dispatchers.io) {
fetchDefaultAppCurrency()
}
}
@ -61,7 +67,10 @@ internal class DefaultAppCurrencyRepository(
"Unable to find app currency with provided code: $currencyCode"
}
selectedAppCurrencyStore.store(currency)
appPreferencesStore.storeObject(
key = PreferencesKeys.SELECTED_APP_CURRENCY_KEY,
value = currency,
)
}
}

View file

@ -4,7 +4,7 @@ import com.tangem.data.appcurrency.DefaultAppCurrencyRepository
import com.tangem.data.common.cache.CacheRegistry
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.local.appcurrency.AvailableAppCurrenciesStore
import com.tangem.datasource.local.appcurrency.SelectedAppCurrencyStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
@ -21,17 +21,17 @@ internal object AppCurrencyDataModule {
@Singleton
fun provideAppCurrencyRepository(
tangemTechApi: TangemTechApi,
appPreferencesStore: AppPreferencesStore,
availableAppCurrenciesStore: AvailableAppCurrenciesStore,
selectedAppCurrencyStore: SelectedAppCurrencyStore,
cacheRegistry: CacheRegistry,
dispatchers: CoroutineDispatcherProvider,
): AppCurrencyRepository {
return DefaultAppCurrencyRepository(
tangemTechApi,
availableAppCurrenciesStore,
selectedAppCurrencyStore,
cacheRegistry,
dispatchers,
tangemTechApi = tangemTechApi,
appPreferencesStore = appPreferencesStore,
availableAppCurrenciesStore = availableAppCurrenciesStore,
cacheRegistry = cacheRegistry,
dispatchers = dispatchers,
)
}
}

View file

@ -27,4 +27,7 @@ dependencies {
/** Other */
implementation(deps.kotlin.coroutines)
/** Local storages */
implementation(deps.androidx.datastore)
}

View file

@ -1,35 +1,25 @@
package com.tangem.data.apptheme
import com.tangem.datasource.local.apptheme.AppThemeModeStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.preferences.PreferencesKeys
import com.tangem.datasource.local.preferences.utils.getObject
import com.tangem.datasource.local.preferences.utils.storeObject
import com.tangem.domain.apptheme.model.AppThemeMode
import com.tangem.domain.apptheme.repository.AppThemeModeRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.flow.Flow
internal class DefaultAppThemeModeRepository(
private val appThemeModeStore: AppThemeModeStore,
private val dispatchers: CoroutineDispatcherProvider,
private val appPreferencesStore: AppPreferencesStore,
) : AppThemeModeRepository {
override fun getAppThemeMode(): Flow<AppThemeMode> {
return channelFlow {
launch(dispatchers.io) {
if (appThemeModeStore.isEmpty()) {
appThemeModeStore.store(AppThemeMode.DEFAULT)
}
}
launch(dispatchers.io) {
appThemeModeStore.get().collect(::send)
}
}
return appPreferencesStore.getObject(
key = PreferencesKeys.APP_THEME_MODE_KEY,
default = AppThemeMode.DEFAULT,
)
}
override suspend fun changeAppThemeMode(mode: AppThemeMode) {
withContext(dispatchers.io) {
appThemeModeStore.store(mode)
}
appPreferencesStore.storeObject(key = PreferencesKeys.APP_THEME_MODE_KEY, value = mode)
}
}

View file

@ -1,9 +1,8 @@
package com.tangem.data.apptheme.di
import com.tangem.data.apptheme.DefaultAppThemeModeRepository
import com.tangem.datasource.local.apptheme.AppThemeModeStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.domain.apptheme.repository.AppThemeModeRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@ -16,10 +15,7 @@ internal object AppThemeModeDataModule {
@Provides
@Singleton
fun provideAppThemeModeRepository(
appThemeModeStore: AppThemeModeStore,
dispatchers: CoroutineDispatcherProvider,
): AppThemeModeRepository {
return DefaultAppThemeModeRepository(appThemeModeStore, dispatchers)
fun provideAppThemeModeRepository(appPreferencesStore: AppPreferencesStore): AppThemeModeRepository {
return DefaultAppThemeModeRepository(appPreferencesStore = appPreferencesStore)
}
}

View file

@ -11,10 +11,10 @@ android {
}
dependencies {
implementation(deps.androidx.datastore)
/** DI */
implementation(deps.hilt.android)
kapt(deps.hilt.kapt)
implementation(deps.kotlin.coroutines)

View file

@ -1,36 +1,41 @@
package com.tangem.data.balancehiding
import com.tangem.datasource.local.appcurrency.BalanceHidingSettingsStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.preferences.PreferencesKeys
import com.tangem.datasource.local.preferences.utils.getObject
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrDefault
import com.tangem.datasource.local.preferences.utils.storeObject
import com.tangem.domain.balancehiding.BalanceHidingSettings
import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.withContext
internal class DefaultBalanceHidingRepository(
private val balanceHidingSettingsStore: BalanceHidingSettingsStore,
private val dispatchers: CoroutineDispatcherProvider,
private val appPreferencesStore: AppPreferencesStore,
) : BalanceHidingRepository {
override fun getBalanceHidingSettingsFlow(): Flow<BalanceHidingSettings> {
return balanceHidingSettingsStore.get()
.onStart { emit(getBalanceHidingSettings()) }
.flowOn(dispatchers.io)
.distinctUntilChanged()
return appPreferencesStore.getObject(
key = PreferencesKeys.BALANCE_HIDING_SETTINGS_KEY,
default = DEFAULT_HIDING_SETTINGS,
)
}
override suspend fun storeBalanceHidingSettings(balanceHidingSettings: BalanceHidingSettings) {
withContext(dispatchers.io) {
balanceHidingSettingsStore.store(balanceHidingSettings)
}
override suspend fun storeBalanceHidingSettings(isBalanceHidden: BalanceHidingSettings) {
appPreferencesStore.storeObject(key = PreferencesKeys.BALANCE_HIDING_SETTINGS_KEY, value = isBalanceHidden)
}
override suspend fun getBalanceHidingSettings(): BalanceHidingSettings {
return withContext(dispatchers.io) {
balanceHidingSettingsStore.getSyncOrDefault()
}
return appPreferencesStore.getObjectSyncOrDefault(
key = PreferencesKeys.BALANCE_HIDING_SETTINGS_KEY,
default = DEFAULT_HIDING_SETTINGS,
)
}
private companion object {
val DEFAULT_HIDING_SETTINGS = BalanceHidingSettings(
isHidingEnabledInSettings = false,
isBalanceHidden = false,
isBalanceHidingNotificationEnabled = true,
)
}
}

View file

@ -3,16 +3,15 @@ package com.tangem.data.balancehiding.di
import android.content.Context
import com.tangem.data.balancehiding.DefaultBalanceHidingRepository
import com.tangem.data.balancehiding.DefaultDeviceFlipDetector
import com.tangem.datasource.local.appcurrency.BalanceHidingSettingsStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.domain.balancehiding.DeviceFlipDetector
import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
import dagger.hilt.android.qualifiers.ApplicationContext
@Module
@InstallIn(SingletonComponent::class)
@ -20,14 +19,8 @@ internal object BalanceHidingModule {
@Provides
@Singleton
fun provideBalanceHidingRepository(
balanceHidingSettingsStore: BalanceHidingSettingsStore,
dispatchers: CoroutineDispatcherProvider,
): BalanceHidingRepository {
return DefaultBalanceHidingRepository(
balanceHidingSettingsStore = balanceHidingSettingsStore,
dispatchers = dispatchers,
)
fun provideBalanceHidingRepository(appPreferencesStore: AppPreferencesStore): BalanceHidingRepository {
return DefaultBalanceHidingRepository(appPreferencesStore = appPreferencesStore)
}
@Provides

View file

@ -11,6 +11,8 @@ android {
}
dependencies {
implementation(deps.androidx.datastore)
implementation(deps.hilt.android)
kapt(deps.hilt.kapt)

View file

@ -1,43 +1,37 @@
package com.tangem.data.card
import com.tangem.datasource.local.card.UsedCardInfo
import com.tangem.datasource.local.card.UsedCardsStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.preferences.PreferencesKeys
import com.tangem.datasource.local.preferences.utils.getObject
import com.tangem.domain.card.repository.CardRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.extensions.addOrReplace
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.flow.map
internal class DefaultCardRepository(
private val usedCardsStore: UsedCardsStore,
private val dispatchers: CoroutineDispatcherProvider,
private val appPreferencesStore: AppPreferencesStore,
) : CardRepository {
override fun wasCardScanned(cardId: String): Flow<Boolean> {
return channelFlow {
launch(dispatchers.io) {
usedCardsStore.get()
.collect { savedCards ->
send(element = savedCards.any { it.cardId == cardId })
}
return appPreferencesStore.getObject<List<UsedCardInfo>>(key = PreferencesKeys.USED_CARDS_INFO_KEY)
.map { savedCards ->
savedCards?.any { it.cardId == cardId } ?: false
}
withContext(dispatchers.io) {
if (usedCardsStore.getSyncOrNull() == null) {
send(element = false)
}
}
}
}
override suspend fun setCardWasScanned(cardId: String) {
withContext(dispatchers.io) {
usedCardsStore.store(
item = usedCardsStore.getSyncOrNull()
?.updateCard(cardId)
?: listOf(UsedCardInfo(cardId = cardId, isScanned = true)),
appPreferencesStore.editData { mutablePreferences ->
val usedCards: List<UsedCardInfo>? = mutablePreferences.getObject(
key = PreferencesKeys.USED_CARDS_INFO_KEY,
)
val updatedUsedCards = usedCards?.updateCard(cardId)
?: listOf(UsedCardInfo(cardId = cardId, isScanned = true))
mutablePreferences.setObject(
key = PreferencesKeys.USED_CARDS_INFO_KEY,
value = updatedUsedCards,
)
}
}

View file

@ -4,10 +4,9 @@ import com.tangem.data.card.DefaultCardRepository
import com.tangem.data.card.DefaultCardSdkConfigRepository
import com.tangem.data.card.sdk.CardSdkProvider
import com.tangem.data.source.preferences.PreferencesDataSource
import com.tangem.datasource.local.card.UsedCardsStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.domain.card.repository.CardRepository
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@ -32,10 +31,7 @@ internal object CardDataModule {
@Provides
@Singleton
fun provideCardRepository(
usedCardsStore: UsedCardsStore,
dispatchers: CoroutineDispatcherProvider,
): CardRepository {
return DefaultCardRepository(usedCardsStore = usedCardsStore, dispatchers = dispatchers)
fun provideCardRepository(appPreferencesStore: AppPreferencesStore): CardRepository {
return DefaultCardRepository(appPreferencesStore = appPreferencesStore)
}
}

View file

@ -12,18 +12,19 @@ android {
dependencies {
implementation(projects.core.datasource)
implementation(projects.core.utils)
implementation(projects.data.source.preferences)
implementation(projects.domain.balanceHiding.models)
implementation(projects.domain.settings)
implementation(deps.androidx.datastore)
/** DI */
implementation(deps.hilt.android)
kapt(deps.hilt.kapt)
implementation(deps.kotlin.coroutines)
implementation(projects.core.utils)
implementation(projects.core.datasource)
implementation(projects.domain.settings)
implementation(projects.domain.balanceHiding.models)
implementation(projects.data.source.preferences)
}

View file

@ -1,68 +1,42 @@
package com.tangem.data.settings
import com.tangem.datasource.local.settings.AppLaunchCountStore
import com.tangem.datasource.local.settings.AppRatingShowingCountStore
import com.tangem.datasource.local.settings.FundsFoundDateInMillisStore
import com.tangem.datasource.local.settings.UserInteractingStatusStore
import androidx.datastore.preferences.core.MutablePreferences
import androidx.datastore.preferences.core.edit
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.preferences.PreferencesKeys
import com.tangem.datasource.local.preferences.utils.get
import com.tangem.domain.settings.repositories.AppRatingRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.withContext
import java.util.Calendar
internal class DefaultAppRatingRepository(
private val fundsFoundDateInMillisStore: FundsFoundDateInMillisStore,
private val appLaunchCountStore: AppLaunchCountStore,
private val appRatingShowingCountStore: AppRatingShowingCountStore,
private val userInteractingStatusStore: UserInteractingStatusStore,
private val dispatchers: CoroutineDispatcherProvider,
private val appPreferencesStore: AppPreferencesStore,
) : AppRatingRepository {
override suspend fun initialize() {
fundsFoundDateInMillisStore.getSyncOrNull()
?: fundsFoundDateInMillisStore.store(item = FUNDS_FOUND_DATE_UNDEFINED)
appLaunchCountStore.getSyncOrNull()
?: appLaunchCountStore.store(item = DEFAULT_APP_LAUNCH_COUNT)
appRatingShowingCountStore.getSyncOrNull()
?: appRatingShowingCountStore.store(item = FIRST_SHOWING_COUNT)
userInteractingStatusStore.getSyncOrNull()
?: userInteractingStatusStore.store(item = false)
}
override suspend fun setWalletWithFundsFound() {
withContext(dispatchers.io) {
val foundDate = fundsFoundDateInMillisStore.getSyncOrNull()
if (foundDate != null && foundDate != FUNDS_FOUND_DATE_UNDEFINED) return@withContext
appPreferencesStore.edit { mutablePreferences ->
val foundDate = mutablePreferences[PreferencesKeys.FUNDS_FOUND_DATE_KEY]
if (foundDate != null && foundDate != FUNDS_FOUND_DATE_UNDEFINED) return@edit
fundsFoundDateInMillisStore.store(item = Calendar.getInstance().timeInMillis)
mutablePreferences[PreferencesKeys.FUNDS_FOUND_DATE_KEY] = Calendar.getInstance().timeInMillis
val appLaunchCount = appLaunchCountStore.getSyncOrNull().let { count ->
if (count == null) {
appLaunchCountStore.store(item = DEFAULT_APP_LAUNCH_COUNT)
DEFAULT_APP_LAUNCH_COUNT
} else {
count
}
}
appRatingShowingCountStore.store(item = appLaunchCount + FIRST_SHOWING_COUNT)
userInteractingStatusStore.getSyncOrNull()
?: userInteractingStatusStore.store(item = false)
val appLaunchCount = mutablePreferences[PreferencesKeys.APP_LAUNCH_COUNT_KEY] ?: DEFAULT_APP_LAUNCH_COUNT
mutablePreferences[PreferencesKeys.SHOW_RATING_DIALOG_AT_LAUNCH_COUNT_KEY] =
appLaunchCount + FIRST_SHOWING_COUNT
}
}
override fun isReadyToShow(): Flow<Boolean> {
// TODO: [REDACTED_JIRA]
return combine(
userInteractingStatusStore.get(),
appRatingShowingCountStore.get(),
appLaunchCountStore.get(),
fundsFoundDateInMillisStore.get(),
appPreferencesStore.get(key = PreferencesKeys.USER_WAS_INTERACT_WITH_RATING_KEY, default = false),
appPreferencesStore.get(
key = PreferencesKeys.SHOW_RATING_DIALOG_AT_LAUNCH_COUNT_KEY,
default = FIRST_SHOWING_COUNT,
),
appPreferencesStore.get(key = PreferencesKeys.APP_LAUNCH_COUNT_KEY, default = DEFAULT_APP_LAUNCH_COUNT),
appPreferencesStore.get(key = PreferencesKeys.FUNDS_FOUND_DATE_KEY, default = FUNDS_FOUND_DATE_UNDEFINED),
) { isInteracting, ratingShowingCount, appLaunchCount, fundsFoundDate ->
if (!isInteracting) {
val diff = Calendar.getInstance().timeInMillis - fundsFoundDate
@ -77,20 +51,22 @@ internal class DefaultAppRatingRepository(
}
override suspend fun remindLater() {
appLaunchCountStore.getSyncOrNull()?.let {
updateNextShowing(at = it + DEFER_SHOWING_COUNT)
appPreferencesStore.edit { mutablePreferences ->
mutablePreferences[PreferencesKeys.APP_LAUNCH_COUNT_KEY]?.let {
mutablePreferences.updateNextShowing(it + DEFER_SHOWING_COUNT)
}
}
}
override suspend fun setNeverToShow() {
updateNextShowing(at = Int.MAX_VALUE)
appPreferencesStore.edit { mutablePreferences ->
mutablePreferences.updateNextShowing(at = Int.MAX_VALUE)
}
}
private suspend fun updateNextShowing(at: Int) {
withContext(dispatchers.io) {
appRatingShowingCountStore.store(item = at)
userInteractingStatusStore.store(item = true)
}
private fun MutablePreferences.updateNextShowing(at: Int) {
this[PreferencesKeys.SHOW_RATING_DIALOG_AT_LAUNCH_COUNT_KEY] = at
this[PreferencesKeys.USER_WAS_INTERACT_WITH_RATING_KEY] = true
}
private companion object {

View file

@ -3,10 +3,7 @@ package com.tangem.data.settings.di
import com.tangem.data.settings.DefaultAppRatingRepository
import com.tangem.data.settings.DefaultSettingsRepository
import com.tangem.data.source.preferences.PreferencesDataSource
import com.tangem.datasource.local.settings.AppLaunchCountStore
import com.tangem.datasource.local.settings.AppRatingShowingCountStore
import com.tangem.datasource.local.settings.FundsFoundDateInMillisStore
import com.tangem.datasource.local.settings.UserInteractingStatusStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.domain.settings.repositories.AppRatingRepository
import com.tangem.domain.settings.repositories.SettingsRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
@ -34,19 +31,7 @@ internal object SettingsDataModule {
@Provides
@Singleton
fun provideAppRatingRepository(
fundsFoundDateInMillisStore: FundsFoundDateInMillisStore,
appLaunchCountStore: AppLaunchCountStore,
appRatingShowingCountStore: AppRatingShowingCountStore,
userInteractingStatusStore: UserInteractingStatusStore,
dispatchers: CoroutineDispatcherProvider,
): AppRatingRepository {
return DefaultAppRatingRepository(
fundsFoundDateInMillisStore = fundsFoundDateInMillisStore,
appLaunchCountStore = appLaunchCountStore,
appRatingShowingCountStore = appRatingShowingCountStore,
userInteractingStatusStore = userInteractingStatusStore,
dispatchers = dispatchers,
)
fun provideAppRatingRepository(appPreferencesStore: AppPreferencesStore): AppRatingRepository {
return DefaultAppRatingRepository(appPreferencesStore = appPreferencesStore)
}
}

View file

@ -32,6 +32,9 @@ dependencies {
implementation(deps.tangem.blockchain)
implementation(deps.tangem.card.core)
/** AndroidX */
implementation(deps.androidx.datastore)
/** DI */
implementation(deps.hilt.core)
kapt(deps.hilt.kapt)

View file

@ -7,8 +7,8 @@ import com.tangem.data.tokens.repository.DefaultNetworksRepository
import com.tangem.data.tokens.repository.DefaultQuotesRepository
import com.tangem.datasource.api.express.TangemExpressApi
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.local.appcurrency.SelectedAppCurrencyStore
import com.tangem.datasource.local.network.NetworksStatusesStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.quote.QuotesStore
import com.tangem.datasource.local.token.AssetsStore
import com.tangem.datasource.local.token.UserTokensStore
@ -55,15 +55,15 @@ internal object TokensDataModule {
@Singleton
fun provideQuotesRepository(
tangemTechApi: TangemTechApi,
appPreferencesStore: AppPreferencesStore,
quotesStore: QuotesStore,
selectedAppCurrencyStore: SelectedAppCurrencyStore,
cacheRegistry: CacheRegistry,
dispatchers: CoroutineDispatcherProvider,
): QuotesRepository {
return DefaultQuotesRepository(
tangemTechApi = tangemTechApi,
appPreferencesStore = appPreferencesStore,
quotesStore = quotesStore,
selectedAppCurrencyStore = selectedAppCurrencyStore,
cacheRegistry = cacheRegistry,
dispatchers = dispatchers,
)

View file

@ -5,7 +5,12 @@ import com.tangem.data.common.cache.CacheRegistry
import com.tangem.data.tokens.utils.QuotesConverter
import com.tangem.data.tokens.utils.QuotesUnsupportedCurrenciesIdAdapter
import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.local.appcurrency.SelectedAppCurrencyStore
import com.tangem.datasource.api.tangemTech.models.CurrenciesResponse
import com.tangem.datasource.local.*
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.preferences.PreferencesKeys
import com.tangem.datasource.local.preferences.utils.getObject
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
import com.tangem.datasource.local.quote.QuotesStore
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.Quote
@ -17,8 +22,8 @@ import kotlinx.coroutines.withContext
internal class DefaultQuotesRepository(
private val tangemTechApi: TangemTechApi,
private val appPreferencesStore: AppPreferencesStore,
private val quotesStore: QuotesStore,
private val selectedAppCurrencyStore: SelectedAppCurrencyStore,
private val cacheRegistry: CacheRegistry,
private val dispatchers: CoroutineDispatcherProvider,
) : QuotesRepository {
@ -31,8 +36,11 @@ internal class DefaultQuotesRepository(
@OptIn(ExperimentalCoroutinesApi::class)
override fun getQuotesUpdates(currenciesIds: Set<CryptoCurrency.ID>): Flow<Set<Quote>> {
return selectedAppCurrencyStore.get()
return appPreferencesStore.getObject<CurrenciesResponse.Currency>(
key = PreferencesKeys.SELECTED_APP_CURRENCY_KEY,
)
.distinctUntilChanged()
.filterNotNull()
.flatMapLatest { appCurrency ->
fetchExpiredQuotes(currenciesIds, appCurrency.id, refresh = false)
@ -44,13 +52,16 @@ internal class DefaultQuotesRepository(
override suspend fun getQuotesSync(currenciesIds: Set<CryptoCurrency.ID>, refresh: Boolean): Set<Quote> {
return withContext(dispatchers.io) {
val selectedAppCurrency = requireNotNull(selectedAppCurrencyStore.getSyncOrNull()) {
"Unable to get selected application currency to update quotes"
}
val selectedAppCurrency = requireNotNull(
value = appPreferencesStore.getObjectSyncOrNull<CurrenciesResponse.Currency>(
key = PreferencesKeys.SELECTED_APP_CURRENCY_KEY,
),
lazyMessage = { "Unable to get selected application currency to update quotes" },
)
fetchExpiredQuotes(currenciesIds, selectedAppCurrency.id, refresh)
val quotes = quotesStore.get(currenciesIds).first()
val quotes = quotesStore.getSync(currenciesIds)
quotesConverter.convertSet(quotes)
}

View file

@ -13,10 +13,12 @@ android {
dependencies {
implementation(projects.core.datasource)
implementation(projects.core.utils)
implementation(projects.data.source.preferences)
implementation(projects.domain.wallets)
/** DI */
implementation(deps.hilt.android)
kapt(deps.hilt.kapt)
/** Local storages */
implementation(deps.androidx.datastore)
}

View file

@ -1,29 +1,26 @@
package com.tangem.data.wallets
import com.tangem.datasource.local.userwallet.ShouldSaveUserWalletStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.preferences.PreferencesKeys
import com.tangem.datasource.local.preferences.utils.get
import com.tangem.datasource.local.preferences.utils.getSyncOrDefault
import com.tangem.datasource.local.preferences.utils.store
import com.tangem.domain.wallets.repository.WalletsRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.withContext
internal class DefaultWalletsRepository(
private val shouldSaveUserWalletStore: ShouldSaveUserWalletStore,
private val dispatchers: CoroutineDispatcherProvider,
private val appPreferencesStore: AppPreferencesStore,
) : WalletsRepository {
override suspend fun initialize() {
withContext(dispatchers.io) {
shouldSaveUserWalletStore.getSyncOrNull() ?: shouldSaveUserWalletStore.store(item = false)
}
}
override suspend fun shouldSaveUserWalletsSync(): Boolean {
return withContext(dispatchers.io) { shouldSaveUserWalletStore.getSyncOrNull() ?: false }
return appPreferencesStore.getSyncOrDefault(key = PreferencesKeys.SAVE_USER_WALLETS_KEY, default = false)
}
override fun shouldSaveUserWallets(): Flow<Boolean> = shouldSaveUserWalletStore.get()
override fun shouldSaveUserWallets(): Flow<Boolean> {
return appPreferencesStore.get(key = PreferencesKeys.SAVE_USER_WALLETS_KEY, default = false)
}
override suspend fun saveShouldSaveUserWallets(item: Boolean) {
withContext(dispatchers.io) { shouldSaveUserWalletStore.store(item = item) }
appPreferencesStore.store(key = PreferencesKeys.SAVE_USER_WALLETS_KEY, value = item)
}
}

View file

@ -1,9 +1,8 @@
package com.tangem.data.wallets.di
import com.tangem.data.wallets.DefaultWalletsRepository
import com.tangem.datasource.local.userwallet.ShouldSaveUserWalletStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.domain.wallets.repository.WalletsRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@ -12,17 +11,11 @@ import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object WalletsDataModule {
internal object WalletsDataModule {
@Provides
@Singleton
fun providesWalletsRepository(
shouldSaveUserWalletStore: ShouldSaveUserWalletStore,
coroutineDispatcherProvider: CoroutineDispatcherProvider,
): WalletsRepository {
return DefaultWalletsRepository(
shouldSaveUserWalletStore = shouldSaveUserWalletStore,
dispatchers = coroutineDispatcherProvider,
)
fun providesWalletsRepository(appPreferencesStore: AppPreferencesStore): WalletsRepository {
return DefaultWalletsRepository(appPreferencesStore = appPreferencesStore)
}
}