diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index c67f289238..420a6ff091 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -30,7 +30,6 @@ import com.tangem.domain.apptheme.repository.AppThemeModeRepository import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository import com.tangem.domain.card.ScanCardProcessor import com.tangem.domain.common.LogConfig -import com.tangem.domain.settings.repositories.AppRatingRepository import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.tokens.repository.NetworksRepository import com.tangem.domain.walletmanager.WalletManagersFacade @@ -209,9 +208,6 @@ internal class TapApplication : Application(), ImageLoaderFactory { @Inject lateinit var userTokensStore: UserTokensStore - @Inject - lateinit var appRatingRepository: AppRatingRepository - @Inject lateinit var getAppThemeModeUseCase: GetAppThemeModeUseCase @@ -248,10 +244,8 @@ internal class TapApplication : Application(), ImageLoaderFactory { // TODO: Try to performance and user experience. // [REDACTED_JIRA] runBlocking { - walletsRepository.initialize() initUserWalletsListManager() featureTogglesManager.init() - appRatingRepository.initialize() // learn2earnInteractor.init() } diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/AppCurrencyDataModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/AppCurrencyDataModule.kt index e25e15471b..fade673123 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/di/AppCurrencyDataModule.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/di/AppCurrencyDataModule.kt @@ -1,18 +1,11 @@ package com.tangem.datasource.di -import android.content.Context -import com.squareup.moshi.Moshi -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.appcurrency.implementation.DefaultAvailableAppCurrenciesStore -import com.tangem.datasource.local.appcurrency.implementation.DefaultSelectedAppCurrencyStore -import com.tangem.datasource.local.datastore.JsonSharedPreferencesDataStore import com.tangem.datasource.local.datastore.RuntimeDataStore 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 @@ -23,23 +16,6 @@ internal object AppCurrencyDataModule { @Provides @Singleton fun provideAvailableAppCurrenciesStore(): AvailableAppCurrenciesStore { - return DefaultAvailableAppCurrenciesStore( - dataStore = RuntimeDataStore(), - ) - } - - @Provides - @Singleton - fun provideSelectedAppCurrencyStore( - @ApplicationContext context: Context, - @NetworkMoshi moshi: Moshi, - ): SelectedAppCurrencyStore { - return DefaultSelectedAppCurrencyStore( - dataStore = JsonSharedPreferencesDataStore( - preferencesName = "selected_app_currency", - context = context, - adapter = moshi.adapter(CurrenciesResponse.Currency::class.java), - ), - ) + return DefaultAvailableAppCurrenciesStore(dataStore = RuntimeDataStore()) } } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/AppThemeModeDataModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/AppThemeModeDataModule.kt deleted file mode 100644 index a6e8020146..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/di/AppThemeModeDataModule.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.tangem.datasource.di - -import android.content.Context -import com.squareup.moshi.Moshi -import com.tangem.datasource.local.apptheme.AppThemeModeStore -import com.tangem.datasource.local.apptheme.DefaultAppThemeModeStore -import com.tangem.datasource.local.datastore.JsonSharedPreferencesDataStore -import com.tangem.domain.apptheme.model.AppThemeMode -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.android.qualifiers.ApplicationContext -import dagger.hilt.components.SingletonComponent - -@Module -@InstallIn(SingletonComponent::class) -internal object AppThemeModeDataModule { - - @Provides - fun provideAppThemeModeStore(@ApplicationContext context: Context, @NetworkMoshi moshi: Moshi): AppThemeModeStore { - return DefaultAppThemeModeStore( - dataStore = JsonSharedPreferencesDataStore( - preferencesName = "app_theme", - context = context, - adapter = moshi.adapter(AppThemeMode::class.java), - ), - ) - } -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/CardDataModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/CardDataModule.kt deleted file mode 100644 index f06e5ac8e5..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/di/CardDataModule.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.tangem.datasource.di - -import android.content.Context -import com.squareup.moshi.Moshi -import com.squareup.moshi.Types -import com.tangem.datasource.local.card.DefaultUsedCardsStore -import com.tangem.datasource.local.card.UsedCardInfo -import com.tangem.datasource.local.card.UsedCardsStore -import com.tangem.datasource.local.datastore.JsonSharedPreferencesDataStore -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 - -@Module -@InstallIn(SingletonComponent::class) -internal object CardDataModule { - - @Provides - @Singleton - fun provideUsedCardsStore(@ApplicationContext context: Context, @NetworkMoshi moshi: Moshi): UsedCardsStore { - return DefaultUsedCardsStore( - store = JsonSharedPreferencesDataStore( - preferencesName = "tapPrefs", - context = context, - adapter = moshi.adapter( - Types.newParameterizedType(List::class.java, UsedCardInfo::class.java), - ), - ), - ) - } -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/HiddenBalanceDataModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/HiddenBalanceDataModule.kt deleted file mode 100644 index 9b59f30477..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/di/HiddenBalanceDataModule.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.tangem.datasource.di - -import android.content.Context -import com.squareup.moshi.Moshi -import com.tangem.datasource.local.appcurrency.BalanceHidingSettingsStore -import com.tangem.datasource.local.appcurrency.implementation.BalanceStateHidingSettingsStore -import com.tangem.datasource.local.datastore.JsonSharedPreferencesDataStore -import com.tangem.domain.balancehiding.BalanceHidingSettings -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.android.qualifiers.ApplicationContext -import dagger.hilt.components.SingletonComponent - -@Module -@InstallIn(SingletonComponent::class) -internal object HiddenBalanceDataModule { - - @Provides - fun provideHiddenBalanceStateStore( - @ApplicationContext context: Context, - @NetworkMoshi moshi: Moshi, - ): BalanceHidingSettingsStore { - return BalanceStateHidingSettingsStore( - dataStore = JsonSharedPreferencesDataStore( - preferencesName = "balance_hiding_settings", - context = context, - adapter = moshi.adapter(BalanceHidingSettings::class.java), - ), - ) - } -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/SettingsDataModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/SettingsDataModule.kt deleted file mode 100644 index ba757806d6..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/di/SettingsDataModule.kt +++ /dev/null @@ -1,50 +0,0 @@ -package com.tangem.datasource.di - -import android.content.Context -import com.tangem.datasource.local.datastore.BooleanSharedPreferencesDataStore -import com.tangem.datasource.local.datastore.IntSharedPreferencesDataStore -import com.tangem.datasource.local.datastore.LongSharedPreferencesDataStore -import com.tangem.datasource.local.settings.* -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 - -@Module -@InstallIn(SingletonComponent::class) -internal object SettingsDataModule { - - @Provides - @Singleton - fun provideAppLaunchCountStore(@ApplicationContext context: Context): AppLaunchCountStore { - return DefaultAppLaunchCountStore( - store = IntSharedPreferencesDataStore(preferencesName = "tapPrefs", context = context), - ) - } - - @Provides - @Singleton - fun provideAppRatingShowingCountStore(@ApplicationContext context: Context): AppRatingShowingCountStore { - return DefaultAppRatingShowingCountStore( - store = IntSharedPreferencesDataStore(preferencesName = "tapPrefs", context = context), - ) - } - - @Provides - @Singleton - fun provideFundsFoundDateInMillisStore(@ApplicationContext context: Context): FundsFoundDateInMillisStore { - return DefaultFundsFoundDateInMillisStore( - store = LongSharedPreferencesDataStore(preferencesName = "tapPrefs", context = context), - ) - } - - @Provides - @Singleton - fun provideUserInteractingStatusStore(@ApplicationContext context: Context): UserInteractingStatusStore { - return DefaultUserInteractingStatusStore( - store = BooleanSharedPreferencesDataStore(preferencesName = "tapPrefs", context = context), - ) - } -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/di/WalletsDataModule.kt b/core/datasource/src/main/java/com/tangem/datasource/di/WalletsDataModule.kt deleted file mode 100644 index 61cdcacad3..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/di/WalletsDataModule.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.tangem.datasource.di - -import android.content.Context -import com.tangem.datasource.local.datastore.BooleanSharedPreferencesDataStore -import com.tangem.datasource.local.settings.* -import com.tangem.datasource.local.userwallet.DefaultShouldSaveUserWalletStore -import com.tangem.datasource.local.userwallet.ShouldSaveUserWalletStore -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 - -@Module -@InstallIn(SingletonComponent::class) -internal object WalletsDataModule { - - @Provides - @Singleton - fun provideShouldSaveUserWalletsStore(@ApplicationContext context: Context): ShouldSaveUserWalletStore { - return DefaultShouldSaveUserWalletStore( - store = BooleanSharedPreferencesDataStore(preferencesName = "tapPrefs", context = context), - ) - } -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/AppPreferenceStorage.kt b/core/datasource/src/main/java/com/tangem/datasource/local/AppPreferenceStorage.kt index 3e30c7344b..d56ca29fa0 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/AppPreferenceStorage.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/AppPreferenceStorage.kt @@ -5,6 +5,7 @@ package com.tangem.datasource.local * [REDACTED_AUTHOR] */ +@Deprecated(message = "Use AppPreferencesStore", level = DeprecationLevel.WARNING) interface AppPreferenceStorage { /** Json config with feature toggles 'ToggleName: String - Availability: Boolean' */ diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/BalanceHidingSettingsStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/BalanceHidingSettingsStore.kt deleted file mode 100644 index a29714251b..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/BalanceHidingSettingsStore.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.tangem.datasource.local.appcurrency - -import com.tangem.domain.balancehiding.BalanceHidingSettings -import kotlinx.coroutines.flow.Flow - -interface BalanceHidingSettingsStore { - - fun get(): Flow - - suspend fun getSyncOrDefault(): BalanceHidingSettings - - suspend fun store(settings: BalanceHidingSettings) -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/SelectedAppCurrencyStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/SelectedAppCurrencyStore.kt deleted file mode 100644 index e732ce8415..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/SelectedAppCurrencyStore.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.tangem.datasource.local.appcurrency - -import com.tangem.datasource.api.tangemTech.models.CurrenciesResponse -import kotlinx.coroutines.flow.Flow - -interface SelectedAppCurrencyStore { - - fun get(): Flow - - suspend fun getSyncOrNull(): CurrenciesResponse.Currency? - - suspend fun store(item: CurrenciesResponse.Currency) - - suspend fun isEmpty(): Boolean -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/implementation/BalanceStateHidingSettingsStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/implementation/BalanceStateHidingSettingsStore.kt deleted file mode 100644 index 0314d6549d..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/implementation/BalanceStateHidingSettingsStore.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.tangem.datasource.local.appcurrency.implementation - -import com.tangem.datasource.local.appcurrency.BalanceHidingSettingsStore -import com.tangem.datasource.local.datastore.core.KeylessDataStoreDecorator -import com.tangem.datasource.local.datastore.core.StringKeyDataStore -import com.tangem.domain.balancehiding.BalanceHidingSettings - -internal class BalanceStateHidingSettingsStore( - dataStore: StringKeyDataStore, -) : BalanceHidingSettingsStore, KeylessDataStoreDecorator(dataStore) { - - override suspend fun getSyncOrDefault(): BalanceHidingSettings { - return getSyncOrNull() ?: BalanceHidingSettings( - isHidingEnabledInSettings = false, - isBalanceHidden = false, - isBalanceHidingNotificationEnabled = true, - ) - } -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/implementation/DefaultSelectedAppCurrencyStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/implementation/DefaultSelectedAppCurrencyStore.kt deleted file mode 100644 index c79bf3045b..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/implementation/DefaultSelectedAppCurrencyStore.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.tangem.datasource.local.appcurrency.implementation - -import com.tangem.datasource.api.tangemTech.models.CurrenciesResponse -import com.tangem.datasource.local.appcurrency.SelectedAppCurrencyStore -import com.tangem.datasource.local.datastore.core.KeylessDataStoreDecorator -import com.tangem.datasource.local.datastore.core.StringKeyDataStore - -internal class DefaultSelectedAppCurrencyStore( - dataStore: StringKeyDataStore, -) : SelectedAppCurrencyStore, KeylessDataStoreDecorator(dataStore) \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/apptheme/AppThemeModeStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/apptheme/AppThemeModeStore.kt deleted file mode 100644 index 78e1fd514c..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/apptheme/AppThemeModeStore.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.tangem.datasource.local.apptheme - -import com.tangem.domain.apptheme.model.AppThemeMode -import kotlinx.coroutines.flow.Flow - -interface AppThemeModeStore { - - fun get(): Flow - - suspend fun store(item: AppThemeMode) - - suspend fun isEmpty(): Boolean -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/apptheme/DefaultAppThemeModeStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/apptheme/DefaultAppThemeModeStore.kt deleted file mode 100644 index 483bf4b525..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/apptheme/DefaultAppThemeModeStore.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.tangem.datasource.local.apptheme - -import com.tangem.datasource.local.datastore.core.KeylessDataStoreDecorator -import com.tangem.datasource.local.datastore.core.StringKeyDataStore -import com.tangem.domain.apptheme.model.AppThemeMode - -internal class DefaultAppThemeModeStore( - dataStore: StringKeyDataStore, -) : AppThemeModeStore, KeylessDataStoreDecorator(dataStore) \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/card/UsedCardsStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/card/UsedCardsStore.kt deleted file mode 100644 index 0d54995dbb..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/card/UsedCardsStore.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.tangem.datasource.local.card - -import com.tangem.datasource.local.datastore.SharedPreferencesDataStore -import com.tangem.datasource.local.datastore.core.KeylessDataStoreDecorator -import kotlinx.coroutines.flow.Flow - -interface UsedCardsStore { - - fun get(): Flow> - - suspend fun getSyncOrNull(): List? - - suspend fun store(item: List) -} - -internal class DefaultUsedCardsStore( - store: SharedPreferencesDataStore>, -) : UsedCardsStore, KeylessDataStoreDecorator>( - wrappedDataStore = store, - key = "usedCardsInfo_v2", -) \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/datastore/BooleanSharedPreferencesDataStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/datastore/BooleanSharedPreferencesDataStore.kt deleted file mode 100644 index 36141207c0..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/datastore/BooleanSharedPreferencesDataStore.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.tangem.datasource.local.datastore - -import android.content.Context -import androidx.core.content.edit - -internal class BooleanSharedPreferencesDataStore( - preferencesName: String, - context: Context, -) : SharedPreferencesDataStore(preferencesName, context) { - - override fun getByKey(key: String): Boolean = sharedPreferences.getBoolean(key, false) - - override fun storeByKey(key: String, value: Boolean) { - sharedPreferences.edit { putBoolean(key, value) } - } -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/datastore/IntSharedPreferencesDataStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/datastore/IntSharedPreferencesDataStore.kt deleted file mode 100644 index 7ef0f70fa6..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/datastore/IntSharedPreferencesDataStore.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.tangem.datasource.local.datastore - -import android.content.Context -import androidx.core.content.edit - -internal class IntSharedPreferencesDataStore( - preferencesName: String, - context: Context, -) : SharedPreferencesDataStore(preferencesName, context) { - - override fun getByKey(key: String): Int = sharedPreferences.getInt(key, 0) - - override fun storeByKey(key: String, value: Int) { - sharedPreferences.edit { putInt(key, value) } - } -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/datastore/JsonSharedPreferencesDataStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/datastore/JsonSharedPreferencesDataStore.kt deleted file mode 100644 index 5e47ee8114..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/datastore/JsonSharedPreferencesDataStore.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.tangem.datasource.local.datastore - -import android.content.Context -import androidx.core.content.edit -import com.squareup.moshi.JsonAdapter - -internal class JsonSharedPreferencesDataStore( - preferencesName: String, - context: Context, - private val adapter: JsonAdapter, -) : SharedPreferencesDataStore(preferencesName, context) { - - override fun getByKey(key: String): Value? { - val json = sharedPreferences.getString(key, null) ?: return null - - return adapter.fromJson(json) - } - - override fun storeByKey(key: String, value: Value) { - val json = adapter.toJson(value) - - sharedPreferences.edit { putString(key, json) } - } -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/datastore/LongSharedPreferencesDataStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/datastore/LongSharedPreferencesDataStore.kt deleted file mode 100644 index b1bb00e4e1..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/datastore/LongSharedPreferencesDataStore.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.tangem.datasource.local.datastore - -import android.content.Context -import androidx.core.content.edit - -internal class LongSharedPreferencesDataStore( - preferencesName: String, - context: Context, -) : SharedPreferencesDataStore(preferencesName, context) { - - override fun getByKey(key: String): Long = sharedPreferences.getLong(key, 0) - - override fun storeByKey(key: String, value: Long) { - sharedPreferences.edit { putLong(key, value) } - } -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/datastore/SharedPreferencesDataStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/datastore/SharedPreferencesDataStore.kt deleted file mode 100644 index 417b4e9ac4..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/datastore/SharedPreferencesDataStore.kt +++ /dev/null @@ -1,98 +0,0 @@ -package com.tangem.datasource.local.datastore - -import android.content.Context -import android.content.Context.MODE_PRIVATE -import android.content.SharedPreferences -import androidx.core.content.edit -import com.tangem.datasource.local.datastore.core.StringKeyDataStore -import com.tangem.datasource.local.datastore.utils.Trigger -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.mapNotNull -import timber.log.Timber - -internal abstract class SharedPreferencesDataStore( - preferencesName: String, - context: Context, -) : StringKeyDataStore { - - protected val sharedPreferences: SharedPreferences by lazy { - context.getSharedPreferences(preferencesName, MODE_PRIVATE) - } - - private val writeTrigger = Trigger() - - abstract fun getByKey(key: String): Value? - - abstract fun storeByKey(key: String, value: Value) - - override suspend fun isEmpty(): Boolean { - return sharedPreferences.all.isEmpty() - } - - override suspend fun contains(key: String): Boolean { - return sharedPreferences.contains(key) - } - - override fun get(key: String): Flow { - return writeTrigger - .mapNotNull { getInternal(key) } - .distinctUntilChanged() - } - - override fun getAll(): Flow> { - throw UnsupportedOperationException("Unknown key") - } - - override suspend fun getSyncOrNull(key: String): Value? = getInternal(key) - - override suspend fun getAllSyncOrNull(): List { - throw UnsupportedOperationException("Unknown key") - } - - override suspend fun store(key: String, value: Value) { - try { - storeByKey(key, value) - writeTrigger.trigger() - } catch (e: Throwable) { - Timber.e(e, "Unable to edit preferences: $key") - } - } - - override suspend fun store(values: Map) { - values.forEach { (key, item) -> - store(key, item) - } - } - - override suspend fun remove(key: String) { - sharedPreferences.edit { remove(key) } - writeTrigger.trigger() - } - - override suspend fun remove(keys: Collection) { - sharedPreferences.edit { - keys.forEach { key -> - remove(key) - } - } - - writeTrigger.trigger() - } - - override suspend fun clear() { - sharedPreferences.edit { clear() } - writeTrigger.trigger() - } - - private fun getInternal(key: String): Value? { - if (!sharedPreferences.contains(key)) return null - - return try { - getByKey(key) - } catch (e: Throwable) { - Timber.e(e, "Unable to get value from preferences: $key") - null - } - } -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/preferences/PreferencesDataStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/preferences/PreferencesDataStore.kt index 7d0d6ba94a..9e9b278b7e 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/preferences/PreferencesDataStore.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/preferences/PreferencesDataStore.kt @@ -4,11 +4,13 @@ import android.content.Context import androidx.datastore.core.DataMigration import androidx.datastore.core.DataStore import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler +import androidx.datastore.preferences.SharedPreferencesMigration import androidx.datastore.preferences.core.PreferenceDataStoreFactory import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.emptyPreferences import androidx.datastore.preferences.preferencesDataStoreFile import com.tangem.datasource.local.preferences.PreferencesDataStore.INSTANCE +import com.tangem.datasource.local.preferences.utils.SharedPreferencesKeyMigration import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import timber.log.Timber @@ -23,6 +25,8 @@ import kotlin.coroutines.CoroutineContext internal object PreferencesDataStore { private const val PREFERENCES_FILE_NAME = "TAP_PREFS" + private const val LEGACY_TAP_PREFS_FILE_NAME = "tapPrefs" + private const val LEGACY_DEFAULT_KEY_NAME = "key" private var INSTANCE: DataStore? = null @@ -33,7 +37,7 @@ internal object PreferencesDataStore { private fun create(context: Context, dispatcher: CoroutineContext): DataStore { return PreferenceDataStoreFactory.create( corruptionHandler = createCorruptionHandler(), - migrations = createMigrations(), + migrations = createMigrations(context = context), scope = CoroutineScope(context = dispatcher + SupervisorJob()), produceFile = { context.preferencesDataStoreFile(name = PREFERENCES_FILE_NAME) }, ) @@ -48,7 +52,31 @@ internal object PreferencesDataStore { ) } - private fun createMigrations(): List> { - return listOf() + private fun createMigrations(context: Context): List> { + return listOf( + SharedPreferencesMigration( + context = context, + sharedPreferencesName = LEGACY_TAP_PREFS_FILE_NAME, + keysToMigrate = getTapPrefKeysToMigrate(), + ), + SharedPreferencesKeyMigration( + context = context, + legacyPrefsName = "app_theme", + legacyKeyName = LEGACY_DEFAULT_KEY_NAME, + keyName = PreferencesKeys.APP_THEME_MODE_KEY.name, + ), + SharedPreferencesKeyMigration( + context = context, + legacyPrefsName = "selected_app_currency", + legacyKeyName = LEGACY_DEFAULT_KEY_NAME, + keyName = PreferencesKeys.SELECTED_APP_CURRENCY_KEY.name, + ), + SharedPreferencesKeyMigration( + context = context, + legacyPrefsName = "balance_hiding_settings", + legacyKeyName = LEGACY_DEFAULT_KEY_NAME, + keyName = PreferencesKeys.BALANCE_HIDING_SETTINGS_KEY.name, + ), + ) } } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/preferences/PreferencesKeys.kt b/core/datasource/src/main/java/com/tangem/datasource/local/preferences/PreferencesKeys.kt index 90f2b61270..d81065c147 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/preferences/PreferencesKeys.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/preferences/PreferencesKeys.kt @@ -1,13 +1,49 @@ package com.tangem.datasource.local.preferences +import androidx.datastore.preferences.core.* +import com.tangem.datasource.local.preferences.PreferencesKeys.APP_LAUNCH_COUNT_KEY +import com.tangem.datasource.local.preferences.PreferencesKeys.FUNDS_FOUND_DATE_KEY +import com.tangem.datasource.local.preferences.PreferencesKeys.SAVE_USER_WALLETS_KEY +import com.tangem.datasource.local.preferences.PreferencesKeys.SHOW_RATING_DIALOG_AT_LAUNCH_COUNT_KEY +import com.tangem.datasource.local.preferences.PreferencesKeys.USED_CARDS_INFO_KEY +import com.tangem.datasource.local.preferences.PreferencesKeys.USER_WAS_INTERACT_WITH_RATING_KEY + /** * All preferences keys that DataStore is stored. * [REDACTED_AUTHOR] */ -object PreferencesKeys +object PreferencesKeys { + + val SAVE_USER_WALLETS_KEY by lazy { booleanPreferencesKey(name = "saveUserWallets") } + + val APP_LAUNCH_COUNT_KEY by lazy { intPreferencesKey(name = "launchCount") } + + val SHOW_RATING_DIALOG_AT_LAUNCH_COUNT_KEY by lazy { intPreferencesKey(name = "showRatingDialogAtLaunchCount") } + + val FUNDS_FOUND_DATE_KEY by lazy { longPreferencesKey(name = "fundsFoundDate") } + + val USER_WAS_INTERACT_WITH_RATING_KEY by lazy { booleanPreferencesKey(name = "userWasInteractWithRating") } + + val USED_CARDS_INFO_KEY by lazy { stringPreferencesKey(name = "usedCardsInfo_v2") } + + val APP_THEME_MODE_KEY by lazy { stringPreferencesKey(name = "appThemeMode") } + + val SELECTED_APP_CURRENCY_KEY by lazy { stringPreferencesKey(name = "selectedAppCurrency") } + + val BALANCE_HIDING_SETTINGS_KEY by lazy { stringPreferencesKey(name = "balanceHidingSettings") } +} /** Preferences keys set that should be migrated from "PreferencesDataSource" to a new DataStore */ internal fun getTapPrefKeysToMigrate(): Set { - return setOf() + return setOf( + SAVE_USER_WALLETS_KEY, + APP_LAUNCH_COUNT_KEY, + SHOW_RATING_DIALOG_AT_LAUNCH_COUNT_KEY, + FUNDS_FOUND_DATE_KEY, + USER_WAS_INTERACT_WITH_RATING_KEY, + USED_CARDS_INFO_KEY, + ) + .map(Preferences.Key<*>::name) + .toSet() } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/quote/DefaultQuotesStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/quote/DefaultQuotesStore.kt index 2b8de0afd9..fc0d1e0e42 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/quote/DefaultQuotesStore.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/quote/DefaultQuotesStore.kt @@ -30,6 +30,14 @@ internal class DefaultQuotesStore( } } + override suspend fun getSync(currenciesIds: Set): Set { + return currenciesIds.mapNotNull { currencyId -> + currencyId.rawCurrencyId?.let { + dataStore.getSyncOrNull(it) + } + }.toSet() + } + override suspend fun store(response: QuotesResponse) { val quotes = response.quotes.mapValues { (id, quote) -> StoredQuote(id, quote) diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/quote/QuotesStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/quote/QuotesStore.kt index 64b3bf2c9c..dd3f577782 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/quote/QuotesStore.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/quote/QuotesStore.kt @@ -9,5 +9,7 @@ interface QuotesStore { fun get(currenciesIds: Set): Flow> + suspend fun getSync(currenciesIds: Set): Set + suspend fun store(response: QuotesResponse) } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/settings/AppLaunchCountStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/settings/AppLaunchCountStore.kt deleted file mode 100644 index a2ee494307..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/settings/AppLaunchCountStore.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.tangem.datasource.local.settings - -import com.tangem.datasource.local.datastore.IntSharedPreferencesDataStore -import com.tangem.datasource.local.datastore.core.KeylessDataStoreDecorator -import kotlinx.coroutines.flow.Flow - -interface AppLaunchCountStore { - - fun get(): Flow - - suspend fun getSyncOrNull(): Int? - - suspend fun store(item: Int) -} - -internal class DefaultAppLaunchCountStore( - store: IntSharedPreferencesDataStore, -) : AppLaunchCountStore, KeylessDataStoreDecorator( - wrappedDataStore = store, - key = "launchCount", -) \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/settings/AppRatingShowingCountStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/settings/AppRatingShowingCountStore.kt deleted file mode 100644 index dfbb452f22..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/settings/AppRatingShowingCountStore.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.tangem.datasource.local.settings - -import com.tangem.datasource.local.datastore.IntSharedPreferencesDataStore -import com.tangem.datasource.local.datastore.core.KeylessDataStoreDecorator -import kotlinx.coroutines.flow.Flow - -interface AppRatingShowingCountStore { - - fun get(): Flow - - suspend fun getSyncOrNull(): Int? - - suspend fun store(item: Int) -} - -internal class DefaultAppRatingShowingCountStore( - store: IntSharedPreferencesDataStore, -) : AppRatingShowingCountStore, KeylessDataStoreDecorator( - wrappedDataStore = store, - key = "showRatingDialogAtLaunchCount", -) \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/settings/FundsFoundDateInMillisStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/settings/FundsFoundDateInMillisStore.kt deleted file mode 100644 index 1e6a50f959..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/settings/FundsFoundDateInMillisStore.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.tangem.datasource.local.settings - -import com.tangem.datasource.local.datastore.LongSharedPreferencesDataStore -import com.tangem.datasource.local.datastore.core.KeylessDataStoreDecorator -import kotlinx.coroutines.flow.Flow - -interface FundsFoundDateInMillisStore { - - fun get(): Flow - - suspend fun getSyncOrNull(): Long? - - suspend fun store(item: Long) -} - -internal class DefaultFundsFoundDateInMillisStore( - store: LongSharedPreferencesDataStore, -) : FundsFoundDateInMillisStore, KeylessDataStoreDecorator( - wrappedDataStore = store, - key = "fundsFoundDate", -) \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/settings/UserInteractingStatusStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/settings/UserInteractingStatusStore.kt deleted file mode 100644 index 1a1ed3bf03..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/settings/UserInteractingStatusStore.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.tangem.datasource.local.settings - -import com.tangem.datasource.local.datastore.BooleanSharedPreferencesDataStore -import com.tangem.datasource.local.datastore.core.KeylessDataStoreDecorator -import kotlinx.coroutines.flow.Flow - -interface UserInteractingStatusStore { - - fun get(): Flow - - suspend fun getSyncOrNull(): Boolean? - - suspend fun store(item: Boolean) -} - -internal class DefaultUserInteractingStatusStore( - store: BooleanSharedPreferencesDataStore, -) : UserInteractingStatusStore, KeylessDataStoreDecorator( - wrappedDataStore = store, - key = "userWasInteractWithRating", -) \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/userwallet/ShouldSaveUserWalletStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/userwallet/ShouldSaveUserWalletStore.kt deleted file mode 100644 index cbc20ba792..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/local/userwallet/ShouldSaveUserWalletStore.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.tangem.datasource.local.userwallet - -import com.tangem.datasource.local.datastore.BooleanSharedPreferencesDataStore -import com.tangem.datasource.local.datastore.core.KeylessDataStoreDecorator -import kotlinx.coroutines.flow.Flow - -/** -[REDACTED_AUTHOR] - */ -interface ShouldSaveUserWalletStore { - - fun get(): Flow - - suspend fun getSyncOrNull(): Boolean? - - suspend fun store(item: Boolean) -} - -internal class DefaultShouldSaveUserWalletStore( - store: BooleanSharedPreferencesDataStore, -) : ShouldSaveUserWalletStore, KeylessDataStoreDecorator( - wrappedDataStore = store, - key = "saveUserWallets", -) \ No newline at end of file diff --git a/data/app-currency/build.gradle.kts b/data/app-currency/build.gradle.kts index 69613e2e85..ca214f10a9 100644 --- a/data/app-currency/build.gradle.kts +++ b/data/app-currency/build.gradle.kts @@ -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) } \ No newline at end of file diff --git a/data/app-currency/src/main/kotlin/com/tangem/data/appcurrency/DefaultAppCurrencyRepository.kt b/data/app-currency/src/main/kotlin/com/tangem/data/appcurrency/DefaultAppCurrencyRepository.kt index 520be9c24d..bce54591e8 100644 --- a/data/app-currency/src/main/kotlin/com/tangem/data/appcurrency/DefaultAppCurrencyRepository.kt +++ b/data/app-currency/src/main/kotlin/com/tangem/data/appcurrency/DefaultAppCurrencyRepository.kt @@ -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 = channelFlow { - launch(dispatchers.io) { - selectedAppCurrencyStore.get() - .map(appCurrencyConverter::convert) - .collect(::send) - } + override fun getSelectedAppCurrency(): Flow { + return channelFlow { + launch { + appPreferencesStore + .getObject(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, + ) } } diff --git a/data/app-currency/src/main/kotlin/com/tangem/data/appcurrency/di/AppCurrencyDataModule.kt b/data/app-currency/src/main/kotlin/com/tangem/data/appcurrency/di/AppCurrencyDataModule.kt index cd80c7c52b..d9cb9be5f7 100644 --- a/data/app-currency/src/main/kotlin/com/tangem/data/appcurrency/di/AppCurrencyDataModule.kt +++ b/data/app-currency/src/main/kotlin/com/tangem/data/appcurrency/di/AppCurrencyDataModule.kt @@ -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, ) } } \ No newline at end of file diff --git a/data/app-theme/build.gradle.kts b/data/app-theme/build.gradle.kts index 7996a21c65..92a28083d7 100644 --- a/data/app-theme/build.gradle.kts +++ b/data/app-theme/build.gradle.kts @@ -27,4 +27,7 @@ dependencies { /** Other */ implementation(deps.kotlin.coroutines) + + /** Local storages */ + implementation(deps.androidx.datastore) } \ No newline at end of file diff --git a/data/app-theme/src/main/kotlin/com/tangem/data/apptheme/DefaultAppThemeModeRepository.kt b/data/app-theme/src/main/kotlin/com/tangem/data/apptheme/DefaultAppThemeModeRepository.kt index 4d8ed9cf4c..8abef1097b 100644 --- a/data/app-theme/src/main/kotlin/com/tangem/data/apptheme/DefaultAppThemeModeRepository.kt +++ b/data/app-theme/src/main/kotlin/com/tangem/data/apptheme/DefaultAppThemeModeRepository.kt @@ -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 { - 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) } } \ No newline at end of file diff --git a/data/app-theme/src/main/kotlin/com/tangem/data/apptheme/di/AppThemeModeDataModule.kt b/data/app-theme/src/main/kotlin/com/tangem/data/apptheme/di/AppThemeModeDataModule.kt index a360ba19b6..11925c23cd 100644 --- a/data/app-theme/src/main/kotlin/com/tangem/data/apptheme/di/AppThemeModeDataModule.kt +++ b/data/app-theme/src/main/kotlin/com/tangem/data/apptheme/di/AppThemeModeDataModule.kt @@ -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) } } \ No newline at end of file diff --git a/data/balance-hiding/build.gradle.kts b/data/balance-hiding/build.gradle.kts index 434d3e0a34..84db19b2d7 100644 --- a/data/balance-hiding/build.gradle.kts +++ b/data/balance-hiding/build.gradle.kts @@ -11,10 +11,10 @@ android { } dependencies { + implementation(deps.androidx.datastore) /** DI */ implementation(deps.hilt.android) - kapt(deps.hilt.kapt) implementation(deps.kotlin.coroutines) diff --git a/data/balance-hiding/src/main/java/com/tangem/data/balancehiding/DefaultBalanceHidingRepository.kt b/data/balance-hiding/src/main/java/com/tangem/data/balancehiding/DefaultBalanceHidingRepository.kt index 879bef5f17..948ec336de 100644 --- a/data/balance-hiding/src/main/java/com/tangem/data/balancehiding/DefaultBalanceHidingRepository.kt +++ b/data/balance-hiding/src/main/java/com/tangem/data/balancehiding/DefaultBalanceHidingRepository.kt @@ -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 { - 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, + ) } } \ No newline at end of file diff --git a/data/balance-hiding/src/main/java/com/tangem/data/balancehiding/di/BalanceHidingModule.kt b/data/balance-hiding/src/main/java/com/tangem/data/balancehiding/di/BalanceHidingModule.kt index 86b293b9fe..f83fac4932 100644 --- a/data/balance-hiding/src/main/java/com/tangem/data/balancehiding/di/BalanceHidingModule.kt +++ b/data/balance-hiding/src/main/java/com/tangem/data/balancehiding/di/BalanceHidingModule.kt @@ -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 diff --git a/data/card/build.gradle.kts b/data/card/build.gradle.kts index c7a692bd7e..6015c1ed3a 100644 --- a/data/card/build.gradle.kts +++ b/data/card/build.gradle.kts @@ -11,6 +11,8 @@ android { } dependencies { + implementation(deps.androidx.datastore) + implementation(deps.hilt.android) kapt(deps.hilt.kapt) diff --git a/data/card/src/main/java/com/tangem/data/card/DefaultCardRepository.kt b/data/card/src/main/java/com/tangem/data/card/DefaultCardRepository.kt index 6f4a1fb553..7f0a56fd9a 100644 --- a/data/card/src/main/java/com/tangem/data/card/DefaultCardRepository.kt +++ b/data/card/src/main/java/com/tangem/data/card/DefaultCardRepository.kt @@ -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 { - return channelFlow { - launch(dispatchers.io) { - usedCardsStore.get() - .collect { savedCards -> - send(element = savedCards.any { it.cardId == cardId }) - } + return appPreferencesStore.getObject>(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? = 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, ) } } diff --git a/data/card/src/main/java/com/tangem/data/card/di/CardDataModule.kt b/data/card/src/main/java/com/tangem/data/card/di/CardDataModule.kt index 0c2cfdecbf..a526073cd2 100644 --- a/data/card/src/main/java/com/tangem/data/card/di/CardDataModule.kt +++ b/data/card/src/main/java/com/tangem/data/card/di/CardDataModule.kt @@ -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) } } \ No newline at end of file diff --git a/data/settings/build.gradle.kts b/data/settings/build.gradle.kts index e59302acd9..5daa9b86f0 100644 --- a/data/settings/build.gradle.kts +++ b/data/settings/build.gradle.kts @@ -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) } diff --git a/data/settings/src/main/java/com/tangem/data/settings/DefaultAppRatingRepository.kt b/data/settings/src/main/java/com/tangem/data/settings/DefaultAppRatingRepository.kt index e7bc353372..78e99623f1 100644 --- a/data/settings/src/main/java/com/tangem/data/settings/DefaultAppRatingRepository.kt +++ b/data/settings/src/main/java/com/tangem/data/settings/DefaultAppRatingRepository.kt @@ -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 { // 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 { diff --git a/data/settings/src/main/java/com/tangem/data/settings/di/SettingsDataModule.kt b/data/settings/src/main/java/com/tangem/data/settings/di/SettingsDataModule.kt index 68355c5d61..254235cf84 100644 --- a/data/settings/src/main/java/com/tangem/data/settings/di/SettingsDataModule.kt +++ b/data/settings/src/main/java/com/tangem/data/settings/di/SettingsDataModule.kt @@ -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) } } \ No newline at end of file diff --git a/data/tokens/build.gradle.kts b/data/tokens/build.gradle.kts index d36f42d591..88d7471830 100644 --- a/data/tokens/build.gradle.kts +++ b/data/tokens/build.gradle.kts @@ -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) diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/TokensDataModule.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/TokensDataModule.kt index b683931af9..1b8b65138e 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/TokensDataModule.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/TokensDataModule.kt @@ -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, ) diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt index 37a89fafd0..cdd04c62ce 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultQuotesRepository.kt @@ -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): Flow> { - return selectedAppCurrencyStore.get() + return appPreferencesStore.getObject( + 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, refresh: Boolean): Set { return withContext(dispatchers.io) { - val selectedAppCurrency = requireNotNull(selectedAppCurrencyStore.getSyncOrNull()) { - "Unable to get selected application currency to update quotes" - } + val selectedAppCurrency = requireNotNull( + value = appPreferencesStore.getObjectSyncOrNull( + 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) } diff --git a/data/wallets/build.gradle.kts b/data/wallets/build.gradle.kts index f39f9b3c1e..c1a86f55ca 100644 --- a/data/wallets/build.gradle.kts +++ b/data/wallets/build.gradle.kts @@ -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) } \ No newline at end of file diff --git a/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletsRepository.kt b/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletsRepository.kt index af326a1a45..2cc72cd098 100644 --- a/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletsRepository.kt +++ b/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletsRepository.kt @@ -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 = shouldSaveUserWalletStore.get() + override fun shouldSaveUserWallets(): Flow { + 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) } } \ No newline at end of file diff --git a/data/wallets/src/main/java/com/tangem/data/wallets/di/WalletsDataModule.kt b/data/wallets/src/main/java/com/tangem/data/wallets/di/WalletsDataModule.kt index 80ff2c2567..29cd5fb5c0 100644 --- a/data/wallets/src/main/java/com/tangem/data/wallets/di/WalletsDataModule.kt +++ b/data/wallets/src/main/java/com/tangem/data/wallets/di/WalletsDataModule.kt @@ -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) } } \ No newline at end of file diff --git a/domain/settings/src/main/java/com/tangem/domain/settings/repositories/AppRatingRepository.kt b/domain/settings/src/main/java/com/tangem/domain/settings/repositories/AppRatingRepository.kt index e10dc94046..33772c3cf6 100644 --- a/domain/settings/src/main/java/com/tangem/domain/settings/repositories/AppRatingRepository.kt +++ b/domain/settings/src/main/java/com/tangem/domain/settings/repositories/AppRatingRepository.kt @@ -4,9 +4,6 @@ import kotlinx.coroutines.flow.Flow interface AppRatingRepository { - // FIXME: We must to initialize all stores before calling [isReadyToShow], otherwise flow will not emit data - suspend fun initialize() - suspend fun setWalletWithFundsFound() fun isReadyToShow(): Flow diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/repository/WalletsRepository.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/repository/WalletsRepository.kt index 6190b6d2e0..003f9b9ff2 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/repository/WalletsRepository.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/repository/WalletsRepository.kt @@ -4,8 +4,6 @@ import kotlinx.coroutines.flow.Flow interface WalletsRepository { - suspend fun initialize() - suspend fun shouldSaveUserWalletsSync(): Boolean fun shouldSaveUserWallets(): Flow diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/domain/SendRecipientListContent.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/domain/SendRecipientListContent.kt index 6cb3516497..7f7216e6e3 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/domain/SendRecipientListContent.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/domain/SendRecipientListContent.kt @@ -17,5 +17,6 @@ internal sealed class SendRecipientListContent { data class Wallets( val list: PersistentList, + val isWalletsOnly: Boolean, ) : SendRecipientListContent() } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendStateFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendStateFactory.kt index 3bb47678a9..38583d0676 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendStateFactory.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendStateFactory.kt @@ -105,10 +105,15 @@ internal class SendStateFactory( //endregion //region recipient - fun onLoadedRecipientList(wallets: List, txHistory: PagingData) { + fun onLoadedRecipientList( + wallets: List, + txHistory: PagingData, + txHistoryCount: Int, + ) { recipientListStateConverter.convert( wallets = wallets, txHistory = txHistory, + txHistoryCount = txHistoryCount, ) } diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/SendRecipientListConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/SendRecipientListConverter.kt index da8a97622d..8fd734e781 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/SendRecipientListConverter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/SendRecipientListConverter.kt @@ -22,7 +22,7 @@ internal class SendRecipientListConverter( private val cryptoCurrencyStatusProvider: Provider, ) { - fun convert(wallets: List, txHistory: PagingData) { + fun convert(wallets: List, txHistory: PagingData, txHistoryCount: Int) { val filteredWallets = wallets.filterNotNull() .groupBy { item -> item.name } .values.flatten() @@ -32,49 +32,58 @@ internal class SendRecipientListConverter( ) } + val walletsItem = getWalletItems(filteredWallets, txHistoryCount) + currentStateProvider().recipientList.update { - txHistory.filter { item -> - val isTransfer = item.type == TxHistoryItem.TransactionType.Transfer - val isNotContract = item.interactionAddressType is TxHistoryItem.InteractionAddressType.User - val isSingleAddress = if (item.isOutgoing) { - item.destinationType is TxHistoryItem.DestinationType.Single - } else { - item.sourceType is TxHistoryItem.SourceType.Single - } - isTransfer && isSingleAddress && isNotContract - }.map { tx -> - SendRecipientListContent.Item( - id = tx.txHash, - title = tx.extractAddress(), - subtitle = TextReference.Str(tx.getAmount()), - info = tx.extractTimestamp(), - subtitleIconRes = tx.extractIconRes(), - ) - }.insertWallets(filteredWallets) + if (txHistoryCount == 0) { + PagingData.from(listOf(walletsItem)) + } else { + txHistory.filter { item -> + val isTransfer = item.type == TxHistoryItem.TransactionType.Transfer + val isNotContract = item.interactionAddressType is TxHistoryItem.InteractionAddressType.User + val isSingleAddress = if (item.isOutgoing) { + item.destinationType is TxHistoryItem.DestinationType.Single + } else { + item.sourceType is TxHistoryItem.SourceType.Single + } + isTransfer && isSingleAddress && isNotContract + }.map { tx -> + SendRecipientListContent.Item( + id = tx.txHash, + title = tx.extractAddress(), + subtitle = TextReference.Str(tx.getAmount()), + info = tx.extractTimestamp(), + subtitleIconRes = tx.extractIconRes(), + ) + }.insertWallets(walletsItem) + } } } private fun PagingData.insertWallets( - wallets: List, + wallets: SendRecipientListContent.Wallets, ): PagingData { return insertSeparators(terminalSeparatorType = TerminalSeparatorType.SOURCE_COMPLETE) { before, after -> return@insertSeparators when { - before == null && after is SendRecipientListContent.Item -> { - SendRecipientListContent.Wallets( - wallets.map { - SendRecipientListContent.Item( - id = it.address, - title = TextReference.Str(it.address), - subtitle = TextReference.Str(it.name), - ) - }.toPersistentList(), - ) - } + before == null && after is SendRecipientListContent.Item -> wallets else -> null } } } + private fun getWalletItems(wallets: List, txHistoryCount: Int): SendRecipientListContent.Wallets { + return SendRecipientListContent.Wallets( + wallets.map { + SendRecipientListContent.Item( + id = it.address, + title = TextReference.Str(it.address), + subtitle = TextReference.Str(it.name), + ) + }.toPersistentList(), + isWalletsOnly = txHistoryCount == 0, + ) + } + private fun TxHistoryItem.extractAddress(): TextReference = if (isOutgoing) { when (val destination = destinationType) { is TxHistoryItem.DestinationType.Multiple -> TextReference.Res( diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/SendRecipientContent.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/SendRecipientContent.kt index ada2667527..30563155b4 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/SendRecipientContent.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/SendRecipientContent.kt @@ -80,6 +80,7 @@ internal fun SendRecipientContent( } } +@Suppress("LongMethod") @OptIn(ExperimentalFoundationApi::class) private fun LazyListScope.recipientListItem( recipientList: LazyPagingItems, @@ -106,10 +107,17 @@ private fun LazyListScope.recipientListItem( .padding(top = TangemTheme.dimens.spacing20) .then( if (index == 0) { + val bottomRadius = if (item.isWalletsOnly) { + TangemTheme.dimens.radius12 + } else { + TangemTheme.dimens.radius0 + } Modifier.clip( RoundedCornerShape( topEnd = TangemTheme.dimens.radius12, topStart = TangemTheme.dimens.radius12, + bottomStart = bottomRadius, + bottomEnd = bottomRadius, ), ) } else { @@ -182,18 +190,25 @@ private fun RecipientWalletListItem( onClick = { clickIntents.onRecipientAddressValueChange(title) }, ) } - Text( - text = stringResource(R.string.send_recent_transactions), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, - modifier = Modifier - .fillMaxWidth() - .padding( - top = TangemTheme.dimens.spacing8, - bottom = TangemTheme.dimens.spacing8, - start = TangemTheme.dimens.spacing12, - end = TangemTheme.dimens.spacing12, - ), - ) + if (!item.isWalletsOnly) { + val topPadding = if (item.list.isNotEmpty()) { + TangemTheme.dimens.spacing8 + } else { + TangemTheme.dimens.spacing0 + } + Text( + text = stringResource(R.string.send_recent_transactions), + style = TangemTheme.typography.subtitle2, + color = TangemTheme.colors.text.tertiary, + modifier = Modifier + .fillMaxWidth() + .padding( + top = topPadding, + bottom = TangemTheme.dimens.spacing8, + start = TangemTheme.dimens.spacing12, + end = TangemTheme.dimens.spacing12, + ), + ) + } } } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt index 3e8bc7477f..02f2caefc6 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt @@ -20,6 +20,7 @@ import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.transaction.usecase.GetFeeUseCase import com.tangem.domain.txhistory.models.TxHistoryItem +import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.models.UserWallet @@ -57,6 +58,7 @@ internal class SendViewModel @Inject constructor( private val getWalletsUseCase: GetWalletsUseCase, private val getCryptoCurrenciesUseCase: GetCryptoCurrenciesUseCase, private val txHistoryItemsUseCase: GetTxHistoryItemsUseCase, + private val txHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase, private val getFeeUseCase: GetFeeUseCase, private val walletManagersFacade: WalletManagersFacade, savedStateHandle: SavedStateHandle, @@ -97,7 +99,6 @@ internal class SendViewModel @Inject constructor( override fun onCreate(owner: LifecycleOwner) { getWalletAddresses() subscribeOnCurrencyStatusUpdates(owner) - getWalletsAndRecent() getFee() } @@ -134,6 +135,7 @@ internal class SendViewModel @Inject constructor( .onEach { either -> either.onRight { cryptoCurrencyStatus = it + getWalletsAndRecent() uiState = stateFactory.getReadyState() } } @@ -158,10 +160,12 @@ internal class SendViewModel @Inject constructor( combine( flow = getUserWallets().conflate(), flow2 = getTxHistory().conflate(), - ) { wallets, txHistory -> + flow3 = getTxHistoryCount().conflate(), + ) { wallets, txHistory, txHistoryCount -> stateFactory.onLoadedRecipientList( wallets = wallets, txHistory = txHistory, + txHistoryCount = txHistoryCount, ) } .flowOn(dispatchers.io) @@ -213,6 +217,18 @@ internal class SendViewModel @Inject constructor( } } + private fun getTxHistoryCount(): Flow { + return flow { + txHistoryItemsCountUseCase( + userWalletId = userWalletId, + currency = cryptoCurrency, + ).fold( + ifRight = { emit(it) }, + ifLeft = { emit(0) }, + ) + } + } + private fun getFee() { viewModelScope.launch(dispatchers.main) { uiState.currentState