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 390d3efddb..c82d569eda 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 @@ -355,7 +355,7 @@ private sealed interface TopLevelDestination { val destination: Destination object Home : TopLevelDestination { - override val destination: Destination = HomeDestination.Home + override val destination: Destination = HomeDestination.Home() } object Insurances : TopLevelDestination { diff --git a/app/app/src/main/kotlin/com/hedvig/android/app/ui/IsTopLevelGraphInHierarchy.kt b/app/app/src/main/kotlin/com/hedvig/android/app/ui/IsTopLevelGraphInHierarchy.kt index 7cbdb27fa5..ff8e482611 100644 --- a/app/app/src/main/kotlin/com/hedvig/android/app/ui/IsTopLevelGraphInHierarchy.kt +++ b/app/app/src/main/kotlin/com/hedvig/android/app/ui/IsTopLevelGraphInHierarchy.kt @@ -32,7 +32,7 @@ internal val TopLevelGraph.destination: Destination internal val TopLevelGraph.startDestination: Destination get() = when (this) { - TopLevelGraph.Home -> HomeDestination.Home + TopLevelGraph.Home -> HomeDestination.Home() TopLevelGraph.Insurances -> InsurancesDestination.Insurances TopLevelGraph.Forever -> ForeverDestination.Forever TopLevelGraph.Payments -> PaymentsDestination.Payments diff --git a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/navigation/HomeDestinations.kt b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/navigation/HomeDestinations.kt index feaf4ed484..4764cd0861 100644 --- a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/navigation/HomeDestinations.kt +++ b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/navigation/HomeDestinations.kt @@ -13,7 +13,11 @@ sealed interface HomeDestination { data object Graph : HomeDestination, Destination @Serializable - data object Home : HomeDestination, Destination + data class Home( + // When true, the home screen automatically opens the start-claim consent sheet on arrival. Defaults to false for + // regular home navigation; set to true when arriving via the `/submit-claim` deep link (see homeGraph). + val startClaimFlow: Boolean = false, + ) : HomeDestination, Destination @Serializable data class FirstVet(val sections: List) : HomeDestination, Destination { diff --git a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/navigation/HomeGraph.kt b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/navigation/HomeGraph.kt index bed682b0bb..49b0b3a6c4 100644 --- a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/navigation/HomeGraph.kt +++ b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/navigation/HomeGraph.kt @@ -1,6 +1,9 @@ package com.hedvig.android.feature.home.home.navigation +import android.content.Intent +import androidx.core.os.BundleCompat import androidx.lifecycle.compose.dropUnlessResumed +import androidx.navigation.NavBackStackEntry import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import coil3.ImageLoader @@ -45,8 +48,10 @@ fun NavGraphBuilder.homeGraph( exitTransition = { MotionDefaults.fadeThroughExit }, ) { val viewModel: HomeViewModel = koinViewModel() + val startClaimFlow = startClaimFlow || it.wasLaunchedFromClaimDeepLink(hedvigDeepLinkContainer) HomeDestination( viewModel = viewModel, + startClaimFlow = startClaimFlow, onNavigateToInbox = dropUnlessResumed { onNavigateToInbox() }, onNavigateToNewConversation = dropUnlessResumed { onNavigateToNewConversation() }, navigateToClaimChat = dropUnlessResumed { navigateToClaimChat() }, @@ -84,3 +89,14 @@ fun NavGraphBuilder.homeGraph( nestedGraphs() } } + +/** + * Whether this back stack entry was opened by the claim flow deep link (`/submit-claim`). The deep link does not carry + * any route argument, so we inspect the launching intent's URI and match it against the known claim flow patterns. + */ +private fun NavBackStackEntry.wasLaunchedFromClaimDeepLink(hedvigDeepLinkContainer: HedvigDeepLinkContainer): Boolean { + val arguments = arguments ?: return false + val deepLinkIntent = BundleCompat.getParcelable(arguments, NavController.KEY_DEEP_LINK_INTENT, Intent::class.java) + val deepLinkUri = deepLinkIntent?.data?.toString() ?: return false + return hedvigDeepLinkContainer.claimFlow.any { claimFlowUri -> deepLinkUri.startsWith(claimFlowUri) } +} diff --git a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/ui/HomeDestination.kt b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/ui/HomeDestination.kt index fd56f30258..b697c23783 100644 --- a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/ui/HomeDestination.kt +++ b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/ui/HomeDestination.kt @@ -38,6 +38,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment @@ -153,6 +154,7 @@ import org.jetbrains.compose.resources.stringResource @Composable internal fun HomeDestination( viewModel: HomeViewModel, + startClaimFlow: Boolean, onNavigateToInbox: () -> Unit, onNavigateToNewConversation: () -> Unit, navigateToClaimChat: () -> Unit, @@ -174,6 +176,7 @@ internal fun HomeDestination( val notificationPermissionState = rememberNotificationPermissionState() HomeScreen( uiState = uiState, + startClaimFlow = startClaimFlow, notificationPermissionState = notificationPermissionState, reload = { viewModel.emit(HomeEvent.RefreshData) }, onNavigateToInbox = onNavigateToInbox, @@ -203,6 +206,7 @@ internal fun HomeDestination( @Composable private fun HomeScreen( uiState: HomeUiState, + startClaimFlow: Boolean, notificationPermissionState: NotificationPermissionState, reload: () -> Unit, onNavigateToInbox: () -> Unit, @@ -247,6 +251,17 @@ private fun HomeScreen( navigateToClaimChatInDevMode = navigateToClaimChatInDevMode, isStagingEnvironment = (uiState as? Success)?.isProduction?.not() ?: false, ) + // Auto-open the start-claim consent sheet when arriving via the `/submit-claim` deep link, mirroring a tap on the + // "Start claim" button. Guarded so it only happens once per entry, surviving recompositions and configuration changes. + if (startClaimFlow) { + var hasOpenedStartClaimSheet by rememberSaveable { mutableStateOf(false) } + LaunchedEffect(Unit) { + if (!hasOpenedStartClaimSheet) { + hasOpenedStartClaimSheet = true + startClaimBottomSheetState.show() + } + } + } Box(Modifier.fillMaxSize()) { val toolbarHeight = 64.dp val transition = updateTransition(targetState = uiState, label = "home ui state") @@ -802,6 +817,7 @@ private fun PreviewHomeScreen( ), isProduction = true, ), + startClaimFlow = false, notificationPermissionState = rememberPreviewNotificationPermissionState(), reload = {}, onNavigateToInbox = {}, @@ -835,6 +851,7 @@ private fun PreviewHomeScreenWithError() { Surface(color = HedvigTheme.colorScheme.backgroundPrimary) { HomeScreen( uiState = HomeUiState.Error(null), + startClaimFlow = false, notificationPermissionState = rememberPreviewNotificationPermissionState(), reload = {}, onNavigateToInbox = {}, @@ -889,6 +906,7 @@ private fun PreviewHomeScreenAllHomeTextTypes( addonBannerInfo = null, isProduction = true, ), + startClaimFlow = false, notificationPermissionState = rememberPreviewNotificationPermissionState(), reload = {}, onNavigateToInbox = {},