Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
128 commits
Select commit Hold shift + click to select a range
60be4f2
Add onboarding feature design spec
StylianosGakis Jul 21, 2026
868b216
Add onboarding implementation plan
StylianosGakis Jul 21, 2026
fb60239
Add tri-state AnalyticsConsent to SettingsDataStore
StylianosGakis Jul 21, 2026
1f5fe8f
Gate Firebase Analytics behind tri-state consent with buffer-and-flush
StylianosGakis Jul 21, 2026
d59d7fe
Add product analytics consent toggle to settings
StylianosGakis Jul 21, 2026
8e2c0de
Scaffold feature-onboarding module with nav keys
StylianosGakis Jul 21, 2026
3a8c34d
Add onboarding query, data models and repository
StylianosGakis Jul 21, 2026
f10f2e4
Add onboarding path builder with per-step skip rules
StylianosGakis Jul 21, 2026
16e1544
Add per-member onboarding seen store
StylianosGakis Jul 21, 2026
2f824da
Add onboarding session store, completion use case and navigator
StylianosGakis Jul 21, 2026
7e5801a
Avoid registering test-only nav key in the serializers module
StylianosGakis Jul 21, 2026
4e4845c
Add onboarding step scaffold with segmented progress bar
StylianosGakis Jul 21, 2026
1dc09b1
Use IconButton for onboarding scaffold back and close actions
StylianosGakis Jul 21, 2026
85bd9cb
Add onboarding welcome step
StylianosGakis Jul 21, 2026
0c5a55a
Remove unused import in onboarding welcome destination
StylianosGakis Jul 21, 2026
c8a732c
Add onboarding analytics consent step
StylianosGakis Jul 21, 2026
d386fb0
Add onboarding phone number step
StylianosGakis Jul 21, 2026
1101f8b
Make onboarding phone save-success test deterministic
StylianosGakis Jul 21, 2026
e2f1710
Add onboarding theme step
StylianosGakis Jul 21, 2026
ff63278
Add onboarding co-insured step
StylianosGakis Jul 21, 2026
07e5a79
Add onboarding pet id step
StylianosGakis Jul 21, 2026
9e4e375
Add onboarding invite a friend step
StylianosGakis Jul 21, 2026
8b075a7
Add onboarding connect payment step
StylianosGakis Jul 21, 2026
530cd7e
Add onboarding bundle discount step
StylianosGakis Jul 21, 2026
007d87e
Register onboarding entries and gate the flow after login
StylianosGakis Jul 21, 2026
594f931
Scope the onboarding session cache to the current member
StylianosGakis Jul 21, 2026
958d96f
Reset phone step submitting state after save
StylianosGakis Jul 21, 2026
5ca6d03
Anchor onboarding step content above the bottom buttons
StylianosGakis Jul 21, 2026
27e3a45
Polish onboarding UI details and comments
StylianosGakis Jul 21, 2026
2e8df46
Disable Firebase SDK collection while analytics consent is denied
StylianosGakis Jul 22, 2026
fdeb5e7
Add debug-only reset for the onboarding seen flag
StylianosGakis Jul 22, 2026
929595c
Polish onboarding chrome, welcome, consent and payment screens
StylianosGakis Jul 22, 2026
33d06c0
Rework onboarding phone input and theme picker
StylianosGakis Jul 22, 2026
52b02b6
Style onboarding co-insured and pet id rows as pillow cards
StylianosGakis Jul 22, 2026
9c4e3da
Show example referrals and open Forever from onboarding invite step
StylianosGakis Jul 22, 2026
1e88502
Show cross-sell pillows on the onboarding bundle step
StylianosGakis Jul 22, 2026
910a088
Add minimum-path and consent-buffer edge tests, document payin decision
StylianosGakis Jul 22, 2026
0ccf857
Add onboarding kill switch, dismiss on welcome back, and undecided co…
StylianosGakis Jul 22, 2026
584b932
Adjust copy for non-new members going through the onboarding
StylianosGakis Jul 22, 2026
c2c3f3e
Mark onboarding seen via dismissal observer instead of a back interce…
StylianosGakis Jul 24, 2026
c4849e6
Add onboarding manual QA checklist
StylianosGakis Jul 24, 2026
0f63649
Remove orphaned back-handling comment from onboarding welcome
StylianosGakis Jul 24, 2026
cae93e4
Merge branch 'develop' into feat/onboarding
StylianosGakis Jul 24, 2026
0ecb824
Use Lokalise string resources in onboarding screens
StylianosGakis Jul 27, 2026
01ec0bf
Merge branch 'develop' into feat/onboarding
StylianosGakis Jul 27, 2026
03b3bd7
Tighten onboarding hint spacing, add theme icons, inset invite card
StylianosGakis Jul 27, 2026
8f2d212
Only claim payment connected when the payin method is active
StylianosGakis Jul 27, 2026
011ae37
Wait for real flag value before deciding onboarding
StylianosGakis Jul 27, 2026
7a16a27
Only show onboarding when the flag backend is reachable
StylianosGakis Jul 28, 2026
a8a7ac7
Act on a cached flag value for the onboarding gate
StylianosGakis Jul 28, 2026
950f1ad
Trim duplicative comments in the onboarding flag gate
StylianosGakis Jul 28, 2026
02606c7
Add comment economy as a second axis in the comments guideline
StylianosGakis Jul 28, 2026
565ee48
Give onboarding step gaps a minimum height so items never touch when …
StylianosGakis Jul 28, 2026
b6a5d41
Inline the weight-plus-fixed spacer idiom to match house style
StylianosGakis Jul 28, 2026
eae3936
Add onboarding welcome, phone, and analytics graphics to core-resources
StylianosGakis Jul 28, 2026
e35c992
Replace onboarding phone keypad image with an animated Compose component
StylianosGakis Jul 28, 2026
1bd9731
Add spec for onboarding persistent top bar shared element
StylianosGakis Jul 28, 2026
ce6cbb5
Pin onboarding top bar as a shared element across steps
StylianosGakis Jul 28, 2026
97c70ba
Animate the "7" button as a fixed decision
StylianosGakis Jul 29, 2026
bf011e0
Animate the analytics-consent verified badge in after a delay
StylianosGakis Jul 29, 2026
85428fb
Make keypad highlight start from active instead
StylianosGakis Jul 29, 2026
f021f98
Make onboarding animations start a bit earleir
StylianosGakis Jul 29, 2026
56b4777
Add a Usage data drill-in screen to Settings for analytics consent
StylianosGakis Jul 29, 2026
0023f30
Use Lokalise strings for the Usage data settings row and screen
StylianosGakis Jul 29, 2026
547741b
Small UI tweaks
StylianosGakis Jul 29, 2026
f4fc520
Remove double spacer
StylianosGakis Jul 29, 2026
d9b4b68
Tweak keypad button corners
StylianosGakis Jul 29, 2026
53a1e77
Add pop-in notification badge to onboarding welcome symbol
StylianosGakis Jul 29, 2026
b37a04b
Create preview for OnboardingThemeDestination.kt
StylianosGakis Jul 29, 2026
1f23a1e
Move welcome icon's badge position according to design
StylianosGakis Jul 29, 2026
cf557e1
Use the transparent Hedvig pebble for the onboarding welcome symbol
StylianosGakis Jul 29, 2026
2f5ca18
Adjust welcome screen label text size
StylianosGakis Jul 29, 2026
40d1874
Add spec for onboarding progress bar progression animation
StylianosGakis Jul 29, 2026
2b5f74e
Animate onboarding progress bar fill across the step transition
StylianosGakis Jul 29, 2026
bc73b56
Express onboarding progress bar fill in step-number units
StylianosGakis Jul 29, 2026
49baff9
Merge branch 'develop' into feat/onboarding
StylianosGakis Jul 30, 2026
43b2a8b
Merge branch 'develop' into feat/onboarding
StylianosGakis Jul 31, 2026
dc60b17
Show opens-in-browser hint on onboarding bundle step
StylianosGakis Jul 31, 2026
a41f065
Detect co-owners vs co-insured in onboarding and drop invented paymen…
StylianosGakis Aug 3, 2026
d97ae95
Wire remaining onboarding strings to Lokalise keys
StylianosGakis Aug 3, 2026
2e030ab
Make co-insured and co-owners counts symmetric, tighten two comments
StylianosGakis Aug 3, 2026
c1c417b
Add spec for staggered invite-card friend animation
StylianosGakis Aug 3, 2026
2bb2846
Add plan for staggered invite-card friend animation
StylianosGakis Aug 3, 2026
6dbee69
Stagger in the example referral rows on the onboarding invite step
StylianosGakis Aug 3, 2026
5d47bbb
Download strings
StylianosGakis Aug 4, 2026
127b9aa
Match the invite example card to the Figma design and refine its reve…
StylianosGakis Aug 4, 2026
0ec59e2
Move the invite-card one-shot animation flag into MVI state and cap t…
StylianosGakis Aug 4, 2026
31a8421
Split the invite step into a stateful destination and previewable screen
StylianosGakis Aug 4, 2026
271129e
Split welcome, payment, consent, and bundle steps into previewable sc…
StylianosGakis Aug 4, 2026
5d44ead
Split pet-id and co-insured steps into previewable screens
StylianosGakis Aug 4, 2026
9bb0f80
Extract onboarding ViewModels and presenters into their own files
StylianosGakis Aug 4, 2026
68243ef
Split the phone step into a previewable screen and standardize theme …
StylianosGakis Aug 4, 2026
2350b06
Match the onboarding progress bar height to the design (4dp)
StylianosGakis Aug 5, 2026
f87b97a
Align the co-insured/pet-id contract row with the design
StylianosGakis Aug 5, 2026
6850b18
Tighten the theme step's option-row spacing and footnote to the design
StylianosGakis Aug 5, 2026
741322f
Match the consent step details to the design
StylianosGakis Aug 5, 2026
9f579b3
Match the bundle cross-sell row to the design
StylianosGakis Aug 5, 2026
fb33a2f
Render the payment footnote and switch-accounts hint at the label style
StylianosGakis Aug 5, 2026
9854518
Add the connected-payment graphic to the connect-payment step
StylianosGakis Aug 5, 2026
deb7f40
Show the connecting graphic from the start and keep the payment title
StylianosGakis Aug 5, 2026
389c1a9
Use the shared ThreeDotsLoading in the payment graphic and keep the s…
StylianosGakis Aug 5, 2026
20cedfa
Make ThreeDotsLoading a smooth continuous wave
StylianosGakis Aug 5, 2026
4f91057
Remove "opens in your browser" not present in the altest design
StylianosGakis Aug 5, 2026
32976ba
Drive the payment check from live status and always allow skipping
StylianosGakis Aug 5, 2026
bcc6792
Render the connected check in payment previews
StylianosGakis Aug 5, 2026
4375662
Clean up after code review
StylianosGakis Aug 5, 2026
9909192
Fix preview
StylianosGakis Aug 6, 2026
4130cbc
Pop the chip-id flow back to its caller instead of going home
StylianosGakis Aug 6, 2026
d4a230e
Only offer the payment skip after an attempt to connect
StylianosGakis Aug 6, 2026
38f3176
QA: check off gate/nav sections and automated phone/theme items
StylianosGakis Aug 11, 2026
4c63bc9
Merge branch 'develop' into feat/onboarding
StylianosGakis Aug 11, 2026
eef3c03
QA: pet-ID pass on a missing-pet member; log the completed-row-vanish…
StylianosGakis Aug 11, 2026
bf83815
Pin onboarding step contracts in the retained session, not the presenter
StylianosGakis Aug 11, 2026
ebf9901
Log analytics consent + effective collection state for on-device QA
StylianosGakis Aug 11, 2026
77d9df5
QA: mark analytics consent gate verified; note pinning bug fixed
StylianosGakis Aug 12, 2026
4f54fd6
Remove the analytics-consent QA debug log now that the gate is verified
StylianosGakis Aug 12, 2026
461e4b2
QA: co-owners branch + pinning fix re-verified on-device; resolve 15%…
StylianosGakis Aug 12, 2026
eb57970
chore: roll onboarding cross-sell subtitle instead of wrapping
StylianosGakis Aug 12, 2026
7dcf4fd
chore: back-and-forth auto-scroll for cross-sell subtitle
StylianosGakis Aug 12, 2026
1bc9a95
chore: use typed Duration for auto-scroll pause delay
StylianosGakis Aug 12, 2026
b3e5807
chore: expose cross-sell auto-scroll as a Modifier
StylianosGakis Aug 12, 2026
6d77c74
chore: move autoScrollingMarquee into design-system-hedvig
StylianosGakis Aug 12, 2026
f7ce102
Merge branch 'develop' into feat/onboarding
StylianosGakis Aug 12, 2026
8360b82
Merge branch 'feat/onboarding' into chore/bundle-discount-crosssell-s…
StylianosGakis Aug 12, 2026
bf530f5
chore: give onboarding cross-sell rows a uniform height
StylianosGakis Aug 12, 2026
c1e1df9
Run lint
StylianosGakis Aug 12, 2026
60408fd
Merge branch 'develop' into chore/onboarding-crosssell-subtitle-marquee
StylianosGakis Aug 12, 2026
0faf166
Merge pull request #3046 from HedvigInsurance/chore/onboarding-crosss…
StylianosGakis Aug 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions .superpowers/sdd/task-20-fixes-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Task 20 whole-branch review fixes

Branch: `feat/onboarding`. All work under `app/feature/feature-onboarding` unless noted.

## Commits

| SHA | Subject |
| --- | --- |
| 594f931a5b | Scope the onboarding session cache to the current member |
| 958d96fad0 | Reset phone step submitting state after save |
| 5ca6d033ae | Anchor onboarding step content above the bottom buttons |
| 27e3a45408 | Polish onboarding UI details and comments |

## A. Member-scoped OnboardingSessionStore cache (CRITICAL)

`data/OnboardingSessionStore.kt`:
- Added internal `fun interface OnboardingMemberIdProvider { fun memberId(): Flow<String?> }` plus
`OnboardingMemberIdProviderImpl` (`@ContributesBinding(AppScope::class)`, `@Inject`) delegating to
`MemberIdService.getMemberId()`.
- `OnboardingSession` gained `val memberId: String` as its first property.
- `OnboardingSessionStore` constructor now takes `memberIdProvider`.
- `getOrFetchSession()` (inside the mutex): resolves `currentMemberId` (returns
`ErrorMessage("No member id for onboarding session").left()` if null); returns the cached
session only when `cachedSession?.memberId == currentMemberId`, otherwise clears the cache and
fetches fresh, storing the session stamped with the current member id.
- `refreshData()`: resolves the member id, treats a cached session with a different memberId as
"no session to refresh" (clears cache, returns the existing error path).
- `OnboardingGateImpl` (`gate/OnboardingGate.kt`) unchanged and still compiles: it resolves memberId
itself then calls `getOrFetchSession()`; the double resolution is harmless.
- Tests: added `FakeOnboardingMemberIdProvider(var memberId)` to `FakeOnboardingRepository.kt`;
updated all 30 `OnboardingSessionStore(...)` construction sites across 10 test files (phone, theme,
consent, welcome, coinsured, petid, invite, payment, bundle presenter tests + navigator test) to
pass the fake, with the import added (alphabetically before `FakeOnboardingRepository`).
- New `data/OnboardingSessionStoreTest.kt`:
- `same member reuses the cached session without refetching` — one repository response fed, two
`getOrFetchSession()` calls return equal sessions, `expectNoEvents()` on the Turbine proves no
refetch.
- `a member change discards the cache and fetches fresh` — member A response (phone 111) cached,
fake switched to member B, second response (phone 222) fed, second call returns the member-B
session.

## B. Phone step submit-state bugs

`ui/phone/OnboardingPhoneDestination.kt` submit LaunchedEffect:
- On success: `currentState = content.copy(isSubmitting = false)` BEFORE `navigator.continueFrom(...)`.
- On failure: `currentState = (currentState as? OnboardingPhoneUiState.Content ?: content).copy(isSubmitting = false, showSubmissionError = true)` so digits typed during submission survive.
- Test `save success advances to the next step` updated for the extra emission and asserts the final
emitted Content has `isSubmitting == false`.

## C. Single ownership of vertical free space

`ui/OnboardingStepScaffold.kt`: removed the leading `Spacer(Modifier.weight(1f))` from
`OnboardingStepButtons` (kept its 16dp spacing); added a `Spacer(weight(1f))` to both previews.
Per-destination arrangement now has exactly one `weight(1f)` split each:
- welcome: added the second `Spacer(weight(1f))` after the centered content block.
- phone: added `Spacer(weight(1f))` between the text field and the buttons.
- invite: added `Spacer(weight(1f))` before and after the centered code text.
- bundle: added `Spacer(weight(1f))` after the rows loop.
- consent, theme, coinsured, petid, payment (both connected/not-connected): already had the single
weight in the required place, left unchanged.

## D. Small quality fixes

1. `OnboardingStepHeader`: `Spacer(Modifier.height(4.dp))` between title and description.
2. `ui/theme/OnboardingThemeDestination.kt`: (a) load-effect initial Content now uses
`selectedTheme = Theme.SYSTEM_DEFAULT` with comment `// Placeholder; the return site merges the
live stored theme.` (b) `ThemeOptionRow` internal padding changed `padding(16.dp)` ->
`padding(vertical = 16.dp)`; call sites keep horizontal 16dp so the total horizontal inset is 16dp
and the ripple (clip+clickable before the padding) still covers the row.
3. `navigation/OnboardingNavigator.kt`: removed the dead `navigateBack()` (no source references).
4. `tracking-firebase/.../ConsentAwareEventTrackingClient.kt`: added the public-hints comment on the
providers interface (ktlint moved it above the annotations, which is the correct spot).
5. `build.gradle.kts`: comment above `isReturnDefaultValues = true`.
6. Removed redundant `val content = state` aliases in invite and bundle destinations (use the
smart-cast `state` directly).

## Verification

Commands run (grepped for BUILD SUCCESSFUL, piped exit codes not trusted):

- `./gradlew :feature-onboarding:testDebugUnitTest :tracking-firebase:testDebugUnitTest` -> BUILD SUCCESSFUL
- `./gradlew :app:compileDebugKotlin` -> BUILD SUCCESSFUL
- `./gradlew ktlintFormat` -> BUILD SUCCESSFUL (only reflowed the new tracking-firebase comment,
committed in D)

Working tree clean after the four commits.

## Deviations

None. The theme ThemeOptionRow modifier order (clip -> clickable -> padding) already produced a
ripple covering the row, so no reorder beyond the padding change was needed.

## Fix: DENIED disables SDK collection

### What changed

`ConsentAwareEventTrackingClient.kt`:
- Added `private var collectionRequestedEnabled: Boolean = true` (guarded by `lock`).
- `setCollectionEnabled(enabled)` now stores the value under the lock, then calls
`applyCollectionEnabled()` instead of delegating directly.
- New `private fun applyCollectionEnabled()`: computes `effective = collectionRequestedEnabled &&
consent != DENIED` under the lock, then calls `delegate.setCollectionEnabled(effective)` outside
it. NOT_DECIDED and GRANTED leave collection enabled (subject to the demo gate); only DENIED forces
it off; flipping back to GRANTED re-enables if the demo gate allows.
- The consent collector's `init` block now calls `applyCollectionEnabled()` after every consent
update.
- KDoc updated to document the DENIED-disables-SDK-collection behavior.

`ConsentAwareEventTrackingClientTest.kt`:
- `RecordingClient.setCollectionEnabled` now records each call into `collectionEnabledCalls`.
- Three new tests added:
- `denying consent disables SDK collection and granting re-enables it`
- `demo mode wins over granted consent`
- `enabling collection while denied stays disabled`

`docs/superpowers/specs/2026-07-21-onboarding-design.md`:
- Appended one sentence to the "Analytics consent mechanism" section documenting the post-review
product decision.

### Commands run

```
./gradlew :tracking-firebase:testDebugUnitTest 2>&1 | tee /tmp/test_output.txt
grep "BUILD SUCCESSFUL" /tmp/test_output.txt -> BUILD SUCCESSFUL in 1m 3s

./gradlew ktlintFormat 2>&1 | tee /tmp/ktlint_output.txt
grep "BUILD SUCCESSFUL" /tmp/ktlint_output.txt -> BUILD SUCCESSFUL in 41s
```

Both BUILD SUCCESSFUL outputs confirmed. ktlintFormat made no further changes to the modified files.
4 changes: 3 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -482,14 +482,16 @@ Configuration in `.editorconfig`:

### Comments

Code comments and KDoc must describe the **current** code and stand on their own. Before writing one, apply the test: *would this make sense to someone reading the file cold, with no knowledge of the PR, the conversation, or what was decided against?* If not, it does not belong in the source. Do not reference:
Code comments and KDoc must describe the **current** code and stand on their own. A comment fails to earn its place in two ways: it tells the wrong kind of story, or it repeats what is already there. Before writing one, apply the test: *would this make sense to someone reading the file cold, with no knowledge of the PR, the conversation, or what was decided against?* If not, it does not belong in the source. Do not reference:

- **History / migration:** "Replaces Nav2…", "used to live in…".
- **Rejected alternatives:** "…not the iOS glass", "instead of the old Y".
- **Conversation / design-process state:** "pending design", "for now", "TBD".

When tempted to write "X instead of Y", drop the Y half and justify X on its own terms. If that leaves nothing, the code was self-explanatory, so delete the comment. Migration/history/process context belongs in the commit message.

**Say only what the code and its neighbours don't.** A comment must add information not already visible at its location. Do not restate a signature, a type, or a contract that a nearby or interface KDoc already documents; a paraphrase of something visible at the same spot is noise. Keep it to the non-obvious point (usually the *why*); if it grows into several lines re-describing mechanics that the code already shows, cut it back. If the same point already lives elsewhere (an interface's KDoc, a constant's own comment), state it once, at the spot that owns it, rather than repeating it at each use. Prefer no comment over a redundant or verbose one.

## Working with GraphQL

### Apollo Schema
Expand Down
1 change: 1 addition & 0 deletions app/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ dependencies {
implementation(projects.featureLogin)
implementation(projects.featureMovingflow)
implementation(projects.featureMovingflowNavigation)
implementation(projects.featureOnboarding)

implementation(projects.featureRemoveAddons)
implementation(projects.featurePayoutAccount)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import com.hedvig.android.core.demomode.DemoManager
import com.hedvig.android.core.rive.RiveInitializer
import com.hedvig.android.core.tracking.EventTrackingClient
import com.hedvig.android.data.settings.datastore.SettingsDataStore
import com.hedvig.android.feature.onboarding.data.ResetOnboardingSeenUseCase
import com.hedvig.android.featureflags.FeatureManager
import com.hedvig.android.language.LanguageLaunchCheckUseCase
import com.hedvig.android.language.LanguageService
Expand Down Expand Up @@ -114,6 +115,9 @@ class MainActivity : AppCompatActivity() {
@Inject
private lateinit var serializersModules: Set<SerializersModule>

@Inject
private lateinit var resetOnboardingSeenUseCase: ResetOnboardingSeenUseCase

/**
* Per-Activity host for the navigation state. A retained `ViewModel`, so it (and the
* [BackstackController] it owns) survives a config change but dies with this Activity — giving each
Expand Down Expand Up @@ -274,6 +278,8 @@ class MainActivity : AppCompatActivity() {
currentDestinationHolder = currentDestinationHolder,
eventTrackingClient = eventTrackingClient,
screenParameterExtractor = screenParameterExtractor,
onboardingGate = navRetainedViewModel.onboardingGate,
resetOnboardingSeenUseCase = resetOnboardingSeenUseCase,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.hedvig.android.app.navigation.BackstackController
import com.hedvig.android.app.navigation.SessionReconciler
import com.hedvig.android.core.common.di.ActivityRetainedScope
import com.hedvig.android.core.common.di.AppScope
import com.hedvig.android.feature.onboarding.gate.OnboardingGate
import com.hedvig.android.navigation.compose.Backstack
import dev.zacsweers.metro.ContributesTo
import dev.zacsweers.metro.GraphExtension
Expand All @@ -28,6 +29,8 @@ import dev.zacsweers.metrox.viewmodel.MetroViewModelMultibindings
internal interface ActivityRetainedGraph : MetroViewModelMultibindings {
val sessionReconciler: SessionReconciler

val onboardingGate: OnboardingGate

@Provides
fun bindBackstack(controller: BackstackController): Backstack = controller

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ import com.hedvig.android.feature.login.navigation.loginEntries
import com.hedvig.android.feature.movingflow.MovingSource
import com.hedvig.android.feature.movingflow.SelectContractForMovingKey
import com.hedvig.android.feature.movingflow.movingFlowEntries
import com.hedvig.android.feature.onboarding.data.ResetOnboardingSeenUseCase
import com.hedvig.android.feature.onboarding.navigation.onboardingEntries
import com.hedvig.android.feature.payments.navigation.paymentsEntries
import com.hedvig.android.feature.payoutaccount.navigation.PayoutAccountKey
import com.hedvig.android.feature.payoutaccount.navigation.payoutAccountEntries
Expand All @@ -57,6 +59,7 @@ import com.hedvig.android.feature.terminateinsurance.navigation.TerminateInsuran
import com.hedvig.android.feature.terminateinsurance.navigation.terminateInsuranceEntries
import com.hedvig.android.feature.travelcertificate.navigation.TravelCertificateKey
import com.hedvig.android.feature.travelcertificate.navigation.travelCertificateEntries
import com.hedvig.android.language.Language
import com.hedvig.android.language.LanguageService
import com.hedvig.android.logger.logcat
import com.hedvig.android.memberquickactions.InnerHelpCenterDestination
Expand Down Expand Up @@ -97,6 +100,7 @@ internal fun EntryProviderScope<HedvigNavKey>.hedvigEntryProvider(
imageLoader: ImageLoader,
languageService: LanguageService,
hedvigBuildConstants: HedvigBuildConstants,
resetOnboardingSeenUseCase: ResetOnboardingSeenUseCase,
) {
val shouldShowRequestPermissionRationale: (String) -> Boolean = androidAppHost::shouldShowPermissionRationale
val navigateToConnectPayment: () -> Unit = { backstack.add(TrustlyKey) }
Expand Down Expand Up @@ -167,6 +171,13 @@ internal fun EntryProviderScope<HedvigNavKey>.hedvigEntryProvider(
navigateToConnectPayment = navigateToConnectPayment,
navigateToPayoutAccount = navigateToPayoutAccount,
navigateToNewConversation = navigateToNewConversation,
onResetOnboardingForDebug = {
scope.launch {
resetOnboardingSeenUseCase.invoke()
// Debug-only feedback for non-production builds; deliberately not translated.
globalSnackBarState.show("Onboarding reset. Background and foreground the app to see it.")
}
},
)
addChatEntries(
backstack = backstack,
Expand All @@ -184,9 +195,19 @@ internal fun EntryProviderScope<HedvigNavKey>.hedvigEntryProvider(
externalNavigator = externalNavigator,
navigateToNewConversation = navigateToNewConversation,
navigateToInbox = navigateToInbox,
openPrivacyPolicy = { openUrl(privacyPolicyUrl(languageService.getLanguage())) },
)
}

/**
* The public privacy-policy page, per language. Mirrors the links used by the profile "about app"
* screen; kept here so `:app` owns the URL rather than `feature-onboarding`.
*/
private fun privacyPolicyUrl(language: Language): String = when (language) {
Language.SV_SE -> "https://www.hedvig.com/se/hedvig/personuppgifter"
Language.EN_SE -> "https://www.hedvig.com/se-en/hedvig/privacy-policy"
}

private fun EntryProviderScope<HedvigNavKey>.addLoginEntries(
backstack: BackstackController,
hedvigBuildConstants: HedvigBuildConstants,
Expand Down Expand Up @@ -463,6 +484,7 @@ private fun EntryProviderScope<HedvigNavKey>.addProfileEntries(
navigateToConnectPayment: () -> Unit,
navigateToPayoutAccount: () -> Unit,
navigateToNewConversation: () -> Unit,
onResetOnboardingForDebug: () -> Unit,
) {
profileEntries(
settingsDestinationNestedGraphs = {
Expand All @@ -489,8 +511,10 @@ private fun EntryProviderScope<HedvigNavKey>.addProfileEntries(
onNavigateToTravelCertificate = { backstack.add(TravelCertificateKey) },
onNavigateToInsuranceEvidence = { backstack.add(InsuranceEvidenceKey) },
openUrl = openUrl,
openPrivacyPolicy = { openUrl(privacyPolicyUrl(languageService.getLanguage())) },
navigateToChipId = { backstack.add(ChipIdKey()) },
languageService = languageService,
onResetOnboardingForDebug = onResetOnboardingForDebug,
)
}

Expand Down Expand Up @@ -531,6 +555,7 @@ private fun EntryProviderScope<HedvigNavKey>.addSharedFlowEntries(
externalNavigator: ExternalNavigator,
navigateToNewConversation: () -> Unit,
navigateToInbox: () -> Unit,
openPrivacyPolicy: () -> Unit,
) {
addonPurchaseEntries(
backstack = backstack,
Expand Down Expand Up @@ -566,4 +591,11 @@ private fun EntryProviderScope<HedvigNavKey>.addSharedFlowEntries(
)
imageViewerEntries(backstack, imageLoader)
removeAddonsEntries(backstack = backstack)
onboardingEntries(
backstack = backstack,
imageLoader = imageLoader,
openUrl = openUrl,
openPrivacyPolicy = openPrivacyPolicy,
navigateToChipId = { contractId -> backstack.add(ChipIdKey(contractId)) },
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.lifecycle.ViewModel
import com.hedvig.android.app.di.ActivityRetainedGraph
import com.hedvig.android.app.di.AppGraph
import com.hedvig.android.app.di.MergedMetroViewModelFactory
import com.hedvig.android.feature.onboarding.gate.OnboardingGate
import dev.zacsweers.metro.asContribution
import dev.zacsweers.metrox.viewmodel.MetroViewModelFactory

Expand Down Expand Up @@ -39,5 +40,7 @@ internal class NavRetainedViewModel(appGraph: AppGraph, isOwnTask: Boolean) : Vi

val sessionReconciler: SessionReconciler = activityGraph.sessionReconciler

val onboardingGate: OnboardingGate = activityGraph.onboardingGate

val viewModelFactory: MetroViewModelFactory = MergedMetroViewModelFactory(appGraph, activityGraph)
}
Loading
Loading