diff --git a/apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppScreenContent.kt b/apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppScreenContent.kt index 652e54a24..c0a1d2a11 100644 --- a/apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppScreenContent.kt +++ b/apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppScreenContent.kt @@ -90,7 +90,7 @@ fun appEntryProvider( } annotatedEntry { key -> AppRestrictedScreen(key.restrictionType) } annotatedEntry { ScannerScreen() } - annotatedEntry { key -> RegionSelectionScreen(key.kind) } + annotatedEntry { RegionSelectionScreen() } // Sheets (inner content — wrapped in Main.Sheet by navigateTo()) annotatedEntry { key -> CashScreen(key.mint, key.fromTokenInfo) } diff --git a/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/AppRoute.kt b/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/AppRoute.kt index 5b93dabd7..56800e490 100644 --- a/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/AppRoute.kt +++ b/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/AppRoute.kt @@ -4,7 +4,6 @@ import android.os.Parcelable import androidx.navigation3.runtime.NavKey import com.flipcash.app.core.deposit.DepositResult import com.flipcash.app.core.deposit.DepositStep -import com.flipcash.app.core.money.RegionSelectionKind import com.flipcash.app.core.tokens.CurrencyCreatorResult import com.flipcash.app.core.tokens.CurrencyCreatorStep import com.flipcash.app.core.tokens.SwapPurpose @@ -71,7 +70,7 @@ sealed interface AppRoute : NavKey, Parcelable { // TODO: is there a better place for this to live? @Serializable - data class RegionSelection(val kind: RegionSelectionKind) : Main + data object RegionSelection : Main @Serializable @Parcelize diff --git a/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/money/RegionSelectionKind.kt b/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/money/RegionSelectionKind.kt deleted file mode 100644 index 0073ae9db..000000000 --- a/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/money/RegionSelectionKind.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.flipcash.app.core.money - -import kotlinx.serialization.Serializable - -@Serializable -enum class RegionSelectionKind { - Entry, - Balance; -} \ No newline at end of file diff --git a/apps/flipcash/features/balance/src/main/kotlin/com/flipcash/app/balance/BalanceScreen.kt b/apps/flipcash/features/balance/src/main/kotlin/com/flipcash/app/balance/BalanceScreen.kt index 4f8f2b916..25b07dabd 100644 --- a/apps/flipcash/features/balance/src/main/kotlin/com/flipcash/app/balance/BalanceScreen.kt +++ b/apps/flipcash/features/balance/src/main/kotlin/com/flipcash/app/balance/BalanceScreen.kt @@ -11,7 +11,6 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import com.flipcash.app.balance.internal.BalanceScreen import com.flipcash.app.balance.internal.BalanceViewModel import com.flipcash.app.core.AppRoute -import com.flipcash.app.core.money.RegionSelectionKind import com.flipcash.app.core.tokens.TokenPurpose import com.flipcash.app.tokens.ui.SelectTokenViewModel import com.flipcash.core.R @@ -55,11 +54,7 @@ fun BalanceScreen() { viewModel.eventFlow .filterIsInstance() .onEach { - navigator.push( - AppRoute.Main.RegionSelection( - RegionSelectionKind.Balance - ) - ) + navigator.push(AppRoute.Main.RegionSelection) }.launchIn(this) } diff --git a/apps/flipcash/features/cash/src/main/kotlin/com/flipcash/app/cash/internal/CashScreenContent.kt b/apps/flipcash/features/cash/src/main/kotlin/com/flipcash/app/cash/internal/CashScreenContent.kt index ae73f950d..8de8bb958 100644 --- a/apps/flipcash/features/cash/src/main/kotlin/com/flipcash/app/cash/internal/CashScreenContent.kt +++ b/apps/flipcash/features/cash/src/main/kotlin/com/flipcash/app/cash/internal/CashScreenContent.kt @@ -12,7 +12,6 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import com.flipcash.app.core.AppRoute -import com.flipcash.app.core.money.RegionSelectionKind import com.flipcash.app.core.ui.AmountWithKeypad import com.flipcash.features.cash.R import com.getcode.navigation.core.LocalCodeNavigator @@ -46,11 +45,7 @@ internal fun GiveScreenContent(viewModel: CashScreenViewModel) { }, isClickable = true, onAmountClicked = { - navigator.push( - AppRoute.Main.RegionSelection( - kind = RegionSelectionKind.Entry - ) - ) + navigator.push(AppRoute.Main.RegionSelection) }, isError = state.isError, onNumberPressed = { viewModel.dispatchEvent(CashScreenViewModel.Event.OnNumberPressed(it)) }, diff --git a/apps/flipcash/features/cash/src/main/kotlin/com/flipcash/app/cash/internal/CashScreenViewModel.kt b/apps/flipcash/features/cash/src/main/kotlin/com/flipcash/app/cash/internal/CashScreenViewModel.kt index 76b50243b..8c7e7b8ba 100644 --- a/apps/flipcash/features/cash/src/main/kotlin/com/flipcash/app/cash/internal/CashScreenViewModel.kt +++ b/apps/flipcash/features/cash/src/main/kotlin/com/flipcash/app/cash/internal/CashScreenViewModel.kt @@ -142,7 +142,7 @@ internal class CashScreenViewModel @Inject constructor( style = BottomBarManager.BottomBarButtonStyle.Filled, ) { viewModelScope.launch { - val rate = exchange.entryRate + val rate = exchange.preferredRate val (token, balance) = stateFlow.value.token!! val amountFiat = verifiedFiatCalculator.compute( amount = Fiat(amount, rate.currency), @@ -212,7 +212,7 @@ internal class CashScreenViewModel @Inject constructor( combine( tokenCoordinator.tokens, tokenCoordinator.balanceForToken(tokenAddress), - exchange.observeEntryRate(), + exchange.observePreferredRate(), ) { tokens, balance, rate -> val token = tokens.find { it.address == tokenAddress } ?: return@combine null TokenWithLocalizedBalance( @@ -232,7 +232,7 @@ internal class CashScreenViewModel @Inject constructor( dispatchEvent(Event.OnCurrencyChanged(it)) }.launchIn(viewModelScope) - exchange.observeEntryRate() + exchange.observePreferredRate() .onEach { // reset when entry rate changes numberInputHelper.reset() @@ -309,7 +309,7 @@ internal class CashScreenViewModel @Inject constructor( .onEach { data -> dispatchEvent(Event.UpdateLoadingState(loading = true)) val (token, balance) = stateFlow.value.token!! - val rate = exchange.entryRate + val rate = exchange.preferredRate val result = verifiedFiatCalculator.compute( amount = Fiat(data.amountData.amount, rate.currency), @@ -352,9 +352,6 @@ internal class CashScreenViewModel @Inject constructor( }.launchIn(viewModelScope) } - override fun onCleared() { - exchange.resetEntryToBalance() - } internal companion object { val updateStateForEvent: (Event) -> ((State) -> State) = { event -> diff --git a/apps/flipcash/features/cash/src/test/kotlin/com/flipcash/app/cash/internal/CashScreenViewModelTest.kt b/apps/flipcash/features/cash/src/test/kotlin/com/flipcash/app/cash/internal/CashScreenViewModelTest.kt index b58852bc6..0a113d95c 100644 --- a/apps/flipcash/features/cash/src/test/kotlin/com/flipcash/app/cash/internal/CashScreenViewModelTest.kt +++ b/apps/flipcash/features/cash/src/test/kotlin/com/flipcash/app/cash/internal/CashScreenViewModelTest.kt @@ -76,8 +76,8 @@ class CashScreenViewModelTest { every { resources.getString(R.string.error_description_sendLimitReached) } returns "error_description_sendLimitReached" // Default stubs for flows consumed in init - every { exchange.observeEntryRate() } returns emptyFlow() - every { exchange.entryRate } returns Rate.oneToOne + every { exchange.observePreferredRate() } returns emptyFlow() + every { exchange.preferredRate } returns Rate.oneToOne every { tokenCoordinator.observeSelectedTokenMint() } returns emptyFlow() every { tokenCoordinator.tokens } returns emptyFlow() every { transactionController.limits } returns MutableStateFlow(null) diff --git a/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/DepositFlowScreen.kt b/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/DepositFlowScreen.kt index 26249adc8..6f5754bc9 100644 --- a/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/DepositFlowScreen.kt +++ b/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/DepositFlowScreen.kt @@ -118,7 +118,6 @@ private fun DepositSelectTokenScreen() { modifier = Modifier.fillMaxSize(), tokens = state.tokens, selectedToken = state.selectedToken, - showFlags = true, onTokenSelected = { viewModel.dispatchEvent(SelectTokenViewModel.Event.OnTokenSelected(it.address)) }, ) } diff --git a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/internal/SwapEntryScreenContent.kt b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/internal/SwapEntryScreenContent.kt index b1013a923..453c9b19b 100644 --- a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/internal/SwapEntryScreenContent.kt +++ b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/internal/SwapEntryScreenContent.kt @@ -15,7 +15,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.AnnotatedString import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.flipcash.app.core.AppRoute -import com.flipcash.app.core.money.RegionSelectionKind import com.flipcash.app.core.onramp.ui.buildPhantomButtonLabel import com.flipcash.app.core.tokens.FundingSource import com.flipcash.app.core.tokens.SwapPurpose @@ -87,11 +86,7 @@ internal fun SwapEntryScreenContent( decimalPlaces = entryState.currencyModel.fractionUnits, isClickable = (state.purpose as? SwapPurpose.Buy)?.fundingSource != FundingSource.Phantom, onAmountClicked = { - navigator.push( - AppRoute.Main.RegionSelection( - kind = RegionSelectionKind.Entry - ) - ) + navigator.push(AppRoute.Main.RegionSelection) }, isError = state.isError, onNumberPressed = { diff --git a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/internal/TokenInfoScreen.kt b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/internal/TokenInfoScreen.kt index e76e83d8a..426d6850f 100644 --- a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/internal/TokenInfoScreen.kt +++ b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/internal/TokenInfoScreen.kt @@ -35,7 +35,6 @@ import com.flipcash.app.analytics.FlipcashAnalyticsService import com.flipcash.app.analytics.rememberAnalytics import com.flipcash.app.core.AppRoute import com.flipcash.app.core.data.Loadable -import com.flipcash.app.core.money.RegionSelectionKind import com.flipcash.app.core.tokens.SwapPurpose import com.flipcash.app.tokens.internal.components.info.MarketCapSection import com.flipcash.app.tokens.internal.components.info.TokenBalance @@ -145,7 +144,7 @@ private fun TokenInfoScreen( onClick = { dispatch( TokenInfoViewModel.Event.OpenScreen( - AppRoute.Main.RegionSelection(kind = RegionSelectionKind.Balance) + AppRoute.Main.RegionSelection ) ) } diff --git a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/WithdrawalFlowScreen.kt b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/WithdrawalFlowScreen.kt index dfbfcd8a7..90e69bb2e 100644 --- a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/WithdrawalFlowScreen.kt +++ b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/WithdrawalFlowScreen.kt @@ -123,7 +123,6 @@ private fun WithdrawalSelectTokenScreen() { modifier = Modifier.fillMaxSize(), tokens = state.tokens, selectedToken = state.selectedToken, - showFlags = true, onTokenSelected = { viewModel.dispatchEvent(SelectTokenViewModel.Event.OnTokenSelected(it.address)) }, ) } diff --git a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/WithdrawalViewModel.kt b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/WithdrawalViewModel.kt index f21c1a6b2..a97593da8 100644 --- a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/WithdrawalViewModel.kt +++ b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/WithdrawalViewModel.kt @@ -229,7 +229,7 @@ internal class WithdrawalViewModel @Inject constructor( init { numberInputHelper.reset() - dispatchEvent(Event.OnEntryRateUpdated(exchange.entryRate)) + dispatchEvent(Event.OnEntryRateUpdated(exchange.preferredRate)) stateFlow .mapNotNull { it.selectedTokenAddress } @@ -237,7 +237,7 @@ internal class WithdrawalViewModel @Inject constructor( combine( tokenCoordinator.tokens, tokenCoordinator.balanceForToken(tokenAddress), - exchange.observeEntryRate(), + exchange.observePreferredRate(), ) { tokens, balance, rate -> val token = tokens.find { it.address == tokenAddress } ?: return@combine null TokenWithBalance( @@ -271,7 +271,7 @@ internal class WithdrawalViewModel @Inject constructor( numberInputHelper.fractionUnits = it.fractionUnits }.launchIn(viewModelScope) - exchange.observeEntryRate() + exchange.observePreferredRate() .onEach { // reset when entry rate changes numberInputHelper.reset() @@ -329,7 +329,7 @@ internal class WithdrawalViewModel @Inject constructor( .filterNot { checkMinimumExceeded() } .onEach { data -> dispatchEvent(Event.UpdateConfirmingAmountState(loading = true)) - val rate = exchange.entryRate + val rate = exchange.preferredRate val token = stateFlow.value.token!!.token val amountVerified = verifiedFiatCalculator.compute( amount = Fiat(data.amountData.amount, rate.currency), @@ -647,9 +647,6 @@ internal class WithdrawalViewModel @Inject constructor( .launchIn(viewModelScope) } - override fun onCleared() { - exchange.resetEntryToBalance() - } internal companion object { val updateStateForEvent: (Event) -> ((State) -> State) = { event -> diff --git a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/components/TransactionReceipt.kt b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/components/TransactionReceipt.kt index 8844df27b..7576af981 100644 --- a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/components/TransactionReceipt.kt +++ b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/components/TransactionReceipt.kt @@ -102,7 +102,7 @@ internal fun TransactionReceipt( } }, formattedBalance = { amount -> - amount.convertingToUsdIfNeeded(exchange.entryRate) + amount.convertingToUsdIfNeeded(exchange.preferredRate) .estimatedTokenAmountIn(tokenWithBalance.token, fractionDigits = 2) }, styling = rememberTokenBalanceRowStyling( @@ -157,7 +157,7 @@ private fun LineItems( label = AnnotatedString( stringResource(R.string.label_amountInToken, tokenWithBalance.displayName) ), - amount = transferAmount.convertingToUsdIfNeeded(exchange.entryRate) + amount = transferAmount.convertingToUsdIfNeeded(exchange.preferredRate) .estimatedTokenAmountIn(tokenWithBalance.token, fractionDigits = 2), ) } diff --git a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/WithdrawalEntryScreen.kt b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/WithdrawalEntryScreen.kt index 2610854ab..eedfc0a71 100644 --- a/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/WithdrawalEntryScreen.kt +++ b/apps/flipcash/features/withdrawal/src/main/kotlin/com/flipcash/app/withdrawal/internal/screens/WithdrawalEntryScreen.kt @@ -8,7 +8,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import com.flipcash.app.core.AppRoute -import com.flipcash.app.core.money.RegionSelectionKind import com.flipcash.app.core.withdrawal.WithdrawalResult import com.flipcash.app.core.withdrawal.WithdrawalStep import com.flipcash.app.withdrawal.WithdrawalViewModel @@ -45,9 +44,7 @@ internal fun WithdrawalEntryScreen( viewModel = viewModel, mint = selectedMint, onOpenRegionSelection = { - codeNavigator.push( - AppRoute.Main.RegionSelection(kind = RegionSelectionKind.Entry) - ) + codeNavigator.push(AppRoute.Main.RegionSelection) }, ) } diff --git a/apps/flipcash/shared/currency-selection/core/src/main/kotlin/com/flipcash/app/currency/PreferredCurrencyController.kt b/apps/flipcash/shared/currency-selection/core/src/main/kotlin/com/flipcash/app/currency/PreferredCurrencyController.kt index 5b66f71a2..ee88dfa7e 100644 --- a/apps/flipcash/shared/currency-selection/core/src/main/kotlin/com/flipcash/app/currency/PreferredCurrencyController.kt +++ b/apps/flipcash/shared/currency-selection/core/src/main/kotlin/com/flipcash/app/currency/PreferredCurrencyController.kt @@ -9,7 +9,6 @@ import androidx.datastore.preferences.core.emptyPreferences import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.core.stringSetPreferencesKey import androidx.datastore.preferences.preferencesDataStoreFile -import com.flipcash.app.core.money.RegionSelectionKind import com.flipcash.services.controllers.SettingsController import com.flipcash.services.user.UserManager import com.getcode.opencode.exchange.Exchange @@ -43,10 +42,8 @@ class PreferredCurrencyController @Inject constructor( fun initializedKeyForUser(userIdentifier: String) = booleanPreferencesKey("init-$userIdentifier") - fun kindKeyForUser( - kind: RegionSelectionKind, - userIdentifier: String - ) = stringPreferencesKey("${kind.name.lowercase()}-$userIdentifier") + fun currencyKeyForUser(userIdentifier: String) = + stringPreferencesKey("balance-$userIdentifier") fun recentsKeyForUser(userIdentifier: String) = stringSetPreferencesKey("recents-$userIdentifier") @@ -80,34 +77,21 @@ class PreferredCurrencyController @Inject constructor( prefs[initKey] = true } - val balanceCurrency = prefs[kindKeyForUser( - kind = RegionSelectionKind.Balance, - userId - )]?.let { CurrencyCode.tryValueOf(it) } + val currencyCode = prefs[currencyKeyForUser(userId)] + ?.let { CurrencyCode.tryValueOf(it) } ?: CurrencyCode.tryValueOf(locale.getDefaultCurrencyName()) ?: CurrencyCode.USD - // entry defaults to balance — no longer read from DataStore - exchange.setPreferredEntryCurrency(balanceCurrency) - exchange.setPreferredBalanceCurrency(balanceCurrency) + exchange.setPreferredCurrency(currencyCode) } }.launchIn(dataScope) } - fun observePreferredForKind( - kind: RegionSelectionKind - ): Flow { - return when (kind) { - RegionSelectionKind.Entry -> { - exchange.observeEntryRate().map { it.currency.name } - } - RegionSelectionKind.Balance -> { - val identifier = userManager.accountId?.base58 ?: return emptyFlow() - storage.data.map { prefs -> - prefs[kindKeyForUser(kind, identifier)] ?: locale.getDefaultCurrencyName() - } - } + fun observePreferredCurrency(): Flow { + val identifier = userManager.accountId?.base58 ?: return emptyFlow() + return storage.data.map { prefs -> + prefs[currencyKeyForUser(identifier)] ?: locale.getDefaultCurrencyName() } } @@ -117,31 +101,19 @@ class PreferredCurrencyController @Inject constructor( return storage.data.map { prefs -> prefs[recentsKeyForUser(identifier)].orEmpty() } } - suspend fun updateSelection( - kind: RegionSelectionKind, - currency: Currency - ) { + suspend fun updateSelection(currency: Currency) { val code = CurrencyCode.tryValueOf(currency.code) ?: return - when (kind) { - RegionSelectionKind.Entry -> { - // temporary — only update Exchange, don't persist - exchange.setPreferredEntryCurrency(code) - } - RegionSelectionKind.Balance -> { - val identifier = userManager.accountId?.base58 ?: return - storage.edit { prefs -> - prefs[kindKeyForUser(kind, identifier)] = currency.code + val identifier = userManager.accountId?.base58 ?: return + storage.edit { prefs -> + prefs[currencyKeyForUser(identifier)] = currency.code - val recentKey = recentsKeyForUser(identifier) - val recents = prefs[recentKey].orEmpty() + val recentKey = recentsKeyForUser(identifier) + val recents = prefs[recentKey].orEmpty() - prefs[recentKey] = updateRecents(recents, currency.code) - } - exchange.setPreferredBalanceCurrency(code) - exchange.setPreferredEntryCurrency(code) - settingsController.update() - } + prefs[recentKey] = updateRecents(recents, currency.code) } + exchange.setPreferredCurrency(code) + settingsController.update() } suspend fun removeFromRecents( @@ -168,4 +140,4 @@ class PreferredCurrencyController @Inject constructor( return updated } -} \ No newline at end of file +} diff --git a/apps/flipcash/shared/currency-selection/ui/src/main/kotlin/com/flipcash/app/currency/RegionSelectionScreen.kt b/apps/flipcash/shared/currency-selection/ui/src/main/kotlin/com/flipcash/app/currency/RegionSelectionScreen.kt index f1302f2e3..f7232af0a 100644 --- a/apps/flipcash/shared/currency-selection/ui/src/main/kotlin/com/flipcash/app/currency/RegionSelectionScreen.kt +++ b/apps/flipcash/shared/currency-selection/ui/src/main/kotlin/com/flipcash/app/currency/RegionSelectionScreen.kt @@ -3,12 +3,10 @@ package com.flipcash.app.currency import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.hilt.navigation.compose.hiltViewModel -import com.flipcash.app.core.money.RegionSelectionKind import com.flipcash.app.currency.internal.CurrencyViewModel import com.flipcash.app.currency.internal.RegionSelectionModalContent import com.flipcash.core.R @@ -16,7 +14,7 @@ import com.getcode.navigation.core.LocalCodeNavigator import com.getcode.ui.components.AppBarWithTitle @Composable -fun RegionSelectionScreen(kind: RegionSelectionKind) { +fun RegionSelectionScreen() { val navigator = LocalCodeNavigator.current Column( modifier = Modifier.fillMaxSize(), @@ -34,9 +32,5 @@ fun RegionSelectionScreen(kind: RegionSelectionKind) { val viewModel = hiltViewModel() RegionSelectionModalContent(viewModel) - - LaunchedEffect(viewModel, kind) { - viewModel.dispatchEvent(CurrencyViewModel.Event.OnKindChanged(kind)) - } } } diff --git a/apps/flipcash/shared/currency-selection/ui/src/main/kotlin/com/flipcash/app/currency/internal/CurrencyViewModel.kt b/apps/flipcash/shared/currency-selection/ui/src/main/kotlin/com/flipcash/app/currency/internal/CurrencyViewModel.kt index b1a09f66d..4ff1d3c40 100644 --- a/apps/flipcash/shared/currency-selection/ui/src/main/kotlin/com/flipcash/app/currency/internal/CurrencyViewModel.kt +++ b/apps/flipcash/shared/currency-selection/ui/src/main/kotlin/com/flipcash/app/currency/internal/CurrencyViewModel.kt @@ -3,7 +3,6 @@ package com.flipcash.app.currency.internal import androidx.compose.foundation.text.input.TextFieldState import androidx.compose.runtime.snapshotFlow import androidx.lifecycle.viewModelScope -import com.flipcash.app.core.money.RegionSelectionKind import com.flipcash.app.currency.PreferredCurrencyController import com.flipcash.features.currency.R import com.getcode.opencode.exchange.Exchange @@ -35,7 +34,6 @@ class CurrencyViewModel @Inject constructor( defaultDispatcher = dispatchers.Default, ) { data class State( - val kind: RegionSelectionKind? = null, val loading: Boolean = false, val listItems: List = emptyList(), val currencies: List = emptyList(), @@ -46,7 +44,6 @@ class CurrencyViewModel @Inject constructor( ) sealed interface Event { - data class OnKindChanged(val kind: RegionSelectionKind): Event data class OnLoadingChanged(val loading: Boolean) : Event data class OnItemsPopulated(val currencies: List) : Event data class OnCurrenciesUpdated(val currencies: List): Event @@ -61,8 +58,7 @@ class CurrencyViewModel @Inject constructor( init { combine( exchange.observeRates().distinctUntilChanged().map { exchange.getCurrenciesWithRates() }, - stateFlow.mapNotNull { it.kind } - .flatMapLatest { preferredCurrencyController.observePreferredForKind(it) }.distinctUntilChanged(), + preferredCurrencyController.observePreferredCurrency().distinctUntilChanged(), ) { currenciesWithRates, preferredCurrency -> dispatchEvent(Event.OnCurrenciesUpdated(currenciesWithRates)) val preferredWithRate = currenciesWithRates.find { it.code == preferredCurrency } @@ -86,8 +82,7 @@ class CurrencyViewModel @Inject constructor( .filter { it.fromUser } .map { it.currency } .onEach { selected -> - val kind = stateFlow.value.kind ?: return@onEach - preferredCurrencyController.updateSelection(kind, selected) + preferredCurrencyController.updateSelection(selected) }.onEach { dispatchEvent(Event.OnSelectedCurrencyChanged) } .launchIn(viewModelScope) @@ -157,7 +152,6 @@ class CurrencyViewModel @Inject constructor( val updateStateForEvent: (Event) -> ((State) -> State) = { event -> when (event) { is Event.OnItemsPopulated -> { state -> state.copy(listItems = event.currencies) } - is Event.OnKindChanged -> { state -> state.copy(kind = event.kind) } is Event.OnLoadingChanged -> { state -> state.copy(loading = event.loading) } is Event.OnCurrenciesUpdated -> { state -> state.copy(currencies = event.currencies) } is Event.OnRecentCurrenciesUpdated -> { state -> state.copy(recents = event.recents) } @@ -174,4 +168,4 @@ class CurrencyViewModel @Inject constructor( } } } -} \ No newline at end of file +} diff --git a/apps/flipcash/shared/payments/src/main/kotlin/com/flipcash/app/payments/internal/InternalPurchaseMethodController.kt b/apps/flipcash/shared/payments/src/main/kotlin/com/flipcash/app/payments/internal/InternalPurchaseMethodController.kt index cabfe5222..0730e8030 100644 --- a/apps/flipcash/shared/payments/src/main/kotlin/com/flipcash/app/payments/internal/InternalPurchaseMethodController.kt +++ b/apps/flipcash/shared/payments/src/main/kotlin/com/flipcash/app/payments/internal/InternalPurchaseMethodController.kt @@ -67,7 +67,7 @@ class InternalPurchaseMethodController @Inject constructor( combine( reservesBalanceProvider.observeReservesBalance(), - exchange.observeBalanceRate(), + exchange.observePreferredRate(), ) { balance, rate -> LocalFiat( usdf = balance, diff --git a/apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenCoordinator.kt b/apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenCoordinator.kt index 5ed7898ed..ad14c5fe9 100644 --- a/apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenCoordinator.kt +++ b/apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenCoordinator.kt @@ -514,7 +514,7 @@ class TokenCoordinator @Inject constructor( val resolved = resolveTokenSelection( balances = _state.value.balances, currentSelection = currentSelection, - rate = exchange.entryRate, + rate = exchange.preferredRate, ) if (resolved != null && resolved != currentSelection) { diff --git a/apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/ui/SelectTokenViewModel.kt b/apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/ui/SelectTokenViewModel.kt index 2712523ac..a0818b4db 100644 --- a/apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/ui/SelectTokenViewModel.kt +++ b/apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/ui/SelectTokenViewModel.kt @@ -102,10 +102,8 @@ class SelectTokenViewModel @Inject constructor( stateFlow, tokenCoordinator.tokenBalances, when (purpose) { - TokenPurpose.Balance -> exchange.observeBalanceRate() - TokenPurpose.Select -> exchange.observeEntryRate() TokenPurpose.Withdraw -> flowOf(exchange.rateForUsd()) - TokenPurpose.Deposit -> exchange.observeEntryRate() + else -> exchange.observePreferredRate() } ) { state, balances, rate -> dispatchEvent(Event.OnRateChanged(rate)) diff --git a/apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/ui/SwapViewModel.kt b/apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/ui/SwapViewModel.kt index 2a8042913..620e062ca 100644 --- a/apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/ui/SwapViewModel.kt +++ b/apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/ui/SwapViewModel.kt @@ -333,7 +333,7 @@ class SwapViewModel @Inject constructor( combine( tokenCoordinator.tokenBalances, - exchange.observeEntryRate(), + exchange.observePreferredRate(), ) { tokens, rate -> var token = tokens.find { it.token.address == mint } if (token == null) { @@ -379,7 +379,7 @@ class SwapViewModel @Inject constructor( combine( tokenCoordinator.tokens, tokenCoordinator.balanceForToken(tokenAddress), - exchange.observeEntryRate(), + exchange.observePreferredRate(), ) { tokens, balance, rate -> val token = tokens.find { it.address == tokenAddress } ?: return@combine null TokenWithLocalizedBalance( @@ -398,7 +398,7 @@ class SwapViewModel @Inject constructor( combine( tokenCoordinator.observeReservesBalance(), - exchange.observeEntryRate(), + exchange.observePreferredRate(), ) { balance, rate -> LocalFiat( usdf = balance, @@ -410,7 +410,7 @@ class SwapViewModel @Inject constructor( dispatchEvent(Event.OnReservesUpdated(TokenWithBalance(Token.usdf, it.nativeAmount))) }.launchIn(viewModelScope) - exchange.observeEntryRate() + exchange.observePreferredRate() .onEach { numberInputHelper.reset() if (stateFlow.value.pendingInitialAmount == null) { @@ -508,7 +508,7 @@ class SwapViewModel @Inject constructor( .onEach { (data, purpose) -> when (purpose) { is SwapPurpose.Buy -> { - val rate = exchange.entryRate + val rate = exchange.preferredRate val conversionRate = exchange.rateToUsd( stateFlow.value.amountEntryState.currencyModel.code ?: CurrencyCode.USD ) ?: Rate.ignore @@ -561,7 +561,7 @@ class SwapViewModel @Inject constructor( } is SwapPurpose.Sell -> { - val rate = exchange.entryRate + val rate = exchange.preferredRate val tokenWithBalance = stateFlow.value.tokenWithBalance!! val amountFiat = verifiedFiatCalculator.compute( amount = Fiat(data.amountData.amount, rate.currency), @@ -806,7 +806,7 @@ class SwapViewModel @Inject constructor( return@onEach } - val rate = exchange.entryRate + val rate = exchange.preferredRate val amountFiat = verifiedFiatCalculator.compute( amount = amount, token = Token.usdf, @@ -1053,9 +1053,6 @@ class SwapViewModel @Inject constructor( dispatchEvent(Event.UpdateBuyState()) } - override fun onCleared() { - exchange.resetEntryToBalance() - } private fun enterAmount(amount: Fiat) { numberInputHelper.maxLength = 10 diff --git a/apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/ui/TokenInfoViewModel.kt b/apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/ui/TokenInfoViewModel.kt index 508a30f06..7f2c4daa1 100644 --- a/apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/ui/TokenInfoViewModel.kt +++ b/apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/ui/TokenInfoViewModel.kt @@ -139,7 +139,7 @@ class TokenInfoViewModel @Inject constructor( combine( tokenCoordinator.balanceForToken(token.address), tokenCoordinator.appreciationForToken(token.address), - exchange.observeBalanceRate(), + exchange.observePreferredRate(), ) { balance, appreciation, rate -> val localizedBalance = LocalFiat( usdf = balance, @@ -241,7 +241,7 @@ class TokenInfoViewModel @Inject constructor( .flatMapLatest { mcap -> combine( flowOf(mcap), - exchange.observeBalanceRate(), + exchange.observePreferredRate(), ) { usdMcap, rate -> usdMcap?.convertingTo(rate) } diff --git a/services/flipcash/src/main/kotlin/com/flipcash/services/controllers/SettingsController.kt b/services/flipcash/src/main/kotlin/com/flipcash/services/controllers/SettingsController.kt index 49c2cef24..be9669431 100644 --- a/services/flipcash/src/main/kotlin/com/flipcash/services/controllers/SettingsController.kt +++ b/services/flipcash/src/main/kotlin/com/flipcash/services/controllers/SettingsController.kt @@ -15,7 +15,7 @@ class SettingsController @Inject constructor( ) { suspend fun update(): Result { val locale = localeHelper.getLanguageTag() - val currencyRegion = exchange.balanceRate.currency + val currencyRegion = exchange.preferredRate.currency val owner = userManager.accountCluster?.authority?.keyPair ?: return Result.failure(Throwable("No account cluster in UserManager")) diff --git a/services/opencode-compose/src/main/kotlin/com/getcode/opencode/compose/Exchange.kt b/services/opencode-compose/src/main/kotlin/com/getcode/opencode/compose/Exchange.kt index 183de2398..600cfaf18 100644 --- a/services/opencode-compose/src/main/kotlin/com/getcode/opencode/compose/Exchange.kt +++ b/services/opencode-compose/src/main/kotlin/com/getcode/opencode/compose/Exchange.kt @@ -13,29 +13,14 @@ import kotlinx.coroutines.flow.emptyFlow val LocalExchange: ProvidableCompositionLocal = staticCompositionLocalOf { ExchangeNull() } private class ExchangeNull : Exchange { - override val balanceRate: Rate + override val preferredRate: Rate get() = Rate.oneToOne - override val entryRate: Rate - get() = Rate.oneToOne - - - override fun observeEntryRate(): Flow { + override fun observePreferredRate(): Flow { return emptyFlow() } - override suspend fun setPreferredEntryCurrency(currencyCode: CurrencyCode) { - - } - - override fun resetEntryToBalance() = Unit - - override fun observeBalanceRate(): Flow { - return emptyFlow() - } - - override suspend fun setPreferredBalanceCurrency(currencyCode: CurrencyCode) { - + override suspend fun setPreferredCurrency(currencyCode: CurrencyCode) { } override fun updateUserMints(mints: List) = Unit diff --git a/services/opencode-compose/src/main/kotlin/com/getcode/opencode/compose/ExchangeStub.kt b/services/opencode-compose/src/main/kotlin/com/getcode/opencode/compose/ExchangeStub.kt index c477a4acb..1d52f0f74 100644 --- a/services/opencode-compose/src/main/kotlin/com/getcode/opencode/compose/ExchangeStub.kt +++ b/services/opencode-compose/src/main/kotlin/com/getcode/opencode/compose/ExchangeStub.kt @@ -7,7 +7,6 @@ import com.getcode.opencode.model.financial.CurrencyCode import com.getcode.opencode.model.financial.Rate import com.getcode.services.opencode.R import com.getcode.solana.keys.Mint -import com.getcode.solana.keys.Signature import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow @@ -16,21 +15,13 @@ import kotlinx.coroutines.withContext class ExchangeStub( private val providedRates: Map = emptyMap(), - private val providedProofs: Map = emptyMap(), private val context: Context, ): Exchange { - override val entryRate: Rate = Rate.oneToOne + override val preferredRate: Rate = Rate.oneToOne - override fun observeEntryRate(): Flow = emptyFlow() + override fun observePreferredRate(): Flow = emptyFlow() - override suspend fun setPreferredEntryCurrency(currencyCode: CurrencyCode) = Unit - override fun resetEntryToBalance() = Unit - - override val balanceRate: Rate = Rate.oneToOne - - override fun observeBalanceRate(): Flow = emptyFlow() - - override suspend fun setPreferredBalanceCurrency(currencyCode: CurrencyCode) = Unit + override suspend fun setPreferredCurrency(currencyCode: CurrencyCode) = Unit override fun updateUserMints(mints: List) = Unit override fun rates(): Map = providedRates diff --git a/services/opencode/src/main/kotlin/com/getcode/opencode/exchange/Exchange.kt b/services/opencode/src/main/kotlin/com/getcode/opencode/exchange/Exchange.kt index 20b6407ef..5b8f0027b 100644 --- a/services/opencode/src/main/kotlin/com/getcode/opencode/exchange/Exchange.kt +++ b/services/opencode/src/main/kotlin/com/getcode/opencode/exchange/Exchange.kt @@ -4,17 +4,12 @@ import com.getcode.opencode.model.financial.Currency import com.getcode.opencode.model.financial.CurrencyCode import com.getcode.opencode.model.financial.Rate import com.getcode.solana.keys.Mint -import com.getcode.solana.keys.Signature import kotlinx.coroutines.flow.Flow interface Exchange { - val entryRate: Rate - fun observeEntryRate(): Flow - suspend fun setPreferredEntryCurrency(currencyCode: CurrencyCode) - fun resetEntryToBalance() - val balanceRate: Rate - fun observeBalanceRate(): Flow - suspend fun setPreferredBalanceCurrency(currencyCode: CurrencyCode) + val preferredRate: Rate + fun observePreferredRate(): Flow + suspend fun setPreferredCurrency(currencyCode: CurrencyCode) fun updateUserMints(mints: List) diff --git a/services/opencode/src/main/kotlin/com/getcode/opencode/internal/exchange/OpenCodeExchange.kt b/services/opencode/src/main/kotlin/com/getcode/opencode/internal/exchange/OpenCodeExchange.kt index 138d0b3e3..256c4f365 100644 --- a/services/opencode/src/main/kotlin/com/getcode/opencode/internal/exchange/OpenCodeExchange.kt +++ b/services/opencode/src/main/kotlin/com/getcode/opencode/internal/exchange/OpenCodeExchange.kt @@ -43,7 +43,7 @@ internal class OpenCodeExchange @Inject constructor( ProcessLifecycleOwner.get().lifecycle.addObserver(this) scope.launch { val currencyCode = locale.getDefaultCurrencyName() - balanceCurrency = CurrencyCode.tryValueOf(currencyCode) + preferredCurrency = CurrencyCode.tryValueOf(currencyCode) } } @@ -57,20 +57,20 @@ internal class OpenCodeExchange @Inject constructor( } - private val _balanceRate = MutableStateFlow(Rate.oneToOne) - override val balanceRate - get() = _balanceRate.value + private val _preferredRate = MutableStateFlow(Rate.oneToOne) + override val preferredRate: Rate + get() = _preferredRate.value - override fun observeBalanceRate(): Flow = _balanceRate + override fun observePreferredRate(): Flow = _preferredRate private val mints = MutableStateFlow>(emptyList()) - override suspend fun setPreferredBalanceCurrency(currencyCode: CurrencyCode) { - balanceCurrency = currencyCode + override suspend fun setPreferredCurrency(currencyCode: CurrencyCode) { + preferredCurrency = currencyCode verifiedStateManager.rateFor(currencyCode)?.let { - _balanceRate.value = it + _preferredRate.value = it } ?: run { - _balanceRate.value = Rate.oneToOne.copy(currency = currencyCode) + _preferredRate.value = Rate.oneToOne.copy(currency = currencyCode) } } @@ -78,27 +78,7 @@ internal class OpenCodeExchange @Inject constructor( this.mints.value = mints } - private val _entryRate = MutableStateFlow(Rate.oneToOne) - override val entryRate: Rate - get() = _entryRate.value - - override fun observeEntryRate(): Flow = _entryRate - - override suspend fun setPreferredEntryCurrency(currencyCode: CurrencyCode) { - entryCurrency = currencyCode - verifiedStateManager.rateFor(currencyCode)?.let { - _entryRate.value = it - } ?: run { - _entryRate.value = Rate.oneToOne.copy(currency = currencyCode) - } - } - - override fun resetEntryToBalance() { - scope.launch { setPreferredEntryCurrency(balanceRate.currency) } - } - - private var balanceCurrency: CurrencyCode? = null - private var entryCurrency: CurrencyCode? = null + private var preferredCurrency: CurrencyCode? = null override fun rates() = verifiedStateManager.rates() override fun observeRates(): Flow> = verifiedStateManager.observeRates() @@ -175,47 +155,25 @@ internal class OpenCodeExchange @Inject constructor( } private fun updateRates(rates: Map) { - val balanceRate = balanceCurrency?.let { rates[it] } - val balanceChanged = _balanceRate.value != balanceRate - if (balanceChanged) { - _balanceRate.value = if (balanceRate != null) { + val rate = preferredCurrency?.let { rates[it] } + val changed = _preferredRate.value != rate + if (changed) { + _preferredRate.value = if (rate != null) { trace( tag = "Background", - message = "Updated the local currency: $balanceCurrency", + message = "Updated the preferred currency: $preferredCurrency", type = TraceType.Process ) - balanceRate + rate } else { trace( tag = "Background", - message = "local:: Rate for $balanceCurrency not found. Defaulting to USD.", + message = "Rate for $preferredCurrency not found. Defaulting to USD.", type = TraceType.Process ) rates[CurrencyCode.USD] ?: Rate.oneToOne } - } - - val entryRate = entryCurrency?.let { rates[it] } - val entryChanged = _entryRate.value != entryRate - if (entryChanged) { - _entryRate.value = if (entryRate != null) { - trace( - tag = "Background", - message = "Updated the entry currency: $entryCurrency", - type = TraceType.Process - ) - entryRate - } else { - trace( - tag = "Background", - message = "entry:: Rate for $entryCurrency not found. Defaulting to USD.", - type = TraceType.Process - ) - rates[CurrencyCode.USD] ?: Rate.oneToOne - } - } - if (balanceChanged || entryChanged) { trace( tag = "Background", message = "Updated rates",