Skip to content

Commit 186b6c3

Browse files
committed
refactor(analytics): encapsulate event hierarchy behind service interface
- Convert AnalyticsEvent to internal sealed interface with toProperties() on each subclass, removing the shared properties() extension function - Move event data onto subclasses (mint, amount, error, etc.) so callers no longer pass context separately from the event - Replace public AnalyticsEvent references in FlipcashAnalyticsService with domain-typed enums and sealed interfaces (BuyMethod, OnrampSource, OnrampVerificationStep, etc.) - Convert Transfer from enum to sealed interface to support SentCashLink variants (Clipboard, App) alongside simple data objects - Add StubAnalyticsService for tests and DI fallback - Add Throwable?.asProperty() helper to reduce null-check repetition
1 parent 862c92a commit 186b6c3

23 files changed

Lines changed: 374 additions & 459 deletions

File tree

apps/flipcash/features/balance/src/main/kotlin/com/flipcash/app/balance/internal/BalanceViewModel.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.flipcash.app.balance.internal
22

33
import androidx.lifecycle.viewModelScope
4-
import com.flipcash.app.analytics.AnalyticsEvent
4+
import com.flipcash.app.analytics.Analytics
55
import com.flipcash.app.analytics.FlipcashAnalyticsService
66
import com.flipcash.app.core.AppRoute
77
import com.flipcash.app.core.tokens.TokenPurpose
@@ -62,7 +62,7 @@ internal class BalanceViewModel @Inject constructor(
6262
eventFlow
6363
.filterIsInstance<Event.OnAddCashClicked>()
6464
.onEach {
65-
analytics.openOnramp(AnalyticsEvent.OnRampOpenEvent.Balance)
65+
analytics.openOnramp(Analytics.OnrampSource.Balance)
6666
val provider = stateFlow.value.preferredOnRampProvider
6767
if (provider is OnRampProvider.Coinbase && provider.type == OnRampType.Virtual) {
6868
// has coinbase provider supporting google pay - pop selection for quick add

apps/flipcash/features/cash/src/main/kotlin/com/flipcash/app/cash/internal/CashScreenViewModel.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.flipcash.app.cash.internal
22

33
import androidx.lifecycle.viewModelScope
4-
import com.flipcash.app.analytics.AnalyticsEvent
4+
import com.flipcash.app.analytics.Analytics
55
import com.flipcash.app.analytics.FlipcashAnalyticsService
66
import com.flipcash.app.core.AppRoute
77
import com.flipcash.app.core.bill.Bill
@@ -318,7 +318,7 @@ internal class CashScreenViewModel @Inject constructor(
318318
.onEach { amount ->
319319
val provider = stateFlow.value.preferredOnRampProvider
320320
if (provider is OnRampProvider.Coinbase && provider.type == OnRampType.Virtual) {
321-
analytics.openOnramp(AnalyticsEvent.OnRampOpenEvent.Give)
321+
analytics.openOnramp(Analytics.OnrampSource.Give)
322322
// has coinbase provider supporting google pay - pop selection for quick add
323323
dispatchEvent(Event.OpenOnRampAmountModal(amount))
324324
} else {

apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/email/EmailMagicLinkScreen.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ import androidx.compose.ui.platform.LocalContext
1212
import androidx.compose.ui.res.stringResource
1313
import cafe.adriel.voyager.core.annotation.ExperimentalVoyagerApi
1414
import cafe.adriel.voyager.core.lifecycle.LifecycleEffectOnce
15-
import cafe.adriel.voyager.core.screen.Screen
1615
import cafe.adriel.voyager.core.screen.ScreenKey
1716
import cafe.adriel.voyager.core.screen.uniqueScreenKey
18-
import com.flipcash.app.analytics.AnalyticsEvent
17+
import com.flipcash.app.analytics.Analytics
1918
import com.flipcash.app.analytics.rememberAnalytics
2019
import com.flipcash.app.contact.verification.EmailVerificationFlow
2120
import com.flipcash.app.contact.verification.VerificationFlowStep
@@ -59,7 +58,7 @@ class EmailMagicLinkScreen(
5958

6059
val analytics = rememberAnalytics()
6160
LifecycleEffectOnce {
62-
analytics.onrampVerification(AnalyticsEvent.OnRampVerificationEvent.ConfirmEmail)
61+
analytics.onrampVerification(Analytics.OnrampVerificationStep.ConfirmEmail)
6362
}
6463

6564
Column(

apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/email/EmailVerificationScreen.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,11 @@ import androidx.compose.ui.Modifier
1111
import androidx.compose.ui.res.stringResource
1212
import cafe.adriel.voyager.core.annotation.ExperimentalVoyagerApi
1313
import cafe.adriel.voyager.core.lifecycle.LifecycleEffectOnce
14-
import cafe.adriel.voyager.core.screen.Screen
1514
import cafe.adriel.voyager.core.screen.ScreenKey
1615
import cafe.adriel.voyager.core.screen.uniqueScreenKey
1716
import cafe.adriel.voyager.navigator.LocalNavigator
1817
import cafe.adriel.voyager.navigator.currentOrThrow
19-
import com.flipcash.app.analytics.AnalyticsEvent
18+
import com.flipcash.app.analytics.Analytics
2019
import com.flipcash.app.analytics.rememberAnalytics
2120
import com.flipcash.app.contact.verification.EmailVerificationFlow
2221
import com.flipcash.app.contact.verification.internal.email.EmailEntryScreen
@@ -69,7 +68,7 @@ class EmailVerificationScreen : AppScreen, Parcelable {
6968

7069
val analytics = rememberAnalytics()
7170
LifecycleEffectOnce {
72-
analytics.onrampVerification(AnalyticsEvent.OnRampVerificationEvent.EnterEmail)
71+
analytics.onrampVerification(Analytics.OnrampVerificationStep.EnterEmail)
7372
}
7473

7574
BackHandler {

apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/internal/VerificationFlowIntroScreen.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import cafe.adriel.voyager.core.annotation.ExperimentalVoyagerApi
2727
import cafe.adriel.voyager.core.lifecycle.LifecycleEffectOnce
2828
import cafe.adriel.voyager.core.screen.ScreenKey
2929
import cafe.adriel.voyager.core.screen.uniqueScreenKey
30-
import com.flipcash.app.analytics.AnalyticsEvent
30+
import com.flipcash.app.analytics.Analytics
3131
import com.flipcash.app.analytics.rememberAnalytics
3232
import com.flipcash.app.contact.verification.VerificationFlowStep
3333
import com.flipcash.app.navigation.FlowNavigator
@@ -69,7 +69,7 @@ class VerificationFlowIntroScreen(
6969

7070
val analytics = rememberAnalytics()
7171
LifecycleEffectOnce {
72-
analytics.onrampVerification(AnalyticsEvent.OnRampVerificationEvent.ShowInfo)
72+
analytics.onrampVerification(Analytics.OnrampVerificationStep.ShowInfo)
7373
}
7474

7575
BackHandler {

apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/phone/PhoneCodeScreen.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ import androidx.compose.ui.Modifier
1111
import androidx.compose.ui.res.stringResource
1212
import cafe.adriel.voyager.core.annotation.ExperimentalVoyagerApi
1313
import cafe.adriel.voyager.core.lifecycle.LifecycleEffectOnce
14-
import cafe.adriel.voyager.core.screen.Screen
1514
import cafe.adriel.voyager.core.screen.ScreenKey
1615
import cafe.adriel.voyager.core.screen.uniqueScreenKey
17-
import com.flipcash.app.analytics.AnalyticsEvent
16+
import com.flipcash.app.analytics.Analytics
1817
import com.flipcash.app.analytics.rememberAnalytics
1918
import com.flipcash.app.contact.verification.PhoneVerificationFlow
2019
import com.flipcash.app.contact.verification.VerificationFlowStep
@@ -64,7 +63,7 @@ class PhoneCodeScreen: AppScreen, Parcelable {
6463

6564
val analytics = rememberAnalytics()
6665
LifecycleEffectOnce {
67-
analytics.onrampVerification(AnalyticsEvent.OnRampVerificationEvent.ConfirmPhone)
66+
analytics.onrampVerification(Analytics.OnrampVerificationStep.ConfirmPhone)
6867
}
6968

7069
LaunchedEffect(viewModel) {

apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/phone/PhoneVerificationScreen.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,11 @@ import androidx.compose.ui.Modifier
1111
import androidx.compose.ui.res.stringResource
1212
import cafe.adriel.voyager.core.annotation.ExperimentalVoyagerApi
1313
import cafe.adriel.voyager.core.lifecycle.LifecycleEffectOnce
14-
import cafe.adriel.voyager.core.screen.Screen
1514
import cafe.adriel.voyager.core.screen.ScreenKey
1615
import cafe.adriel.voyager.core.screen.uniqueScreenKey
1716
import cafe.adriel.voyager.navigator.LocalNavigator
1817
import cafe.adriel.voyager.navigator.currentOrThrow
19-
import com.flipcash.app.analytics.AnalyticsEvent
18+
import com.flipcash.app.analytics.Analytics
2019
import com.flipcash.app.analytics.rememberAnalytics
2120
import com.flipcash.app.contact.verification.PhoneVerificationFlow
2221
import com.flipcash.app.contact.verification.internal.phone.PhoneEntryScreen
@@ -70,7 +69,7 @@ class PhoneVerificationScreen : AppScreen, Parcelable {
7069

7170
val analytics = rememberAnalytics()
7271
LifecycleEffectOnce {
73-
analytics.onrampVerification(AnalyticsEvent.OnRampVerificationEvent.EnterPhone)
72+
analytics.onrampVerification(Analytics.OnrampVerificationStep.EnterPhone)
7473
}
7574

7675
BackHandler {

apps/flipcash/features/menu/src/main/kotlin/com/flipcash/app/menu/internal/MenuScreenViewModel.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.flipcash.app.menu.internal
22

33
import androidx.lifecycle.viewModelScope
4-
import com.flipcash.app.analytics.AnalyticsEvent
4+
import com.flipcash.app.analytics.Analytics
55
import com.flipcash.app.analytics.FlipcashAnalyticsService
66
import com.flipcash.app.auth.AuthManager
77
import com.flipcash.app.core.AppRoute
@@ -130,7 +130,7 @@ internal class MenuScreenViewModel @Inject constructor(
130130
eventFlow
131131
.filterIsInstance<Event.OnAddCashClicked>()
132132
.onEach {
133-
analytics.openOnramp(AnalyticsEvent.OnRampOpenEvent.Settings)
133+
analytics.openOnramp(Analytics.OnrampSource.Settings)
134134
val provider = stateFlow.value.preferredOnRampProvider
135135
if (provider is OnRampProvider.Coinbase && provider.type == OnRampType.Virtual) {
136136
// has coinbase provider supporting google pay - pop selection for quick add

apps/flipcash/features/scanner/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ dependencies {
5454
implementation(Libs.compose_activities)
5555

5656
implementation(project(":apps:flipcash:core"))
57+
implementation(project(":apps:flipcash:shared:analytics"))
5758
implementation(project(":apps:flipcash:shared:appsettings"))
5859
implementation(project(":apps:flipcash:shared:appupdates"))
5960
implementation(project(":apps:flipcash:shared:bills"))

apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/Scanner.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import androidx.compose.ui.platform.LocalContext
1313
import androidx.lifecycle.Lifecycle
1414
import cafe.adriel.voyager.core.registry.ScreenRegistry
1515
import cafe.adriel.voyager.navigator.currentOrThrow
16+
import com.flipcash.app.analytics.rememberAnalytics
1617
import com.flipcash.app.core.navigation.DeeplinkType
1718
import com.flipcash.app.router.LocalRouter
1819
import com.flipcash.app.scanner.internal.bills.BillContainer
@@ -39,6 +40,7 @@ internal fun Scanner(deepLink: DeeplinkType?) {
3940
val session = LocalSessionController.currentOrThrow
4041
val state by session.state.collectAsState()
4142
val billState by session.billState.collectAsState()
43+
val analytics = rememberAnalytics()
4244

4345
val sheetLifecycleHandler = rememberSheetAutoResign()
4446
LaunchedEffect(sheetLifecycleHandler) {
@@ -71,7 +73,7 @@ internal fun Scanner(deepLink: DeeplinkType?) {
7173
deepLink = deepLinkSaved,
7274
previewing = previewing,
7375
session = session,
74-
navigator = navigator
76+
navigator = navigator,
7577
) {
7678
deepLinkSaved = null
7779
}

0 commit comments

Comments
 (0)