From 40b616868d163f91949b83262844c6e4613c4f7f Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 15 Aug 2023 13:24:38 +0300 Subject: [PATCH] Updated on 2026-08-14 --- app/build.gradle.kts | 1 + .../java/com/tangem/tap/TapApplication.kt | 5 ++ .../common/redux/global/GlobalMiddleware.kt | 46 ++++++++---- .../middlewares/AppCurrencyMiddleware.kt | 73 ++++++++++++++----- .../redux/middlewares/WalletMiddleware.kt | 2 + .../tap/proxy/redux/DaggerGraphState.kt | 2 + .../datasource/di/AppCurrencyDataModule.kt | 20 +++++ .../MockSelectedAppCurrencyStore.kt | 26 +++++++ .../appcurrency/SelectedAppCurrencyStore.kt | 11 +++ .../com/tangem/utils/coroutines}/JobHolder.kt | 6 +- .../appcurrency/MockAppCurrencyRepository.kt | 2 +- .../tangem/data/tokens/di/TokensDataModule.kt | 10 ++- .../repository/DefaultQuotesRepository.kt | 28 +++++-- .../repository/AppCurrencyRepository.kt | 2 +- domain/tokens/build.gradle.kts | 6 ++ features/wallet/impl/build.gradle.kts | 2 + .../router/DefaultWalletRouter.kt | 2 + .../WalletLoadedTokensListConverter.kt | 5 +- ...letSingleCurrencyLoadedBalanceConverter.kt | 21 +++--- .../state/factory/WalletStateFactory.kt | 6 +- ...ryptoCurrencyStatusToTokenItemConverter.kt | 8 +- .../utils/FiatBalanceToWalletCardConverter.kt | 8 +- .../utils/TokenListToContentItemsConverter.kt | 8 +- .../utils/TokenListToWalletStateConverter.kt | 10 +-- .../wallet/viewmodels/WalletViewModel.kt | 26 ++++++- 25 files changed, 258 insertions(+), 78 deletions(-) create mode 100644 core/datasource/src/main/java/com/tangem/datasource/di/AppCurrencyDataModule.kt create mode 100644 core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/MockSelectedAppCurrencyStore.kt create mode 100644 core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/SelectedAppCurrencyStore.kt rename {features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels => core/utils/src/main/java/com/tangem/utils/coroutines}/JobHolder.kt (63%) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 473fbff374..38e1d9c644 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -33,6 +33,7 @@ dependencies { implementation(projects.domain.tokens) implementation(projects.domain.txhistory) implementation(projects.domain.appCurrency) + implementation(projects.domain.appCurrency.models) implementation(project(":common")) implementation(project(":core:analytics")) diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index cb21e52c1d..28cd0f57de 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -23,6 +23,7 @@ import com.tangem.datasource.config.FeaturesLocalLoader import com.tangem.datasource.config.models.Config import com.tangem.datasource.connection.NetworkConnectionManager import com.tangem.domain.DomainLayer +import com.tangem.domain.appcurrency.repository.AppCurrencyRepository import com.tangem.domain.card.ScanCardProcessor import com.tangem.domain.common.LogConfig import com.tangem.domain.wallets.legacy.WalletManagersRepository @@ -161,6 +162,9 @@ class TapApplication : Application(), ImageLoaderFactory { @Inject lateinit var blockchainExceptionHandler: BlockchainExceptionHandler + @Inject + lateinit var appCurrencyRepository: AppCurrencyRepository + override fun onCreate() { super.onCreate() @@ -179,6 +183,7 @@ class TapApplication : Application(), ImageLoaderFactory { walletConnectSessionsRepository = walletConnectSessionsRepository, tokenDetailsFeatureToggles = tokenDetailsFeatureToggles, scanCardProcessor = scanCardProcessor, + appCurrencyRepository = appCurrencyRepository, ), ), ) diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt index 46835f3076..287b5d35f1 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt @@ -8,10 +8,12 @@ import com.tangem.domain.common.LogConfig import com.tangem.domain.common.extensions.withMainContext import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ScanResponse +import com.tangem.tap.* import com.tangem.tap.common.entities.FiatCurrency import com.tangem.tap.common.extensions.dispatchDebugErrorNotification import com.tangem.tap.common.extensions.dispatchDialogShow import com.tangem.tap.common.extensions.dispatchOnMain +import com.tangem.tap.common.extensions.dispatchWithMain import com.tangem.tap.common.redux.AppDialog import com.tangem.tap.common.redux.AppState import com.tangem.tap.domain.configurable.warningMessage.WarningMessagesManager @@ -24,17 +26,13 @@ import com.tangem.tap.network.exchangeServices.ExchangeService import com.tangem.tap.network.exchangeServices.mercuryo.MercuryoEnvironment import com.tangem.tap.network.exchangeServices.mercuryo.MercuryoService import com.tangem.tap.network.exchangeServices.moonpay.MoonPayService -import com.tangem.tap.preferencesStorage -import com.tangem.tap.scope -import com.tangem.tap.store -import com.tangem.tap.tangemSdkManager -import com.tangem.tap.userTokensRepository -import com.tangem.tap.walletCurrenciesManager +import com.tangem.tap.proxy.redux.DaggerGraphState +import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.launch import org.rekotlin.Action import org.rekotlin.DispatchFunction import org.rekotlin.Middleware -import java.util.* +import java.util.Locale object GlobalMiddleware { val handler = globalMiddlewareHandler @@ -68,13 +66,11 @@ private fun handleAction(action: Action, appState: () -> AppState?, dispatch: Di } } is GlobalAction.RestoreAppCurrency -> { - store.dispatch( - GlobalAction.RestoreAppCurrency.Success( - preferencesStorage.fiatCurrenciesPrefStorage.getAppCurrency() - ?.run { FiatCurrency(code, name, symbol) } - ?: FiatCurrency.Default, - ), - ) + if (store.state.daggerGraphState.get(DaggerGraphState::walletFeatureToggles).isRedesignedScreenEnabled) { + restoreAppCurrencyNew() + } else { + restoreAppCurrencyLegacy() + } } is GlobalAction.HideWarningMessage -> { store.state.globalState.warningManager?.let { @@ -193,6 +189,28 @@ private fun handleAction(action: Action, appState: () -> AppState?, dispatch: Di } } +private fun restoreAppCurrencyLegacy() { + store.dispatch( + GlobalAction.RestoreAppCurrency.Success( + preferencesStorage.fiatCurrenciesPrefStorage.getAppCurrency() + ?.run { FiatCurrency(code, name, symbol) } + ?: FiatCurrency.Default, + ), + ) +} + +private fun restoreAppCurrencyNew() { + scope.launch { + val currency = store.state.daggerGraphState.get(DaggerGraphState::appCurrencyRepository) + .getSelectedAppCurrency() + .firstOrNull() + ?.run { FiatCurrency(code, name, symbol) } + ?: FiatCurrency.Default + + store.dispatchWithMain(GlobalAction.RestoreAppCurrency.Success(currency)) + } +} + private fun makeSellExchangeService(config: Config): ExchangeService { return MoonPayService( apiKey = config.moonPayApiKey, diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/AppCurrencyMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/AppCurrencyMiddleware.kt index bc5e960649..402f1aaef9 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/AppCurrencyMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/AppCurrencyMiddleware.kt @@ -3,12 +3,14 @@ package com.tangem.tap.features.wallet.redux.middlewares import com.tangem.common.extensions.guard import com.tangem.core.analytics.Analytics import com.tangem.data.source.preferences.model.DataSourceCurrency -import com.tangem.data.source.preferences.model.DataSourceFiatCurrency import com.tangem.data.source.preferences.storage.FiatCurrenciesPrefStorage +import com.tangem.domain.appcurrency.repository.AppCurrencyRepository +import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.analytics.events.MainScreen import com.tangem.tap.common.entities.FiatCurrency import com.tangem.tap.common.extensions.dispatchDialogShow +import com.tangem.tap.common.extensions.dispatchWithMain import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.domain.TapWalletManager import com.tangem.tap.features.details.redux.DetailsAction @@ -19,6 +21,8 @@ import com.tangem.tap.features.walletSelector.redux.WalletSelectorAction import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.tap.userWalletsListManager +import com.tangem.utils.coroutines.JobHolder +import com.tangem.utils.coroutines.saveIn import kotlinx.coroutines.launch import timber.log.Timber @@ -26,8 +30,12 @@ class AppCurrencyMiddleware( private val walletRepository: WalletRepository, private val tapWalletManager: TapWalletManager, private val fiatCurrenciesPrefStorage: FiatCurrenciesPrefStorage, + private val featureToggles: WalletFeatureToggles, + private val appCurrencyRepository: AppCurrencyRepository, private val appCurrencyProvider: () -> FiatCurrency, ) { + private val showSelectorJobHolder = JobHolder() + fun handle(action: WalletAction.AppCurrencyAction) { when (action) { is WalletAction.AppCurrencyAction.ChooseAppCurrency -> showSelector() @@ -36,6 +44,52 @@ class AppCurrencyMiddleware( } private fun showSelector() { + if (featureToggles.isRedesignedScreenEnabled) { + showSelectorNew() + } else { + showSelectorLegacy() + } + } + + private fun selectCurrency(action: WalletAction.AppCurrencyAction.SelectAppCurrency) { + Analytics.send(MainScreen.MainCurrencyChanged(AnalyticsParam.CurrencyType.FiatCurrency(action.fiatCurrency))) + + scope.launch { + appCurrencyRepository.changeAppCurrency(action.fiatCurrency.code) + + store.dispatchWithMain(GlobalAction.ChangeAppCurrency(action.fiatCurrency)) + store.dispatchWithMain(DetailsAction.ChangeAppCurrency(action.fiatCurrency)) + store.dispatchWithMain(WalletSelectorAction.ChangeAppCurrency(action.fiatCurrency)) + + val selectedUserWallet = userWalletsListManager.selectedUserWalletSync.guard { + Timber.e("Unable to select currency, no user wallet selected") + return@launch + } + + tapWalletManager.loadData(selectedUserWallet, refresh = true) + } + } + + private fun showSelectorNew() { + scope.launch { + val currencies = appCurrencyRepository.getAvailableAppCurrencies() + + store.dispatchDialogShow( + WalletDialog.CurrencySelectionDialog( + currenciesList = currencies.map { appCurrency -> + FiatCurrency( + code = appCurrency.code, + name = appCurrency.name, + symbol = appCurrency.symbol, + ) + }, + currentAppCurrency = appCurrencyProvider.invoke(), + ), + ) + }.saveIn(showSelectorJobHolder) + } + + private fun showSelectorLegacy() { val storedFiatCurrencies = fiatCurrenciesPrefStorage.restore() if (storedFiatCurrencies.isNotEmpty()) { store.dispatchDialogShow( @@ -65,23 +119,6 @@ class AppCurrencyMiddleware( } } - private fun selectCurrency(action: WalletAction.AppCurrencyAction.SelectAppCurrency) { - Analytics.send(MainScreen.MainCurrencyChanged(AnalyticsParam.CurrencyType.FiatCurrency(action.fiatCurrency))) - fiatCurrenciesPrefStorage.saveAppCurrency( - with(action.fiatCurrency) { DataSourceFiatCurrency(code, name, symbol) }, - ) - store.dispatch(GlobalAction.ChangeAppCurrency(action.fiatCurrency)) - store.dispatch(DetailsAction.ChangeAppCurrency(action.fiatCurrency)) - store.dispatch(WalletSelectorAction.ChangeAppCurrency(action.fiatCurrency)) - val selectedUserWallet = userWalletsListManager.selectedUserWalletSync.guard { - Timber.e("Unable to select currency, no user wallet selected") - return - } - scope.launch { - tapWalletManager.loadData(selectedUserWallet, refresh = true) - } - } - private fun List.mapToUiModel(): List { return this.map { FiatCurrency( diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt index e7d5ff135d..c84ac7fa2d 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt @@ -55,6 +55,8 @@ class WalletMiddleware { walletRepository = store.state.featureRepositoryProvider.walletRepository, tapWalletManager = store.state.globalState.tapWalletManager, fiatCurrenciesPrefStorage = preferencesStorage.fiatCurrenciesPrefStorage, + appCurrencyRepository = store.state.daggerGraphState.get(DaggerGraphState::appCurrencyRepository), + featureToggles = store.state.daggerGraphState.get(DaggerGraphState::walletFeatureToggles), appCurrencyProvider = { store.state.globalState.appCurrency }, ) } diff --git a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt index 228d3f014b..b9be4b9f93 100644 --- a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt +++ b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt @@ -2,6 +2,7 @@ package com.tangem.tap.proxy.redux import com.tangem.datasource.asset.AssetReader import com.tangem.datasource.connection.NetworkConnectionManager +import com.tangem.domain.appcurrency.repository.AppCurrencyRepository import com.tangem.domain.card.ScanCardProcessor import com.tangem.domain.card.ScanCardUseCase import com.tangem.domain.card.repository.CardSdkConfigRepository @@ -31,6 +32,7 @@ data class DaggerGraphState( val tokenDetailsRouter: TokenDetailsRouter? = null, val scanCardProcessor: ScanCardProcessor? = null, val cardSdkConfigRepository: CardSdkConfigRepository? = null, + val appCurrencyRepository: AppCurrencyRepository? = null, ) : StateType { inline fun get(getDependency: DaggerGraphState.() -> T?): T { 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 new file mode 100644 index 0000000000..724634e0a3 --- /dev/null +++ b/core/datasource/src/main/java/com/tangem/datasource/di/AppCurrencyDataModule.kt @@ -0,0 +1,20 @@ +package com.tangem.datasource.di + +import com.tangem.datasource.local.appcurrency.MockSelectedAppCurrencyStore +import com.tangem.datasource.local.appcurrency.SelectedAppCurrencyStore +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +internal object AppCurrencyDataModule { + + @Provides + @Singleton + fun provideSelectedAppCurrencyStore(): SelectedAppCurrencyStore { + return MockSelectedAppCurrencyStore() + } +} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/MockSelectedAppCurrencyStore.kt b/core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/MockSelectedAppCurrencyStore.kt new file mode 100644 index 0000000000..58f48aacc8 --- /dev/null +++ b/core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/MockSelectedAppCurrencyStore.kt @@ -0,0 +1,26 @@ +package com.tangem.datasource.local.appcurrency + +import com.tangem.datasource.api.tangemTech.models.CurrenciesResponse +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf + +// TODO: Will be implemented in [REDACTED_TASK_KEY] task +internal class MockSelectedAppCurrencyStore : SelectedAppCurrencyStore { + + override fun get(): Flow { + return flowOf( + CurrenciesResponse.Currency( + id = "usd", + code = "USD", + name = "US Dollar", + unit = "$", + type = "fiat", + rateBTC = "", + ), + ) + } + + override suspend fun store(item: CurrenciesResponse.Currency) { + /* no-op */ + } +} \ 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 new file mode 100644 index 0000000000..e1fbad8329 --- /dev/null +++ b/core/datasource/src/main/java/com/tangem/datasource/local/appcurrency/SelectedAppCurrencyStore.kt @@ -0,0 +1,11 @@ +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 store(item: CurrenciesResponse.Currency) +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/JobHolder.kt b/core/utils/src/main/java/com/tangem/utils/coroutines/JobHolder.kt similarity index 63% rename from features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/JobHolder.kt rename to core/utils/src/main/java/com/tangem/utils/coroutines/JobHolder.kt index 6414445119..3c0ca6bd8d 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/JobHolder.kt +++ b/core/utils/src/main/java/com/tangem/utils/coroutines/JobHolder.kt @@ -1,4 +1,4 @@ -package com.tangem.feature.wallet.presentation.wallet.viewmodels +package com.tangem.utils.coroutines import kotlinx.coroutines.Job @@ -7,7 +7,7 @@ import kotlinx.coroutines.Job * [REDACTED_AUTHOR] */ -internal class JobHolder { +class JobHolder { private var job: Job? = null @@ -18,4 +18,4 @@ internal class JobHolder { } } -internal fun Job.saveIn(jobHolder: JobHolder) = jobHolder.update(job = this) \ No newline at end of file +fun Job.saveIn(jobHolder: JobHolder) = jobHolder.update(job = this) \ No newline at end of file diff --git a/data/app-currency/src/main/kotlin/com/tangem/data/appcurrency/MockAppCurrencyRepository.kt b/data/app-currency/src/main/kotlin/com/tangem/data/appcurrency/MockAppCurrencyRepository.kt index d9c600872c..e3e518afdc 100644 --- a/data/app-currency/src/main/kotlin/com/tangem/data/appcurrency/MockAppCurrencyRepository.kt +++ b/data/app-currency/src/main/kotlin/com/tangem/data/appcurrency/MockAppCurrencyRepository.kt @@ -17,7 +17,7 @@ internal class MockAppCurrencyRepository : AppCurrencyRepository { return mockAppCurrencies } - override suspend fun changeAppCurrency(appCurrency: AppCurrency) { + override suspend fun changeAppCurrency(currencyCode: String) { /* no-op */ } } \ No newline at end of file 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 7d62d72157..c1229cde5b 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 @@ -5,6 +5,7 @@ import com.tangem.data.tokens.repository.DefaultCurrenciesRepository import com.tangem.data.tokens.repository.DefaultNetworksRepository import com.tangem.data.tokens.repository.DefaultQuotesRepository import com.tangem.datasource.api.tangemTech.TangemTechApi +import com.tangem.datasource.local.appcurrency.SelectedAppCurrencyStore import com.tangem.datasource.local.quote.QuotesStore import com.tangem.datasource.local.token.UserTokensStore import com.tangem.datasource.local.userwallet.UserWalletsStore @@ -40,10 +41,17 @@ internal object TokensDataModule { fun provideQuotesRepository( tangemTechApi: TangemTechApi, quotesStore: QuotesStore, + selectedAppCurrencyStore: SelectedAppCurrencyStore, cacheRegistry: CacheRegistry, dispatchers: CoroutineDispatcherProvider, ): QuotesRepository { - return DefaultQuotesRepository(tangemTechApi, quotesStore, cacheRegistry, dispatchers) + return DefaultQuotesRepository( + tangemTechApi, + quotesStore, + selectedAppCurrencyStore, + cacheRegistry, + dispatchers, + ) } @Provides 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 ea7fdbd998..25fb880a50 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 @@ -3,6 +3,7 @@ package com.tangem.data.tokens.repository import com.tangem.data.common.cache.CacheRegistry import com.tangem.data.tokens.utils.QuotesConverter import com.tangem.datasource.api.tangemTech.TangemTechApi +import com.tangem.datasource.local.appcurrency.SelectedAppCurrencyStore import com.tangem.datasource.local.quote.QuotesStore import com.tangem.domain.tokens.models.CryptoCurrency import com.tangem.domain.tokens.models.Quote @@ -10,6 +11,7 @@ import com.tangem.domain.tokens.repository.QuotesRepository import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.channelFlow +import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import timber.log.Timber @@ -17,12 +19,15 @@ import timber.log.Timber internal class DefaultQuotesRepository( private val tangemTechApi: TangemTechApi, private val quotesStore: QuotesStore, + private val selectedAppCurrencyStore: SelectedAppCurrencyStore, private val cacheRegistry: CacheRegistry, private val dispatchers: CoroutineDispatcherProvider, ) : QuotesRepository { private val quotesConverter = QuotesConverter() + private var quotesFetchedForAppCurrency: String? = null + override fun getQuotes(currenciesIds: Set, refresh: Boolean): Flow> { return channelFlow { launch(dispatchers.io) { @@ -32,22 +37,33 @@ internal class DefaultQuotesRepository( } launch(dispatchers.io) { - fetchExpiredQuotes(currenciesIds, refresh) + selectedAppCurrencyStore.get().collectLatest { appCurrency -> + fetchExpiredQuotes(currenciesIds, appCurrency.id, refresh) + } } } } - private suspend fun fetchExpiredQuotes(currenciesIds: Set, refresh: Boolean) { - val expiredCurrenciesIds = filterExpiredCurrenciesIds(currenciesIds, refresh) + private suspend fun fetchExpiredQuotes( + currenciesIds: Set, + appCurrencyId: String, + refresh: Boolean, + ) { + val expiredCurrenciesIds = filterExpiredCurrenciesIds( + currenciesIds = currenciesIds, + refresh = refresh || quotesFetchedForAppCurrency != appCurrencyId, + ) if (expiredCurrenciesIds.isEmpty()) return - fetchQuotes(expiredCurrenciesIds) + quotesFetchedForAppCurrency = appCurrencyId + + fetchQuotes(expiredCurrenciesIds, appCurrencyId) } - private suspend fun fetchQuotes(rawCurrenciesIds: Set) { + private suspend fun fetchQuotes(rawCurrenciesIds: Set, appCurrencyId: String) { try { val response = tangemTechApi.getQuotes( - currencyId = "usd", // TODO: [REDACTED_JIRA] + currencyId = appCurrencyId, coinIds = rawCurrenciesIds.joinToString(separator = ","), ) diff --git a/domain/app-currency/src/main/kotlin/com/tangem/domain/appcurrency/repository/AppCurrencyRepository.kt b/domain/app-currency/src/main/kotlin/com/tangem/domain/appcurrency/repository/AppCurrencyRepository.kt index d2dafbc461..3ba529f8ae 100644 --- a/domain/app-currency/src/main/kotlin/com/tangem/domain/appcurrency/repository/AppCurrencyRepository.kt +++ b/domain/app-currency/src/main/kotlin/com/tangem/domain/appcurrency/repository/AppCurrencyRepository.kt @@ -9,5 +9,5 @@ interface AppCurrencyRepository { suspend fun getAvailableAppCurrencies(): List - suspend fun changeAppCurrency(appCurrency: AppCurrency) + suspend fun changeAppCurrency(currencyCode: String) } \ No newline at end of file diff --git a/domain/tokens/build.gradle.kts b/domain/tokens/build.gradle.kts index 4099f104eb..e2b240e5bc 100644 --- a/domain/tokens/build.gradle.kts +++ b/domain/tokens/build.gradle.kts @@ -4,11 +4,17 @@ plugins { } dependencies { + + /** Project - Domain */ implementation(projects.domain.core) implementation(projects.domain.tokens.models) implementation(projects.domain.wallets.models) + implementation(projects.domain.appCurrency.models) + + /** Project - Other */ implementation(projects.core.utils) + /** Tests */ testImplementation(deps.test.junit) testImplementation(deps.test.coroutine) } \ No newline at end of file diff --git a/features/wallet/impl/build.gradle.kts b/features/wallet/impl/build.gradle.kts index d517ab1def..ed9a84d4f4 100644 --- a/features/wallet/impl/build.gradle.kts +++ b/features/wallet/impl/build.gradle.kts @@ -56,6 +56,8 @@ dependencies { implementation(projects.domain.txhistory.models) implementation(projects.domain.wallets) implementation(projects.domain.wallets.models) + implementation(projects.domain.appCurrency) + implementation(projects.domain.appCurrency.models) /** Feature Apis */ implementation(projects.features.wallet.api) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt index de6989f860..397a39c2ae 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt @@ -83,6 +83,8 @@ internal class DefaultWalletRouter(private val navigationStateHolder: Navigation } override fun openDetailsScreen() { + // FIXME: Prepare details screen (e.g. dispatch action: `DetailsAction.PrepareScreen`) + // [REDACTED_JIRA] navigationStateHolder.navigate(action = NavigationAction.NavigateTo(AppScreen.Details)) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/WalletLoadedTokensListConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/WalletLoadedTokensListConverter.kt index 6b4f617a1b..de50af78d2 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/WalletLoadedTokensListConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/WalletLoadedTokensListConverter.kt @@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.state.factory import arrow.core.Either import com.tangem.common.Provider +import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.common.CardTypesResolver import com.tangem.domain.tokens.error.TokenListError import com.tangem.domain.tokens.model.TokenList @@ -25,6 +26,7 @@ import com.tangem.utils.converter.Converter */ internal class WalletLoadedTokensListConverter( private val currentStateProvider: Provider, + appCurrencyProvider: Provider, cardTypeResolverProvider: Provider, isLockedWalletProvider: Provider, clickIntents: WalletClickIntents, @@ -34,9 +36,8 @@ internal class WalletLoadedTokensListConverter( currentStateProvider = currentStateProvider, cardTypeResolverProvider = cardTypeResolverProvider, isLockedWalletProvider = isLockedWalletProvider, + appCurrencyProvider = appCurrencyProvider, isWalletContentHidden = false, // TODO: [REDACTED_JIRA] - fiatCurrencyCode = "USD", // TODO: [REDACTED_JIRA] - fiatCurrencySymbol = "$", // TODO: [REDACTED_JIRA] clickIntents = clickIntents, ) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/WalletSingleCurrencyLoadedBalanceConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/WalletSingleCurrencyLoadedBalanceConverter.kt index 6abcf3e185..c6d3e7fae9 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/WalletSingleCurrencyLoadedBalanceConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/WalletSingleCurrencyLoadedBalanceConverter.kt @@ -5,6 +5,7 @@ import com.tangem.common.Provider import com.tangem.core.ui.components.marketprice.MarketPriceBlockState import com.tangem.core.ui.components.marketprice.PriceChangeConfig import com.tangem.core.ui.utils.BigDecimalFormatter +import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.common.CardTypesResolver import com.tangem.domain.tokens.error.CurrencyError import com.tangem.domain.tokens.model.CryptoCurrencyStatus @@ -20,8 +21,7 @@ import java.math.BigDecimal internal class WalletSingleCurrencyLoadedBalanceConverter( private val currentStateProvider: Provider, private val cardTypeResolverProvider: Provider, - private val fiatCurrencyCode: String, - private val fiatCurrencySymbol: String, + private val appCurrencyProvider: Provider, ) : Converter, WalletSingleCurrencyState.Content> { override fun convert(value: Either): WalletSingleCurrencyState.Content { @@ -47,7 +47,7 @@ internal class WalletSingleCurrencyLoadedBalanceConverter( is CryptoCurrencyStatus.Loaded, -> MarketPriceBlockState.Content( currencyName = currencyName, - price = formatPrice(status), + price = formatPrice(status, appCurrencyProvider()), priceChangeConfig = PriceChangeConfig( valueInPercent = formatPriceChange(status), type = getPriceChangeType(status), @@ -67,6 +67,7 @@ internal class WalletSingleCurrencyLoadedBalanceConverter( state: WalletSingleCurrencyState, ): WalletsListConfig { val selectedWallet = state.walletsListConfig.wallets[state.walletsListConfig.selectedWalletIndex] + val updatedWallet = when (status) { is CryptoCurrencyStatus.NoQuote, is CryptoCurrencyStatus.Loaded, @@ -81,7 +82,7 @@ internal class WalletSingleCurrencyLoadedBalanceConverter( ), imageResId = selectedWallet.imageResId, onClick = selectedWallet.onClick, - balance = formatFiatAmount(status), + balance = formatFiatAmount(status, appCurrencyProvider()), ) } is CryptoCurrencyStatus.Loading -> { @@ -133,23 +134,23 @@ internal class WalletSingleCurrencyLoadedBalanceConverter( ) } - private fun formatPrice(status: CryptoCurrencyStatus.Status): String { + private fun formatPrice(status: CryptoCurrencyStatus.Status, appCurrency: AppCurrency): String { val fiatRate = status.fiatRate ?: return BigDecimalFormatter.EMPTY_BALANCE_SIGN return BigDecimalFormatter.formatFiatAmount( fiatAmount = fiatRate, - fiatCurrencyCode = fiatCurrencyCode, - fiatCurrencySymbol = fiatCurrencySymbol, + fiatCurrencyCode = appCurrency.code, + fiatCurrencySymbol = appCurrency.symbol, ) } - private fun formatFiatAmount(status: CryptoCurrencyStatus.Status): String { + private fun formatFiatAmount(status: CryptoCurrencyStatus.Status, appCurrency: AppCurrency): String { val fiatAmount = status.fiatAmount ?: return BigDecimalFormatter.EMPTY_BALANCE_SIGN return BigDecimalFormatter.formatFiatAmount( fiatAmount = fiatAmount, - fiatCurrencyCode = fiatCurrencyCode, - fiatCurrencySymbol = fiatCurrencySymbol, + fiatCurrencyCode = appCurrency.code, + fiatCurrencySymbol = appCurrency.symbol, ) } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/WalletStateFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/WalletStateFactory.kt index 80436dcaa8..9e274774b5 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/WalletStateFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/WalletStateFactory.kt @@ -3,6 +3,7 @@ package com.tangem.feature.wallet.presentation.wallet.state.factory import androidx.paging.PagingData import arrow.core.Either import com.tangem.common.Provider +import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.common.CardTypesResolver import com.tangem.domain.tokens.error.CurrencyError import com.tangem.domain.tokens.error.TokenListError @@ -37,6 +38,7 @@ internal class WalletStateFactory( private val currentStateProvider: Provider, private val currentCardTypeResolverProvider: Provider, private val isLockedWalletProvider: Provider, + private val appCurrencyProvider: Provider, private val clickIntents: WalletClickIntents, ) { @@ -47,6 +49,7 @@ internal class WalletStateFactory( currentStateProvider = currentStateProvider, cardTypeResolverProvider = currentCardTypeResolverProvider, isLockedWalletProvider = isLockedWalletProvider, + appCurrencyProvider = appCurrencyProvider, clickIntents = clickIntents, ) } @@ -70,8 +73,7 @@ internal class WalletStateFactory( WalletSingleCurrencyLoadedBalanceConverter( currentStateProvider = currentStateProvider, cardTypeResolverProvider = currentCardTypeResolverProvider, - fiatCurrencyCode = "USD", // TODO: [REDACTED_JIRA] - fiatCurrencySymbol = "$", // TODO: [REDACTED_JIRA] + appCurrencyProvider = appCurrencyProvider, ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/CryptoCurrencyStatusToTokenItemConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/CryptoCurrencyStatusToTokenItemConverter.kt index 2779e6473a..1790a50da4 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/CryptoCurrencyStatusToTokenItemConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/CryptoCurrencyStatusToTokenItemConverter.kt @@ -1,8 +1,10 @@ package com.tangem.feature.wallet.presentation.wallet.utils import androidx.annotation.DrawableRes +import com.tangem.common.Provider import com.tangem.core.ui.components.marketprice.PriceChangeConfig import com.tangem.core.ui.utils.BigDecimalFormatter +import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.models.CryptoCurrency import com.tangem.feature.wallet.impl.R @@ -11,9 +13,8 @@ import com.tangem.utils.converter.Converter import java.math.BigDecimal internal class CryptoCurrencyStatusToTokenItemConverter( + private val appCurrencyProvider: Provider, private val isWalletContentHidden: Boolean, - private val fiatCurrencyCode: String, - private val fiatCurrencySymbol: String, ) : Converter { private val CryptoCurrencyStatus.networkIconResId: Int? @@ -71,8 +72,9 @@ internal class CryptoCurrencyStatusToTokenItemConverter( private fun CryptoCurrencyStatus.getFormattedFiatAmount(): String { val fiatAmount = value.fiatAmount ?: return UNKNOWN_AMOUNT_SIGN + val appCurrency = appCurrencyProvider() - return BigDecimalFormatter.formatFiatAmount(fiatAmount, fiatCurrencyCode, fiatCurrencySymbol) + return BigDecimalFormatter.formatFiatAmount(fiatAmount, appCurrency.code, appCurrency.symbol) } private fun CryptoCurrencyStatus.mapToUnreachableTokenItemState() = TokenItemState.Unreachable( diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/FiatBalanceToWalletCardConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/FiatBalanceToWalletCardConverter.kt index c8b1d0b3b3..8d48f9b5ec 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/FiatBalanceToWalletCardConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/FiatBalanceToWalletCardConverter.kt @@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.utils import com.tangem.common.Provider import com.tangem.core.ui.utils.BigDecimalFormatter.formatFiatAmount +import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.common.CardTypesResolver import com.tangem.domain.tokens.model.TokenList import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory @@ -11,10 +12,9 @@ import com.tangem.utils.converter.Converter internal class FiatBalanceToWalletCardConverter( private val currentState: WalletCardState, private val cardTypeResolverProvider: Provider, + private val appCurrencyProvider: Provider, private val isLockedState: Boolean, private val isWalletContentHidden: Boolean, - private val fiatCurrencyCode: String, - private val fiatCurrencySymbol: String, ) : Converter { override fun convert(value: TokenList.FiatBalance): WalletCardState { @@ -33,13 +33,15 @@ internal class FiatBalanceToWalletCardConverter( if (isWalletContentHidden) { WalletCardState.HiddenContent(id, title, additionalInfo, imageResId, onClick) } else { + val appCurrency = appCurrencyProvider() + WalletCardState.Content( id = id, title = title, additionalInfo = additionalInfo, imageResId = imageResId, onClick = onClick, - balance = formatFiatAmount(value.amount, fiatCurrencyCode, fiatCurrencySymbol), + balance = formatFiatAmount(value.amount, appCurrency.code, appCurrency.symbol), ) } } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/TokenListToContentItemsConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/TokenListToContentItemsConverter.kt index 7fc1815c63..8bef92141f 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/TokenListToContentItemsConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/TokenListToContentItemsConverter.kt @@ -1,6 +1,8 @@ package com.tangem.feature.wallet.presentation.wallet.utils +import com.tangem.common.Provider import com.tangem.core.ui.extensions.TextReference +import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.NetworkGroup import com.tangem.domain.tokens.model.TokenList @@ -14,16 +16,14 @@ import kotlinx.collections.immutable.mutate import kotlinx.collections.immutable.persistentListOf internal class TokenListToContentItemsConverter( + appCurrencyProvider: Provider, isWalletContentHidden: Boolean, - fiatCurrencyCode: String, - fiatCurrencySymbol: String, private val clickIntents: WalletClickIntents, ) : Converter { private val tokenStatusConverter = CryptoCurrencyStatusToTokenItemConverter( isWalletContentHidden = isWalletContentHidden, - fiatCurrencyCode = fiatCurrencyCode, - fiatCurrencySymbol = fiatCurrencySymbol, + appCurrencyProvider = appCurrencyProvider, ) override fun convert(value: TokenList): WalletTokensListState { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/TokenListToWalletStateConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/TokenListToWalletStateConverter.kt index e4e37d8e7d..fb21502fe6 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/TokenListToWalletStateConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/utils/TokenListToWalletStateConverter.kt @@ -1,6 +1,7 @@ package com.tangem.feature.wallet.presentation.wallet.utils import com.tangem.common.Provider +import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.common.CardTypesResolver import com.tangem.domain.tokens.model.TokenList import com.tangem.feature.wallet.presentation.common.state.TokenItemState @@ -18,16 +19,14 @@ internal class TokenListToWalletStateConverter( private val currentStateProvider: Provider, private val cardTypeResolverProvider: Provider, private val isLockedWalletProvider: Provider, + private val appCurrencyProvider: Provider, private val isWalletContentHidden: Boolean, - private val fiatCurrencyCode: String, - private val fiatCurrencySymbol: String, clickIntents: WalletClickIntents, ) : Converter { private val tokenListToContentConverter = TokenListToContentItemsConverter( isWalletContentHidden = isWalletContentHidden, - fiatCurrencyCode = fiatCurrencyCode, - fiatCurrencySymbol = fiatCurrencySymbol, + appCurrencyProvider = appCurrencyProvider, clickIntents = clickIntents, ) @@ -51,9 +50,8 @@ internal class TokenListToWalletStateConverter( currentState = selectedWalletCard, isLockedState = isLockedWalletProvider(), cardTypeResolverProvider = cardTypeResolverProvider, + appCurrencyProvider = appCurrencyProvider, isWalletContentHidden = isWalletContentHidden, - fiatCurrencyCode = fiatCurrencyCode, - fiatCurrencySymbol = fiatCurrencySymbol, ) return walletsListConfig.copy( diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt index f7d4a9fb1b..3745757446 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt @@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.viewmodels import androidx.lifecycle.* import androidx.paging.cachedIn +import arrow.core.getOrElse import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.derivation.DerivationStyle import com.tangem.common.Provider @@ -9,6 +10,8 @@ import com.tangem.common.doOnFailure import com.tangem.common.doOnSuccess import com.tangem.core.ui.components.marketprice.MarketPriceBlockState import com.tangem.core.ui.components.transactions.state.TxHistoryState +import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase +import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.card.* import com.tangem.domain.common.CardTypesResolver import com.tangem.domain.common.extensions.derivationPath @@ -37,11 +40,10 @@ import com.tangem.feature.wallet.presentation.wallet.state.components.WalletCard import com.tangem.feature.wallet.presentation.wallet.state.components.WalletTokensListState import com.tangem.feature.wallet.presentation.wallet.state.factory.WalletStateFactory import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import com.tangem.utils.coroutines.JobHolder +import com.tangem.utils.coroutines.saveIn import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import javax.inject.Inject import kotlin.properties.Delegates @@ -71,12 +73,15 @@ internal class WalletViewModel @Inject constructor( private val txHistoryItemsUseCase: GetTxHistoryItemsUseCase, private val getExploreUrlUseCase: GetExploreUrlUseCase, private val unlockWalletsUseCase: UnlockWalletsUseCase, + private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, private val dispatchers: CoroutineDispatcherProvider, ) : ViewModel(), DefaultLifecycleObserver, WalletClickIntents { /** Feature router */ var router: InnerWalletRouter by Delegates.notNull() + private val selectedAppCurrencyFlow: StateFlow = createSelectedAppCurrencyFlow() + private val notificationsListFactory = WalletNotificationsListFactory( currentStateProvider = Provider { uiState }, wasCardScannedCallback = getCardWasScannedUseCase::invoke, @@ -95,6 +100,7 @@ internal class WalletViewModel @Inject constructor( isLockedWalletProvider = Provider { wallets[requireNotNull(uiState as? WalletState.ContentState).walletsListConfig.selectedWalletIndex].isLocked }, + appCurrencyProvider = Provider(selectedAppCurrencyFlow::value), clickIntents = this, ) @@ -432,4 +438,16 @@ internal class WalletViewModel @Inject constructor( override fun onBottomSheetDismiss() { uiState = stateFactory.getStateWithClosedBottomSheet() } + + private fun createSelectedAppCurrencyFlow(): StateFlow { + return getSelectedAppCurrencyUseCase() + .map { maybeAppCurrency -> + maybeAppCurrency.getOrElse { AppCurrency.Default } + } + .stateIn( + scope = viewModelScope, + started = SharingStarted.Eagerly, + initialValue = AppCurrency.Default, + ) + } } \ No newline at end of file