Skip to content

Commit

Permalink
feat: merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
JNdhlovu committed Sep 11, 2024
2 parents fb4f17e + e620c0d commit 32abd9e
Show file tree
Hide file tree
Showing 9 changed files with 196 additions and 92 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# Release Notes

(Unreleased)
## 10.3.0
* Introduced inflow navigation as well as individual navigation for compose screens

* Introduced inflow navigation as well as individual navigation for compose screens
## 10.2.6

* Make document captured image confirmation to be optional

## 10.2.5

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ internal fun DocumentCaptureScreen(
onConfirm: (File) -> Unit,
onError: (Throwable) -> Unit,
modifier: Modifier = Modifier,
showConfirmation: Boolean = true,
metadata: SnapshotStateList<Metadatum> = LocalMetadata.current,
onSkip: () -> Unit = { },
viewModel: DocumentCaptureViewModel = viewModel(
Expand Down Expand Up @@ -127,28 +128,33 @@ internal fun DocumentCaptureScreen(
}

documentImageToConfirm != null -> {
resultCallbacks.onConfirmCapturedImage = {
if (showConfirmation) {
resultCallbacks.onConfirmCapturedImage = {
viewModel.onConfirm(documentImageToConfirm, onConfirm)
localNavigationState.screensNavigation.getNavController.popBackStack()
}
resultCallbacks.onImageDialogRetake = {
viewModel.onRetry()
localNavigationState.screensNavigation.getNavController.popBackStack()
}
localNavigationState.screensNavigation.navigateTo(
Routes.Shared.ImageConfirmDialog(
ImageConfirmParams(
titleText = R.string.si_smart_selfie_confirmation_dialog_title,
subtitleText = R.string.si_smart_selfie_confirmation_dialog_subtitle,
imageFilePath = encodeUrl(documentImageToConfirm.absolutePath),
confirmButtonText =
R.string.si_doc_v_confirmation_dialog_confirm_button,
retakeButtonText = R.string.si_doc_v_confirmation_dialog_retake_button,
scaleFactor = 1.0f,
),
),
popUpTo = true,
popUpToInclusive = true,
)
} else {
viewModel.onConfirm(documentImageToConfirm, onConfirm)
localNavigationState.screensNavigation.getNavController.popBackStack()
}
resultCallbacks.onImageDialogRetake = {
viewModel.onRetry()
localNavigationState.screensNavigation.getNavController.popBackStack()
}
localNavigationState.screensNavigation.navigateTo(
Routes.Shared.ImageConfirmDialog(
ImageConfirmParams(
titleText = R.string.si_smart_selfie_confirmation_dialog_title,
subtitleText = R.string.si_smart_selfie_confirmation_dialog_subtitle,
imageFilePath = encodeUrl(documentImageToConfirm.absolutePath),
confirmButtonText = R.string.si_doc_v_confirmation_dialog_confirm_button,
retakeButtonText = R.string.si_doc_v_confirmation_dialog_retake_button,
scaleFactor = 1.0f,
),
),
popUpTo = true,
popUpToInclusive = true,
)
}

else -> {
Expand All @@ -170,4 +176,13 @@ internal fun DocumentCaptureScreen(
)
}
}

// NavigationBackHandler(
// navController = localNavigationState.screensNavigation.getNavController,
// ) { currentDestination ->
// localNavigationState.screensNavigation.getNavController.popBackStack()
// if (compareRouteStrings(startRoute, currentDestination)) {
// onResult(SmileIDResult.Error(OperationCanceledException("User cancelled")))
// }
// }
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.smileidentity.compose.document

import android.os.OperationCanceledException
import android.os.Parcelable
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
Expand All @@ -10,17 +11,22 @@ import androidx.compose.foundation.layout.statusBars
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.smileidentity.R
import com.smileidentity.compose.nav.DocumentCaptureParams
import com.smileidentity.compose.nav.NavigationBackHandler
import com.smileidentity.compose.nav.OrchestratedSelfieCaptureParams
import com.smileidentity.compose.nav.ProcessingScreenParams
import com.smileidentity.compose.nav.ResultCallbacks
import com.smileidentity.compose.nav.Routes
import com.smileidentity.compose.nav.SelfieCaptureParams
import com.smileidentity.compose.nav.compareRouteStrings
import com.smileidentity.compose.nav.localNavigationState
import com.smileidentity.models.DocumentCaptureFlow
import com.smileidentity.results.SmileIDCallback
Expand Down Expand Up @@ -49,26 +55,12 @@ internal fun <T : Parcelable> OrchestratedDocumentVerificationScreen(
onResult: SmileIDCallback<T> = {},
) {
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
var startRoute: Routes? by rememberSaveable { mutableStateOf(null) }
resultCallbacks.onDocumentFrontCaptureSuccess = viewModel::onDocumentFrontCaptureSuccess
resultCallbacks.onDocumentBackCaptureSuccess = viewModel::onDocumentBackCaptureSuccess
resultCallbacks.onDocumentCaptureError = viewModel::onError
resultCallbacks.onDocumentBackSkip = viewModel::onDocumentBackSkip
resultCallbacks.onInstructionsAcknowledgedTakePhoto = {
Routes.Document.CaptureFrontScreen(
DocumentCaptureParams(
jobId = jobId,
userId = userId,
showInstructions = showInstructions,
showAttribution = showAttribution,
allowGallerySelection = allowGalleryUpload,
showSkipButton = false,
instructionsHeroImage = R.drawable.si_doc_v_front_hero,
instructionsTitleText = R.string.si_doc_v_instruction_title,
instructionsSubtitleText = R.string.si_verify_identity_instruction_subtitle,
captureTitleText = R.string.si_doc_v_capture_instructions_front_title,
knownIdAspectRatio = idAspectRatio,
),
)
}
resultCallbacks.onProcessingContinue = { viewModel.onFinished(onResult) }
resultCallbacks.onProcessingClose = { viewModel.onFinished(onResult) }
Expand All @@ -89,26 +81,30 @@ internal fun <T : Parcelable> OrchestratedDocumentVerificationScreen(
content()
}
when (val currentStep = uiState.currentStep) {
DocumentCaptureFlow.FrontDocumentCapture ->
localNavigationState.screensNavigation.navigateTo(
Routes.Document.CaptureFrontScreen(
DocumentCaptureParams(
jobId = jobId,
userId = userId,
showInstructions = showInstructions,
showAttribution = showAttribution,
allowGallerySelection = allowGalleryUpload,
showSkipButton = false,
instructionsHeroImage = R.drawable.si_doc_v_front_hero,
instructionsTitleText = R.string.si_doc_v_instruction_title,
instructionsSubtitleText = R.string.si_verify_identity_instruction_subtitle,
captureTitleText = R.string.si_doc_v_capture_instructions_front_title,
knownIdAspectRatio = idAspectRatio,
),
DocumentCaptureFlow.FrontDocumentCapture -> {
startRoute = Routes.Document.CaptureFrontScreen(
DocumentCaptureParams(
jobId = jobId,
userId = userId,
showInstructions = showInstructions,
showAttribution = showAttribution,
allowGallerySelection = allowGalleryUpload,
showSkipButton = false,
instructionsHeroImage = R.drawable.si_doc_v_front_hero,
instructionsTitleText = R.string.si_doc_v_instruction_title,
instructionsSubtitleText = R.string.si_verify_identity_instruction_subtitle,
captureTitleText = R.string.si_doc_v_capture_instructions_front_title,
knownIdAspectRatio = idAspectRatio,
),
popUpTo = true,
popUpToInclusive = true,
)
startRoute?.let {
localNavigationState.screensNavigation.navigateTo(
startRoute as Routes.Document.CaptureFrontScreen,
popUpTo = true,
popUpToInclusive = true,
)
}
}

DocumentCaptureFlow.BackDocumentCapture ->
localNavigationState.screensNavigation.navigateTo(
Expand Down Expand Up @@ -174,4 +170,13 @@ internal fun <T : Parcelable> OrchestratedDocumentVerificationScreen(
popUpToInclusive = true,
)
}

NavigationBackHandler(
navController = localNavigationState.screensNavigation.getNavController,
) { currentDestination ->
localNavigationState.screensNavigation.getNavController.popBackStack()
if (compareRouteStrings(startRoute, currentDestination)) {
onResult(SmileIDResult.Error(OperationCanceledException("User cancelled")))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,16 @@ class MultiNavigationAppState(
private val startDestination: Routes? = null,
) {

// fun observeNavController() {
// val navBackStackEntry = getNavController.currentBackStackEntryAsState()
// navBackStackEntry?.let {
// val currentDestination = navBackStackEntry?.destination
// }
// }

fun setNavController(_navController: NavHostController) {
navController = _navController
// observeNavController()
}

var getStartDestination: Routes = startDestination!!
Expand Down Expand Up @@ -52,16 +60,16 @@ class MultiNavigationAppState(
false
}
}

fun navigateTo(route: Routes, popUpTo: Boolean, popUpToInclusive: Boolean) {
getNavController.navigate(route) {
launchSingleTop = true
restoreState = true
// if (popUpTo) {
// popUpTo(route) {
// inclusive = popUpToInclusive
// saveState = false
// }
// }
if (popUpTo) {
popUpTo(route) {
inclusive = popUpToInclusive
}
}
}
}
}
Expand All @@ -72,6 +80,7 @@ fun NavHostController.getDestination(): Sequence<NavDestination>? {
val currentDestination = navBackStackEntry?.destination
return currentDestination?.hierarchy
}

data class MultiNavigationStates(
var rootNavigation: MultiNavigationAppState = MultiNavigationAppState(),
var orchestratedNavigation: MultiNavigationAppState = MultiNavigationAppState(),
Expand Down
19 changes: 18 additions & 1 deletion lib/src/main/java/com/smileidentity/compose/nav/NavUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.smileidentity.compose.nav
import android.os.Build
import android.os.Bundle
import android.os.Parcelable
import androidx.navigation.NavDestination
import androidx.navigation.NavType
import java.io.File
import java.net.URLDecoder
Expand Down Expand Up @@ -78,6 +79,22 @@ fun encodeUrl(url: String): String {
return URLEncoder.encode(url, StandardCharsets.UTF_8.toString())
}

fun decodeUrl(encodedUrl: String): String {
internal fun decodeUrl(encodedUrl: String): String {
return URLDecoder.decode(encodedUrl, StandardCharsets.UTF_8.toString())
}

internal fun compareRouteStrings(
routeClass: Routes?,
currentDestination: NavDestination?,
): Boolean {
routeClass?.let {
val clazz = routeClass::class
val routeName = clazz.simpleName ?: return false

currentDestination?.route?.let { route ->
val destinationName = route.split(".")
.lastOrNull()?.split("/")?.firstOrNull() ?: return false
return routeName == destinationName
} ?: return false
} ?: return false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.smileidentity.compose.nav

import androidx.activity.compose.BackHandler
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.navigation.NavController
import androidx.navigation.NavDestination
import androidx.navigation.compose.currentBackStackEntryAsState

@Composable
fun NavigationBackHandler(
navController: NavController,
enabled: Boolean = true,
onBack: (currentDestination: NavDestination?) -> Unit,
) {
val currentBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = currentBackStackEntry?.destination
BackHandler(enabled = enabled) {
onBack(currentDestination)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ internal fun BaseSmileIDScreen(
startDestination = Routes.BaseScreens,
),
)
// val rememberResultCallbacks = remember { resultCallbacks }
val childNavHost: @Composable () -> Unit = {
localNavigationState.screensNavigation.setNavController(rememberNavController())
NavHost(
Expand Down
Loading

0 comments on commit 32abd9e

Please sign in to comment.