diff --git a/.claude/agents/module-scaffolder.md b/.claude/agents/module-scaffolder.md index f2cb2839a..c9b3952d3 100644 --- a/.claude/agents/module-scaffolder.md +++ b/.claude/agents/module-scaffolder.md @@ -117,14 +117,14 @@ fun Screen() { package com.flipcash.app..internal import com.flipcash.libs.coroutines.DispatcherProvider -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @HiltViewModel internal class ViewModel @Inject constructor( dispatchers: DispatcherProvider, -) : BaseViewModel2<ViewModel.State, ViewModel.Event>( +) : BaseViewModel<ViewModel.State, ViewModel.Event>( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, diff --git a/.claude/agents/test-gap-finder.md b/.claude/agents/test-gap-finder.md index 56f329ad0..f191b2ba2 100644 --- a/.claude/agents/test-gap-finder.md +++ b/.claude/agents/test-gap-finder.md @@ -39,7 +39,7 @@ class ViewModelTest { @get:Rule val mainCoroutineRule = MainCoroutineRule() // Dependencies as mockk(relaxed = true) - // VMs extend BaseViewModel2 with a companion `updateStateForEvent` reducer + // VMs extend BaseViewModel with a companion `updateStateForEvent` reducer // Test the pure updateStateForEvent reducer function directly when possible // For integration: create VM, dispatch events, advanceUntilIdle(), assert stateFlow value } diff --git a/apps/flipcash/features/advanced/src/main/kotlin/com/flipcash/app/advanced/internal/AdvancedFeaturesScreenViewModel.kt b/apps/flipcash/features/advanced/src/main/kotlin/com/flipcash/app/advanced/internal/AdvancedFeaturesScreenViewModel.kt index e046da1f2..38f795feb 100644 --- a/apps/flipcash/features/advanced/src/main/kotlin/com/flipcash/app/advanced/internal/AdvancedFeaturesScreenViewModel.kt +++ b/apps/flipcash/features/advanced/src/main/kotlin/com/flipcash/app/advanced/internal/AdvancedFeaturesScreenViewModel.kt @@ -7,7 +7,7 @@ import com.flipcash.app.featureflags.FeatureFlagController import com.flipcash.app.menu.MenuItem import com.flipcash.app.userflags.UserFlagsCoordinator import com.flipcash.libs.coroutines.DispatcherProvider -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn @@ -25,7 +25,7 @@ internal class AdvancedFeaturesScreenViewModel @Inject constructor( featureFlagController: FeatureFlagController, userFlags: UserFlagsCoordinator, dispatchers: DispatcherProvider, -) : BaseViewModel2( +) : BaseViewModel( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, diff --git a/apps/flipcash/features/balance/src/main/kotlin/com/flipcash/app/balance/internal/BalanceViewModel.kt b/apps/flipcash/features/balance/src/main/kotlin/com/flipcash/app/balance/internal/BalanceViewModel.kt index 33f287867..4990d046d 100644 --- a/apps/flipcash/features/balance/src/main/kotlin/com/flipcash/app/balance/internal/BalanceViewModel.kt +++ b/apps/flipcash/features/balance/src/main/kotlin/com/flipcash/app/balance/internal/BalanceViewModel.kt @@ -7,7 +7,7 @@ import com.flipcash.services.internal.model.thirdparty.OnRampProvider import com.flipcash.services.user.AuthState import com.flipcash.services.user.UserManager import com.flipcash.libs.coroutines.DispatcherProvider -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterIsInstance @@ -23,7 +23,7 @@ internal class BalanceViewModel @Inject constructor( userManager: UserManager, userFlags: UserFlagsCoordinator, dispatchers: DispatcherProvider, -) : BaseViewModel2( +) : BaseViewModel( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, 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 3964ff26d..76b50243b 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 @@ -26,7 +26,7 @@ import com.getcode.solana.keys.Mint import com.getcode.ui.components.text.AmountAnimatedInputUiModel import com.getcode.ui.components.text.NumberInputHelper import com.getcode.util.resources.ResourceHelper -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import com.getcode.view.LoadingSuccessState import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.CompletableDeferred @@ -54,7 +54,7 @@ internal class CashScreenViewModel @Inject constructor( tokenCoordinator: TokenCoordinator, transactionController: TransactionOperations, dispatchers: DispatcherProvider, -) : BaseViewModel2( +) : BaseViewModel( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, diff --git a/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/internal/email/EmailVerificationViewModel.kt b/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/internal/email/EmailVerificationViewModel.kt index e3931593e..aa4bdc1fe 100644 --- a/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/internal/email/EmailVerificationViewModel.kt +++ b/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/internal/email/EmailVerificationViewModel.kt @@ -19,7 +19,7 @@ import com.getcode.manager.BottomBarManager import com.getcode.manager.BottomBarManager.BottomBarButtonStyle import com.getcode.util.resources.ResourceHelper import com.flipcash.libs.coroutines.DispatcherProvider -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import com.getcode.view.LoadingSuccessState import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers @@ -45,7 +45,7 @@ class EmailVerificationViewModel @Inject constructor( private val resources: ResourceHelper, private val dispatchers: DispatcherProvider, private val emailCodeChannel: EmailCodeChannel, -) : BaseViewModel2( +) : BaseViewModel( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, diff --git a/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/internal/phone/PhoneVerificationViewModel.kt b/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/internal/phone/PhoneVerificationViewModel.kt index c04754016..b01ada715 100644 --- a/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/internal/phone/PhoneVerificationViewModel.kt +++ b/apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/internal/phone/PhoneVerificationViewModel.kt @@ -14,7 +14,7 @@ import com.flipcash.services.models.ContactMethod import com.flipcash.services.models.PhoneVerificationError import com.getcode.manager.BottomBarManager import com.getcode.util.resources.ResourceHelper -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import com.getcode.view.LoadingSuccessState import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.delay @@ -39,7 +39,7 @@ internal class PhoneVerificationViewModel @Inject constructor( private val profileController: ProfileController, private val resources: ResourceHelper, private val dispatchers: DispatcherProvider, -) : BaseViewModel2( +) : BaseViewModel( initialState = State(selectedLocale = phoneUtils.defaultCountryLocale), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, diff --git a/apps/flipcash/features/currency-creator/src/main/kotlin/com/flipcash/app/currencycreator/internal/CurrencyCreatorViewModel.kt b/apps/flipcash/features/currency-creator/src/main/kotlin/com/flipcash/app/currencycreator/internal/CurrencyCreatorViewModel.kt index 01e73af71..3e9f72fd3 100644 --- a/apps/flipcash/features/currency-creator/src/main/kotlin/com/flipcash/app/currencycreator/internal/CurrencyCreatorViewModel.kt +++ b/apps/flipcash/features/currency-creator/src/main/kotlin/com/flipcash/app/currencycreator/internal/CurrencyCreatorViewModel.kt @@ -57,7 +57,7 @@ import com.getcode.opencode.model.ui.TokenBillCustomizations import com.getcode.solana.keys.Mint import com.getcode.util.resources.ContentReader import com.getcode.util.resources.ResourceHelper -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import com.getcode.view.LoadingSuccessState import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.FlowPreview @@ -98,7 +98,7 @@ internal class CurrencyCreatorViewModel @Inject constructor( val contentReader: ContentReader, val purchaseMethodController: PurchaseMethodController, private val currencyCreatorCoordinator: CurrencyCreatorCoordinator, -) : BaseViewModel2( +) : BaseViewModel( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, diff --git a/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/internal/DepositViewModel.kt b/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/internal/DepositViewModel.kt index 606a74cdb..ba2fb8280 100644 --- a/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/internal/DepositViewModel.kt +++ b/apps/flipcash/features/deposit/src/main/kotlin/com/flipcash/app/deposit/internal/DepositViewModel.kt @@ -17,7 +17,7 @@ import com.flipcash.app.featureflags.FeatureFlag import com.flipcash.app.featureflags.FeatureFlagController import com.getcode.opencode.model.financial.Token import com.getcode.opencode.model.financial.usdf -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.delay import kotlinx.coroutines.flow.filterIsInstance @@ -36,7 +36,7 @@ internal class DepositViewModel @Inject constructor( resources: ResourceHelper, dispatchers: DispatcherProvider, featureFlags: FeatureFlagController, -) : BaseViewModel2( +) : BaseViewModel( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, diff --git a/apps/flipcash/features/device-logs/src/main/kotlin/com/flipcash/app/devicelogs/internal/DeviceLogsScreenViewModel.kt b/apps/flipcash/features/device-logs/src/main/kotlin/com/flipcash/app/devicelogs/internal/DeviceLogsScreenViewModel.kt index 9b081183e..b62a8c7d1 100644 --- a/apps/flipcash/features/device-logs/src/main/kotlin/com/flipcash/app/devicelogs/internal/DeviceLogsScreenViewModel.kt +++ b/apps/flipcash/features/device-logs/src/main/kotlin/com/flipcash/app/devicelogs/internal/DeviceLogsScreenViewModel.kt @@ -3,7 +3,7 @@ package com.flipcash.app.devicelogs.internal import androidx.lifecycle.viewModelScope import com.flipcash.libs.coroutines.DispatcherProvider import com.getcode.utils.TraceManager -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.launchIn @@ -13,7 +13,7 @@ import javax.inject.Inject @HiltViewModel internal class DeviceLogsScreenViewModel @Inject constructor( dispatchers: DispatcherProvider, -) : BaseViewModel2( +) : BaseViewModel( // Subscribing to the SharedFlow replay cache below seeds history naturally — // new collectors receive the last N lines as emissions. initialState = State(), diff --git a/apps/flipcash/features/discovery/src/main/kotlin/com/flipcash/app/discovery/internal/TokenDiscoveryViewModel.kt b/apps/flipcash/features/discovery/src/main/kotlin/com/flipcash/app/discovery/internal/TokenDiscoveryViewModel.kt index 4c8ab1b3d..355333f29 100644 --- a/apps/flipcash/features/discovery/src/main/kotlin/com/flipcash/app/discovery/internal/TokenDiscoveryViewModel.kt +++ b/apps/flipcash/features/discovery/src/main/kotlin/com/flipcash/app/discovery/internal/TokenDiscoveryViewModel.kt @@ -12,7 +12,7 @@ import com.getcode.opencode.model.ui.DiscoverCategory import com.getcode.solana.keys.Mint import com.getcode.util.resources.ResourceHelper import com.flipcash.libs.coroutines.DispatcherProvider -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.delay import kotlinx.coroutines.flow.filterIsInstance @@ -28,7 +28,7 @@ internal class TokenDiscoveryViewModel @Inject constructor( private val resources: ResourceHelper, featureFlags: FeatureFlagController, dispatchers: DispatcherProvider, -) : BaseViewModel2( +) : BaseViewModel( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, diff --git a/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/router/LoginViewModel.kt b/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/router/LoginViewModel.kt index 500e53479..edbf50a60 100644 --- a/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/router/LoginViewModel.kt +++ b/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/router/LoginViewModel.kt @@ -10,7 +10,7 @@ import com.getcode.manager.BottomBarManager import com.getcode.util.resources.ResourceHelper import com.getcode.utils.encodeBase64 import com.flipcash.libs.coroutines.DispatcherProvider -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import com.getcode.view.LoadingSuccessState import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.filter @@ -30,7 +30,7 @@ class LoginViewModel @Inject constructor( private val resources: ResourceHelper, private val analytics: FlipcashAnalyticsService, dispatchers: DispatcherProvider, -) : BaseViewModel2( +) : BaseViewModel( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, diff --git a/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/seed/SeedInputViewModel.kt b/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/seed/SeedInputViewModel.kt index fe98ac6ee..984064f84 100644 --- a/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/seed/SeedInputViewModel.kt +++ b/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/seed/SeedInputViewModel.kt @@ -18,7 +18,7 @@ import com.getcode.manager.BottomBarManager import com.getcode.navigation.core.CodeNavigator import com.getcode.opencode.managers.MnemonicManager import com.getcode.util.resources.ResourceHelper -import com.getcode.view.BaseViewModel +import androidx.lifecycle.ViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -47,7 +47,7 @@ class SeedInputViewModel @Inject constructor( private val userFlags: UserFlagsCoordinator, private val resources: ResourceHelper, private val mnemonicManager: MnemonicManager, -) : BaseViewModel(resources) { +) : ViewModel() { val uiFlow = MutableStateFlow(SeedInputUiModel()) private val mnemonicCode = mnemonicManager.mnemonicCode @@ -99,8 +99,8 @@ class SeedInputViewModel @Inject constructor( .onFailure { if (it is AuthManager.AuthManagerException.TimelockUnlockedException) { BottomBarManager.showAlert( - getString(R.string.error_title_timelockUnlocked), - getString(R.string.error_description_timelockUnlocked) + resources.getString(R.string.error_title_timelockUnlocked), + resources.getString(R.string.error_description_timelockUnlocked) ) navigator.popAll() } else { @@ -118,8 +118,8 @@ class SeedInputViewModel @Inject constructor( }.onFailure { setState(isLoading = false, isSuccess = false, isContinueEnabled = false) BottomBarManager.showError( - getString(R.string.error_title_loginFailed), - getString(R.string.error_description_loginFailed) + resources.getString(R.string.error_title_loginFailed), + resources.getString(R.string.error_description_loginFailed) ) } } else { @@ -157,8 +157,8 @@ class SeedInputViewModel @Inject constructor( is SelectCredentialError.UserCancelled -> { /* no op */ } else -> { BottomBarManager.showError( - getString(R.string.error_title_selectCredential), - getString(R.string.error_description_selectCredential) + resources.getString(R.string.error_title_selectCredential), + resources.getString(R.string.error_description_selectCredential) ) } } @@ -175,15 +175,6 @@ class SeedInputViewModel @Inject constructor( } } - override fun setIsLoading(isLoading: Boolean) { - uiFlow.update { - it.copy( - isLoading = isLoading, - continueEnabled = false - ) - } - } - private fun getValidCount(userWordList: List, mnemonicWordList: List): Int { return userWordList.filter { it in mnemonicWordList }.size } diff --git a/apps/flipcash/features/menu/src/main/kotlin/com/flipcash/app/menu/internal/MenuScreenViewModel.kt b/apps/flipcash/features/menu/src/main/kotlin/com/flipcash/app/menu/internal/MenuScreenViewModel.kt index ca23a852b..9f781755c 100644 --- a/apps/flipcash/features/menu/src/main/kotlin/com/flipcash/app/menu/internal/MenuScreenViewModel.kt +++ b/apps/flipcash/features/menu/src/main/kotlin/com/flipcash/app/menu/internal/MenuScreenViewModel.kt @@ -20,7 +20,7 @@ import com.getcode.opencode.managers.MnemonicManager import com.getcode.util.resources.ResourceHelper import com.flipcash.libs.coroutines.DispatcherProvider import com.getcode.manager.BottomBarAction -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.delay @@ -55,7 +55,7 @@ internal class MenuScreenViewModel @Inject constructor( dispatchers: DispatcherProvider, releaseStageProvider: ReleaseStageProvider, ) : - BaseViewModel2( + BaseViewModel( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, diff --git a/apps/flipcash/features/myaccount/src/main/kotlin/com/flipcash/app/myaccount/internal/MyAccountScreenViewModel.kt b/apps/flipcash/features/myaccount/src/main/kotlin/com/flipcash/app/myaccount/internal/MyAccountScreenViewModel.kt index d85c1cf12..9b68d1c6d 100644 --- a/apps/flipcash/features/myaccount/src/main/kotlin/com/flipcash/app/myaccount/internal/MyAccountScreenViewModel.kt +++ b/apps/flipcash/features/myaccount/src/main/kotlin/com/flipcash/app/myaccount/internal/MyAccountScreenViewModel.kt @@ -14,7 +14,7 @@ import com.getcode.manager.BottomBarManager import com.getcode.solana.keys.base58 import com.getcode.util.resources.ResourceHelper import com.getcode.utils.base64 -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.delay import kotlinx.coroutines.flow.combine @@ -43,7 +43,7 @@ internal class MyAccountScreenViewModel @Inject constructor( authManager: AuthManager, clipboardManager: ClipboardManager, dispatchers: DispatcherProvider, -) : BaseViewModel2( +) : BaseViewModel( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, diff --git a/apps/flipcash/features/purchase/src/main/kotlin/com/flipcash/app/purchase/internal/PurchaseAccountViewModel.kt b/apps/flipcash/features/purchase/src/main/kotlin/com/flipcash/app/purchase/internal/PurchaseAccountViewModel.kt index 4d4bb883e..c9caabdde 100644 --- a/apps/flipcash/features/purchase/src/main/kotlin/com/flipcash/app/purchase/internal/PurchaseAccountViewModel.kt +++ b/apps/flipcash/features/purchase/src/main/kotlin/com/flipcash/app/purchase/internal/PurchaseAccountViewModel.kt @@ -16,7 +16,7 @@ import com.getcode.manager.BottomBarManager import com.getcode.opencode.model.financial.Fiat import com.getcode.util.resources.ResourceHelper import com.flipcash.libs.coroutines.DispatcherProvider -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import com.getcode.view.LoadingSuccessState import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.delay @@ -37,7 +37,7 @@ internal class PurchaseAccountViewModel @Inject constructor( billingClient: BillingClient, resources: ResourceHelper, dispatchers: DispatcherProvider, -) : BaseViewModel2( +) : BaseViewModel( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, diff --git a/apps/flipcash/features/transactions/src/main/kotlin/com/flipcash/app/transactions/internal/TransactionHistoryViewModel.kt b/apps/flipcash/features/transactions/src/main/kotlin/com/flipcash/app/transactions/internal/TransactionHistoryViewModel.kt index 5f9d3df75..dee726518 100644 --- a/apps/flipcash/features/transactions/src/main/kotlin/com/flipcash/app/transactions/internal/TransactionHistoryViewModel.kt +++ b/apps/flipcash/features/transactions/src/main/kotlin/com/flipcash/app/transactions/internal/TransactionHistoryViewModel.kt @@ -19,7 +19,7 @@ import com.getcode.opencode.model.core.ID import com.getcode.solana.keys.Mint import com.getcode.solana.keys.PublicKey import com.getcode.util.resources.ResourceHelper -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.flatMapLatest @@ -39,7 +39,7 @@ class TransactionHistoryViewModel @Inject constructor( userManager: UserManager, resources: ResourceHelper, dispatchers: DispatcherProvider, -): BaseViewModel2( +): BaseViewModel( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, diff --git a/apps/flipcash/features/userflags/src/main/kotlin/com/flipcash/app/userflags/internal/UserFlagsViewModel.kt b/apps/flipcash/features/userflags/src/main/kotlin/com/flipcash/app/userflags/internal/UserFlagsViewModel.kt index 448a969e1..5f68994c3 100644 --- a/apps/flipcash/features/userflags/src/main/kotlin/com/flipcash/app/userflags/internal/UserFlagsViewModel.kt +++ b/apps/flipcash/features/userflags/src/main/kotlin/com/flipcash/app/userflags/internal/UserFlagsViewModel.kt @@ -11,7 +11,7 @@ import com.flipcash.app.userflags.UserFlagsCoordinator import com.flipcash.app.userflags.internal.components.FieldEditorSheet import com.flipcash.features.userflags.R import com.flipcash.libs.coroutines.DispatcherProvider -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.launchIn @@ -22,7 +22,7 @@ import javax.inject.Inject internal class UserFlagsViewModel @Inject constructor( flagsCoordinator: UserFlagsCoordinator, dispatchers: DispatcherProvider, -) : BaseViewModel2( +) : BaseViewModel( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, 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 c38187cb7..82fbe2ba4 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 @@ -36,7 +36,7 @@ import com.getcode.ui.components.text.NumberInputHelper import com.getcode.util.resources.ResourceHelper import com.getcode.utils.base58 import com.getcode.vendor.Base58 -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import com.getcode.view.LoadingSuccessState import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.coroutineScope @@ -81,7 +81,7 @@ internal class WithdrawalViewModel @Inject constructor( analytics: FlipcashAnalyticsService, private val tokenCoordinator: TokenCoordinator, dispatchers: DispatcherProvider, -) : BaseViewModel2( +) : BaseViewModel( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, diff --git a/apps/flipcash/shared/accesskey/src/main/kotlin/com/flipcash/app/accesskey/BaseAccessKeyViewModel.kt b/apps/flipcash/shared/accesskey/src/main/kotlin/com/flipcash/app/accesskey/BaseAccessKeyViewModel.kt index 75d94f26d..42996fd37 100644 --- a/apps/flipcash/shared/accesskey/src/main/kotlin/com/flipcash/app/accesskey/BaseAccessKeyViewModel.kt +++ b/apps/flipcash/shared/accesskey/src/main/kotlin/com/flipcash/app/accesskey/BaseAccessKeyViewModel.kt @@ -27,7 +27,7 @@ import com.getcode.theme.White import com.getcode.ui.utils.toAGColor import com.getcode.util.resources.ResourceHelper import com.getcode.utils.decodeBase64 -import com.getcode.view.BaseViewModel +import androidx.lifecycle.ViewModel import com.getcode.view.LoadingSuccessState import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -66,7 +66,7 @@ abstract class BaseAccessKeyViewModel( private val mediaScanner: MediaScanner, userManager: UserManager, private val qrCodeGenerator: QRCodeGenerator -) : BaseViewModel(resources) { +) : ViewModel() { val uiFlow = MutableStateFlow(AccessKeyUiModel()) init { @@ -177,7 +177,7 @@ abstract class BaseAccessKeyViewModel( drawPaint(paintBackground) } - val topTextChunks = getString(R.string.subtitle_accessKeySnapshotWarning) + val topTextChunks = resources.getString(R.string.subtitle_accessKeySnapshotWarning) .split(" ", "\n") .chunked(7) .map { it.joinToString(" ") } @@ -253,7 +253,7 @@ abstract class BaseAccessKeyViewModel( text = accessKeyText[1] ) - val bottomTextChunks = getString(R.string.subtitle_accessKeySnapshotDescription) + val bottomTextChunks = resources.getString(R.string.subtitle_accessKeySnapshotDescription) .split(" ") .chunked(8) .map { it.joinToString(" ") } 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 5d506990c..b1a09f66d 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 @@ -10,7 +10,7 @@ import com.getcode.opencode.exchange.Exchange import com.getcode.opencode.model.financial.Currency import com.getcode.util.resources.ResourceHelper import com.flipcash.libs.coroutines.DispatcherProvider -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged @@ -29,7 +29,7 @@ class CurrencyViewModel @Inject constructor( preferredCurrencyController: PreferredCurrencyController, private val resources: ResourceHelper, dispatchers: DispatcherProvider, -) : BaseViewModel2( +) : BaseViewModel( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, 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 ec3a1f95b..31bae0cd5 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 @@ -23,7 +23,7 @@ import com.getcode.opencode.model.financial.toFiat import com.getcode.solana.keys.Mint import com.getcode.util.resources.ResourceHelper import com.flipcash.libs.coroutines.DispatcherProvider -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged @@ -43,7 +43,7 @@ class SelectTokenViewModel @Inject constructor( featureFlags: FeatureFlagController, resources: ResourceHelper, dispatchers: DispatcherProvider, -) : BaseViewModel2( +) : BaseViewModel( initialState = State(purpose = TokenPurpose.Balance), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, 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 4e2e5d76f..ca6c8d68d 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 @@ -51,7 +51,7 @@ import com.getcode.ui.components.text.AmountAnimatedInputUiModel import com.getcode.ui.components.text.NumberInputHelper import com.getcode.util.resources.ResourceHelper import com.getcode.utils.trace -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import com.getcode.view.LoadingSuccessState import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.combine @@ -91,7 +91,7 @@ class SwapViewModel @Inject constructor( private val purchaseMethodController: PurchaseMethodController, private val coinbaseOnRampController: CoinbaseOnRampController, dispatchers: DispatcherProvider, -) : BaseViewModel2( +) : BaseViewModel( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, 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 8bf1a016b..508a30f06 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 @@ -26,7 +26,7 @@ import com.getcode.opencode.model.financial.Token import com.getcode.opencode.model.ui.WindowedRange import com.getcode.solana.keys.Mint import com.getcode.util.resources.ResourceHelper -import com.getcode.view.BaseViewModel2 +import com.getcode.view.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged @@ -50,7 +50,7 @@ class TokenInfoViewModel @Inject constructor( private val resources: ResourceHelper, features: FeatureFlagController, dispatchers: DispatcherProvider, -) : BaseViewModel2( +) : BaseViewModel( initialState = State(), updateStateForEvent = updateStateForEvent, defaultDispatcher = dispatchers.Default, diff --git a/ui/navigation/src/main/kotlin/com/getcode/view/BaseViewModel.kt b/ui/navigation/src/main/kotlin/com/getcode/view/BaseViewModel.kt index b65b901f3..0ffe4bb18 100644 --- a/ui/navigation/src/main/kotlin/com/getcode/view/BaseViewModel.kt +++ b/ui/navigation/src/main/kotlin/com/getcode/view/BaseViewModel.kt @@ -1,15 +1,66 @@ package com.getcode.view import androidx.lifecycle.ViewModel -import com.getcode.util.resources.ResourceHelper +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import kotlin.coroutines.CoroutineContext -@Deprecated( - message = "Replaced With BaseViewModel2", - replaceWith = ReplaceWith("Use BaseViewModel2", "com.getcode.view.BaseViewModel2")) -abstract class BaseViewModel( - private val resources: ResourceHelper, +abstract class BaseViewModel( + initialState: ViewState, + private val updateStateForEvent: (Event) -> (ViewState.() -> ViewState), + private val defaultDispatcher: CoroutineContext = Dispatchers.Default, ) : ViewModel() { - open fun setIsLoading(isLoading: Boolean) {} - fun getString(resId: Int): String = resources.getString(resId) + private val _eventFlow: MutableSharedFlow = MutableSharedFlow() + val eventFlow: SharedFlow = _eventFlow.asSharedFlow() + + private val _stateFlow: MutableStateFlow = MutableStateFlow(initialState) + val stateFlow: StateFlow = _stateFlow.asStateFlow() + + fun dispatchEvent(event: Event) { + setState(updateStateForEvent(event)) + viewModelScope.launch(defaultDispatcher) { + _eventFlow.emit(event) + } + } + + suspend fun dispatchEvent(context: CoroutineContext, event: Event) { + withContext(context) { + dispatchEvent(event) + } + } + + private fun setState(update: ViewState.() -> ViewState) { + _stateFlow.value = _stateFlow.value.update() + } +} + +data class LoadingSuccessState( + val loading: Boolean = false, + val success: Boolean = false, + val error: Boolean = false, +) { + sealed interface State { + data object Idle: State + data object Loading : State + data object Success : State + data object Error : State + } + + val state: State = when { + loading -> State.Loading + success -> State.Success + error -> State.Error + else -> State.Idle + } + + val isIdle: Boolean = state is State.Idle } diff --git a/ui/navigation/src/main/kotlin/com/getcode/view/BaseViewModel2.kt b/ui/navigation/src/main/kotlin/com/getcode/view/BaseViewModel2.kt deleted file mode 100644 index 0a2da7cec..000000000 --- a/ui/navigation/src/main/kotlin/com/getcode/view/BaseViewModel2.kt +++ /dev/null @@ -1,66 +0,0 @@ -package com.getcode.view - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.SharedFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asSharedFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import kotlin.coroutines.CoroutineContext - -abstract class BaseViewModel2( - initialState: ViewState, - private val updateStateForEvent: (Event) -> (ViewState.() -> ViewState), - private val defaultDispatcher: CoroutineContext = Dispatchers.Default, -) : ViewModel() { - - private val _eventFlow: MutableSharedFlow = MutableSharedFlow() - val eventFlow: SharedFlow = _eventFlow.asSharedFlow() - - private val _stateFlow: MutableStateFlow = MutableStateFlow(initialState) - val stateFlow: StateFlow = _stateFlow.asStateFlow() - - fun dispatchEvent(event: Event) { - setState(updateStateForEvent(event)) - viewModelScope.launch(defaultDispatcher) { - _eventFlow.emit(event) - } - } - - suspend fun dispatchEvent(context: CoroutineContext, event: Event) { - withContext(context) { - dispatchEvent(event) - } - } - - private fun setState(update: ViewState.() -> ViewState) { - _stateFlow.value = _stateFlow.value.update() - } -} - -data class LoadingSuccessState( - val loading: Boolean = false, - val success: Boolean = false, - val error: Boolean = false, -) { - sealed interface State { - data object Idle: State - data object Loading : State - data object Success : State - data object Error : State - } - - val state: State = when { - loading -> State.Loading - success -> State.Success - error -> State.Error - else -> State.Idle - } - - val isIdle: Boolean = state is State.Idle -}