Skip to content

Commit d3d1a73

Browse files
bmc08gtclaude
andcommitted
feat(verification): support full-screen and target navigation for drop-in use cases
Add `target` and `fullScreen` params to AppRoute.Verification so the flow can forward-navigate on success (replace) and render with status bar padding when used outside of a modal sheet (e.g. onboarding). Wire phone verification into the onboarding flow from AccessKeyScreen. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent 9757de1 commit d3d1a73

6 files changed

Lines changed: 27 additions & 16 deletions

File tree

apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/AppRoute.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ sealed interface AppRoute : NavKey, Parcelable {
4949
@Serializable
5050
data class Purchase(val fromLogin: Boolean = false) : Onboarding
5151

52+
@Serializable
53+
data class ContactPermission(val postCreate: Boolean): Onboarding
5254
@Serializable
5355
data class NotificationPermission(val postCreate: Boolean = false) : Onboarding
5456
@Serializable
@@ -88,6 +90,8 @@ sealed interface AppRoute : NavKey, Parcelable {
8890
val includeEmail: Boolean = true,
8991
val email: String? = null,
9092
val emailVerificationCode: String? = null,
93+
val target: AppRoute? = null,
94+
val fullScreen: Boolean = false,
9195
) : AppRoute, FlowRouteWithResult<VerificationResult> {
9296
override val initialStack: List<NavKey>
9397
get() = buildVerificationInitialStack(

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ fun VerificationFlowScreen(
4646
route = route,
4747
value = NavResultOrCanceled.ReturnValue(result),
4848
)
49-
outerNavigator.pop()
49+
if (route.target != null && result is VerificationResult.Success) {
50+
outerNavigator.replace(route.target!!)
51+
} else {
52+
outerNavigator.pop()
53+
}
5054
},
5155
entryProvider = verificationEntryProvider(route),
5256
)
@@ -59,13 +63,13 @@ private fun verificationEntryProvider(
5963
VerificationFlowIntroContent(isForOnRamp = step.isForOnRamp)
6064
}
6165
annotatedEntry<VerificationStep.PhoneEntry> {
62-
PhoneVerificationContent()
66+
PhoneVerificationContent(isInModal = !route.fullScreen)
6367
}
6468
annotatedEntry<VerificationStep.PhoneCode> {
65-
PhoneCodeContent(includeEmail = route.includeEmail)
69+
PhoneCodeContent(includeEmail = route.includeEmail, isInModal = !route.fullScreen)
6670
}
6771
annotatedEntry<VerificationStep.PhoneCountryCode> {
68-
PhoneCountryCodeContent()
72+
PhoneCountryCodeContent(isInModal = !route.fullScreen)
6973
}
7074
annotatedEntry<VerificationStep.EmailEntry> {
7175
EmailVerificationContent(

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import kotlinx.coroutines.flow.onEach
2424
@Composable
2525
fun PhoneCodeContent(
2626
includeEmail: Boolean,
27+
isInModal: Boolean = true,
2728
) {
2829
val flowNavigator = rememberFlowNavigator<VerificationStep, VerificationResult>()
2930
val viewModel = flowSharedViewModel<PhoneVerificationViewModel>()
@@ -34,7 +35,7 @@ fun PhoneCodeContent(
3435
) {
3536
AppBarWithTitle(
3637
title = stringResource(R.string.title_enterTheCode),
37-
isInModal = true,
38+
isInModal = isInModal,
3839
titleAlignment = Alignment.CenterHorizontally,
3940
backButton = true,
4041
onBackIconClicked = { flowNavigator.back() },

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import kotlinx.coroutines.flow.launchIn
2020
import kotlinx.coroutines.flow.onEach
2121

2222
@Composable
23-
fun PhoneCountryCodeContent() {
23+
fun PhoneCountryCodeContent(isInModal: Boolean = true) {
2424
val flowNavigator = rememberFlowNavigator<VerificationStep, VerificationResult>()
2525
val viewModel = flowSharedViewModel<PhoneVerificationViewModel>()
2626

@@ -30,7 +30,7 @@ fun PhoneCountryCodeContent() {
3030
) {
3131
AppBarWithTitle(
3232
title = stringResource(R.string.title_verifyPhoneNumber),
33-
isInModal = true,
33+
isInModal = isInModal,
3434
titleAlignment = Alignment.CenterHorizontally,
3535
backButton = true,
3636
onBackIconClicked = { flowNavigator.back() },

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import kotlinx.coroutines.flow.launchIn
2525
import kotlinx.coroutines.flow.onEach
2626

2727
@Composable
28-
fun PhoneVerificationContent() {
28+
fun PhoneVerificationContent(isInModal: Boolean = true) {
2929
val codeNavigator = LocalCodeNavigator.current
3030
val flowNavigator = rememberFlowNavigator<VerificationStep, VerificationResult>()
3131
val viewModel = flowSharedViewModel<PhoneVerificationViewModel>()
@@ -37,7 +37,7 @@ fun PhoneVerificationContent() {
3737
) {
3838
AppBarWithTitle(
3939
title = stringResource(R.string.title_verifyPhoneNumber),
40-
isInModal = true,
40+
isInModal = isInModal,
4141
titleAlignment = Alignment.CenterHorizontally,
4242
backButton = true,
4343
onBackIconClicked = {

apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/accesskey/AccessKeyScreen.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,11 @@ import com.flipcash.app.login.internal.AccessKeyScreen
1212
import com.flipcash.features.login.R
1313
import com.getcode.navigation.core.LocalCodeNavigator
1414
import com.getcode.ui.components.AppBarWithTitle
15-
import com.getcode.util.permissions.rememberNotificationPermission
1615

1716
@Composable
1817
fun AccessKeyScreen() {
1918
val viewModel = hiltViewModel<LoginAccessKeyViewModel>()
2019
val navigator = LocalCodeNavigator.current
21-
val notificationPermissions = rememberNotificationPermission()
2220
Column(
2321
modifier = Modifier.fillMaxSize(),
2422
horizontalAlignment = Alignment.CenterHorizontally,
@@ -33,11 +31,15 @@ fun AccessKeyScreen() {
3331
if (requiresIap) {
3432
navigator.push(AppRoute.Onboarding.Purchase())
3533
} else {
36-
if (notificationPermissions.isPermanentlyDenied) {
37-
navigator.push(AppRoute.Onboarding.NotificationPermissionRationale(true))
38-
} else {
39-
navigator.push(AppRoute.Onboarding.NotificationPermission(true))
40-
}
34+
navigator.push(
35+
AppRoute.Verification(
36+
origin = AppRoute.Onboarding.AccessKey,
37+
includePhone = true,
38+
includeEmail = false,
39+
target = AppRoute.Onboarding.ContactPermission(postCreate = true),
40+
fullScreen = true,
41+
)
42+
)
4143
}
4244
}
4345
}

0 commit comments

Comments
 (0)