From fe096021d17672fa68daf823262c9d51e1a6929d Mon Sep 17 00:00:00 2001 From: stylianosgakis Date: Mon, 22 Jun 2026 17:14:51 +0200 Subject: [PATCH 1/5] Remove ProdOrDemoProvider in favor of simple switcher implementations Now all callers just take in the interface directly and whether the info comes from a prod or demo implementation is hidden from them --- .../com/hedvig/android/app/MainActivity.kt | 5 +- .../com/hedvig/android/app/ui/HedvigApp.kt | 5 +- .../hedvig/android/app/ui/HedvigAppState.kt | 13 ++--- .../core/demomode/ProdOrDemoProvider.kt | 17 ------ .../hedvig/android/core/demomode/Provider.kt | 5 -- ...GetTravelAddonBannerInfoUseCaseProvider.kt | 19 ------- .../SwitchingGetAddonBannerInfoUseCase.kt | 25 +++++++++ .../paying/member/GetMemberTypeUseCase.kt | 31 ++++++----- .../ui/triage/TravelAddonTriageViewModel.kt | 9 ++-- .../android/feature/chat/CbmChatViewModel.kt | 25 +++++---- .../chat/data/GetCbmChatRepositoryProvider.kt | 19 ------- .../chat/data/SwitchingCbmChatRepository.kt | 50 +++++++++++++++++ .../feature/chat/paging/ChatRemoteMediator.kt | 5 +- .../sell/sheet/CrossSellSheetViewModel.kt | 29 +++++----- .../home/di/GetHomeDataUseCaseProvider.kt | 22 -------- .../home/di/SwitchingGetHomeDataUseCase.kt | 28 ++++++++++ .../home/home/data/GetHomeDataUseCase.kt | 5 +- .../feature/home/home/ui/HomePresenter.kt | 15 +++--- .../feature/home/home/ui/HomeViewModel.kt | 9 ++-- .../home/home/data/GetHomeUseCaseTest.kt | 23 ++++---- .../feature/home/home/ui/HomePresenterTest.kt | 44 +++++++-------- .../GetInsuranceContractsUseCaseProvider.kt | 22 -------- ...er.kt => SwitchingGetCrossSellsUseCase.kt} | 20 +++---- .../SwitchingGetInsuranceContractsUseCase.kt | 29 ++++++++++ .../presentation/InsurancePresenter.kt | 13 +++-- .../presentation/InsuranceViewModel.kt | 11 ++-- .../GetContractForContractIdUseCase.kt | 6 +-- .../TerminatedContractsViewModel.kt | 10 ++-- .../presentation/InsurancePresenterTest.kt | 54 +++++++++---------- .../TerminatedContractsPresenterTest.kt | 18 +++---- .../GetShouldShowPayoutUseCaseProvider.kt | 19 ------- .../data/GetUpcomingPaymentUseCase.kt | 5 +- .../data/GetUpcomingPaymentUseCaseProvider.kt | 19 ------- .../SwitchingGetShouldShowPayoutUseCase.kt | 21 ++++++++ .../SwitchingGetUpcomingPaymentUseCase.kt | 21 ++++++++ .../payments/ui/payments/PaymentsPresenter.kt | 11 ++-- .../payments/ui/payments/PaymentsViewModel.kt | 5 +- .../contactinfo/ContactInfoViewModel.kt | 8 ++- .../profile/di/ProfileRepositoryProvider.kt | 22 -------- .../di/SwitchingContactInfoRepository.kt | 28 ++++++++++ .../contactinfo/ContactInfoPresenterTest.kt | 11 ++-- .../ui/history/CertificateHistoryViewModel.kt | 9 ++-- .../GetConnectPaymentReminderUseCase.kt | 1 - .../CrossSellHomeNotificationServiceImpl.kt | 34 ++++++++---- .../MissedPaymentNotificationService.kt | 25 +++++---- .../ui/data/ForeverRepositoryProvider.kt | 19 ------- .../ui/data/SwitchingForeverRepository.kt | 23 ++++++++ .../foreverui/ui/ui/ForeverViewModel.kt | 11 ++-- 48 files changed, 461 insertions(+), 417 deletions(-) delete mode 100644 app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/ProdOrDemoProvider.kt delete mode 100644 app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/Provider.kt delete mode 100644 app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/GetTravelAddonBannerInfoUseCaseProvider.kt create mode 100644 app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/SwitchingGetAddonBannerInfoUseCase.kt delete mode 100644 app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/data/GetCbmChatRepositoryProvider.kt create mode 100644 app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/data/SwitchingCbmChatRepository.kt delete mode 100644 app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/di/GetHomeDataUseCaseProvider.kt create mode 100644 app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/di/SwitchingGetHomeDataUseCase.kt delete mode 100644 app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/GetInsuranceContractsUseCaseProvider.kt rename app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/{GetCrossSellsUseCaseProvider.kt => SwitchingGetCrossSellsUseCase.kt} (53%) create mode 100644 app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetInsuranceContractsUseCase.kt delete mode 100644 app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/GetShouldShowPayoutUseCaseProvider.kt delete mode 100644 app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/GetUpcomingPaymentUseCaseProvider.kt create mode 100644 app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetShouldShowPayoutUseCase.kt create mode 100644 app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetUpcomingPaymentUseCase.kt delete mode 100644 app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/di/ProfileRepositoryProvider.kt create mode 100644 app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/di/SwitchingContactInfoRepository.kt delete mode 100644 app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/data/ForeverRepositoryProvider.kt create mode 100644 app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/data/SwitchingForeverRepository.kt diff --git a/app/app/src/main/kotlin/com/hedvig/android/app/MainActivity.kt b/app/app/src/main/kotlin/com/hedvig/android/app/MainActivity.kt index 7a34efab97..bbacee25fc 100644 --- a/app/app/src/main/kotlin/com/hedvig/android/app/MainActivity.kt +++ b/app/app/src/main/kotlin/com/hedvig/android/app/MainActivity.kt @@ -38,7 +38,6 @@ import com.hedvig.android.auth.MemberIdService import com.hedvig.android.core.appreview.WaitUntilAppReviewDialogShouldBeOpenedUseCase import com.hedvig.android.core.buildconstants.HedvigBuildConstants import com.hedvig.android.core.demomode.DemoManager -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.core.rive.RiveInitializer import com.hedvig.android.data.settings.datastore.SettingsDataStore import com.hedvig.android.featureflags.FeatureManager @@ -99,7 +98,7 @@ class MainActivity : AppCompatActivity() { private lateinit var memberIdService: MemberIdService @Inject - private lateinit var missedPaymentNotificationServiceProvider: Provider + private lateinit var missedPaymentNotificationService: MissedPaymentNotificationService @Inject private lateinit var currentDestinationHolder: CurrentDestinationHolder @@ -244,7 +243,7 @@ class MainActivity : AppCompatActivity() { externalNavigator = externalNavigator, logoutUseCase = logoutUseCase, getMemberAuthorizationCodeUseCase = getMemberAuthorizationCodeUseCase, - missedPaymentNotificationServiceProvider = missedPaymentNotificationServiceProvider, + missedPaymentNotificationService = missedPaymentNotificationService, currentDestinationHolder = currentDestinationHolder, ) } diff --git a/app/app/src/main/kotlin/com/hedvig/android/app/ui/HedvigApp.kt b/app/app/src/main/kotlin/com/hedvig/android/app/ui/HedvigApp.kt index 73ed768398..b260fe18ad 100644 --- a/app/app/src/main/kotlin/com/hedvig/android/app/ui/HedvigApp.kt +++ b/app/app/src/main/kotlin/com/hedvig/android/app/ui/HedvigApp.kt @@ -60,7 +60,6 @@ import com.hedvig.android.compose.ui.LocalSharedTransitionScope import com.hedvig.android.core.appreview.WaitUntilAppReviewDialogShouldBeOpenedUseCase import com.hedvig.android.core.buildconstants.HedvigBuildConstants import com.hedvig.android.core.demomode.DemoManager -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.data.settings.datastore.SettingsDataStore import com.hedvig.android.design.system.hedvig.DemoModeLabel import com.hedvig.android.design.system.hedvig.Surface @@ -109,7 +108,7 @@ internal fun HedvigApp( externalNavigator: ExternalNavigator, logoutUseCase: LogoutUseCase, getMemberAuthorizationCodeUseCase: GetMemberAuthorizationCodeUseCase, - missedPaymentNotificationServiceProvider: Provider, + missedPaymentNotificationService: MissedPaymentNotificationService, currentDestinationHolder: CurrentDestinationHolder, ) { ReportCurrentDestinationEffect(backstackController, currentDestinationHolder) @@ -118,7 +117,7 @@ internal fun HedvigApp( windowSizeClass = windowSizeClass, settingsDataStore = settingsDataStore, featureManager = featureManager, - missedPaymentNotificationServiceProvider = missedPaymentNotificationServiceProvider, + missedPaymentNotificationService = missedPaymentNotificationService, ) val darkTheme = hedvigAppState.darkTheme HedvigTheme(darkTheme = darkTheme) { diff --git a/app/app/src/main/kotlin/com/hedvig/android/app/ui/HedvigAppState.kt b/app/app/src/main/kotlin/com/hedvig/android/app/ui/HedvigAppState.kt index 10d328b7e3..44fd82fa4a 100644 --- a/app/app/src/main/kotlin/com/hedvig/android/app/ui/HedvigAppState.kt +++ b/app/app/src/main/kotlin/com/hedvig/android/app/ui/HedvigAppState.kt @@ -9,7 +9,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import com.hedvig.android.app.navigation.BackstackController -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.data.settings.datastore.SettingsDataStore import com.hedvig.android.featureflags.FeatureManager import com.hedvig.android.featureflags.flags.Feature @@ -31,7 +30,7 @@ internal fun rememberHedvigAppState( windowSizeClass: WindowSizeClass, settingsDataStore: SettingsDataStore, featureManager: FeatureManager, - missedPaymentNotificationServiceProvider: Provider, + missedPaymentNotificationService: MissedPaymentNotificationService, coroutineScope: CoroutineScope = rememberCoroutineScope(), ): HedvigAppState { val appState = remember( @@ -40,7 +39,7 @@ internal fun rememberHedvigAppState( coroutineScope, settingsDataStore, featureManager, - missedPaymentNotificationServiceProvider, + missedPaymentNotificationService, ) { HedvigAppState( backstackController = backstackController, @@ -48,7 +47,7 @@ internal fun rememberHedvigAppState( coroutineScope = coroutineScope, settingsDataStore = settingsDataStore, featureManager = featureManager, - missedPaymentNotificationServiceProvider = missedPaymentNotificationServiceProvider, + missedPaymentNotificationService = missedPaymentNotificationService, ) } return appState @@ -61,7 +60,7 @@ internal class HedvigAppState( coroutineScope: CoroutineScope, private val settingsDataStore: SettingsDataStore, featureManager: FeatureManager, - missedPaymentNotificationServiceProvider: Provider, + missedPaymentNotificationService: MissedPaymentNotificationService, ) { /** * App kill-switch. If this is enabled we must show nothing in the app but a button to try to update the app @@ -88,9 +87,7 @@ internal class HedvigAppState( ) val showPaymentsBadge: StateFlow = flow { - val service = missedPaymentNotificationServiceProvider - .provide() - emitAll(service.showRedDotNotification()) + emitAll(missedPaymentNotificationService.showRedDotNotification()) }.stateIn( coroutineScope, SharingStarted.WhileSubscribed(5_000), diff --git a/app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/ProdOrDemoProvider.kt b/app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/ProdOrDemoProvider.kt deleted file mode 100644 index e1ba30371a..0000000000 --- a/app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/ProdOrDemoProvider.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.hedvig.android.core.demomode - -import kotlinx.coroutines.flow.first - -interface ProdOrDemoProvider : Provider { - val demoManager: DemoManager - val demoImpl: T - val prodImpl: T - - override suspend fun provide(): T { - return if (demoManager.isDemoMode().first()) { - demoImpl - } else { - prodImpl - } - } -} diff --git a/app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/Provider.kt b/app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/Provider.kt deleted file mode 100644 index 295934f952..0000000000 --- a/app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/Provider.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.hedvig.android.core.demomode - -fun interface Provider { - suspend fun provide(): T -} diff --git a/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/GetTravelAddonBannerInfoUseCaseProvider.kt b/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/GetTravelAddonBannerInfoUseCaseProvider.kt deleted file mode 100644 index 4ba12e073d..0000000000 --- a/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/GetTravelAddonBannerInfoUseCaseProvider.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.hedvig.android.data.addons.data - -import com.hedvig.android.core.common.di.AppScope -import com.hedvig.android.core.demomode.DemoManager -import com.hedvig.android.core.demomode.ProdOrDemoProvider -import com.hedvig.android.core.demomode.Provider -import dev.zacsweers.metro.ContributesBinding -import dev.zacsweers.metro.Inject -import dev.zacsweers.metro.SingleIn -import dev.zacsweers.metro.binding - -@Inject -@SingleIn(AppScope::class) -@ContributesBinding(AppScope::class, binding>()) -internal class GetTravelAddonBannerInfoUseCaseProvider( - override val demoManager: DemoManager, - override val demoImpl: DemoGetAddonBannerInfoUseCase, - override val prodImpl: GetAddonBannerInfoUseCaseImpl, -) : ProdOrDemoProvider diff --git a/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/SwitchingGetAddonBannerInfoUseCase.kt b/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/SwitchingGetAddonBannerInfoUseCase.kt new file mode 100644 index 0000000000..cd7b89747c --- /dev/null +++ b/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/SwitchingGetAddonBannerInfoUseCase.kt @@ -0,0 +1,25 @@ +package com.hedvig.android.data.addons.data + +import com.hedvig.android.core.common.di.AppScope +import com.hedvig.android.core.demomode.DemoManager +import dev.zacsweers.metro.ContributesBinding +import dev.zacsweers.metro.Inject +import dev.zacsweers.metro.SingleIn +import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flow + +@Inject +@SingleIn(AppScope::class) +@ContributesBinding(AppScope::class) +internal class SwitchingGetAddonBannerInfoUseCase( + private val demoManager: DemoManager, + private val demoImpl: DemoGetAddonBannerInfoUseCase, + private val prodImpl: GetAddonBannerInfoUseCaseImpl, +) : GetAddonBannerInfoUseCase { + override fun invoke(source: AddonBannerSource) = flow { + emitAll(pick().invoke(source)) + } + + private suspend fun pick(): GetAddonBannerInfoUseCase = if (demoManager.isDemoMode().first()) demoImpl else prodImpl +} diff --git a/app/data/data-paying-member/src/main/kotlin/com/hedvig/android/data/paying/member/GetMemberTypeUseCase.kt b/app/data/data-paying-member/src/main/kotlin/com/hedvig/android/data/paying/member/GetMemberTypeUseCase.kt index a484dc06a5..d3a2d16dc3 100644 --- a/app/data/data-paying-member/src/main/kotlin/com/hedvig/android/data/paying/member/GetMemberTypeUseCase.kt +++ b/app/data/data-paying-member/src/main/kotlin/com/hedvig/android/data/paying/member/GetMemberTypeUseCase.kt @@ -9,15 +9,12 @@ import com.hedvig.android.apollo.safeExecute import com.hedvig.android.core.common.ErrorMessage import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.demomode.DemoManager -import com.hedvig.android.core.demomode.ProdOrDemoProvider -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.data.contract.ContractType import com.hedvig.android.data.contract.toContractType -import com.hedvig.android.logger.logcat import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn -import dev.zacsweers.metro.binding +import kotlinx.coroutines.flow.first import octopus.ActiveInsuranceContractTypesQuery interface GetMemberTypeUseCase { @@ -34,7 +31,7 @@ enum class MemberType { STANDARD_MEMBER, // current logic - STANDARD_TO_QASA_MEMBER + STANDARD_TO_QASA_MEMBER, // in Payments: if no upcoming payments: hide discounts and member payment details // in Payments: if upcoming payment and missing payin: show connect payin reminder, // else show connect payout reminder if missing @@ -43,12 +40,16 @@ enum class MemberType { @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class, binding>()) -internal class GetMemberTypeUseCaseProvider( - override val demoManager: DemoManager, - override val demoImpl: GetMemberTypeUseCaseDemo, - override val prodImpl: GetMemberTypeUseCaseImpl, -) : ProdOrDemoProvider +@ContributesBinding(AppScope::class) +internal class SwitchingGetMemberTypeUseCase( + private val demoManager: DemoManager, + private val demoImpl: GetMemberTypeUseCaseDemo, + private val prodImpl: GetMemberTypeUseCaseImpl, +) : GetMemberTypeUseCase { + override suspend fun invoke() = pick().invoke() + + private suspend fun pick(): GetMemberTypeUseCase = if (demoManager.isDemoMode().first()) demoImpl else prodImpl +} @SingleIn(AppScope::class) @Inject @@ -67,9 +68,11 @@ internal class GetMemberTypeUseCaseImpl( .terminatedContracts .map { it.currentAgreement.productVariant.typeOfContract.toContractType() } - val onlyQasaContracts = (activeContractsTypes.isNotEmpty() - || terminatedContractsTypes.isNotEmpty()) && - activeContractsTypes.all { it == ContractType.SE_QASA_LANDLORD } && + val onlyQasaContracts = ( + activeContractsTypes.isNotEmpty() || + terminatedContractsTypes.isNotEmpty() + ) && + activeContractsTypes.all { it == ContractType.SE_QASA_LANDLORD } && terminatedContractsTypes.all { it == ContractType.SE_QASA_LANDLORD } if (onlyQasaContracts) return@either MemberType.QASA_ONLY_MEMBER diff --git a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/ui/triage/TravelAddonTriageViewModel.kt b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/ui/triage/TravelAddonTriageViewModel.kt index 7250457666..4bac844880 100644 --- a/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/ui/triage/TravelAddonTriageViewModel.kt +++ b/app/feature/feature-addon-purchase/src/main/kotlin/com/hedvig/android/feature/addon/purchase/ui/triage/TravelAddonTriageViewModel.kt @@ -9,7 +9,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import com.hedvig.android.core.common.di.ActivityRetainedScope import com.hedvig.android.core.common.di.HedvigViewModel -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.data.addons.data.AddonBannerSource import com.hedvig.android.data.addons.data.GetAddonBannerInfoUseCase import com.hedvig.android.molecule.public.MoleculePresenter @@ -22,15 +21,15 @@ import kotlinx.coroutines.flow.first @AssistedInject @HedvigViewModel(ActivityRetainedScope::class) internal class TravelAddonTriageViewModel( - getAddonBannerInfoUseCaseProvider: Provider, + getAddonBannerInfoUseCase: GetAddonBannerInfoUseCase, @Assisted addonBannerSource: AddonBannerSource, ) : MoleculeViewModel( initialState = TravelAddonTriageState.Loading, - presenter = TravelAddonTriagePresenter(getAddonBannerInfoUseCaseProvider, addonBannerSource), + presenter = TravelAddonTriagePresenter(getAddonBannerInfoUseCase, addonBannerSource), ) internal class TravelAddonTriagePresenter( - private val getAddonBannerInfoUseCaseProvider: Provider, + private val getAddonBannerInfoUseCase: GetAddonBannerInfoUseCase, private val addonBannerSource: AddonBannerSource, ) : MoleculePresenter { @Composable @@ -42,7 +41,7 @@ internal class TravelAddonTriagePresenter( LaunchedEffect(loadIteration) { currentState = TravelAddonTriageState.Loading - val result = getAddonBannerInfoUseCaseProvider.provide().invoke(addonBannerSource) + val result = getAddonBannerInfoUseCase.invoke(addonBannerSource) result.first().fold( ifLeft = { _ -> currentState = TravelAddonTriageState.Failure(FailureReason.GENERAL) diff --git a/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/CbmChatViewModel.kt b/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/CbmChatViewModel.kt index 40aeca51c2..3bcfbf696f 100644 --- a/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/CbmChatViewModel.kt +++ b/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/CbmChatViewModel.kt @@ -32,7 +32,6 @@ import arrow.core.Either import com.benasher44.uuid.Uuid import com.hedvig.android.core.common.di.ActivityRetainedScope import com.hedvig.android.core.common.di.HedvigViewModel -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.data.chat.database.ChatDao import com.hedvig.android.data.chat.database.ChatMessageEntity import com.hedvig.android.data.chat.database.RemoteKeyDao @@ -82,7 +81,7 @@ internal class CbmChatViewModel @AssistedInject constructor( database: RoomDatabase, chatDao: ChatDao, remoteKeyDao: RemoteKeyDao, - chatRepository: Provider, + chatRepository: CbmChatRepository, featureManager: FeatureManager, clock: Clock, context: Context, @@ -114,7 +113,7 @@ private fun cbmChatPresenterPagingData( database: RoomDatabase, chatDao: ChatDao, remoteKeyDao: RemoteKeyDao, - chatRepository: Provider, + chatRepository: CbmChatRepository, clock: Clock, scope: CoroutineScope, ): Flow> { @@ -143,7 +142,7 @@ internal class CbmChatPresenter( private val conversationId: Uuid, private val pagingData: Flow>, private val chatDao: ChatDao, - private val chatRepository: Provider, + private val chatRepository: CbmChatRepository, private val featureManager: FeatureManager, private val context: Context, ) : MoleculePresenter { @@ -178,7 +177,7 @@ internal class CbmChatPresenter( return@LaunchedEffect } conversationInfoStatus = Initializing - chatRepository.provide().getConversationInfo(conversationId).collect { result -> + chatRepository.getConversationInfo(conversationId).collect { result -> result.fold( ifLeft = { conversationInfoStatus = Failed @@ -210,7 +209,7 @@ internal class CbmChatPresenter( } } if (!conversationAlreadyStarted) { - chatRepository.provide().createConversation(conversationId).onRight { backendConversationInfo -> + chatRepository.createConversation(conversationId).onRight { backendConversationInfo -> conversationInfoStatus = Loaded(backendConversationInfo) } } @@ -224,7 +223,7 @@ internal class CbmChatPresenter( launch { numberOfOngoingUploads.update { it + 1 } startConversationIfNecessary() - chatRepository.provide().sendText(conversationId, null, event.message) + chatRepository.sendText(conversationId, null, event.message) numberOfOngoingUploads.update { it - 1 } } } @@ -233,7 +232,7 @@ internal class CbmChatPresenter( launch { numberOfOngoingUploads.update { it + 1 } startConversationIfNecessary() - chatRepository.provide().sendPhotos(conversationId, event.uriList) + chatRepository.sendPhotos(conversationId, event.uriList) numberOfOngoingUploads.update { it - 1 } } } @@ -242,7 +241,7 @@ internal class CbmChatPresenter( launch { numberOfOngoingUploads.update { it + 1 } startConversationIfNecessary() - val result = chatRepository.provide().sendMedia(conversationId, event.uriList) + val result = chatRepository.sendMedia(conversationId, event.uriList) Snapshot.withMutableSnapshot { for (result in result) { result.onError( @@ -259,7 +258,7 @@ internal class CbmChatPresenter( launch { numberOfOngoingUploads.update { it + 1 } startConversationIfNecessary() - val result = chatRepository.provide().retrySendMessage(conversationId, event.messageId) + val result = chatRepository.retrySendMessage(conversationId, event.messageId) result.onError( onFailedToPersistUriPermissionError = { showFileFailedToBeSendToast = true }, onFileTooBigError = { showFileTooBigErrorToast = true }, @@ -317,7 +316,7 @@ private fun presentLoadedChat( enableInlineMediaPlayer: Boolean, conversationId: Uuid, chatDao: ChatDao, - chatRepository: Provider, + chatRepository: CbmChatRepository, showUploading: Boolean, showFileTooBigErrorToast: Boolean, hideBanner: Boolean, @@ -329,7 +328,7 @@ private fun presentLoadedChat( val bannerText by if (!hideBanner) { remember(conversationId, chatRepository) { - flow { emitAll(chatRepository.provide().bannerText(conversationId)) } + flow { emitAll(chatRepository.bannerText(conversationId)) } }.collectAsState(null) } else { remember { mutableStateOf(null) } @@ -348,7 +347,7 @@ private fun presentLoadedChat( .distinctUntilChanged() .collectLatest { poll -> if (poll) { - chatRepository.provide().pollNewestMessages(conversationId).collect { + chatRepository.pollNewestMessages(conversationId).collect { logcat { "Polling error: $it" } } } diff --git a/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/data/GetCbmChatRepositoryProvider.kt b/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/data/GetCbmChatRepositoryProvider.kt deleted file mode 100644 index 9fd8046b0a..0000000000 --- a/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/data/GetCbmChatRepositoryProvider.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.hedvig.android.feature.chat.data - -import com.hedvig.android.core.common.di.AppScope -import com.hedvig.android.core.demomode.DemoManager -import com.hedvig.android.core.demomode.ProdOrDemoProvider -import com.hedvig.android.core.demomode.Provider -import dev.zacsweers.metro.ContributesBinding -import dev.zacsweers.metro.Inject -import dev.zacsweers.metro.SingleIn -import dev.zacsweers.metro.binding - -@Inject -@SingleIn(AppScope::class) -@ContributesBinding(AppScope::class, binding>()) -internal class GetCbmChatRepositoryProvider( - override val demoManager: DemoManager, - override val prodImpl: CbmChatRepositoryImpl, - override val demoImpl: CbmChatRepositoryDemo, -) : ProdOrDemoProvider diff --git a/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/data/SwitchingCbmChatRepository.kt b/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/data/SwitchingCbmChatRepository.kt new file mode 100644 index 0000000000..8c6e197f9b --- /dev/null +++ b/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/data/SwitchingCbmChatRepository.kt @@ -0,0 +1,50 @@ +package com.hedvig.android.feature.chat.data + +import android.net.Uri +import com.benasher44.uuid.Uuid +import com.hedvig.android.core.common.di.AppScope +import com.hedvig.android.core.demomode.DemoManager +import dev.zacsweers.metro.ContributesBinding +import dev.zacsweers.metro.Inject +import dev.zacsweers.metro.SingleIn +import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flow + +@Inject +@SingleIn(AppScope::class) +@ContributesBinding(AppScope::class) +internal class SwitchingCbmChatRepository( + private val demoManager: DemoManager, + private val prodImpl: CbmChatRepositoryImpl, + private val demoImpl: CbmChatRepositoryDemo, +) : CbmChatRepository { + override suspend fun createConversation(conversationId: Uuid) = pick().createConversation(conversationId) + + override fun getConversationInfo(conversationId: Uuid) = flow { + emitAll(pick().getConversationInfo(conversationId)) + } + + override fun bannerText(conversationId: Uuid) = flow { + emitAll(pick().bannerText(conversationId)) + } + + override suspend fun chatMessages(conversationId: Uuid, pagingToken: PagingToken?) = + pick().chatMessages(conversationId, pagingToken) + + override fun pollNewestMessages(conversationId: Uuid) = flow { + emitAll(pick().pollNewestMessages(conversationId)) + } + + override suspend fun retrySendMessage(conversationId: Uuid, messageId: String) = + pick().retrySendMessage(conversationId, messageId) + + override suspend fun sendText(conversationId: Uuid, retryingMessageId: Uuid?, text: String) = + pick().sendText(conversationId, retryingMessageId, text) + + override suspend fun sendPhotos(conversationId: Uuid, uriList: List) = pick().sendPhotos(conversationId, uriList) + + override suspend fun sendMedia(conversationId: Uuid, uriList: List) = pick().sendMedia(conversationId, uriList) + + private suspend fun pick(): CbmChatRepository = if (demoManager.isDemoMode().first()) demoImpl else prodImpl +} diff --git a/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/paging/ChatRemoteMediator.kt b/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/paging/ChatRemoteMediator.kt index c466294341..1bac822dd7 100644 --- a/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/paging/ChatRemoteMediator.kt +++ b/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/paging/ChatRemoteMediator.kt @@ -8,7 +8,6 @@ import androidx.room.RoomDatabase import androidx.room.withTransaction import arrow.core.getOrElse import com.benasher44.uuid.Uuid -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.data.chat.database.ChatDao import com.hedvig.android.data.chat.database.ChatMessageEntity import com.hedvig.android.data.chat.database.RemoteKeyDao @@ -27,7 +26,7 @@ internal class ChatRemoteMediator( private val database: RoomDatabase, private val chatDao: ChatDao, private val remoteKeyDao: RemoteKeyDao, - private val chatRepository: Provider, + private val chatRepository: CbmChatRepository, private val clock: Clock, ) : RemoteMediator() { override suspend fun load(loadType: LoadType, state: PagingState): MediatorResult { @@ -49,7 +48,7 @@ internal class ChatRemoteMediator( PagingToken.OlderToken(olderToken) } } - val response = chatRepository.provide().chatMessages(conversationId, pagingToken).getOrElse { + val response = chatRepository.chatMessages(conversationId, pagingToken).getOrElse { logcat { "ChatRemoteMediator: Failed to fetch chat messages: $it [MediatorResult.Error(it)]" } return MediatorResult.Error(it) } diff --git a/app/feature/feature-cross-sell-sheet/src/main/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetViewModel.kt b/app/feature/feature-cross-sell-sheet/src/main/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetViewModel.kt index cceaeaf094..9c9b35505c 100644 --- a/app/feature/feature-cross-sell-sheet/src/main/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetViewModel.kt +++ b/app/feature/feature-cross-sell-sheet/src/main/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetViewModel.kt @@ -18,8 +18,6 @@ import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.common.di.ActivityRetainedScope import com.hedvig.android.core.common.di.HedvigViewModel import com.hedvig.android.core.demomode.DemoManager -import com.hedvig.android.core.demomode.ProdOrDemoProvider -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.crosssells.BundleProgress import com.hedvig.android.crosssells.CrossSellSheetData import com.hedvig.android.crosssells.RecommendedCrossSell @@ -33,10 +31,10 @@ import com.hedvig.android.molecule.public.MoleculeViewModel import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn -import dev.zacsweers.metro.binding import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest @@ -51,11 +49,11 @@ import octopus.type.UserFlow @Inject @HedvigViewModel(ActivityRetainedScope::class) internal class CrossSellSheetViewModel( - getCrossSellSheetDataUseCaseProvider: Provider, + getCrossSellSheetDataUseCase: GetCrossSellSheetDataUseCase, crossSellAfterFlowRepository: CrossSellAfterFlowRepository, ) : MoleculeViewModel( CrossSellSheetState.Loading, - CrossSellSheetPresenter(getCrossSellSheetDataUseCaseProvider, crossSellAfterFlowRepository), + CrossSellSheetPresenter(getCrossSellSheetDataUseCase, crossSellAfterFlowRepository), ) internal sealed interface CrossSellSheetEvent { @@ -73,7 +71,7 @@ internal sealed interface CrossSellSheetState { } private class CrossSellSheetPresenter( - private val getCrossSellSheetDataUseCaseProvider: Provider, + private val getCrossSellSheetDataUseCase: GetCrossSellSheetDataUseCase, private val crossSellAfterFlowRepository: CrossSellAfterFlowRepository, ) : MoleculePresenter { @Composable @@ -97,7 +95,7 @@ private class CrossSellSheetPresenter( return@transformLatest } emitAll( - getCrossSellSheetDataUseCaseProvider.provide().invoke(infoType.toCrossSellSource()) + getCrossSellSheetDataUseCase.invoke(infoType.toCrossSellSource()) .mapLatest { result -> result.fold( ifLeft = { error -> CrossSellSheetState.Error(error) }, @@ -132,12 +130,17 @@ internal fun CrossSellInfoType.toCrossSellSource(): CrossSellInput { @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class, binding>()) -internal class GetCrossSellSheetDataUseCaseProvider( - override val demoManager: DemoManager, - override val prodImpl: GetCrossSellSheetDataUseCaseImpl, - override val demoImpl: DemoGetCrossSellSheetDataUseCase, -) : ProdOrDemoProvider +@ContributesBinding(AppScope::class) +internal class SwitchingGetCrossSellSheetDataUseCase( + private val demoManager: DemoManager, + private val prodImpl: GetCrossSellSheetDataUseCaseImpl, + private val demoImpl: DemoGetCrossSellSheetDataUseCase, +) : GetCrossSellSheetDataUseCase { + override suspend fun invoke(source: CrossSellInput) = pick().invoke(source) + + private suspend fun pick(): GetCrossSellSheetDataUseCase = + if (demoManager.isDemoMode().first()) demoImpl else prodImpl +} internal interface GetCrossSellSheetDataUseCase { suspend fun invoke(source: CrossSellInput): Flow> diff --git a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/di/GetHomeDataUseCaseProvider.kt b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/di/GetHomeDataUseCaseProvider.kt deleted file mode 100644 index b171fe2004..0000000000 --- a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/di/GetHomeDataUseCaseProvider.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.hedvig.android.feature.home.di - -import com.hedvig.android.core.common.di.AppScope -import com.hedvig.android.core.demomode.DemoManager -import com.hedvig.android.core.demomode.ProdOrDemoProvider -import com.hedvig.android.core.demomode.Provider -import com.hedvig.android.feature.home.home.data.GetHomeDataUseCase -import com.hedvig.android.feature.home.home.data.GetHomeDataUseCaseDemo -import com.hedvig.android.feature.home.home.data.GetHomeDataUseCaseImpl -import dev.zacsweers.metro.ContributesBinding -import dev.zacsweers.metro.Inject -import dev.zacsweers.metro.SingleIn -import dev.zacsweers.metro.binding - -@Inject -@SingleIn(AppScope::class) -@ContributesBinding(AppScope::class, binding>()) -internal class GetHomeDataUseCaseProvider( - override val demoManager: DemoManager, - override val prodImpl: GetHomeDataUseCaseImpl, - override val demoImpl: GetHomeDataUseCaseDemo, -) : ProdOrDemoProvider diff --git a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/di/SwitchingGetHomeDataUseCase.kt b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/di/SwitchingGetHomeDataUseCase.kt new file mode 100644 index 0000000000..d73d9d8f6b --- /dev/null +++ b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/di/SwitchingGetHomeDataUseCase.kt @@ -0,0 +1,28 @@ +package com.hedvig.android.feature.home.di + +import com.hedvig.android.core.common.di.AppScope +import com.hedvig.android.core.demomode.DemoManager +import com.hedvig.android.feature.home.home.data.GetHomeDataUseCase +import com.hedvig.android.feature.home.home.data.GetHomeDataUseCaseDemo +import com.hedvig.android.feature.home.home.data.GetHomeDataUseCaseImpl +import dev.zacsweers.metro.ContributesBinding +import dev.zacsweers.metro.Inject +import dev.zacsweers.metro.SingleIn +import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flow + +@Inject +@SingleIn(AppScope::class) +@ContributesBinding(AppScope::class) +internal class SwitchingGetHomeDataUseCase( + private val demoManager: DemoManager, + private val prodImpl: GetHomeDataUseCaseImpl, + private val demoImpl: GetHomeDataUseCaseDemo, +) : GetHomeDataUseCase { + override fun invoke(forceNetworkFetch: Boolean) = flow { + emitAll(pick().invoke(forceNetworkFetch)) + } + + private suspend fun pick(): GetHomeDataUseCase = if (demoManager.isDemoMode().first()) demoImpl else prodImpl +} diff --git a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/data/GetHomeDataUseCase.kt b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/data/GetHomeDataUseCase.kt index 6c4fe1dbda..a817f0ecdb 100644 --- a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/data/GetHomeDataUseCase.kt +++ b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/data/GetHomeDataUseCase.kt @@ -12,7 +12,6 @@ import com.apollographql.apollo.cache.normalized.FetchPolicy import com.apollographql.apollo.cache.normalized.fetchPolicy import com.hedvig.android.apollo.ApolloOperationError import com.hedvig.android.apollo.safeFlow -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.crosssells.BundleProgress import com.hedvig.android.crosssells.CrossSellSheetData import com.hedvig.android.crosssells.RecommendedCrossSell @@ -59,7 +58,7 @@ internal class GetHomeDataUseCaseImpl( private val featureManager: FeatureManager, private val clock: Clock, private val timeZone: TimeZone, - private val getTravelAddonBannerInfoUseCaseProvider: Provider, + private val getAddonBannerInfoUseCase: GetAddonBannerInfoUseCase, private val hasAnyActiveConversationUseCase: HasAnyActiveConversationUseCase, ) : GetHomeDataUseCase { override fun invoke(forceNetworkFetch: Boolean): Flow> { @@ -81,7 +80,7 @@ internal class GetHomeDataUseCaseImpl( }, getMemberRemindersUseCase.invoke(), flow { - emitAll(getTravelAddonBannerInfoUseCaseProvider.provide().invoke(AddonBannerSource.INSURANCES_TAB)) + emitAll(getAddonBannerInfoUseCase.invoke(AddonBannerSource.INSURANCES_TAB)) }, featureManager.isFeatureEnabled(Feature.HELP_CENTER), featureManager.isFeatureEnabled(Feature.ALWAYS_AVAILABLE_INBOX_AND_NEW_CHAT), diff --git a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/ui/HomePresenter.kt b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/ui/HomePresenter.kt index 93b4981b1b..fafa5cb3bc 100644 --- a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/ui/HomePresenter.kt +++ b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/ui/HomePresenter.kt @@ -12,7 +12,6 @@ import androidx.compose.runtime.snapshots.Snapshot import arrow.core.Either import com.hedvig.android.apollo.ApolloOperationError import com.hedvig.android.core.common.ApplicationScope -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.crosssells.CrossSellSheetData import com.hedvig.android.data.addons.data.AddonBannerInfo import com.hedvig.android.feature.home.home.data.GetHomeDataUseCase @@ -32,9 +31,9 @@ import kotlinx.datetime.TimeZone import kotlinx.datetime.toLocalDateTime internal class HomePresenter( - private val getHomeDataUseCaseProvider: Provider, + private val getHomeDataUseCase: GetHomeDataUseCase, private val seenImportantMessagesStorage: SeenImportantMessagesStorage, - private val crossSellHomeNotificationServiceProvider: Provider, + private val crossSellHomeNotificationService: CrossSellHomeNotificationService, private val applicationScope: ApplicationScope, private val isProduction: Boolean, ) : MoleculePresenter { @@ -60,7 +59,7 @@ internal class HomePresenter( HomeEvent.MarkCardCrossSellsAsSeen -> { applicationScope.launch { - crossSellHomeNotificationServiceProvider.provide().markAsSeen() + crossSellHomeNotificationService.markAsSeen() } } @@ -72,7 +71,7 @@ internal class HomePresenter( LaunchedEffect(crossSellToolTipShownEpochDay) { val epochDay = crossSellToolTipShownEpochDay if (epochDay != null) { - crossSellHomeNotificationServiceProvider.provide().setLastEpochDayNewRecommendationNotificationWasShown( + crossSellHomeNotificationService.setLastEpochDayNewRecommendationNotificationWasShown( epochDay, ) } @@ -84,9 +83,9 @@ internal class HomePresenter( hasError = false } combine( - getHomeDataUseCaseProvider.provide().invoke(forceNetworkFetch), - crossSellHomeNotificationServiceProvider.provide().showRedDotNotification(), - crossSellHomeNotificationServiceProvider.provide().getLastEpochDayNewRecommendationNotificationWasShown(), + getHomeDataUseCase.invoke(forceNetworkFetch), + crossSellHomeNotificationService.showRedDotNotification(), + crossSellHomeNotificationService.getLastEpochDayNewRecommendationNotificationWasShown(), ) { homeResult: Either, showRedDot: Boolean, epochDay: Long? -> homeResult to CrossSellRecommendationNotification( showRedDot, diff --git a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/ui/HomeViewModel.kt b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/ui/HomeViewModel.kt index bad8ef7acf..49654c4e97 100644 --- a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/ui/HomeViewModel.kt +++ b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/ui/HomeViewModel.kt @@ -4,7 +4,6 @@ import com.hedvig.android.core.buildconstants.HedvigBuildConstants import com.hedvig.android.core.common.ApplicationScope import com.hedvig.android.core.common.di.ActivityRetainedScope import com.hedvig.android.core.common.di.HedvigViewModel -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.feature.home.home.data.GetHomeDataUseCase import com.hedvig.android.feature.home.home.data.SeenImportantMessagesStorage import com.hedvig.android.molecule.public.MoleculeViewModel @@ -14,17 +13,17 @@ import dev.zacsweers.metro.Inject @Inject @HedvigViewModel(ActivityRetainedScope::class) internal class HomeViewModel( - getHomeDataUseCaseProvider: Provider, + getHomeDataUseCase: GetHomeDataUseCase, seenImportantMessagesStorage: SeenImportantMessagesStorage, - crossSellHomeNotificationServiceProvider: Provider, + crossSellHomeNotificationService: CrossSellHomeNotificationService, applicationScope: ApplicationScope, hedvigBuildConstants: HedvigBuildConstants, ) : MoleculeViewModel( HomeUiState.Loading, HomePresenter( - getHomeDataUseCaseProvider, + getHomeDataUseCase, seenImportantMessagesStorage, - crossSellHomeNotificationServiceProvider, + crossSellHomeNotificationService, applicationScope, hedvigBuildConstants.isProduction, ), diff --git a/app/feature/feature-home/src/test/kotlin/com/hedvig/android/feature/home/home/data/GetHomeUseCaseTest.kt b/app/feature/feature-home/src/test/kotlin/com/hedvig/android/feature/home/home/data/GetHomeUseCaseTest.kt index f34bfbd4ef..e85c63c579 100644 --- a/app/feature/feature-home/src/test/kotlin/com/hedvig/android/feature/home/home/data/GetHomeUseCaseTest.kt +++ b/app/feature/feature-home/src/test/kotlin/com/hedvig/android/feature/home/home/data/GetHomeUseCaseTest.kt @@ -25,7 +25,6 @@ import com.hedvig.android.apollo.test.TestApolloClientRule import com.hedvig.android.apollo.test.TestNetworkTransportType import com.hedvig.android.core.common.ErrorMessage import com.hedvig.android.core.common.test.isRight -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.data.addons.data.AddonBannerInfo import com.hedvig.android.data.addons.data.AddonBannerSource import com.hedvig.android.data.addons.data.GetAddonBannerInfoUseCase @@ -71,15 +70,13 @@ internal class GetHomeUseCaseTest { @get:Rule val testLogcatLogger = TestLogcatLoggingRule() - val travelBannerProvider = Provider { - object : GetAddonBannerInfoUseCase { - override fun invoke(source: AddonBannerSource): Flow>> { - return flowOf( - either { - emptyList() - }, - ) - } + val travelBannerUseCase = object : GetAddonBannerInfoUseCase { + override fun invoke(source: AddonBannerSource): Flow>> { + return flowOf( + either { + emptyList() + }, + ) } } @@ -110,7 +107,7 @@ internal class GetHomeUseCaseTest { FakeFeatureManager(true), TestClock(), TimeZone.UTC, - getTravelAddonBannerInfoUseCaseProvider = travelBannerProvider, + getAddonBannerInfoUseCase = travelBannerUseCase, HasAnyActiveConversationUseCase(apolloClient), ) val testId = "test" @@ -159,7 +156,7 @@ internal class GetHomeUseCaseTest { FakeFeatureManager(true), TestClock(), TimeZone.UTC, - travelBannerProvider, + travelBannerUseCase, HasAnyActiveConversationUseCase(apolloClient), ) @@ -757,7 +754,7 @@ internal class GetHomeUseCaseTest { featureManager, testClock, timeZone, - travelBannerProvider, + travelBannerUseCase, HasAnyActiveConversationUseCase(apolloClient), ) } diff --git a/app/feature/feature-home/src/test/kotlin/com/hedvig/android/feature/home/home/ui/HomePresenterTest.kt b/app/feature/feature-home/src/test/kotlin/com/hedvig/android/feature/home/home/ui/HomePresenterTest.kt index 27b90ac1d9..4f7fde4823 100644 --- a/app/feature/feature-home/src/test/kotlin/com/hedvig/android/feature/home/home/ui/HomePresenterTest.kt +++ b/app/feature/feature-home/src/test/kotlin/com/hedvig/android/feature/home/home/ui/HomePresenterTest.kt @@ -58,9 +58,9 @@ internal class HomePresenterTest { fun `asking to refresh successfully asks for a fetch from the network`() = runTest { val getHomeDataUseCase = TestGetHomeDataUseCase() val homePresenter = HomePresenter( - { getHomeDataUseCase }, + getHomeDataUseCase, SeenImportantMessagesStorageImpl(), - { FakeCrossSellHomeNotificationService() }, + FakeCrossSellHomeNotificationService(), ApplicationScope(backgroundScope), false, ) @@ -85,9 +85,9 @@ internal class HomePresenterTest { fun `getting a failed response and retrying, should result in a successful state`() = runTest { val getHomeDataUseCase = TestGetHomeDataUseCase() val homePresenter = HomePresenter( - { getHomeDataUseCase }, + getHomeDataUseCase, SeenImportantMessagesStorageImpl(), - { FakeCrossSellHomeNotificationService() }, + FakeCrossSellHomeNotificationService(), ApplicationScope(backgroundScope), false, ) @@ -110,9 +110,9 @@ internal class HomePresenterTest { fun `a successful response, properly propagates the info to the UI State`() = runTest { val getHomeDataUseCase = TestGetHomeDataUseCase() val homePresenter = HomePresenter( - { getHomeDataUseCase }, + getHomeDataUseCase, SeenImportantMessagesStorageImpl(), - { FakeCrossSellHomeNotificationService() }, + FakeCrossSellHomeNotificationService(), ApplicationScope(backgroundScope), false, ) @@ -183,9 +183,9 @@ internal class HomePresenterTest { fun `the notification member reminder must not show for the home presenter`() = runTest { val getHomeDataUseCase = TestGetHomeDataUseCase() val homePresenter = HomePresenter( - { getHomeDataUseCase }, + getHomeDataUseCase, SeenImportantMessagesStorageImpl(), - { FakeCrossSellHomeNotificationService() }, + FakeCrossSellHomeNotificationService(), ApplicationScope(backgroundScope), false, ) @@ -234,9 +234,9 @@ internal class HomePresenterTest { fun `receiving a failed state and then a successful one propagates the success without having to retry`() = runTest { val getHomeDataUseCase = TestGetHomeDataUseCase() val homePresenter = HomePresenter( - { getHomeDataUseCase }, + getHomeDataUseCase, SeenImportantMessagesStorageImpl(), - { FakeCrossSellHomeNotificationService() }, + FakeCrossSellHomeNotificationService(), ApplicationScope(backgroundScope), false, ) @@ -258,9 +258,9 @@ internal class HomePresenterTest { ) = runTest { val getHomeDataUseCase = TestGetHomeDataUseCase() val homePresenter = HomePresenter( - { getHomeDataUseCase }, + getHomeDataUseCase, SeenImportantMessagesStorageImpl(), - { FakeCrossSellHomeNotificationService() }, + FakeCrossSellHomeNotificationService(), ApplicationScope(backgroundScope), false, ) @@ -295,9 +295,9 @@ internal class HomePresenterTest { fun `if firstVet sections and crossSells lists are empty do not show first vet icon and crossSells icon`() = runTest { val getHomeDataUseCase = TestGetHomeDataUseCase() val homePresenter = HomePresenter( - { getHomeDataUseCase }, + getHomeDataUseCase, SeenImportantMessagesStorageImpl(), - { FakeCrossSellHomeNotificationService() }, + FakeCrossSellHomeNotificationService(), ApplicationScope(backgroundScope), false, ) @@ -342,9 +342,9 @@ internal class HomePresenterTest { fun `if not empty firstVet sections list state should have first vet action with same firstVetSections`() = runTest { val getHomeDataUseCase = TestGetHomeDataUseCase() val homePresenter = HomePresenter( - { getHomeDataUseCase }, + getHomeDataUseCase, SeenImportantMessagesStorageImpl(), - { FakeCrossSellHomeNotificationService() }, + FakeCrossSellHomeNotificationService(), ApplicationScope(backgroundScope), false, ) @@ -396,9 +396,9 @@ internal class HomePresenterTest { fun `if crossSell has recommendation or otherCrossSells list show crossSells icon`() = runTest { val getHomeDataUseCase = TestGetHomeDataUseCase() val homePresenter = HomePresenter( - { getHomeDataUseCase }, + getHomeDataUseCase, SeenImportantMessagesStorageImpl(), - { FakeCrossSellHomeNotificationService() }, + FakeCrossSellHomeNotificationService(), ApplicationScope(backgroundScope), false, ) @@ -453,9 +453,9 @@ internal class HomePresenterTest { fun `if should show chat show chat icon`() = runTest { val getHomeDataUseCase = TestGetHomeDataUseCase() val homePresenter = HomePresenter( - { getHomeDataUseCase }, + getHomeDataUseCase, SeenImportantMessagesStorageImpl(), - { FakeCrossSellHomeNotificationService() }, + FakeCrossSellHomeNotificationService(), ApplicationScope(backgroundScope), false, ) @@ -499,9 +499,9 @@ internal class HomePresenterTest { fun `if shouldn't show chat do not show chat icon`() = runTest { val getHomeDataUseCase = TestGetHomeDataUseCase() val homePresenter = HomePresenter( - { getHomeDataUseCase }, + getHomeDataUseCase, SeenImportantMessagesStorageImpl(), - { FakeCrossSellHomeNotificationService() }, + FakeCrossSellHomeNotificationService(), ApplicationScope(backgroundScope), false, ) diff --git a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/GetInsuranceContractsUseCaseProvider.kt b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/GetInsuranceContractsUseCaseProvider.kt deleted file mode 100644 index ef3967abff..0000000000 --- a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/GetInsuranceContractsUseCaseProvider.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.hedvig.android.feature.insurances.di - -import com.hedvig.android.core.common.di.AppScope -import com.hedvig.android.core.demomode.DemoManager -import com.hedvig.android.core.demomode.ProdOrDemoProvider -import com.hedvig.android.core.demomode.Provider -import com.hedvig.android.feature.insurances.data.GetInsuranceContractsUseCase -import com.hedvig.android.feature.insurances.data.GetInsuranceContractsUseCaseDemo -import com.hedvig.android.feature.insurances.data.GetInsuranceContractsUseCaseImpl -import dev.zacsweers.metro.ContributesBinding -import dev.zacsweers.metro.Inject -import dev.zacsweers.metro.SingleIn -import dev.zacsweers.metro.binding - -@Inject -@SingleIn(AppScope::class) -@ContributesBinding(AppScope::class, binding>()) -internal class GetInsuranceContractsUseCaseProvider( - override val demoManager: DemoManager, - override val prodImpl: GetInsuranceContractsUseCaseImpl, - override val demoImpl: GetInsuranceContractsUseCaseDemo, -) : ProdOrDemoProvider diff --git a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/GetCrossSellsUseCaseProvider.kt b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetCrossSellsUseCase.kt similarity index 53% rename from app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/GetCrossSellsUseCaseProvider.kt rename to app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetCrossSellsUseCase.kt index d547c6ede9..8192233e95 100644 --- a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/GetCrossSellsUseCaseProvider.kt +++ b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetCrossSellsUseCase.kt @@ -2,21 +2,23 @@ package com.hedvig.android.feature.insurances.di import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.demomode.DemoManager -import com.hedvig.android.core.demomode.ProdOrDemoProvider -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.feature.insurances.data.GetCrossSellsUseCase import com.hedvig.android.feature.insurances.data.GetCrossSellsUseCaseDemo import com.hedvig.android.feature.insurances.data.GetCrossSellsUseCaseImpl import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn -import dev.zacsweers.metro.binding +import kotlinx.coroutines.flow.first @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class, binding>()) -internal class GetCrossSellsUseCaseProvider( - override val demoManager: DemoManager, - override val prodImpl: GetCrossSellsUseCaseImpl, - override val demoImpl: GetCrossSellsUseCaseDemo, -) : ProdOrDemoProvider +@ContributesBinding(AppScope::class) +internal class SwitchingGetCrossSellsUseCase( + private val demoManager: DemoManager, + private val prodImpl: GetCrossSellsUseCaseImpl, + private val demoImpl: GetCrossSellsUseCaseDemo, +) : GetCrossSellsUseCase { + override suspend fun invoke() = pick().invoke() + + private suspend fun pick(): GetCrossSellsUseCase = if (demoManager.isDemoMode().first()) demoImpl else prodImpl +} diff --git a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetInsuranceContractsUseCase.kt b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetInsuranceContractsUseCase.kt new file mode 100644 index 0000000000..0a5e796384 --- /dev/null +++ b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetInsuranceContractsUseCase.kt @@ -0,0 +1,29 @@ +package com.hedvig.android.feature.insurances.di + +import com.hedvig.android.core.common.di.AppScope +import com.hedvig.android.core.demomode.DemoManager +import com.hedvig.android.feature.insurances.data.GetInsuranceContractsUseCase +import com.hedvig.android.feature.insurances.data.GetInsuranceContractsUseCaseDemo +import com.hedvig.android.feature.insurances.data.GetInsuranceContractsUseCaseImpl +import dev.zacsweers.metro.ContributesBinding +import dev.zacsweers.metro.Inject +import dev.zacsweers.metro.SingleIn +import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flow + +@Inject +@SingleIn(AppScope::class) +@ContributesBinding(AppScope::class) +internal class SwitchingGetInsuranceContractsUseCase( + private val demoManager: DemoManager, + private val prodImpl: GetInsuranceContractsUseCaseImpl, + private val demoImpl: GetInsuranceContractsUseCaseDemo, +) : GetInsuranceContractsUseCase { + override fun invoke() = flow { + emitAll(pick().invoke()) + } + + private suspend fun pick(): GetInsuranceContractsUseCase = + if (demoManager.isDemoMode().first()) demoImpl else prodImpl +} diff --git a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsurancePresenter.kt b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsurancePresenter.kt index 8cdee22dab..121664970f 100644 --- a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsurancePresenter.kt +++ b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsurancePresenter.kt @@ -11,7 +11,6 @@ import androidx.compose.runtime.snapshots.Snapshot import arrow.core.Either import arrow.core.raise.either import com.hedvig.android.core.common.ErrorMessage -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.data.addons.data.AddonBannerInfo import com.hedvig.android.data.addons.data.AddonBannerSource import com.hedvig.android.data.addons.data.GetAddonBannerInfoUseCase @@ -61,9 +60,9 @@ internal data class InsuranceUiState( } internal class InsurancePresenter( - private val getInsuranceContractsUseCaseProvider: Provider, - private val getCrossSellsUseCaseProvider: Provider, - private val getAddonBannerInfoUseCase: Provider, + private val getInsuranceContractsUseCase: GetInsuranceContractsUseCase, + private val getCrossSellsUseCase: GetCrossSellsUseCase, + private val getAddonBannerInfoUseCase: GetAddonBannerInfoUseCase, ) : MoleculePresenter { @Composable override fun MoleculePresenterScope.present(lastState: InsuranceUiState): InsuranceUiState { @@ -90,9 +89,9 @@ internal class InsurancePresenter( isRetrying = isRetryingIteration } loadInsuranceData( - getInsuranceContractsUseCase = getInsuranceContractsUseCaseProvider.provide(), - getCrossSellsUseCase = getCrossSellsUseCaseProvider.provide(), - getAddonBannerInfoUseCase = getAddonBannerInfoUseCase.provide(), + getInsuranceContractsUseCase = getInsuranceContractsUseCase, + getCrossSellsUseCase = getCrossSellsUseCase, + getAddonBannerInfoUseCase = getAddonBannerInfoUseCase, ).collectLatest { result -> result.fold( ifLeft = { diff --git a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsuranceViewModel.kt b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsuranceViewModel.kt index bbb76ec7f2..095b1f8aec 100644 --- a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsuranceViewModel.kt +++ b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsuranceViewModel.kt @@ -2,7 +2,6 @@ package com.hedvig.android.feature.insurances.insurance.presentation import com.hedvig.android.core.common.di.ActivityRetainedScope import com.hedvig.android.core.common.di.HedvigViewModel -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.data.addons.data.GetAddonBannerInfoUseCase import com.hedvig.android.feature.insurances.data.GetCrossSellsUseCase import com.hedvig.android.feature.insurances.data.GetInsuranceContractsUseCase @@ -12,14 +11,14 @@ import dev.zacsweers.metro.Inject @Inject @HedvigViewModel(ActivityRetainedScope::class) internal class InsuranceViewModel( - getInsuranceContractsUseCaseProvider: Provider, - getCrossSellsUseCaseProvider: Provider, - getAddonBannerInfoUseCase: Provider, + getInsuranceContractsUseCase: GetInsuranceContractsUseCase, + getCrossSellsUseCase: GetCrossSellsUseCase, + getAddonBannerInfoUseCase: GetAddonBannerInfoUseCase, ) : MoleculeViewModel( initialState = InsuranceUiState.initialState, presenter = InsurancePresenter( - getInsuranceContractsUseCaseProvider = getInsuranceContractsUseCaseProvider, - getCrossSellsUseCaseProvider = getCrossSellsUseCaseProvider, + getInsuranceContractsUseCase = getInsuranceContractsUseCase, + getCrossSellsUseCase = getCrossSellsUseCase, getAddonBannerInfoUseCase = getAddonBannerInfoUseCase, ), ) diff --git a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurancedetail/GetContractForContractIdUseCase.kt b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurancedetail/GetContractForContractIdUseCase.kt index d6667b58d5..86909388b0 100644 --- a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurancedetail/GetContractForContractIdUseCase.kt +++ b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/insurancedetail/GetContractForContractIdUseCase.kt @@ -5,7 +5,6 @@ import arrow.core.raise.either import arrow.core.raise.ensureNotNull import com.hedvig.android.core.common.ErrorMessage import com.hedvig.android.core.common.di.AppScope -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.feature.insurances.data.GetInsuranceContractsUseCase import com.hedvig.android.feature.insurances.data.InsuranceContract import com.hedvig.android.feature.insurances.insurancedetail.GetContractForContractIdUseCaseImpl.GetContractForContractIdError @@ -26,12 +25,11 @@ internal interface GetContractForContractIdUseCase { @SingleIn(AppScope::class) @Inject internal class GetContractForContractIdUseCaseImpl( - private val getInsuranceContractsUseCaseProvider: Provider, + private val getInsuranceContractsUseCase: GetInsuranceContractsUseCase, ) : GetContractForContractIdUseCase { override fun invoke(contractId: String): Flow> { return flow { - getInsuranceContractsUseCaseProvider - .provide() + getInsuranceContractsUseCase .invoke() .map { insuranceContractResult -> either { diff --git a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/terminatedcontracts/TerminatedContractsViewModel.kt b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/terminatedcontracts/TerminatedContractsViewModel.kt index f1a0115b75..4f9bcca7bf 100644 --- a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/terminatedcontracts/TerminatedContractsViewModel.kt +++ b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/terminatedcontracts/TerminatedContractsViewModel.kt @@ -12,7 +12,6 @@ import arrow.core.raise.either import com.hedvig.android.core.common.ErrorMessage import com.hedvig.android.core.common.di.ActivityRetainedScope import com.hedvig.android.core.common.di.HedvigViewModel -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.feature.insurances.data.GetInsuranceContractsUseCase import com.hedvig.android.feature.insurances.data.InsuranceContract import com.hedvig.android.feature.insurances.data.InsuranceContract.EstablishedInsuranceContract @@ -28,14 +27,14 @@ import kotlinx.coroutines.flow.onEach @Inject @HedvigViewModel(ActivityRetainedScope::class) internal class TerminatedContractsViewModel( - getInsuranceContractsUseCaseProvider: Provider, + getInsuranceContractsUseCase: GetInsuranceContractsUseCase, ) : MoleculeViewModel( initialState = TerminatedContractsUiState.Loading, - presenter = TerminatedContractsPresenter(getInsuranceContractsUseCaseProvider), + presenter = TerminatedContractsPresenter(getInsuranceContractsUseCase), ) internal class TerminatedContractsPresenter( - private val getInsuranceContractsUseCaseProvider: Provider, + private val getInsuranceContractsUseCase: GetInsuranceContractsUseCase, ) : MoleculePresenter { @Composable override fun MoleculePresenterScope.present( @@ -54,8 +53,7 @@ internal class TerminatedContractsPresenter( if (currentState !is TerminatedContractsUiState.Success) { currentState = TerminatedContractsUiState.Loading } - getInsuranceContractsUseCaseProvider - .provide() + getInsuranceContractsUseCase .invoke() .onEach { result: Either> -> result.onLeft { errorMessage -> diff --git a/app/feature/feature-insurances/src/test/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsurancePresenterTest.kt b/app/feature/feature-insurances/src/test/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsurancePresenterTest.kt index de47dddaa9..1ab23b44eb 100644 --- a/app/feature/feature-insurances/src/test/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsurancePresenterTest.kt +++ b/app/feature/feature-insurances/src/test/kotlin/com/hedvig/android/feature/insurances/insurance/presentation/InsurancePresenterTest.kt @@ -270,9 +270,9 @@ internal class InsurancePresenterTest { val getCrossSellsUseCase = FakeGetCrossSellsUseCase() val getTravelAddonBannerInfoUseCase = FakeGetAddonBannerInfoUseCase() val presenter = InsurancePresenter( - { getInsuranceContractsUseCase }, - { getCrossSellsUseCase }, - { getTravelAddonBannerInfoUseCase }, + getInsuranceContractsUseCase, + getCrossSellsUseCase, + getTravelAddonBannerInfoUseCase, ) presenter.test(InsuranceUiState.initialState) { awaitItem().also { uiState -> @@ -304,9 +304,9 @@ internal class InsurancePresenterTest { val getCrossSellsUseCase = FakeGetCrossSellsUseCase() val getTravelAddonBannerInfoUseCase = FakeGetAddonBannerInfoUseCase() val presenter = InsurancePresenter( - { getInsuranceContractsUseCase }, - { getCrossSellsUseCase }, - { getTravelAddonBannerInfoUseCase }, + getInsuranceContractsUseCase, + getCrossSellsUseCase, + getTravelAddonBannerInfoUseCase, ) presenter.test(InsuranceUiState.initialState) { skipItems(1) @@ -329,9 +329,9 @@ internal class InsurancePresenterTest { val getCrossSellsUseCase = FakeGetCrossSellsUseCase() val getTravelAddonBannerInfoUseCase = FakeGetAddonBannerInfoUseCase() val presenter = InsurancePresenter( - { getInsuranceContractsUseCase }, - { getCrossSellsUseCase }, - { getTravelAddonBannerInfoUseCase }, + getInsuranceContractsUseCase, + getCrossSellsUseCase, + getTravelAddonBannerInfoUseCase, ) presenter.test(InsuranceUiState.initialState) { skipItems(1) @@ -354,9 +354,9 @@ internal class InsurancePresenterTest { val getCrossSellsUseCase = FakeGetCrossSellsUseCase() val getTravelAddonBannerInfoUseCase = FakeGetAddonBannerInfoUseCase() val presenter = InsurancePresenter( - { getInsuranceContractsUseCase }, - { getCrossSellsUseCase }, - { getTravelAddonBannerInfoUseCase }, + getInsuranceContractsUseCase, + getCrossSellsUseCase, + getTravelAddonBannerInfoUseCase, ) presenter.test(InsuranceUiState.initialState) { skipItems(1) @@ -398,9 +398,9 @@ internal class InsurancePresenterTest { val getCrossSellsUseCase = FakeGetCrossSellsUseCase() val getTravelAddonBannerInfoUseCase = FakeGetAddonBannerInfoUseCase() val presenter = InsurancePresenter( - { getInsuranceContractsUseCase }, - { getCrossSellsUseCase }, - { getTravelAddonBannerInfoUseCase }, + getInsuranceContractsUseCase, + getCrossSellsUseCase, + getTravelAddonBannerInfoUseCase, ) val allContracts = validContracts + terminatedContracts presenter.test(InsuranceUiState.initialState) { @@ -430,9 +430,9 @@ internal class InsurancePresenterTest { val getCrossSellsUseCase = FakeGetCrossSellsUseCase() val getTravelAddonBannerInfoUseCase = FakeGetAddonBannerInfoUseCase() val presenter = InsurancePresenter( - { getInsuranceContractsUseCase }, - { getCrossSellsUseCase }, - { getTravelAddonBannerInfoUseCase }, + getInsuranceContractsUseCase, + getCrossSellsUseCase, + getTravelAddonBannerInfoUseCase, ) val contracts = validContracts.map { it.copy(supportsAddressChange = supportsAddressChange) } presenter.test(InsuranceUiState.initialState) { @@ -451,9 +451,9 @@ internal class InsurancePresenterTest { val getCrossSellsUseCase = FakeGetCrossSellsUseCase() val getTravelAddonBannerInfoUseCase = FakeGetAddonBannerInfoUseCase() val presenter = InsurancePresenter( - { getInsuranceContractsUseCase }, - { getCrossSellsUseCase }, - { getTravelAddonBannerInfoUseCase }, + getInsuranceContractsUseCase, + getCrossSellsUseCase, + getTravelAddonBannerInfoUseCase, ) presenter.test(InsuranceUiState.initialState) { skipItems(1) @@ -470,9 +470,9 @@ internal class InsurancePresenterTest { val getCrossSellsUseCase = FakeGetCrossSellsUseCase() val getTravelAddonBannerInfoUseCase = FakeGetAddonBannerInfoUseCase() val presenter = InsurancePresenter( - { getInsuranceContractsUseCase }, - { getCrossSellsUseCase }, - { getTravelAddonBannerInfoUseCase }, + getInsuranceContractsUseCase, + getCrossSellsUseCase, + getTravelAddonBannerInfoUseCase, ) presenter.test(InsuranceUiState.initialState) { skipItems(1) @@ -489,9 +489,9 @@ internal class InsurancePresenterTest { val getCrossSellsUseCase = FakeGetCrossSellsUseCase() val getTravelAddonBannerInfoUseCase = FakeGetAddonBannerInfoUseCase() val presenter = InsurancePresenter( - { getInsuranceContractsUseCase }, - { getCrossSellsUseCase }, - { getTravelAddonBannerInfoUseCase }, + getInsuranceContractsUseCase, + getCrossSellsUseCase, + getTravelAddonBannerInfoUseCase, ) val initialState = InsuranceUiState( contracts = listOf(), diff --git a/app/feature/feature-insurances/src/test/kotlin/com/hedvig/android/feature/insurances/terminatedcontracts/TerminatedContractsPresenterTest.kt b/app/feature/feature-insurances/src/test/kotlin/com/hedvig/android/feature/insurances/terminatedcontracts/TerminatedContractsPresenterTest.kt index 5eb5643317..6a9c139e0c 100644 --- a/app/feature/feature-insurances/src/test/kotlin/com/hedvig/android/feature/insurances/terminatedcontracts/TerminatedContractsPresenterTest.kt +++ b/app/feature/feature-insurances/src/test/kotlin/com/hedvig/android/feature/insurances/terminatedcontracts/TerminatedContractsPresenterTest.kt @@ -34,7 +34,7 @@ class TerminatedContractsPresenterTest { @Test fun `if there are no terminated insurances we get no terminated insurances state`() = runTest { val getInsuranceContractsUseCase = FakeGetInsuranceContractsUseCase() - val presenter = TerminatedContractsPresenter { getInsuranceContractsUseCase } + val presenter = TerminatedContractsPresenter(getInsuranceContractsUseCase) presenter.test(TerminatedContractsUiState.Loading) { assertThat(awaitItem()).isEqualTo(TerminatedContractsUiState.Loading) getInsuranceContractsUseCase.addOnlyActiveInsurancesToResponse() @@ -48,7 +48,7 @@ class TerminatedContractsPresenterTest { fun `with an initial success state, if there is an error, we are able to retry and get back in success state again`() = runTest { val getInsuranceContractsUseCase = FakeGetInsuranceContractsUseCase() - val presenter = TerminatedContractsPresenter { getInsuranceContractsUseCase } + val presenter = TerminatedContractsPresenter(getInsuranceContractsUseCase) presenter.test(TerminatedContractsUiState.Success(getInsuranceContractsUseCase.getTerminatedInsurances())) { assertThat(awaitItem()).isInstanceOf() getInsuranceContractsUseCase.addErrorToResponse() @@ -63,7 +63,7 @@ class TerminatedContractsPresenterTest { @Test fun `with an initial error state, we are able to retry and if response is successful show success state`() = runTest { val getInsuranceContractsUseCase = FakeGetInsuranceContractsUseCase() - val presenter = TerminatedContractsPresenter { getInsuranceContractsUseCase } + val presenter = TerminatedContractsPresenter(getInsuranceContractsUseCase) presenter.test(TerminatedContractsUiState.Error) { assertThat(awaitItem()).isInstanceOf() sendEvent(TerminatedContractsEvent.Retry) @@ -76,7 +76,7 @@ class TerminatedContractsPresenterTest { @Test fun `with an initial error state, if there comes a successful response in flow, show success state`() = runTest { val getInsuranceContractsUseCase = FakeGetInsuranceContractsUseCase() - val presenter = TerminatedContractsPresenter { getInsuranceContractsUseCase } + val presenter = TerminatedContractsPresenter(getInsuranceContractsUseCase) presenter.test(TerminatedContractsUiState.Error) { assertThat(awaitItem()).isInstanceOf() assertThat(awaitItem()).isInstanceOf() @@ -88,7 +88,7 @@ class TerminatedContractsPresenterTest { @Test fun `with an initial success state, if there comes the same response, do not show loading`() = runTest { val getInsuranceContractsUseCase = FakeGetInsuranceContractsUseCase() - val presenter = TerminatedContractsPresenter { getInsuranceContractsUseCase } + val presenter = TerminatedContractsPresenter(getInsuranceContractsUseCase) val successState = TerminatedContractsUiState.Success(getInsuranceContractsUseCase.getTerminatedInsurances()) presenter.test(successState) { assertThat(awaitItem()).isInstanceOf() @@ -101,7 +101,7 @@ class TerminatedContractsPresenterTest { @Test fun `with an initial success state, if there comes a different successful response, do not show loading`() = runTest { val getInsuranceContractsUseCase = FakeGetInsuranceContractsUseCase() - val presenter = TerminatedContractsPresenter { getInsuranceContractsUseCase } + val presenter = TerminatedContractsPresenter(getInsuranceContractsUseCase) val successStateFirst = TerminatedContractsUiState.Success(getInsuranceContractsUseCase.getTerminatedInsurances()) val successStateSecond = TerminatedContractsUiState.Success( getInsuranceContractsUseCase.getAnotherSetOfTerminatedInsurances(), @@ -116,7 +116,7 @@ class TerminatedContractsPresenterTest { @Test fun `if there are terminated insurances they are all passed to success state`() = runTest { val getInsuranceContractsUseCase = FakeGetInsuranceContractsUseCase() - val presenter = TerminatedContractsPresenter { getInsuranceContractsUseCase } + val presenter = TerminatedContractsPresenter(getInsuranceContractsUseCase) presenter.test(TerminatedContractsUiState.Loading) { assertThat(awaitItem()).isEqualTo(TerminatedContractsUiState.Loading) getInsuranceContractsUseCase.addTerminatedInsurancesToResponse() @@ -131,7 +131,7 @@ class TerminatedContractsPresenterTest { @Test fun `if there are terminated and active insurances success state has no active insurances`() = runTest { val getInsuranceContractsUseCase = FakeGetInsuranceContractsUseCase() - val presenter = TerminatedContractsPresenter { getInsuranceContractsUseCase } + val presenter = TerminatedContractsPresenter(getInsuranceContractsUseCase) presenter.test(TerminatedContractsUiState.Loading) { assertThat(awaitItem()).isEqualTo(TerminatedContractsUiState.Loading) getInsuranceContractsUseCase.addTerminatedAndActiveInsurancesToResponse() @@ -146,7 +146,7 @@ class TerminatedContractsPresenterTest { @Test fun `if receive error show error uiState`() = runTest { val getInsuranceContractsUseCase = FakeGetInsuranceContractsUseCase() - val presenter = TerminatedContractsPresenter { getInsuranceContractsUseCase } + val presenter = TerminatedContractsPresenter(getInsuranceContractsUseCase) presenter.test(TerminatedContractsUiState.Loading) { assertThat(awaitItem()).isEqualTo(TerminatedContractsUiState.Loading) getInsuranceContractsUseCase.addErrorToResponse() diff --git a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/GetShouldShowPayoutUseCaseProvider.kt b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/GetShouldShowPayoutUseCaseProvider.kt deleted file mode 100644 index f953808cf0..0000000000 --- a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/GetShouldShowPayoutUseCaseProvider.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.hedvig.android.feature.payments.overview.data - -import com.hedvig.android.core.common.di.AppScope -import com.hedvig.android.core.demomode.DemoManager -import com.hedvig.android.core.demomode.ProdOrDemoProvider -import com.hedvig.android.core.demomode.Provider -import dev.zacsweers.metro.ContributesBinding -import dev.zacsweers.metro.Inject -import dev.zacsweers.metro.SingleIn -import dev.zacsweers.metro.binding - -@Inject -@SingleIn(AppScope::class) -@ContributesBinding(AppScope::class, binding>()) -internal class GetShouldShowPayoutUseCaseProvider( - override val demoManager: DemoManager, - override val prodImpl: GetShouldShowPayoutUseCaseImpl, - override val demoImpl: GetShouldShowPayoutUseCaseDemo, -) : ProdOrDemoProvider diff --git a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/GetUpcomingPaymentUseCase.kt b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/GetUpcomingPaymentUseCase.kt index 609cf35087..a980677b6a 100644 --- a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/GetUpcomingPaymentUseCase.kt +++ b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/GetUpcomingPaymentUseCase.kt @@ -9,7 +9,6 @@ import com.apollographql.apollo.cache.normalized.fetchPolicy import com.hedvig.android.apollo.ErrorMessage import com.hedvig.android.apollo.safeExecute import com.hedvig.android.core.common.ErrorMessage -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.core.uidata.UiCurrencyCode import com.hedvig.android.core.uidata.UiMoney import com.hedvig.android.data.paying.member.GetMemberTypeUseCase @@ -41,14 +40,14 @@ internal interface GetUpcomingPaymentUseCase { internal data class GetUpcomingPaymentUseCaseImpl( val apolloClient: ApolloClient, val clock: Clock, - val getMemberTypeUseCaseProvider: Provider, + val getMemberTypeUseCase: GetMemberTypeUseCase, ) : GetUpcomingPaymentUseCase { override suspend fun invoke(): Either = either { val result = apolloClient.query(UpcomingPaymentQuery()) .fetchPolicy(FetchPolicy.NetworkFirst) .safeExecute(::ErrorMessage) .bind() - val memberType = getMemberTypeUseCaseProvider.provide().invoke().bind() + val memberType = getMemberTypeUseCase.invoke().bind() val missedChargeIdToChargeManually: String? = result.currentMember.missedChargeIdToChargeManually diff --git a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/GetUpcomingPaymentUseCaseProvider.kt b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/GetUpcomingPaymentUseCaseProvider.kt deleted file mode 100644 index 1c44167c5e..0000000000 --- a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/GetUpcomingPaymentUseCaseProvider.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.hedvig.android.feature.payments.overview.data - -import com.hedvig.android.core.common.di.AppScope -import com.hedvig.android.core.demomode.DemoManager -import com.hedvig.android.core.demomode.ProdOrDemoProvider -import com.hedvig.android.core.demomode.Provider -import dev.zacsweers.metro.ContributesBinding -import dev.zacsweers.metro.Inject -import dev.zacsweers.metro.SingleIn -import dev.zacsweers.metro.binding - -@Inject -@SingleIn(AppScope::class) -@ContributesBinding(AppScope::class, binding>()) -internal class GetUpcomingPaymentUseCaseProvider( - override val demoManager: DemoManager, - override val prodImpl: GetUpcomingPaymentUseCaseImpl, - override val demoImpl: GetUpcomingPaymentUseCaseDemo, -) : ProdOrDemoProvider diff --git a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetShouldShowPayoutUseCase.kt b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetShouldShowPayoutUseCase.kt new file mode 100644 index 0000000000..e77ee1db15 --- /dev/null +++ b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetShouldShowPayoutUseCase.kt @@ -0,0 +1,21 @@ +package com.hedvig.android.feature.payments.overview.data + +import com.hedvig.android.core.common.di.AppScope +import com.hedvig.android.core.demomode.DemoManager +import dev.zacsweers.metro.ContributesBinding +import dev.zacsweers.metro.Inject +import dev.zacsweers.metro.SingleIn +import kotlinx.coroutines.flow.first + +@Inject +@SingleIn(AppScope::class) +@ContributesBinding(AppScope::class) +internal class SwitchingGetShouldShowPayoutUseCase( + private val demoManager: DemoManager, + private val prodImpl: GetShouldShowPayoutUseCaseImpl, + private val demoImpl: GetShouldShowPayoutUseCaseDemo, +) : GetShouldShowPayoutUseCase { + override suspend fun invoke() = pick().invoke() + + private suspend fun pick(): GetShouldShowPayoutUseCase = if (demoManager.isDemoMode().first()) demoImpl else prodImpl +} diff --git a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetUpcomingPaymentUseCase.kt b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetUpcomingPaymentUseCase.kt new file mode 100644 index 0000000000..a0bddefd38 --- /dev/null +++ b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetUpcomingPaymentUseCase.kt @@ -0,0 +1,21 @@ +package com.hedvig.android.feature.payments.overview.data + +import com.hedvig.android.core.common.di.AppScope +import com.hedvig.android.core.demomode.DemoManager +import dev.zacsweers.metro.ContributesBinding +import dev.zacsweers.metro.Inject +import dev.zacsweers.metro.SingleIn +import kotlinx.coroutines.flow.first + +@Inject +@SingleIn(AppScope::class) +@ContributesBinding(AppScope::class) +internal class SwitchingGetUpcomingPaymentUseCase( + private val demoManager: DemoManager, + private val prodImpl: GetUpcomingPaymentUseCaseImpl, + private val demoImpl: GetUpcomingPaymentUseCaseDemo, +) : GetUpcomingPaymentUseCase { + override suspend fun invoke() = pick().invoke() + + private suspend fun pick(): GetUpcomingPaymentUseCase = if (demoManager.isDemoMode().first()) demoImpl else prodImpl +} diff --git a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/ui/payments/PaymentsPresenter.kt b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/ui/payments/PaymentsPresenter.kt index 7b7e00797a..ff386900df 100644 --- a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/ui/payments/PaymentsPresenter.kt +++ b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/ui/payments/PaymentsPresenter.kt @@ -9,7 +9,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import arrow.core.Either import com.hedvig.android.core.common.ErrorMessage -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.core.uidata.UiMoney import com.hedvig.android.data.paying.member.MemberType import com.hedvig.android.feature.payments.data.ManualChargeToPrompt @@ -31,8 +30,8 @@ import kotlinx.coroutines.delay import kotlinx.datetime.LocalDate internal class PaymentsPresenter( - private val getUpcomingPaymentUseCase: Provider, - getShouldShowPayoutUseCase: Provider, + private val getUpcomingPaymentUseCase: GetUpcomingPaymentUseCase, + getShouldShowPayoutUseCase: GetShouldShowPayoutUseCase, ) : MoleculePresenter { private val shouldShowPayoutPresenter = ShouldShowPayoutPresenter(getShouldShowPayoutUseCase) @@ -49,7 +48,7 @@ internal class PaymentsPresenter( LaunchedEffect(loadIteration) { paymentOverviewResult = null - paymentOverviewResult = getUpcomingPaymentUseCase.provide().invoke() + paymentOverviewResult = getUpcomingPaymentUseCase.invoke() } val shouldShowPayout = shouldShowPayoutPresenter.present(loadIteration) @@ -93,7 +92,7 @@ internal class PaymentsPresenter( } private class ShouldShowPayoutPresenter( - private val getShouldShowPayoutUseCase: Provider, + private val getShouldShowPayoutUseCase: GetShouldShowPayoutUseCase, ) { @Composable fun present(loadIteration: Int): Boolean { @@ -102,7 +101,7 @@ private class ShouldShowPayoutPresenter( shouldShowPayout = false for (attempt in 0..2) { delay(attempt.seconds) - getShouldShowPayoutUseCase.provide().invoke().fold( + getShouldShowPayoutUseCase.invoke().fold( ifLeft = {}, ifRight = { result -> shouldShowPayout = result diff --git a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/ui/payments/PaymentsViewModel.kt b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/ui/payments/PaymentsViewModel.kt index 0bbcf8820e..21dc4d8064 100644 --- a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/ui/payments/PaymentsViewModel.kt +++ b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/ui/payments/PaymentsViewModel.kt @@ -2,7 +2,6 @@ package com.hedvig.android.feature.payments.ui.payments import com.hedvig.android.core.common.di.ActivityRetainedScope import com.hedvig.android.core.common.di.HedvigViewModel -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.feature.payments.overview.data.GetShouldShowPayoutUseCase import com.hedvig.android.feature.payments.overview.data.GetUpcomingPaymentUseCase import com.hedvig.android.molecule.public.MoleculeViewModel @@ -11,8 +10,8 @@ import dev.zacsweers.metro.Inject @Inject @HedvigViewModel(ActivityRetainedScope::class) internal class PaymentsViewModel( - getUpcomingPaymentUseCase: Provider, - getShouldShowPayoutUseCase: Provider, + getUpcomingPaymentUseCase: GetUpcomingPaymentUseCase, + getShouldShowPayoutUseCase: GetShouldShowPayoutUseCase, ) : MoleculeViewModel( PaymentsUiState.Loading, PaymentsPresenter( diff --git a/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/contactinfo/ContactInfoViewModel.kt b/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/contactinfo/ContactInfoViewModel.kt index ac7e0c2ecd..e70b820377 100644 --- a/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/contactinfo/ContactInfoViewModel.kt +++ b/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/contactinfo/ContactInfoViewModel.kt @@ -18,7 +18,6 @@ import arrow.core.getOrElse import com.hedvig.android.core.common.ErrorMessage import com.hedvig.android.core.common.di.ActivityRetainedScope import com.hedvig.android.core.common.di.HedvigViewModel -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.feature.profile.contactinfo.ContactInfoEvent.RetryLoadData import com.hedvig.android.feature.profile.contactinfo.ContactInfoEvent.SubmitData import com.hedvig.android.feature.profile.contactinfo.ContactInfoUiState.Content @@ -106,14 +105,14 @@ internal sealed interface ContactInfoUiState { @Inject @HedvigViewModel(ActivityRetainedScope::class) internal class ContactInfoViewModel( - repository: Provider, + repository: ContactInfoRepository, ) : MoleculeViewModel( Loading, ContactInfoPresenter(repository), ) internal class ContactInfoPresenter( - private val repository: Provider, + private val repository: ContactInfoRepository, ) : MoleculePresenter { @Composable override fun MoleculePresenterScope.present(lastState: ContactInfoUiState): ContactInfoUiState { @@ -158,7 +157,7 @@ internal class ContactInfoPresenter( } errorSnackBarText = null dataFetchingState = Fetching - repository.provide().contactInfo().fold( + repository.contactInfo().fold( ifLeft = { dataFetchingState = Error }, @@ -180,7 +179,6 @@ internal class ContactInfoPresenter( } errorSnackBarText = null repository - .provide() .updateInfo( phoneNumber = submittingPhoneNumber, email = submittingEmail, diff --git a/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/di/ProfileRepositoryProvider.kt b/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/di/ProfileRepositoryProvider.kt deleted file mode 100644 index c71a89cef3..0000000000 --- a/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/di/ProfileRepositoryProvider.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.hedvig.android.feature.profile.di - -import com.hedvig.android.core.common.di.AppScope -import com.hedvig.android.core.demomode.DemoManager -import com.hedvig.android.core.demomode.ProdOrDemoProvider -import com.hedvig.android.core.demomode.Provider -import com.hedvig.android.feature.profile.data.ContactInfoRepository -import com.hedvig.android.feature.profile.data.ContactInfoRepositoryDemo -import com.hedvig.android.feature.profile.data.ContactInfoRepositoryImpl -import dev.zacsweers.metro.ContributesBinding -import dev.zacsweers.metro.Inject -import dev.zacsweers.metro.SingleIn -import dev.zacsweers.metro.binding - -@Inject -@SingleIn(AppScope::class) -@ContributesBinding(AppScope::class, binding>()) -internal class ProfileRepositoryProvider( - override val demoManager: DemoManager, - override val prodImpl: ContactInfoRepositoryImpl, - override val demoImpl: ContactInfoRepositoryDemo, -) : ProdOrDemoProvider diff --git a/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/di/SwitchingContactInfoRepository.kt b/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/di/SwitchingContactInfoRepository.kt new file mode 100644 index 0000000000..c572356451 --- /dev/null +++ b/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/di/SwitchingContactInfoRepository.kt @@ -0,0 +1,28 @@ +package com.hedvig.android.feature.profile.di + +import com.hedvig.android.core.common.di.AppScope +import com.hedvig.android.core.demomode.DemoManager +import com.hedvig.android.feature.profile.data.ContactInfoRepository +import com.hedvig.android.feature.profile.data.ContactInfoRepositoryDemo +import com.hedvig.android.feature.profile.data.ContactInfoRepositoryImpl +import com.hedvig.android.feature.profile.data.ContactInformation.Email +import com.hedvig.android.feature.profile.data.ContactInformation.PhoneNumber +import dev.zacsweers.metro.ContributesBinding +import dev.zacsweers.metro.Inject +import dev.zacsweers.metro.SingleIn +import kotlinx.coroutines.flow.first + +@Inject +@SingleIn(AppScope::class) +@ContributesBinding(AppScope::class) +internal class SwitchingContactInfoRepository( + private val demoManager: DemoManager, + private val prodImpl: ContactInfoRepositoryImpl, + private val demoImpl: ContactInfoRepositoryDemo, +) : ContactInfoRepository { + override suspend fun contactInfo() = pick().contactInfo() + + override suspend fun updateInfo(phoneNumber: PhoneNumber, email: Email) = pick().updateInfo(phoneNumber, email) + + private suspend fun pick(): ContactInfoRepository = if (demoManager.isDemoMode().first()) demoImpl else prodImpl +} diff --git a/app/feature/feature-profile/src/test/kotlin/com/hedvig/android/feature/profile/contactinfo/ContactInfoPresenterTest.kt b/app/feature/feature-profile/src/test/kotlin/com/hedvig/android/feature/profile/contactinfo/ContactInfoPresenterTest.kt index 1bc79c0b9f..bb3e3be12a 100644 --- a/app/feature/feature-profile/src/test/kotlin/com/hedvig/android/feature/profile/contactinfo/ContactInfoPresenterTest.kt +++ b/app/feature/feature-profile/src/test/kotlin/com/hedvig/android/feature/profile/contactinfo/ContactInfoPresenterTest.kt @@ -17,7 +17,6 @@ import com.hedvig.android.apollo.test.TestApolloClientRule import com.hedvig.android.apollo.test.TestNetworkTransportType import com.hedvig.android.apollo.test.registerSuspendingTestNetworkError import com.hedvig.android.apollo.test.registerSuspendingTestResponse -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.feature.NoopNetworkCacheManager import com.hedvig.android.feature.profile.data.ContactInfoRepositoryImpl import com.hedvig.android.feature.profile.data.ContactInformation.Email @@ -47,7 +46,7 @@ class ContactInfoPresenterTest { @Test fun `Changing the info to a new valid input should be reflected in the state after it`() = runTest { val repository = ContactInfoRepositoryImpl(apolloClient, NoopNetworkCacheManager) - val presenter = ContactInfoPresenter(Provider { repository }) + val presenter = ContactInfoPresenter(repository) val originalEmail = "test@hedvig.com" val originalPhoneNumber = "+123" val alteredEmail = "test2@hedvig.com" @@ -121,7 +120,7 @@ class ContactInfoPresenterTest { @Test fun `Allowing submission should depend on if the input is valid`() = runTest { val repository = ContactInfoRepositoryImpl(apolloClient, NoopNetworkCacheManager) - val presenter = ContactInfoPresenter(Provider { repository }) + val presenter = ContactInfoPresenter(repository) val originalEmail = "test@hedvig.com" val originalPhoneNumber = "+123" val validEmails = listOf( @@ -189,7 +188,7 @@ class ContactInfoPresenterTest { @Test fun `Retrying does fetch the new state after an initial failure`() = runTest { val repository = ContactInfoRepositoryImpl(apolloClient, NoopNetworkCacheManager) - val presenter = ContactInfoPresenter(Provider { repository }) + val presenter = ContactInfoPresenter(repository) presenter.test(ContactInfoUiState.Error) { assertThat(awaitItem()).isEqualTo(ContactInfoUiState.Error) // By default, coming back to a failed screen should automatically trigger a refresh and go into a loading state @@ -216,7 +215,7 @@ class ContactInfoPresenterTest { @TestParameter testingNullPhoneNumber: Boolean, ) = runTest { val repository = ContactInfoRepositoryImpl(apolloClient, NoopNetworkCacheManager) - val presenter = ContactInfoPresenter(Provider { repository }) + val presenter = ContactInfoPresenter(repository) val backendEmail = "" val backendPhoneNumber = "".takeIf { !testingNullPhoneNumber } apolloClient.registerSuspendingTestResponse( @@ -244,7 +243,7 @@ class ContactInfoPresenterTest { @Test fun `Can not submit new contact info if that would mean deleting some previously present info`() = runTest { val repository = ContactInfoRepositoryImpl(apolloClient, NoopNetworkCacheManager) - val presenter = ContactInfoPresenter(Provider { repository }) + val presenter = ContactInfoPresenter(repository) val backendEmail = "test@hedvig.com" val backendPhoneNumber = "+123" apolloClient.registerSuspendingTestResponse( diff --git a/app/feature/feature-travel-certificate/src/main/kotlin/com/hedvig/android/feature/travelcertificate/ui/history/CertificateHistoryViewModel.kt b/app/feature/feature-travel-certificate/src/main/kotlin/com/hedvig/android/feature/travelcertificate/ui/history/CertificateHistoryViewModel.kt index 36fc77f785..15444f91a4 100644 --- a/app/feature/feature-travel-certificate/src/main/kotlin/com/hedvig/android/feature/travelcertificate/ui/history/CertificateHistoryViewModel.kt +++ b/app/feature/feature-travel-certificate/src/main/kotlin/com/hedvig/android/feature/travelcertificate/ui/history/CertificateHistoryViewModel.kt @@ -9,7 +9,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import com.hedvig.android.core.common.di.ActivityRetainedScope import com.hedvig.android.core.common.di.HedvigViewModel -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.core.fileupload.DownloadPdfUseCase import com.hedvig.android.core.fileupload.DownloadedFile import com.hedvig.android.data.addons.data.AddonBannerInfo @@ -37,7 +36,7 @@ internal class CertificateHistoryViewModel( checkTravelCertificateAvailabilityForCurrentContractsUseCase: CheckTravelCertificateAvailabilityForCurrentContractsUseCase, getEligibleContractsWithAddressUseCase: GetEligibleContractsWithAddressUseCase, - getAddonBannerInfoUseCaseProvider: Provider, + getAddonBannerInfoUseCase: GetAddonBannerInfoUseCase, ) : MoleculeViewModel( initialState = CertificateHistoryUiState.Loading, presenter = CertificateHistoryPresenter( @@ -45,7 +44,7 @@ internal class CertificateHistoryViewModel( downloadPdfUseCase, getEligibleContractsWithAddressUseCase, checkTravelCertificateAvailabilityForCurrentContractsUseCase, - getAddonBannerInfoUseCaseProvider, + getAddonBannerInfoUseCase, ), ) @@ -55,7 +54,7 @@ internal class CertificateHistoryPresenter( private val getEligibleContractsWithAddressUseCase: GetEligibleContractsWithAddressUseCase, private val checkTravelCertificateAvailabilityForCurrentContractsUseCase: CheckTravelCertificateAvailabilityForCurrentContractsUseCase, - private val getAddonBannerInfoUseCaseProvider: Provider, + private val getAddonBannerInfoUseCase: GetAddonBannerInfoUseCase, ) : MoleculePresenter { @Composable @@ -144,7 +143,7 @@ internal class CertificateHistoryPresenter( flow { emit(getTravelCertificatesHistoryUseCase.invoke()) }, flow { emit(checkTravelCertificateAvailabilityForCurrentContractsUseCase.invoke()) }, flow { emit(getEligibleContractsWithAddressUseCase.invoke()) }, - getAddonBannerInfoUseCaseProvider.provide().invoke(AddonBannerSource.TRAVEL_CERTIFICATES), + getAddonBannerInfoUseCase.invoke(AddonBannerSource.TRAVEL_CERTIFICATES), ) { travelCertificateHistoryResult, eligibilityResult, eligibleContractsResult, travelAddonBannerResult -> val history = travelCertificateHistoryResult.getOrNull() val eligibility = eligibilityResult.getOrNull() diff --git a/app/member-reminders/member-reminders-public/src/main/kotlin/com/hedvig/android/memberreminders/GetConnectPaymentReminderUseCase.kt b/app/member-reminders/member-reminders-public/src/main/kotlin/com/hedvig/android/memberreminders/GetConnectPaymentReminderUseCase.kt index 2aebad6462..2bfd778bd3 100644 --- a/app/member-reminders/member-reminders-public/src/main/kotlin/com/hedvig/android/memberreminders/GetConnectPaymentReminderUseCase.kt +++ b/app/member-reminders/member-reminders-public/src/main/kotlin/com/hedvig/android/memberreminders/GetConnectPaymentReminderUseCase.kt @@ -10,7 +10,6 @@ import com.hedvig.android.apollo.ErrorMessage import com.hedvig.android.apollo.safeExecute import com.hedvig.android.core.common.ErrorMessage import com.hedvig.android.core.common.di.AppScope -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.logger.logcat import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject diff --git a/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/crosssell/home/CrossSellHomeNotificationServiceImpl.kt b/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/crosssell/home/CrossSellHomeNotificationServiceImpl.kt index 3af8fa66eb..18bbe2e4f7 100644 --- a/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/crosssell/home/CrossSellHomeNotificationServiceImpl.kt +++ b/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/crosssell/home/CrossSellHomeNotificationServiceImpl.kt @@ -6,27 +6,43 @@ import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.longPreferencesKey import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.demomode.DemoManager -import com.hedvig.android.core.demomode.ProdOrDemoProvider -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.notification.badge.data.crosssell.CrossSellNotificationBadgeService import com.hedvig.android.notification.badge.data.storage.NotificationBadge import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn -import dev.zacsweers.metro.binding import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class, binding>()) -internal class CrossSellHomeNotificationServiceProvider( - override val demoManager: DemoManager, - override val prodImpl: CrossSellHomeNotificationServiceImpl, - override val demoImpl: DemoCrossSellHomeNotificationService, -) : ProdOrDemoProvider +@ContributesBinding(AppScope::class) +internal class SwitchingCrossSellHomeNotificationService( + private val demoManager: DemoManager, + private val prodImpl: CrossSellHomeNotificationServiceImpl, + private val demoImpl: DemoCrossSellHomeNotificationService, +) : CrossSellHomeNotificationService { + override fun showRedDotNotification() = flow { + emitAll(pick().showRedDotNotification()) + } + + override fun getLastEpochDayNewRecommendationNotificationWasShown() = flow { + emitAll(pick().getLastEpochDayNewRecommendationNotificationWasShown()) + } + + override suspend fun markAsSeen() = pick().markAsSeen() + + override suspend fun setLastEpochDayNewRecommendationNotificationWasShown(epochDay: Long) = + pick().setLastEpochDayNewRecommendationNotificationWasShown(epochDay) + + private suspend fun pick(): CrossSellHomeNotificationService = + if (demoManager.isDemoMode().first()) demoImpl else prodImpl +} @Inject internal class DemoCrossSellHomeNotificationService() : CrossSellHomeNotificationService { diff --git a/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/payment/MissedPaymentNotificationService.kt b/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/payment/MissedPaymentNotificationService.kt index 2618c28e3a..74ec59cdd8 100644 --- a/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/payment/MissedPaymentNotificationService.kt +++ b/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/payment/MissedPaymentNotificationService.kt @@ -2,23 +2,30 @@ package com.hedvig.android.notification.badge.data.payment import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.demomode.DemoManager -import com.hedvig.android.core.demomode.ProdOrDemoProvider -import com.hedvig.android.core.demomode.Provider import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn -import dev.zacsweers.metro.binding import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class, binding>()) -internal class MissedPaymentNotificationServiceProvider( - override val demoManager: DemoManager, - override val demoImpl: DemoMissedPaymentNotificationService, - override val prodImpl: MissedPaymentNotificationServiceImpl, -) : ProdOrDemoProvider +@ContributesBinding(AppScope::class) +internal class SwitchingMissedPaymentNotificationService( + private val demoManager: DemoManager, + private val demoImpl: DemoMissedPaymentNotificationService, + private val prodImpl: MissedPaymentNotificationServiceImpl, +) : MissedPaymentNotificationService { + override fun showRedDotNotification() = flow { + emitAll(pick().showRedDotNotification()) + } + + private suspend fun pick(): MissedPaymentNotificationService = + if (demoManager.isDemoMode().first()) demoImpl else prodImpl +} interface MissedPaymentNotificationService { fun showRedDotNotification(): Flow diff --git a/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/data/ForeverRepositoryProvider.kt b/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/data/ForeverRepositoryProvider.kt deleted file mode 100644 index e6a9ae448e..0000000000 --- a/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/data/ForeverRepositoryProvider.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.hedvig.android.shared.foreverui.ui.data - -import com.hedvig.android.core.common.di.AppScope -import com.hedvig.android.core.demomode.DemoManager -import com.hedvig.android.core.demomode.ProdOrDemoProvider -import com.hedvig.android.core.demomode.Provider -import dev.zacsweers.metro.ContributesBinding -import dev.zacsweers.metro.Inject -import dev.zacsweers.metro.SingleIn -import dev.zacsweers.metro.binding - -@Inject -@SingleIn(AppScope::class) -@ContributesBinding(AppScope::class, binding>()) -internal class ForeverRepositoryProvider( - override val demoManager: DemoManager, - override val prodImpl: ForeverRepositoryImpl, - override val demoImpl: ForeverRepositoryDemo, -) : ProdOrDemoProvider diff --git a/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/data/SwitchingForeverRepository.kt b/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/data/SwitchingForeverRepository.kt new file mode 100644 index 0000000000..f269e61495 --- /dev/null +++ b/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/data/SwitchingForeverRepository.kt @@ -0,0 +1,23 @@ +package com.hedvig.android.shared.foreverui.ui.data + +import com.hedvig.android.core.common.di.AppScope +import com.hedvig.android.core.demomode.DemoManager +import dev.zacsweers.metro.ContributesBinding +import dev.zacsweers.metro.Inject +import dev.zacsweers.metro.SingleIn +import kotlinx.coroutines.flow.first + +@Inject +@SingleIn(AppScope::class) +@ContributesBinding(AppScope::class) +internal class SwitchingForeverRepository( + private val demoManager: DemoManager, + private val prodImpl: ForeverRepositoryImpl, + private val demoImpl: ForeverRepositoryDemo, +) : ForeverRepository { + override suspend fun getReferralsData() = pick().getReferralsData() + + override suspend fun updateCode(newCode: String) = pick().updateCode(newCode) + + private suspend fun pick(): ForeverRepository = if (demoManager.isDemoMode().first()) demoImpl else prodImpl +} diff --git a/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/ui/ForeverViewModel.kt b/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/ui/ForeverViewModel.kt index f792fdb23a..47c8813e24 100644 --- a/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/ui/ForeverViewModel.kt +++ b/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/ui/ForeverViewModel.kt @@ -12,7 +12,6 @@ import arrow.core.raise.either import com.hedvig.android.core.buildconstants.HedvigBuildConstants import com.hedvig.android.core.common.di.ActivityRetainedScope import com.hedvig.android.core.common.di.HedvigViewModel -import com.hedvig.android.core.demomode.Provider import com.hedvig.android.language.LanguageService import com.hedvig.android.logger.LogPriority import com.hedvig.android.logger.logcat @@ -29,13 +28,13 @@ import dev.zacsweers.metro.Inject @Inject @HedvigViewModel(ActivityRetainedScope::class) class ForeverViewModel( - foreverRepositoryProvider: Provider, + foreverRepository: ForeverRepository, private val languageService: LanguageService, private val hedvigBuildConstants: HedvigBuildConstants, ) : MoleculeViewModel( ForeverUiState.Loading, ForeverPresenter( - foreverRepositoryProvider = foreverRepositoryProvider, + foreverRepository = foreverRepository, ), ) { fun referralShareUrl(code: String): String = buildString { @@ -48,7 +47,7 @@ class ForeverViewModel( } internal class ForeverPresenter( - private val foreverRepositoryProvider: Provider, + private val foreverRepository: ForeverRepository, ) : MoleculePresenter { @Composable override fun MoleculePresenterScope.present(lastState: ForeverUiState): ForeverUiState { @@ -86,7 +85,7 @@ internal class ForeverPresenter( state.copy(reloading = true) } either { - val referralsData = foreverRepositoryProvider.provide().getReferralsData().bind() + val referralsData = foreverRepository.getReferralsData().bind() ForeverData(referralsData = referralsData) }.fold( ifLeft = { @@ -109,7 +108,7 @@ internal class ForeverPresenter( val codeToSubmit = referralCodeToSubmit ?: return@LaunchedEffect val state = currentState as? ForeverUiState.Success ?: return@LaunchedEffect currentState = state.copy(referralCodeLoading = true) - foreverRepositoryProvider.provide().updateCode(codeToSubmit).fold( + foreverRepository.updateCode(codeToSubmit).fold( ifLeft = { referralCodeToSubmit = null currentState = state.copy( From a5ced24e59d05d42d439c750dba867f91b5ccd55 Mon Sep 17 00:00:00 2001 From: stylianosgakis Date: Mon, 22 Jun 2026 17:38:11 +0200 Subject: [PATCH 2/5] Hide the `pick` code behind an abstract class --- .../hedvig/android/core/demomode/DemoSwitcher.kt | 15 +++++++++++++++ .../data/SwitchingGetAddonBannerInfoUseCase.kt | 15 +++++++-------- .../data/paying/member/GetMemberTypeUseCase.kt | 15 +++++++-------- .../chat/data/SwitchingCbmChatRepository.kt | 15 +++++++-------- .../cross/sell/sheet/CrossSellSheetViewModel.kt | 16 +++++++--------- .../home/di/SwitchingGetHomeDataUseCase.kt | 15 +++++++-------- .../di/SwitchingGetCrossSellsUseCase.kt | 15 +++++++-------- .../di/SwitchingGetInsuranceContractsUseCase.kt | 16 +++++++--------- .../data/SwitchingGetShouldShowPayoutUseCase.kt | 15 +++++++-------- .../data/SwitchingGetUpcomingPaymentUseCase.kt | 15 +++++++-------- .../profile/di/SwitchingContactInfoRepository.kt | 15 +++++++-------- .../home/CrossSellHomeNotificationServiceImpl.kt | 16 +++++++--------- .../payment/MissedPaymentNotificationService.kt | 16 +++++++--------- .../ui/data/SwitchingForeverRepository.kt | 15 +++++++-------- 14 files changed, 106 insertions(+), 108 deletions(-) create mode 100644 app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/DemoSwitcher.kt diff --git a/app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/DemoSwitcher.kt b/app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/DemoSwitcher.kt new file mode 100644 index 0000000000..c9217e31d9 --- /dev/null +++ b/app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/DemoSwitcher.kt @@ -0,0 +1,15 @@ +package com.hedvig.android.core.demomode + +import kotlinx.coroutines.flow.first + +/** + * Shared selection logic for a type that has a prod and a demo implementation. Implementors also implement [T] itself + * and forward each member through [pick], so consumers inject the plain [T] and never know demo mode exists. + */ +interface DemoSwitcher { + val demoManager: DemoManager + val demoImpl: T + val prodImpl: T + + suspend fun pick(): T = if (demoManager.isDemoMode().first()) demoImpl else prodImpl +} diff --git a/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/SwitchingGetAddonBannerInfoUseCase.kt b/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/SwitchingGetAddonBannerInfoUseCase.kt index cd7b89747c..fe39a8c713 100644 --- a/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/SwitchingGetAddonBannerInfoUseCase.kt +++ b/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/SwitchingGetAddonBannerInfoUseCase.kt @@ -2,24 +2,23 @@ package com.hedvig.android.data.addons.data import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.demomode.DemoManager +import com.hedvig.android.core.demomode.DemoSwitcher import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn +import dev.zacsweers.metro.binding import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flow @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class) +@ContributesBinding(AppScope::class, binding = binding()) internal class SwitchingGetAddonBannerInfoUseCase( - private val demoManager: DemoManager, - private val demoImpl: DemoGetAddonBannerInfoUseCase, - private val prodImpl: GetAddonBannerInfoUseCaseImpl, -) : GetAddonBannerInfoUseCase { + override val demoManager: DemoManager, + override val demoImpl: DemoGetAddonBannerInfoUseCase, + override val prodImpl: GetAddonBannerInfoUseCaseImpl, +) : GetAddonBannerInfoUseCase, DemoSwitcher { override fun invoke(source: AddonBannerSource) = flow { emitAll(pick().invoke(source)) } - - private suspend fun pick(): GetAddonBannerInfoUseCase = if (demoManager.isDemoMode().first()) demoImpl else prodImpl } diff --git a/app/data/data-paying-member/src/main/kotlin/com/hedvig/android/data/paying/member/GetMemberTypeUseCase.kt b/app/data/data-paying-member/src/main/kotlin/com/hedvig/android/data/paying/member/GetMemberTypeUseCase.kt index d3a2d16dc3..17e2c4089e 100644 --- a/app/data/data-paying-member/src/main/kotlin/com/hedvig/android/data/paying/member/GetMemberTypeUseCase.kt +++ b/app/data/data-paying-member/src/main/kotlin/com/hedvig/android/data/paying/member/GetMemberTypeUseCase.kt @@ -9,12 +9,13 @@ import com.hedvig.android.apollo.safeExecute import com.hedvig.android.core.common.ErrorMessage import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.demomode.DemoManager +import com.hedvig.android.core.demomode.DemoSwitcher import com.hedvig.android.data.contract.ContractType import com.hedvig.android.data.contract.toContractType import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn -import kotlinx.coroutines.flow.first +import dev.zacsweers.metro.binding import octopus.ActiveInsuranceContractTypesQuery interface GetMemberTypeUseCase { @@ -40,15 +41,13 @@ enum class MemberType { @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class) +@ContributesBinding(AppScope::class, binding = binding()) internal class SwitchingGetMemberTypeUseCase( - private val demoManager: DemoManager, - private val demoImpl: GetMemberTypeUseCaseDemo, - private val prodImpl: GetMemberTypeUseCaseImpl, -) : GetMemberTypeUseCase { + override val demoManager: DemoManager, + override val demoImpl: GetMemberTypeUseCaseDemo, + override val prodImpl: GetMemberTypeUseCaseImpl, +) : GetMemberTypeUseCase, DemoSwitcher { override suspend fun invoke() = pick().invoke() - - private suspend fun pick(): GetMemberTypeUseCase = if (demoManager.isDemoMode().first()) demoImpl else prodImpl } @SingleIn(AppScope::class) diff --git a/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/data/SwitchingCbmChatRepository.kt b/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/data/SwitchingCbmChatRepository.kt index 8c6e197f9b..3413573a6d 100644 --- a/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/data/SwitchingCbmChatRepository.kt +++ b/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/data/SwitchingCbmChatRepository.kt @@ -4,21 +4,22 @@ import android.net.Uri import com.benasher44.uuid.Uuid import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.demomode.DemoManager +import com.hedvig.android.core.demomode.DemoSwitcher import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn +import dev.zacsweers.metro.binding import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flow @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class) +@ContributesBinding(AppScope::class, binding = binding()) internal class SwitchingCbmChatRepository( - private val demoManager: DemoManager, - private val prodImpl: CbmChatRepositoryImpl, - private val demoImpl: CbmChatRepositoryDemo, -) : CbmChatRepository { + override val demoManager: DemoManager, + override val prodImpl: CbmChatRepositoryImpl, + override val demoImpl: CbmChatRepositoryDemo, +) : CbmChatRepository, DemoSwitcher { override suspend fun createConversation(conversationId: Uuid) = pick().createConversation(conversationId) override fun getConversationInfo(conversationId: Uuid) = flow { @@ -45,6 +46,4 @@ internal class SwitchingCbmChatRepository( override suspend fun sendPhotos(conversationId: Uuid, uriList: List) = pick().sendPhotos(conversationId, uriList) override suspend fun sendMedia(conversationId: Uuid, uriList: List) = pick().sendMedia(conversationId, uriList) - - private suspend fun pick(): CbmChatRepository = if (demoManager.isDemoMode().first()) demoImpl else prodImpl } diff --git a/app/feature/feature-cross-sell-sheet/src/main/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetViewModel.kt b/app/feature/feature-cross-sell-sheet/src/main/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetViewModel.kt index 9c9b35505c..b35314bceb 100644 --- a/app/feature/feature-cross-sell-sheet/src/main/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetViewModel.kt +++ b/app/feature/feature-cross-sell-sheet/src/main/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetViewModel.kt @@ -18,6 +18,7 @@ import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.common.di.ActivityRetainedScope import com.hedvig.android.core.common.di.HedvigViewModel import com.hedvig.android.core.demomode.DemoManager +import com.hedvig.android.core.demomode.DemoSwitcher import com.hedvig.android.crosssells.BundleProgress import com.hedvig.android.crosssells.CrossSellSheetData import com.hedvig.android.crosssells.RecommendedCrossSell @@ -31,10 +32,10 @@ import com.hedvig.android.molecule.public.MoleculeViewModel import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn +import dev.zacsweers.metro.binding import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest @@ -130,16 +131,13 @@ internal fun CrossSellInfoType.toCrossSellSource(): CrossSellInput { @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class) +@ContributesBinding(AppScope::class, binding = binding()) internal class SwitchingGetCrossSellSheetDataUseCase( - private val demoManager: DemoManager, - private val prodImpl: GetCrossSellSheetDataUseCaseImpl, - private val demoImpl: DemoGetCrossSellSheetDataUseCase, -) : GetCrossSellSheetDataUseCase { + override val demoManager: DemoManager, + override val prodImpl: GetCrossSellSheetDataUseCaseImpl, + override val demoImpl: DemoGetCrossSellSheetDataUseCase, +) : GetCrossSellSheetDataUseCase, DemoSwitcher { override suspend fun invoke(source: CrossSellInput) = pick().invoke(source) - - private suspend fun pick(): GetCrossSellSheetDataUseCase = - if (demoManager.isDemoMode().first()) demoImpl else prodImpl } internal interface GetCrossSellSheetDataUseCase { diff --git a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/di/SwitchingGetHomeDataUseCase.kt b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/di/SwitchingGetHomeDataUseCase.kt index d73d9d8f6b..7bd2b3b95e 100644 --- a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/di/SwitchingGetHomeDataUseCase.kt +++ b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/di/SwitchingGetHomeDataUseCase.kt @@ -2,27 +2,26 @@ package com.hedvig.android.feature.home.di import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.demomode.DemoManager +import com.hedvig.android.core.demomode.DemoSwitcher import com.hedvig.android.feature.home.home.data.GetHomeDataUseCase import com.hedvig.android.feature.home.home.data.GetHomeDataUseCaseDemo import com.hedvig.android.feature.home.home.data.GetHomeDataUseCaseImpl import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn +import dev.zacsweers.metro.binding import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flow @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class) +@ContributesBinding(AppScope::class, binding = binding()) internal class SwitchingGetHomeDataUseCase( - private val demoManager: DemoManager, - private val prodImpl: GetHomeDataUseCaseImpl, - private val demoImpl: GetHomeDataUseCaseDemo, -) : GetHomeDataUseCase { + override val demoManager: DemoManager, + override val prodImpl: GetHomeDataUseCaseImpl, + override val demoImpl: GetHomeDataUseCaseDemo, +) : GetHomeDataUseCase, DemoSwitcher { override fun invoke(forceNetworkFetch: Boolean) = flow { emitAll(pick().invoke(forceNetworkFetch)) } - - private suspend fun pick(): GetHomeDataUseCase = if (demoManager.isDemoMode().first()) demoImpl else prodImpl } diff --git a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetCrossSellsUseCase.kt b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetCrossSellsUseCase.kt index 8192233e95..5a5b9dbedb 100644 --- a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetCrossSellsUseCase.kt +++ b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetCrossSellsUseCase.kt @@ -2,23 +2,22 @@ package com.hedvig.android.feature.insurances.di import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.demomode.DemoManager +import com.hedvig.android.core.demomode.DemoSwitcher import com.hedvig.android.feature.insurances.data.GetCrossSellsUseCase import com.hedvig.android.feature.insurances.data.GetCrossSellsUseCaseDemo import com.hedvig.android.feature.insurances.data.GetCrossSellsUseCaseImpl import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn -import kotlinx.coroutines.flow.first +import dev.zacsweers.metro.binding @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class) +@ContributesBinding(AppScope::class, binding = binding()) internal class SwitchingGetCrossSellsUseCase( - private val demoManager: DemoManager, - private val prodImpl: GetCrossSellsUseCaseImpl, - private val demoImpl: GetCrossSellsUseCaseDemo, -) : GetCrossSellsUseCase { + override val demoManager: DemoManager, + override val prodImpl: GetCrossSellsUseCaseImpl, + override val demoImpl: GetCrossSellsUseCaseDemo, +) : GetCrossSellsUseCase, DemoSwitcher { override suspend fun invoke() = pick().invoke() - - private suspend fun pick(): GetCrossSellsUseCase = if (demoManager.isDemoMode().first()) demoImpl else prodImpl } diff --git a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetInsuranceContractsUseCase.kt b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetInsuranceContractsUseCase.kt index 0a5e796384..ef4903f9e1 100644 --- a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetInsuranceContractsUseCase.kt +++ b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetInsuranceContractsUseCase.kt @@ -2,28 +2,26 @@ package com.hedvig.android.feature.insurances.di import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.demomode.DemoManager +import com.hedvig.android.core.demomode.DemoSwitcher import com.hedvig.android.feature.insurances.data.GetInsuranceContractsUseCase import com.hedvig.android.feature.insurances.data.GetInsuranceContractsUseCaseDemo import com.hedvig.android.feature.insurances.data.GetInsuranceContractsUseCaseImpl import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn +import dev.zacsweers.metro.binding import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flow @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class) +@ContributesBinding(AppScope::class, binding = binding()) internal class SwitchingGetInsuranceContractsUseCase( - private val demoManager: DemoManager, - private val prodImpl: GetInsuranceContractsUseCaseImpl, - private val demoImpl: GetInsuranceContractsUseCaseDemo, -) : GetInsuranceContractsUseCase { + override val demoManager: DemoManager, + override val prodImpl: GetInsuranceContractsUseCaseImpl, + override val demoImpl: GetInsuranceContractsUseCaseDemo, +) : GetInsuranceContractsUseCase, DemoSwitcher { override fun invoke() = flow { emitAll(pick().invoke()) } - - private suspend fun pick(): GetInsuranceContractsUseCase = - if (demoManager.isDemoMode().first()) demoImpl else prodImpl } diff --git a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetShouldShowPayoutUseCase.kt b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetShouldShowPayoutUseCase.kt index e77ee1db15..5455faab7d 100644 --- a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetShouldShowPayoutUseCase.kt +++ b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetShouldShowPayoutUseCase.kt @@ -2,20 +2,19 @@ package com.hedvig.android.feature.payments.overview.data import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.demomode.DemoManager +import com.hedvig.android.core.demomode.DemoSwitcher import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn -import kotlinx.coroutines.flow.first +import dev.zacsweers.metro.binding @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class) +@ContributesBinding(AppScope::class, binding = binding()) internal class SwitchingGetShouldShowPayoutUseCase( - private val demoManager: DemoManager, - private val prodImpl: GetShouldShowPayoutUseCaseImpl, - private val demoImpl: GetShouldShowPayoutUseCaseDemo, -) : GetShouldShowPayoutUseCase { + override val demoManager: DemoManager, + override val prodImpl: GetShouldShowPayoutUseCaseImpl, + override val demoImpl: GetShouldShowPayoutUseCaseDemo, +) : GetShouldShowPayoutUseCase, DemoSwitcher { override suspend fun invoke() = pick().invoke() - - private suspend fun pick(): GetShouldShowPayoutUseCase = if (demoManager.isDemoMode().first()) demoImpl else prodImpl } diff --git a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetUpcomingPaymentUseCase.kt b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetUpcomingPaymentUseCase.kt index a0bddefd38..b437b6a21f 100644 --- a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetUpcomingPaymentUseCase.kt +++ b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetUpcomingPaymentUseCase.kt @@ -2,20 +2,19 @@ package com.hedvig.android.feature.payments.overview.data import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.demomode.DemoManager +import com.hedvig.android.core.demomode.DemoSwitcher import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn -import kotlinx.coroutines.flow.first +import dev.zacsweers.metro.binding @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class) +@ContributesBinding(AppScope::class, binding = binding()) internal class SwitchingGetUpcomingPaymentUseCase( - private val demoManager: DemoManager, - private val prodImpl: GetUpcomingPaymentUseCaseImpl, - private val demoImpl: GetUpcomingPaymentUseCaseDemo, -) : GetUpcomingPaymentUseCase { + override val demoManager: DemoManager, + override val prodImpl: GetUpcomingPaymentUseCaseImpl, + override val demoImpl: GetUpcomingPaymentUseCaseDemo, +) : GetUpcomingPaymentUseCase, DemoSwitcher { override suspend fun invoke() = pick().invoke() - - private suspend fun pick(): GetUpcomingPaymentUseCase = if (demoManager.isDemoMode().first()) demoImpl else prodImpl } diff --git a/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/di/SwitchingContactInfoRepository.kt b/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/di/SwitchingContactInfoRepository.kt index c572356451..6ff3decfc1 100644 --- a/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/di/SwitchingContactInfoRepository.kt +++ b/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/di/SwitchingContactInfoRepository.kt @@ -2,6 +2,7 @@ package com.hedvig.android.feature.profile.di import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.demomode.DemoManager +import com.hedvig.android.core.demomode.DemoSwitcher import com.hedvig.android.feature.profile.data.ContactInfoRepository import com.hedvig.android.feature.profile.data.ContactInfoRepositoryDemo import com.hedvig.android.feature.profile.data.ContactInfoRepositoryImpl @@ -10,19 +11,17 @@ import com.hedvig.android.feature.profile.data.ContactInformation.PhoneNumber import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn -import kotlinx.coroutines.flow.first +import dev.zacsweers.metro.binding @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class) +@ContributesBinding(AppScope::class, binding = binding()) internal class SwitchingContactInfoRepository( - private val demoManager: DemoManager, - private val prodImpl: ContactInfoRepositoryImpl, - private val demoImpl: ContactInfoRepositoryDemo, -) : ContactInfoRepository { + override val demoManager: DemoManager, + override val prodImpl: ContactInfoRepositoryImpl, + override val demoImpl: ContactInfoRepositoryDemo, +) : ContactInfoRepository, DemoSwitcher { override suspend fun contactInfo() = pick().contactInfo() override suspend fun updateInfo(phoneNumber: PhoneNumber, email: Email) = pick().updateInfo(phoneNumber, email) - - private suspend fun pick(): ContactInfoRepository = if (demoManager.isDemoMode().first()) demoImpl else prodImpl } diff --git a/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/crosssell/home/CrossSellHomeNotificationServiceImpl.kt b/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/crosssell/home/CrossSellHomeNotificationServiceImpl.kt index 18bbe2e4f7..2748c6b75c 100644 --- a/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/crosssell/home/CrossSellHomeNotificationServiceImpl.kt +++ b/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/crosssell/home/CrossSellHomeNotificationServiceImpl.kt @@ -6,27 +6,28 @@ import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.longPreferencesKey import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.demomode.DemoManager +import com.hedvig.android.core.demomode.DemoSwitcher import com.hedvig.android.notification.badge.data.crosssell.CrossSellNotificationBadgeService import com.hedvig.android.notification.badge.data.storage.NotificationBadge import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn +import dev.zacsweers.metro.binding import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class) +@ContributesBinding(AppScope::class, binding = binding()) internal class SwitchingCrossSellHomeNotificationService( - private val demoManager: DemoManager, - private val prodImpl: CrossSellHomeNotificationServiceImpl, - private val demoImpl: DemoCrossSellHomeNotificationService, -) : CrossSellHomeNotificationService { + override val demoManager: DemoManager, + override val prodImpl: CrossSellHomeNotificationServiceImpl, + override val demoImpl: DemoCrossSellHomeNotificationService, +) : CrossSellHomeNotificationService, DemoSwitcher { override fun showRedDotNotification() = flow { emitAll(pick().showRedDotNotification()) } @@ -39,9 +40,6 @@ internal class SwitchingCrossSellHomeNotificationService( override suspend fun setLastEpochDayNewRecommendationNotificationWasShown(epochDay: Long) = pick().setLastEpochDayNewRecommendationNotificationWasShown(epochDay) - - private suspend fun pick(): CrossSellHomeNotificationService = - if (demoManager.isDemoMode().first()) demoImpl else prodImpl } @Inject diff --git a/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/payment/MissedPaymentNotificationService.kt b/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/payment/MissedPaymentNotificationService.kt index 74ec59cdd8..6dd4df23c9 100644 --- a/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/payment/MissedPaymentNotificationService.kt +++ b/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/payment/MissedPaymentNotificationService.kt @@ -2,29 +2,27 @@ package com.hedvig.android.notification.badge.data.payment import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.demomode.DemoManager +import com.hedvig.android.core.demomode.DemoSwitcher import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn +import dev.zacsweers.metro.binding import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class) +@ContributesBinding(AppScope::class, binding = binding()) internal class SwitchingMissedPaymentNotificationService( - private val demoManager: DemoManager, - private val demoImpl: DemoMissedPaymentNotificationService, - private val prodImpl: MissedPaymentNotificationServiceImpl, -) : MissedPaymentNotificationService { + override val demoManager: DemoManager, + override val demoImpl: DemoMissedPaymentNotificationService, + override val prodImpl: MissedPaymentNotificationServiceImpl, +) : MissedPaymentNotificationService, DemoSwitcher { override fun showRedDotNotification() = flow { emitAll(pick().showRedDotNotification()) } - - private suspend fun pick(): MissedPaymentNotificationService = - if (demoManager.isDemoMode().first()) demoImpl else prodImpl } interface MissedPaymentNotificationService { diff --git a/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/data/SwitchingForeverRepository.kt b/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/data/SwitchingForeverRepository.kt index f269e61495..6f38059b86 100644 --- a/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/data/SwitchingForeverRepository.kt +++ b/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/data/SwitchingForeverRepository.kt @@ -2,22 +2,21 @@ package com.hedvig.android.shared.foreverui.ui.data import com.hedvig.android.core.common.di.AppScope import com.hedvig.android.core.demomode.DemoManager +import com.hedvig.android.core.demomode.DemoSwitcher import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn -import kotlinx.coroutines.flow.first +import dev.zacsweers.metro.binding @Inject @SingleIn(AppScope::class) -@ContributesBinding(AppScope::class) +@ContributesBinding(AppScope::class, binding = binding()) internal class SwitchingForeverRepository( - private val demoManager: DemoManager, - private val prodImpl: ForeverRepositoryImpl, - private val demoImpl: ForeverRepositoryDemo, -) : ForeverRepository { + override val demoManager: DemoManager, + override val prodImpl: ForeverRepositoryImpl, + override val demoImpl: ForeverRepositoryDemo, +) : ForeverRepository, DemoSwitcher { override suspend fun getReferralsData() = pick().getReferralsData() override suspend fun updateCode(newCode: String) = pick().updateCode(newCode) - - private suspend fun pick(): ForeverRepository = if (demoManager.isDemoMode().first()) demoImpl else prodImpl } From 61dd00d81b1fa041fd0e92eb74f4f1508bbb037c Mon Sep 17 00:00:00 2001 From: stylianosgakis Date: Mon, 22 Jun 2026 17:59:55 +0200 Subject: [PATCH 3/5] Introduce `pickFlow` for the flow callers of DemoSwitcher --- .../android/core/demomode/DemoSwitcher.kt | 24 ++++++++++++++----- .../SwitchingGetAddonBannerInfoUseCase.kt | 8 ++----- .../paying/member/GetMemberTypeUseCase.kt | 2 +- .../chat/data/SwitchingCbmChatRepository.kt | 16 ++++--------- .../sell/sheet/CrossSellSheetViewModel.kt | 4 ++-- .../home/di/SwitchingGetHomeDataUseCase.kt | 8 ++----- .../di/SwitchingGetCrossSellsUseCase.kt | 2 +- .../SwitchingGetInsuranceContractsUseCase.kt | 8 ++----- .../SwitchingGetShouldShowPayoutUseCase.kt | 2 +- .../SwitchingGetUpcomingPaymentUseCase.kt | 2 +- .../di/SwitchingContactInfoRepository.kt | 2 +- .../CrossSellHomeNotificationServiceImpl.kt | 13 ++++------ .../MissedPaymentNotificationService.kt | 8 ++----- .../ui/data/SwitchingForeverRepository.kt | 2 +- 14 files changed, 42 insertions(+), 59 deletions(-) diff --git a/app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/DemoSwitcher.kt b/app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/DemoSwitcher.kt index c9217e31d9..bb2033b8e8 100644 --- a/app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/DemoSwitcher.kt +++ b/app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/DemoSwitcher.kt @@ -1,15 +1,27 @@ package com.hedvig.android.core.demomode +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flatMapLatest /** * Shared selection logic for a type that has a prod and a demo implementation. Implementors also implement [T] itself - * and forward each member through [pick], so consumers inject the plain [T] and never know demo mode exists. + * and forward each member through [pick] (suspend members) or [pickFlow] (Flow-returning members), so consumers inject + * the plain [T] and never know demo mode exists. */ -interface DemoSwitcher { - val demoManager: DemoManager - val demoImpl: T - val prodImpl: T +abstract class DemoSwitcher { + abstract val demoManager: DemoManager + abstract val demoImpl: T + abstract val prodImpl: T - suspend fun pick(): T = if (demoManager.isDemoMode().first()) demoImpl else prodImpl + protected suspend fun pick(): T { + return if (demoManager.isDemoMode().first()) demoImpl else prodImpl + } + + protected fun pickFlow(block: suspend (T) -> Flow): Flow { + return demoManager.isDemoMode().distinctUntilChanged().flatMapLatest { isDemo -> + block(if (isDemo) demoImpl else prodImpl) + } + } } diff --git a/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/SwitchingGetAddonBannerInfoUseCase.kt b/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/SwitchingGetAddonBannerInfoUseCase.kt index fe39a8c713..d978ffae72 100644 --- a/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/SwitchingGetAddonBannerInfoUseCase.kt +++ b/app/data/data-addons/src/main/kotlin/com/hedvig/android/data/addons/data/SwitchingGetAddonBannerInfoUseCase.kt @@ -7,8 +7,6 @@ import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn import dev.zacsweers.metro.binding -import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.flow @Inject @SingleIn(AppScope::class) @@ -17,8 +15,6 @@ internal class SwitchingGetAddonBannerInfoUseCase( override val demoManager: DemoManager, override val demoImpl: DemoGetAddonBannerInfoUseCase, override val prodImpl: GetAddonBannerInfoUseCaseImpl, -) : GetAddonBannerInfoUseCase, DemoSwitcher { - override fun invoke(source: AddonBannerSource) = flow { - emitAll(pick().invoke(source)) - } +) : GetAddonBannerInfoUseCase, DemoSwitcher() { + override fun invoke(source: AddonBannerSource) = pickFlow { it.invoke(source) } } diff --git a/app/data/data-paying-member/src/main/kotlin/com/hedvig/android/data/paying/member/GetMemberTypeUseCase.kt b/app/data/data-paying-member/src/main/kotlin/com/hedvig/android/data/paying/member/GetMemberTypeUseCase.kt index 17e2c4089e..4e1b5e5098 100644 --- a/app/data/data-paying-member/src/main/kotlin/com/hedvig/android/data/paying/member/GetMemberTypeUseCase.kt +++ b/app/data/data-paying-member/src/main/kotlin/com/hedvig/android/data/paying/member/GetMemberTypeUseCase.kt @@ -46,7 +46,7 @@ internal class SwitchingGetMemberTypeUseCase( override val demoManager: DemoManager, override val demoImpl: GetMemberTypeUseCaseDemo, override val prodImpl: GetMemberTypeUseCaseImpl, -) : GetMemberTypeUseCase, DemoSwitcher { +) : GetMemberTypeUseCase, DemoSwitcher() { override suspend fun invoke() = pick().invoke() } diff --git a/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/data/SwitchingCbmChatRepository.kt b/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/data/SwitchingCbmChatRepository.kt index 3413573a6d..dc97d79258 100644 --- a/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/data/SwitchingCbmChatRepository.kt +++ b/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/data/SwitchingCbmChatRepository.kt @@ -9,8 +9,6 @@ import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn import dev.zacsweers.metro.binding -import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.flow @Inject @SingleIn(AppScope::class) @@ -19,23 +17,17 @@ internal class SwitchingCbmChatRepository( override val demoManager: DemoManager, override val prodImpl: CbmChatRepositoryImpl, override val demoImpl: CbmChatRepositoryDemo, -) : CbmChatRepository, DemoSwitcher { +) : CbmChatRepository, DemoSwitcher() { override suspend fun createConversation(conversationId: Uuid) = pick().createConversation(conversationId) - override fun getConversationInfo(conversationId: Uuid) = flow { - emitAll(pick().getConversationInfo(conversationId)) - } + override fun getConversationInfo(conversationId: Uuid) = pickFlow { it.getConversationInfo(conversationId) } - override fun bannerText(conversationId: Uuid) = flow { - emitAll(pick().bannerText(conversationId)) - } + override fun bannerText(conversationId: Uuid) = pickFlow { it.bannerText(conversationId) } override suspend fun chatMessages(conversationId: Uuid, pagingToken: PagingToken?) = pick().chatMessages(conversationId, pagingToken) - override fun pollNewestMessages(conversationId: Uuid) = flow { - emitAll(pick().pollNewestMessages(conversationId)) - } + override fun pollNewestMessages(conversationId: Uuid) = pickFlow { it.pollNewestMessages(conversationId) } override suspend fun retrySendMessage(conversationId: Uuid, messageId: String) = pick().retrySendMessage(conversationId, messageId) diff --git a/app/feature/feature-cross-sell-sheet/src/main/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetViewModel.kt b/app/feature/feature-cross-sell-sheet/src/main/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetViewModel.kt index b35314bceb..93862f4833 100644 --- a/app/feature/feature-cross-sell-sheet/src/main/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetViewModel.kt +++ b/app/feature/feature-cross-sell-sheet/src/main/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetViewModel.kt @@ -136,8 +136,8 @@ internal class SwitchingGetCrossSellSheetDataUseCase( override val demoManager: DemoManager, override val prodImpl: GetCrossSellSheetDataUseCaseImpl, override val demoImpl: DemoGetCrossSellSheetDataUseCase, -) : GetCrossSellSheetDataUseCase, DemoSwitcher { - override suspend fun invoke(source: CrossSellInput) = pick().invoke(source) +) : GetCrossSellSheetDataUseCase, DemoSwitcher() { + override suspend fun invoke(source: CrossSellInput) = pickFlow { it.invoke(source) } } internal interface GetCrossSellSheetDataUseCase { diff --git a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/di/SwitchingGetHomeDataUseCase.kt b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/di/SwitchingGetHomeDataUseCase.kt index 7bd2b3b95e..522b2311e3 100644 --- a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/di/SwitchingGetHomeDataUseCase.kt +++ b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/di/SwitchingGetHomeDataUseCase.kt @@ -10,8 +10,6 @@ import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn import dev.zacsweers.metro.binding -import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.flow @Inject @SingleIn(AppScope::class) @@ -20,8 +18,6 @@ internal class SwitchingGetHomeDataUseCase( override val demoManager: DemoManager, override val prodImpl: GetHomeDataUseCaseImpl, override val demoImpl: GetHomeDataUseCaseDemo, -) : GetHomeDataUseCase, DemoSwitcher { - override fun invoke(forceNetworkFetch: Boolean) = flow { - emitAll(pick().invoke(forceNetworkFetch)) - } +) : GetHomeDataUseCase, DemoSwitcher() { + override fun invoke(forceNetworkFetch: Boolean) = pickFlow { it.invoke(forceNetworkFetch) } } diff --git a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetCrossSellsUseCase.kt b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetCrossSellsUseCase.kt index 5a5b9dbedb..d5fc45eefa 100644 --- a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetCrossSellsUseCase.kt +++ b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetCrossSellsUseCase.kt @@ -18,6 +18,6 @@ internal class SwitchingGetCrossSellsUseCase( override val demoManager: DemoManager, override val prodImpl: GetCrossSellsUseCaseImpl, override val demoImpl: GetCrossSellsUseCaseDemo, -) : GetCrossSellsUseCase, DemoSwitcher { +) : GetCrossSellsUseCase, DemoSwitcher() { override suspend fun invoke() = pick().invoke() } diff --git a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetInsuranceContractsUseCase.kt b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetInsuranceContractsUseCase.kt index ef4903f9e1..57db114d73 100644 --- a/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetInsuranceContractsUseCase.kt +++ b/app/feature/feature-insurances/src/main/kotlin/com/hedvig/android/feature/insurances/di/SwitchingGetInsuranceContractsUseCase.kt @@ -10,8 +10,6 @@ import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn import dev.zacsweers.metro.binding -import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.flow @Inject @SingleIn(AppScope::class) @@ -20,8 +18,6 @@ internal class SwitchingGetInsuranceContractsUseCase( override val demoManager: DemoManager, override val prodImpl: GetInsuranceContractsUseCaseImpl, override val demoImpl: GetInsuranceContractsUseCaseDemo, -) : GetInsuranceContractsUseCase, DemoSwitcher { - override fun invoke() = flow { - emitAll(pick().invoke()) - } +) : GetInsuranceContractsUseCase, DemoSwitcher() { + override fun invoke() = pickFlow { it.invoke() } } diff --git a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetShouldShowPayoutUseCase.kt b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetShouldShowPayoutUseCase.kt index 5455faab7d..3979515a65 100644 --- a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetShouldShowPayoutUseCase.kt +++ b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetShouldShowPayoutUseCase.kt @@ -15,6 +15,6 @@ internal class SwitchingGetShouldShowPayoutUseCase( override val demoManager: DemoManager, override val prodImpl: GetShouldShowPayoutUseCaseImpl, override val demoImpl: GetShouldShowPayoutUseCaseDemo, -) : GetShouldShowPayoutUseCase, DemoSwitcher { +) : GetShouldShowPayoutUseCase, DemoSwitcher() { override suspend fun invoke() = pick().invoke() } diff --git a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetUpcomingPaymentUseCase.kt b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetUpcomingPaymentUseCase.kt index b437b6a21f..39f04e5c8f 100644 --- a/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetUpcomingPaymentUseCase.kt +++ b/app/feature/feature-payments/src/main/kotlin/com/hedvig/android/feature/payments/overview/data/SwitchingGetUpcomingPaymentUseCase.kt @@ -15,6 +15,6 @@ internal class SwitchingGetUpcomingPaymentUseCase( override val demoManager: DemoManager, override val prodImpl: GetUpcomingPaymentUseCaseImpl, override val demoImpl: GetUpcomingPaymentUseCaseDemo, -) : GetUpcomingPaymentUseCase, DemoSwitcher { +) : GetUpcomingPaymentUseCase, DemoSwitcher() { override suspend fun invoke() = pick().invoke() } diff --git a/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/di/SwitchingContactInfoRepository.kt b/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/di/SwitchingContactInfoRepository.kt index 6ff3decfc1..7c04c808fd 100644 --- a/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/di/SwitchingContactInfoRepository.kt +++ b/app/feature/feature-profile/src/main/kotlin/com/hedvig/android/feature/profile/di/SwitchingContactInfoRepository.kt @@ -20,7 +20,7 @@ internal class SwitchingContactInfoRepository( override val demoManager: DemoManager, override val prodImpl: ContactInfoRepositoryImpl, override val demoImpl: ContactInfoRepositoryDemo, -) : ContactInfoRepository, DemoSwitcher { +) : ContactInfoRepository, DemoSwitcher() { override suspend fun contactInfo() = pick().contactInfo() override suspend fun updateInfo(phoneNumber: PhoneNumber, email: Email) = pick().updateInfo(phoneNumber, email) diff --git a/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/crosssell/home/CrossSellHomeNotificationServiceImpl.kt b/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/crosssell/home/CrossSellHomeNotificationServiceImpl.kt index 2748c6b75c..3c7e62e8ad 100644 --- a/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/crosssell/home/CrossSellHomeNotificationServiceImpl.kt +++ b/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/crosssell/home/CrossSellHomeNotificationServiceImpl.kt @@ -15,8 +15,6 @@ import dev.zacsweers.metro.SingleIn import dev.zacsweers.metro.binding import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map @@ -27,14 +25,11 @@ internal class SwitchingCrossSellHomeNotificationService( override val demoManager: DemoManager, override val prodImpl: CrossSellHomeNotificationServiceImpl, override val demoImpl: DemoCrossSellHomeNotificationService, -) : CrossSellHomeNotificationService, DemoSwitcher { - override fun showRedDotNotification() = flow { - emitAll(pick().showRedDotNotification()) - } +) : CrossSellHomeNotificationService, DemoSwitcher() { + override fun showRedDotNotification() = pickFlow { it.showRedDotNotification() } - override fun getLastEpochDayNewRecommendationNotificationWasShown() = flow { - emitAll(pick().getLastEpochDayNewRecommendationNotificationWasShown()) - } + override fun getLastEpochDayNewRecommendationNotificationWasShown() = + pickFlow { it.getLastEpochDayNewRecommendationNotificationWasShown() } override suspend fun markAsSeen() = pick().markAsSeen() diff --git a/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/payment/MissedPaymentNotificationService.kt b/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/payment/MissedPaymentNotificationService.kt index 6dd4df23c9..b9cce897a6 100644 --- a/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/payment/MissedPaymentNotificationService.kt +++ b/app/notification-badge-data/notification-badge-data-public/src/main/kotlin/com/hedvig/android/notification/badge/data/payment/MissedPaymentNotificationService.kt @@ -8,8 +8,6 @@ import dev.zacsweers.metro.Inject import dev.zacsweers.metro.SingleIn import dev.zacsweers.metro.binding import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf @Inject @@ -19,10 +17,8 @@ internal class SwitchingMissedPaymentNotificationService( override val demoManager: DemoManager, override val demoImpl: DemoMissedPaymentNotificationService, override val prodImpl: MissedPaymentNotificationServiceImpl, -) : MissedPaymentNotificationService, DemoSwitcher { - override fun showRedDotNotification() = flow { - emitAll(pick().showRedDotNotification()) - } +) : MissedPaymentNotificationService, DemoSwitcher() { + override fun showRedDotNotification() = pickFlow { it.showRedDotNotification() } } interface MissedPaymentNotificationService { diff --git a/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/data/SwitchingForeverRepository.kt b/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/data/SwitchingForeverRepository.kt index 6f38059b86..382b411f42 100644 --- a/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/data/SwitchingForeverRepository.kt +++ b/app/shared/forever-ui/src/main/kotlin/com/hedvig/android/shared/foreverui/ui/data/SwitchingForeverRepository.kt @@ -15,7 +15,7 @@ internal class SwitchingForeverRepository( override val demoManager: DemoManager, override val prodImpl: ForeverRepositoryImpl, override val demoImpl: ForeverRepositoryDemo, -) : ForeverRepository, DemoSwitcher { +) : ForeverRepository, DemoSwitcher() { override suspend fun getReferralsData() = pick().getReferralsData() override suspend fun updateCode(newCode: String) = pick().updateCode(newCode) From 26d294f03691e077d430e904ae12af7fb6353397 Mon Sep 17 00:00:00 2001 From: stylianosgakis Date: Mon, 22 Jun 2026 22:43:10 +0200 Subject: [PATCH 4/5] Move picking logic into core `selected()`, used by both protected API functions --- .../hedvig/android/core/demomode/DemoSwitcher.kt | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/DemoSwitcher.kt b/app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/DemoSwitcher.kt index bb2033b8e8..b89713aaf8 100644 --- a/app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/DemoSwitcher.kt +++ b/app/core/core-demo-mode/src/main/kotlin/com/hedvig/android/core/demomode/DemoSwitcher.kt @@ -4,6 +4,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.map /** * Shared selection logic for a type that has a prod and a demo implementation. Implementors also implement [T] itself @@ -15,13 +16,10 @@ abstract class DemoSwitcher { abstract val demoImpl: T abstract val prodImpl: T - protected suspend fun pick(): T { - return if (demoManager.isDemoMode().first()) demoImpl else prodImpl - } + private fun selected(): Flow = + demoManager.isDemoMode().distinctUntilChanged().map { isDemo -> if (isDemo) demoImpl else prodImpl } - protected fun pickFlow(block: suspend (T) -> Flow): Flow { - return demoManager.isDemoMode().distinctUntilChanged().flatMapLatest { isDemo -> - block(if (isDemo) demoImpl else prodImpl) - } - } + protected suspend fun pick(): T = selected().first() + + protected fun pickFlow(block: suspend (T) -> Flow): Flow = selected().flatMapLatest(block) } From 809fd237f37c1b9e0cc061d33a658b84ed0c3dd1 Mon Sep 17 00:00:00 2001 From: stylianosgakis Date: Tue, 23 Jun 2026 11:16:31 +0200 Subject: [PATCH 5/5] Remove unecessary wrapper --- .../kotlin/com/hedvig/android/feature/chat/CbmChatViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/CbmChatViewModel.kt b/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/CbmChatViewModel.kt index 3bcfbf696f..1358797a52 100644 --- a/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/CbmChatViewModel.kt +++ b/app/feature/feature-chat/src/main/kotlin/com/hedvig/android/feature/chat/CbmChatViewModel.kt @@ -328,7 +328,7 @@ private fun presentLoadedChat( val bannerText by if (!hideBanner) { remember(conversationId, chatRepository) { - flow { emitAll(chatRepository.bannerText(conversationId)) } + chatRepository.bannerText(conversationId) }.collectAsState(null) } else { remember { mutableStateOf(null) }