diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index a051f8f5a4..13cc92062e 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -62,6 +62,7 @@ import com.tangem.tap.domain.walletStores.repository.di.provideDefaultImplementa import com.tangem.tap.domain.walletconnect.WalletConnectRepository import com.tangem.tap.domain.walletconnect2.domain.WalletConnectSessionsRepository import com.tangem.tap.features.customtoken.api.featuretoggles.CustomTokenFeatureToggles +import com.tangem.tap.features.details.featuretoggles.DetailsFeatureToggles import com.tangem.tap.proxy.AppStateHolder import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.wallet.BuildConfig @@ -176,6 +177,9 @@ class TapApplication : Application(), ImageLoaderFactory { @Inject lateinit var appThemeModeRepository: AppThemeModeRepository + @Inject + lateinit var detailsFeatureToggles: DetailsFeatureToggles + override fun onCreate() { super.onCreate() @@ -199,6 +203,7 @@ class TapApplication : Application(), ImageLoaderFactory { appStateHolder = appStateHolder, currenciesRepository = currenciesRepository, appThemeModeRepository = appThemeModeRepository, + detailsFeatureToggles = detailsFeatureToggles, ), ), ) diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt index f90e296e22..5f4abc182a 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt @@ -7,6 +7,7 @@ import com.tangem.core.navigation.FragmentShareTransition import com.tangem.feature.referral.ReferralFragment import com.tangem.feature.swap.presentation.SwapFragment import com.tangem.tap.features.customtoken.impl.presentation.AddCustomTokenFragment +import com.tangem.tap.features.details.ui.appcurrency.AppCurrencySelectorFragment import com.tangem.tap.features.details.ui.appsettings.AppSettingsFragment import com.tangem.tap.features.details.ui.cardsettings.CardSettingsFragment import com.tangem.tap.features.details.ui.cardsettings.coderecovery.AccessCodeRecoveryFragment @@ -174,5 +175,6 @@ private fun fragmentFactory(screen: AppScreen): Fragment { AppScreen.Welcome -> WelcomeFragment() AppScreen.SaveWallet -> SaveWalletBottomSheetFragment() AppScreen.WalletSelector -> WalletSelectorBottomSheetFragment() + AppScreen.AppCurrencySelector -> AppCurrencySelectorFragment() } } \ No newline at end of file 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 4f74fdbdf9..0f2f76f8d0 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 @@ -66,7 +66,13 @@ private fun handleAction(action: Action, appState: () -> AppState?, dispatch: Di } } is GlobalAction.RestoreAppCurrency -> { - if (store.state.daggerGraphState.get(DaggerGraphState::walletFeatureToggles).isRedesignedScreenEnabled) { + val daggerGraphState = store.state.daggerGraphState + val walletFeatureToggles = daggerGraphState.get(DaggerGraphState::walletFeatureToggles) + val detailsFeatureToggles = daggerGraphState.get(DaggerGraphState::detailsFeatureToggles) + + if (walletFeatureToggles.isRedesignedScreenEnabled || + detailsFeatureToggles.isRedesignedAppCurrencySelectorEnabled + ) { restoreAppCurrencyNew() } else { restoreAppCurrencyLegacy() diff --git a/app/src/main/java/com/tangem/tap/features/details/featuretoggles/DefaultDetailsFeatureToggles.kt b/app/src/main/java/com/tangem/tap/features/details/featuretoggles/DefaultDetailsFeatureToggles.kt new file mode 100644 index 0000000000..2ed04a4c94 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/details/featuretoggles/DefaultDetailsFeatureToggles.kt @@ -0,0 +1,11 @@ +package com.tangem.tap.features.details.featuretoggles + +import com.tangem.core.featuretoggle.manager.FeatureTogglesManager + +internal class DefaultDetailsFeatureToggles( + private val featureTogglesManager: FeatureTogglesManager, +) : DetailsFeatureToggles { + + override val isRedesignedAppCurrencySelectorEnabled: Boolean + get() = featureTogglesManager.isFeatureEnabled(name = "REDESIGNED_APP_CURRENCY_SELECTOR_ENABLED") +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/featuretoggles/DetailsFeatureToggles.kt b/app/src/main/java/com/tangem/tap/features/details/featuretoggles/DetailsFeatureToggles.kt new file mode 100644 index 0000000000..dd1cd3bbdd --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/details/featuretoggles/DetailsFeatureToggles.kt @@ -0,0 +1,6 @@ +package com.tangem.tap.features.details.featuretoggles + +interface DetailsFeatureToggles { + + val isRedesignedAppCurrencySelectorEnabled: Boolean +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/featuretoggles/DetailsFeatureTogglesModule.kt b/app/src/main/java/com/tangem/tap/features/details/featuretoggles/DetailsFeatureTogglesModule.kt new file mode 100644 index 0000000000..2e6fd9874a --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/details/featuretoggles/DetailsFeatureTogglesModule.kt @@ -0,0 +1,17 @@ +package com.tangem.tap.features.details.featuretoggles + +import com.tangem.core.featuretoggle.manager.FeatureTogglesManager +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent + +@Module +@InstallIn(SingletonComponent::class) +internal object DetailsFeatureTogglesModule { + + @Provides + fun provideDetailsFeatureToggles(featureTogglesManager: FeatureTogglesManager): DetailsFeatureToggles { + return DefaultDetailsFeatureToggles(featureTogglesManager) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt index f65bb76b14..5ad30d0372 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt @@ -84,6 +84,10 @@ sealed class DetailsAction : Action { data class ChangeAppThemeMode( val appThemeMode: AppThemeMode, ) : AppSettings() + + data class ChangeAppCurrency( + val fiatCurrency: FiatCurrency, + ) : AppSettings() } data class ChangeAppCurrency(val fiatCurrency: FiatCurrency) : DetailsAction() diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt index 6c15790af7..11c2dd536a 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt @@ -39,6 +39,7 @@ import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.features.onboarding.products.twins.redux.CreateTwinWalletMode import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction import com.tangem.tap.features.wallet.redux.WalletAction +import com.tangem.tap.features.walletSelector.redux.WalletSelectorAction import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.tap.tangemSdkManager import com.tangem.wallet.R @@ -206,6 +207,11 @@ class DetailsMiddleware { is DetailsAction.AppSettings.ChangeAppThemeMode -> { changeAppThemeMode(action.appThemeMode) } + is DetailsAction.AppSettings.ChangeAppCurrency -> { + store.dispatch(GlobalAction.ChangeAppCurrency(action.fiatCurrency)) + store.dispatch(DetailsAction.ChangeAppCurrency(action.fiatCurrency)) + store.dispatch(WalletSelectorAction.ChangeAppCurrency(action.fiatCurrency)) + } is DetailsAction.AppSettings.SwitchPrivacySetting.Success, is DetailsAction.AppSettings.SwitchPrivacySetting.Failure, is DetailsAction.AppSettings.BiometricsStatusChanged, diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt index b2754c775e..0c603db0cd 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt @@ -216,6 +216,11 @@ private fun handlePrivacyAction(action: DetailsAction.AppSettings, state: Detail selectedThemeMode = action.appThemeMode, ), ) + is DetailsAction.AppSettings.ChangeAppCurrency -> state.copy( + appSettingsState = state.appSettingsState.copy( + selectedFiatCurrency = action.fiatCurrency, + ), + ) is DetailsAction.AppSettings.EnrollBiometrics, is DetailsAction.AppSettings.CheckBiometricsStatus, -> state diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/AppCurrencySelectorFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/AppCurrencySelectorFragment.kt index 72550be701..b9273ef99b 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/AppCurrencySelectorFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/AppCurrencySelectorFragment.kt @@ -1,7 +1,10 @@ package com.tangem.tap.features.details.ui.appcurrency import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.fragment.app.viewModels +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.tangem.core.ui.components.SystemBarsEffect import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.screen.ComposeFragment @@ -15,6 +18,8 @@ internal class AppCurrencySelectorFragment : ComposeFragment() { @Inject override lateinit var appThemeModeHolder: AppThemeModeHolder + private val viewModel: AppCurrencySelectorViewModel by viewModels() + @Composable override fun ScreenContent(modifier: Modifier) { val systemBarsColor = TangemTheme.colors.background.secondary @@ -22,9 +27,10 @@ internal class AppCurrencySelectorFragment : ComposeFragment() { setSystemBarsColor(systemBarsColor) } + val uiState by viewModel.uiState.collectAsStateWithLifecycle() AppCurrencySelectorScreen( modifier = modifier, - state = AppCurrencySelectorState.Loading({}), // TODO: Will be updated in next MR + state = uiState, ) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/AppCurrencySelectorIntents.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/AppCurrencySelectorIntents.kt new file mode 100644 index 0000000000..b6d25d03a0 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/AppCurrencySelectorIntents.kt @@ -0,0 +1,14 @@ +package com.tangem.tap.features.details.ui.appcurrency + +internal interface AppCurrencySelectorIntents { + + fun onBackClick() + + fun onSearchClick() + + fun onSearchInputChange(input: String) + + fun onCurrencyClick(currency: AppCurrencySelectorState.Currency) + + fun onDismissSearchClick() +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/AppCurrencySelectorState.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/AppCurrencySelectorState.kt index f50d52cc3e..b3b606c396 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/AppCurrencySelectorState.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/AppCurrencySelectorState.kt @@ -20,6 +20,29 @@ internal sealed class AppCurrencySelectorState { abstract val items: PersistentList abstract val onCurrencyClick: (Currency) -> Unit abstract val onTopBarActionClick: () -> Unit + + fun copySealed( + selectedId: String? = this.selectedId, + items: PersistentList = this.items, + scrollToSelected: StateEvent = this.scrollToSelected, + onCurrencyClick: (Currency) -> Unit = this.onCurrencyClick, + onTopBarActionClick: () -> Unit = this.onTopBarActionClick, + ): AppCurrencySelectorState = when (this) { + is Default -> this.copy( + selectedId = selectedId.orEmpty(), + items = items, + scrollToSelected = scrollToSelected, + onCurrencyClick = onCurrencyClick, + onTopBarActionClick = onTopBarActionClick, + ) + is Search -> this.copy( + selectedId = selectedId.orEmpty(), + items = items, + scrollToSelected = scrollToSelected, + onCurrencyClick = onCurrencyClick, + onTopBarActionClick = onTopBarActionClick, + ) + } } data class Default( diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/AppCurrencySelectorStateHolder.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/AppCurrencySelectorStateHolder.kt new file mode 100644 index 0000000000..6f091f4376 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/AppCurrencySelectorStateHolder.kt @@ -0,0 +1,125 @@ +package com.tangem.tap.features.details.ui.appcurrency + +import com.tangem.core.ui.event.consumedEvent +import com.tangem.core.ui.event.triggeredEvent +import com.tangem.domain.appcurrency.model.AppCurrency +import com.tangem.tap.features.details.ui.appcurrency.converter.CurrencyConverter +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.mutate +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toPersistentList +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.* + +internal class AppCurrencySelectorStateHolder( + private val intents: AppCurrencySelectorIntents, + private val onSubscription: () -> Unit, + stateFlowScope: CoroutineScope, +) { + + private var availableCurrencies: PersistentList = persistentListOf() + + private val stateFlowInternal: MutableStateFlow = MutableStateFlow(getInitialState()) + + private val currencyConverter by lazy(mode = LazyThreadSafetyMode.NONE) { CurrencyConverter() } + + val stateFlow: StateFlow = stateFlowInternal + .onSubscription { onSubscription() } + .stateIn( + scope = stateFlowScope, + started = SharingStarted.WhileSubscribed(), + initialValue = getInitialState(), + ) + + fun updateStateWithAvailableCurrencies(currencies: List) { + availableCurrencies = currencyConverter.convertList(currencies).toPersistentList() + + updateState { + when (this) { + is AppCurrencySelectorState.Loading -> getContentState(availableCurrencies) + is AppCurrencySelectorState.Content -> copySealed(items = availableCurrencies) + } + } + } + + fun updateStateWithSelectedCurrency(selectedCurrency: AppCurrency, selectedCurrencyIndex: Int) { + val selectedCurrencyId = selectedCurrency.code + + updateState { + when (this) { + is AppCurrencySelectorState.Loading -> this + is AppCurrencySelectorState.Content -> copySealed( + selectedId = selectedCurrencyId, + scrollToSelected = triggeredEvent(selectedCurrencyIndex, ::consumeScrollToSelectedEvent), + ) + } + } + } + + fun updateStateWithSearch(input: String = "") { + val filteredItems = availableCurrencies.mutate { list -> + list.removeAll { input.lowercase() !in it.name.lowercase() } + } + + updateState { + when (this) { + is AppCurrencySelectorState.Loading -> this + is AppCurrencySelectorState.Search -> copy(items = filteredItems) + is AppCurrencySelectorState.Default -> getSearchState(filteredItems, selectedId) + } + } + } + + fun updateStateWithoutSearch() { + updateState { + when (this) { + is AppCurrencySelectorState.Search -> getContentState(availableCurrencies, selectedId) + is AppCurrencySelectorState.Default, + is AppCurrencySelectorState.Loading, + -> this + } + } + } + + private fun getInitialState() = AppCurrencySelectorState.Loading( + onBackClick = intents::onBackClick, + ) + + private fun getContentState( + items: PersistentList, + selectedCurrencyId: String = "", + ) = AppCurrencySelectorState.Default( + selectedId = selectedCurrencyId, + items = items, + onBackClick = intents::onBackClick, + onCurrencyClick = intents::onCurrencyClick, + onTopBarActionClick = intents::onSearchClick, + scrollToSelected = consumedEvent(), + ) + + private fun getSearchState( + filteredItems: PersistentList, + selectedCurrencyId: String, + ) = AppCurrencySelectorState.Search( + selectedId = selectedCurrencyId, + items = filteredItems, + scrollToSelected = consumedEvent(), + onBackClick = intents::onBackClick, + onCurrencyClick = intents::onCurrencyClick, + onSearchInputChange = intents::onSearchInputChange, + onTopBarActionClick = intents::onDismissSearchClick, + ) + + private inline fun updateState(block: AppCurrencySelectorState.() -> AppCurrencySelectorState) { + stateFlowInternal.update(block) + } + + private fun consumeScrollToSelectedEvent() { + updateState { + when (this) { + is AppCurrencySelectorState.Loading -> this + is AppCurrencySelectorState.Content -> copySealed(scrollToSelected = consumedEvent()) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/AppCurrencySelectorViewModel.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/AppCurrencySelectorViewModel.kt new file mode 100644 index 0000000000..4013947c19 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/AppCurrencySelectorViewModel.kt @@ -0,0 +1,74 @@ +package com.tangem.tap.features.details.ui.appcurrency + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.tangem.core.navigation.ReduxNavController +import com.tangem.domain.appcurrency.GetAvailableCurrenciesUseCase +import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase +import com.tangem.domain.appcurrency.SelectAppCurrencyUseCase +import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +internal class AppCurrencySelectorViewModel @Inject constructor( + private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, + private val getAvailableCurrenciesUseCase: GetAvailableCurrenciesUseCase, + private val selectAppCurrencyUseCase: SelectAppCurrencyUseCase, + private val reduxNavController: ReduxNavController, + private val dispatchers: CoroutineDispatcherProvider, +) : ViewModel(), AppCurrencySelectorIntents { + + private val stateController = AppCurrencySelectorStateHolder( + intents = this, + onSubscription = { fetchCurrencies() }, + stateFlowScope = viewModelScope, + ) + + val uiState: StateFlow = stateController.stateFlow + + override fun onBackClick() { + reduxNavController.popBackStack() + } + + override fun onSearchClick() { + stateController.updateStateWithSearch() + } + + override fun onSearchInputChange(input: String) { + stateController.updateStateWithSearch(input) + } + + override fun onCurrencyClick(currency: AppCurrencySelectorState.Currency) { + viewModelScope.launch(dispatchers.io) { + selectAppCurrencyUseCase(currency.id) + .onRight { reduxNavController.popBackStack() } + } + } + + override fun onDismissSearchClick() { + stateController.updateStateWithoutSearch() + } + + private fun fetchCurrencies() { + viewModelScope.launch(dispatchers.io) { + val availableCurrencies = getAvailableCurrenciesUseCase() + .onRight(stateController::updateStateWithAvailableCurrencies) + .getOrNull() + + getSelectedAppCurrencyUseCase().collectLatest { maybeSelectedCurrency -> + maybeSelectedCurrency + .onRight { selectedCurrency -> + val selectedCurrencyIndex = availableCurrencies?.indexOfFirst { it == selectedCurrency } + + if (selectedCurrencyIndex != null && selectedCurrencyIndex != -1) { + stateController.updateStateWithSelectedCurrency(selectedCurrency, selectedCurrencyIndex) + } + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/converter/CurrencyConverter.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/converter/CurrencyConverter.kt new file mode 100644 index 0000000000..9e6df0ed22 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/details/ui/appcurrency/converter/CurrencyConverter.kt @@ -0,0 +1,14 @@ +package com.tangem.tap.features.details.ui.appcurrency.converter + +import com.tangem.domain.appcurrency.model.AppCurrency +import com.tangem.tap.features.details.ui.appcurrency.AppCurrencySelectorState +import com.tangem.utils.converter.Converter + +internal class CurrencyConverter : Converter { + + override fun convert(value: AppCurrency): AppCurrencySelectorState.Currency { + val fullCurrencyName = with(value) { "$name ($code) - $symbol" } + + return AppCurrencySelectorState.Currency(value.code, fullCurrencyName) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsFragment.kt index b1d8e9b55c..7086d1408e 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsFragment.kt @@ -8,6 +8,8 @@ import androidx.transition.TransitionInflater import com.tangem.core.navigation.NavigationAction import com.tangem.core.ui.screen.ComposeFragment import com.tangem.core.ui.theme.AppThemeModeHolder +import com.tangem.domain.appcurrency.repository.AppCurrencyRepository +import com.tangem.tap.features.details.featuretoggles.DetailsFeatureToggles import com.tangem.tap.features.details.redux.DetailsAction import com.tangem.tap.features.details.redux.DetailsState import com.tangem.tap.store @@ -22,7 +24,15 @@ internal class AppSettingsFragment : ComposeFragment(), StoreSubscriber) { +internal class AppSettingsViewModel( + private val store: Store, + private val detailsFeatureToggles: DetailsFeatureToggles, + private val appCurrencyRepository: AppCurrencyRepository, +) { private val itemsFactory = AppSettingsItemsFactory() private val dialogsFactory = AppSettingsDialogsFactory() + private val appCurrencyUpdatesJobHolder = JobHolder() + var uiState: AppSettingsScreenState by mutableStateOf(AppSettingsScreenState.Loading) private set + init { + if (detailsFeatureToggles.isRedesignedAppCurrencySelectorEnabled) { + bootstrapAppCurrencyUpdates() + } + } + fun updateState(state: DetailsState) { uiState = AppSettingsScreenState.Content( items = buildItems(state.appSettingsState), @@ -89,7 +112,13 @@ internal class AppSettingsViewModel(private val store: Store) { } private fun showAppCurrencySelector() { - store.dispatchOnMain(WalletAction.AppCurrencyAction.ChooseAppCurrency) + val action = if (detailsFeatureToggles.isRedesignedAppCurrencySelectorEnabled) { + NavigationAction.NavigateTo(AppScreen.AppCurrencySelector) + } else { + WalletAction.AppCurrencyAction.ChooseAppCurrency + } + + store.dispatchOnMain(action) } private fun showThemeModeSelector(selectedMode: AppThemeMode) { @@ -151,6 +180,17 @@ internal class AppSettingsViewModel(private val store: Store) { updateContentState { copy(dialog = null) } } + private fun bootstrapAppCurrencyUpdates() { + appCurrencyRepository + .getSelectedAppCurrency() + .onEach { + val fiatCurrency = with(it) { FiatCurrency(code, name, symbol) } + store.dispatchWithMain(DetailsAction.AppSettings.ChangeAppCurrency(fiatCurrency)) + } + .launchIn(scope) + .saveIn(appCurrencyUpdatesJobHolder) + } + private fun updateContentState(block: AppSettingsScreenState.Content.() -> AppSettingsScreenState.Content) { uiState = when (val state = uiState) { is AppSettingsScreenState.Content -> block(state) diff --git a/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt b/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt index 5aa105d76a..d19842021e 100644 --- a/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt +++ b/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt @@ -58,6 +58,10 @@ class AppStateHolder @Inject constructor() : WalletsStateHolder, ReduxNavControl override fun getBackStack(): List = mainStore?.state?.navigationState?.backStack.orEmpty() + override fun popBackStack(screen: AppScreen?) { + mainStore?.dispatch(NavigationAction.PopBackTo(screen)) + } + override fun dispatch(action: Action) { mainStore?.dispatch(action) } 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 7be3ae88ba..215e6e22de 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 @@ -18,6 +18,7 @@ import com.tangem.tap.domain.walletconnect2.domain.WalletConnectInteractor import com.tangem.tap.domain.walletconnect2.domain.WalletConnectRepository import com.tangem.tap.domain.walletconnect2.domain.WalletConnectSessionsRepository import com.tangem.tap.features.customtoken.api.featuretoggles.CustomTokenFeatureToggles +import com.tangem.tap.features.details.featuretoggles.DetailsFeatureToggles import com.tangem.tap.proxy.AppStateHolder import org.rekotlin.StateType @@ -40,6 +41,7 @@ data class DaggerGraphState( val walletManagersFacade: WalletManagersFacade? = null, val appStateHolder: AppStateHolder? = null, val appThemeModeRepository: AppThemeModeRepository? = null, + val detailsFeatureToggles: DetailsFeatureToggles? = null, // FIXME: It is used only for TokensList screen. Remove after refactoring of TokensList val currenciesRepository: CurrenciesRepository? = null, diff --git a/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json b/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json index 2c809df137..04942a36f2 100644 --- a/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json +++ b/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json @@ -22,5 +22,9 @@ { "name": "SHOPIFY_DYNAMIC_ENABLED", "version": "undefined" + }, + { + "name": "REDESIGNED_APP_CURRENCY_SELECTOR_ENABLED", + "version": "undefined" } ] diff --git a/core/navigation/src/main/java/com/tangem/core/navigation/NavigationState.kt b/core/navigation/src/main/java/com/tangem/core/navigation/NavigationState.kt index db33dd330d..9aea608408 100644 --- a/core/navigation/src/main/java/com/tangem/core/navigation/NavigationState.kt +++ b/core/navigation/src/main/java/com/tangem/core/navigation/NavigationState.kt @@ -35,4 +35,5 @@ enum class AppScreen(val isDialogFragment: Boolean = false) { Welcome, SaveWallet(isDialogFragment = true), WalletSelector(isDialogFragment = true), + AppCurrencySelector, } \ No newline at end of file diff --git a/core/navigation/src/main/java/com/tangem/core/navigation/ReduxNavController.kt b/core/navigation/src/main/java/com/tangem/core/navigation/ReduxNavController.kt index ff8e8ced9e..20e37f3958 100644 --- a/core/navigation/src/main/java/com/tangem/core/navigation/ReduxNavController.kt +++ b/core/navigation/src/main/java/com/tangem/core/navigation/ReduxNavController.kt @@ -10,5 +10,7 @@ interface ReduxNavController { /** Navigate by [action] */ fun navigate(action: NavigationAction) + fun popBackStack(screen: AppScreen? = null) + fun getBackStack(): List } \ No newline at end of file