From 3d65653aadf66db8522d13df0489e507c4ed318c Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 7 Oct 2025 12:57:57 +0300 Subject: [PATCH 1/9] =?UTF-8?q?[MS-1170]=20MF-ID:=20Initial=20implementati?= =?UTF-8?q?on=20of=20the=20'Confirm=20Identity'=20flow=20with=20ability=20?= =?UTF-8?q?to=20add=20external=20credential=CB=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../externalcredential/ext/ResourceExt.kt | 18 ++- .../feature/externalcredential/ext/ViewExt.kt | 50 ------- .../externalcredential/model/BoundingBox.kt | 4 +- .../model/CredentialMatch.kt | 2 +- .../ExternalCredentialControllerFragment.kt | 9 +- .../controller/ExternalCredentialViewModel.kt | 15 -- .../ExternalCredentialScanOcrFragment.kt | 24 ++-- .../ExternalCredentialScanOcrViewModel.kt | 41 +++--- .../ExternalCredentialScanQrFragment.kt | 22 +-- .../ExternalCredentialScanQrViewModel.kt | 1 - .../ExternalCredentialSearchFragment.kt | 39 ++--- .../ExternalCredentialSearchViewModel.kt | 47 +++--- .../screens/search/model/ScannedCredential.kt | 11 +- .../ExternalCredentialSelectFragment.kt | 5 +- .../view/ScannedCredentialDialog.kt | 135 ++++++++++++++++++ .../res/layout/dialog_scanned_credential.xml | 95 ++++++++++++ .../main/res/layout/item_scanned_image.xml | 24 ++++ .../externalcredential/ext/ResourceExtTest.kt | 44 ++++++ .../ExternalCredentialViewModelTest.kt | 19 +-- .../search/model/ScannedCredentialTest.kt | 35 +++++ .../orchestrator/OrchestratorViewModel.kt | 16 ++- .../feature/orchestrator/steps/Step.kt | 1 + .../response/CreateEnrolResponseUseCase.kt | 13 +- .../response/CreateIdentifyResponseUseCase.kt | 87 ++++++----- .../usecases/steps/BuildStepsUseCase.kt | 27 ++-- .../orchestrator/OrchestratorViewModelTest.kt | 75 +++++++--- ...reateConfirmIdentityResponseUseCaseTest.kt | 2 +- .../CreateEnrolResponseUseCaseTest.kt | 12 +- .../CreateIdentifyResponseUseCaseTest.kt | 106 +++++++------- .../usecases/steps/BuildStepsUseCaseTest.kt | 93 ++++++++---- feature/select-subject/build.gradle.kts | 4 + .../selectsubject/SelectSubjectContract.kt | 5 +- .../selectsubject/SelectSubjectParams.kt | 2 + .../selectsubject/SelectSubjectResult.kt | 4 +- .../selectsubject/model/SelectSubjectState.kt | 23 +++ .../screen/SelectSubjectFragment.kt | 110 +++++++++++++- .../screen/SelectSubjectViewModel.kt | 106 ++++++++++++-- .../AddExternalCredentialToSubjectUseCase.kt | 27 ++++ .../main/res/drawable/rounded_image_bg.xml | 4 + .../res/layout/fragment_select_subject.xml | 96 +++++++++---- .../store/models/ProjectConfiguration.kt | 11 +- .../store/models/ProjectConfigurationTest.kt | 16 ++- .../ExternalCredentialType.kt | 4 +- .../RoomEnrolmentRecordLocalDataSource.kt | 3 +- .../RoomEnrolmentRecordLocalDataSourceTest.kt | 50 +++++-- .../resources/src/main/res/values/strings.xml | 4 + .../src/main/res/values/styles-text.xml | 9 ++ .../simprints/infra/uibase/view/View.ext.kt | 46 ++++++ 48 files changed, 1181 insertions(+), 415 deletions(-) delete mode 100644 feature/external-credential/src/main/java/com/simprints/feature/externalcredential/ext/ViewExt.kt create mode 100644 feature/external-credential/src/main/java/com/simprints/feature/externalcredential/view/ScannedCredentialDialog.kt create mode 100644 feature/external-credential/src/main/res/layout/dialog_scanned_credential.xml create mode 100644 feature/external-credential/src/main/res/layout/item_scanned_image.xml create mode 100644 feature/external-credential/src/test/java/com/simprints/feature/externalcredential/ext/ResourceExtTest.kt create mode 100644 feature/external-credential/src/test/java/com/simprints/feature/externalcredential/screens/search/model/ScannedCredentialTest.kt create mode 100644 feature/select-subject/src/main/java/com/simprints/feature/selectsubject/model/SelectSubjectState.kt create mode 100644 feature/select-subject/src/main/java/com/simprints/feature/selectsubject/usecase/AddExternalCredentialToSubjectUseCase.kt create mode 100644 feature/select-subject/src/main/res/drawable/rounded_image_bg.xml diff --git a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/ext/ResourceExt.kt b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/ext/ResourceExt.kt index acaa6ed77f..fe00b7ee70 100644 --- a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/ext/ResourceExt.kt +++ b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/ext/ResourceExt.kt @@ -4,6 +4,7 @@ import android.content.res.Resources import androidx.annotation.PluralsRes import androidx.annotation.StringRes import com.simprints.core.domain.externalcredential.ExternalCredentialType +import com.simprints.infra.resources.R as IDR fun Resources.getQuantityCredentialString( @PluralsRes id: Int, @@ -20,6 +21,21 @@ fun Resources.getQuantityCredentialString( return getQuantityString( id, credentialsAmount, - getString(documentTypeRes) + getString(documentTypeRes), ) } + +fun Resources.getCredentialFieldTitle(type: ExternalCredentialType): String = when (type) { + ExternalCredentialType.NHISCard -> IDR.string.mfid_nhis_card_credential_field + ExternalCredentialType.GhanaIdCard -> IDR.string.mfid_ghana_id_credential_field + ExternalCredentialType.QRCode -> IDR.string.mfid_qr_credential_field +}.run(::getString) + +fun Resources.getCredentialTypeString(type: ExternalCredentialType?): String = getCredentialTypeRes(type).run(::getString) + +fun Resources.getCredentialTypeRes(type: ExternalCredentialType?): Int = when (type) { + ExternalCredentialType.NHISCard -> IDR.string.mfid_type_nhis_card + ExternalCredentialType.GhanaIdCard -> IDR.string.mfid_type_ghana_id_card + ExternalCredentialType.QRCode -> IDR.string.mfid_type_qr_code + null -> IDR.string.mfid_type_any_document +} diff --git a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/ext/ViewExt.kt b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/ext/ViewExt.kt deleted file mode 100644 index a801914d63..0000000000 --- a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/ext/ViewExt.kt +++ /dev/null @@ -1,50 +0,0 @@ -package com.simprints.feature.externalcredential.ext - -import android.view.View -import android.view.ViewPropertyAnimator -import android.view.animation.AccelerateInterpolator -import android.view.animation.DecelerateInterpolator -import androidx.core.view.isVisible -import androidx.fragment.app.Fragment -import com.simprints.infra.uibase.annotations.ExcludedFromGeneratedTestCoverageReports - -@ExcludedFromGeneratedTestCoverageReports("View animation") -fun View.animateOut( - duration: Long, - scaleX: Boolean, - fragment: Fragment, -): ViewPropertyAnimator { - return animate() - .alpha(0f) - .setDuration(duration) - .setInterpolator(DecelerateInterpolator()) - .withEndAction { - if (fragment.isAdded) { - this.isVisible = false - } - }.also { - if (scaleX) { - it.scaleX(0f) - } - it.start() - } -} - -@ExcludedFromGeneratedTestCoverageReports("View animation") -fun View.animateIn( - duration: Long, - onComplete: (() -> Unit)?, - fragment: Fragment, -): ViewPropertyAnimator { - return animate() - .alpha(1f) - .setInterpolator(AccelerateInterpolator()) - .setDuration(duration) - .withEndAction { - if (fragment.isAdded) { - this.isVisible = true - onComplete?.invoke() - } - } - .also { it.start() } -} diff --git a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/model/BoundingBox.kt b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/model/BoundingBox.kt index f8ad0e13d7..d0d622dba3 100644 --- a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/model/BoundingBox.kt +++ b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/model/BoundingBox.kt @@ -16,6 +16,6 @@ data class BoundingBox( val bottom: Int, ) : Serializable -internal fun Rect.toBoundingBox(): BoundingBox = BoundingBox(left, top, right, bottom) +fun Rect.toBoundingBox(): BoundingBox = BoundingBox(left, top, right, bottom) -internal fun BoundingBox.toRect(): Rect = Rect(left, top, right, bottom) +fun BoundingBox.toRect(): Rect = Rect(left, top, right, bottom) diff --git a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/model/CredentialMatch.kt b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/model/CredentialMatch.kt index 94d40d09fe..a628729173 100644 --- a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/model/CredentialMatch.kt +++ b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/model/CredentialMatch.kt @@ -14,7 +14,7 @@ data class CredentialMatch( val matchResult: MatchResultItem, val verificationThreshold: Float, val faceBioSdk: FaceConfiguration.BioSdk?, - val fingerprintBioSdk: FingerprintConfiguration.BioSdk? + val fingerprintBioSdk: FingerprintConfiguration.BioSdk?, ) { val isVerificationSuccessful = matchResult.confidence >= verificationThreshold } diff --git a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/controller/ExternalCredentialControllerFragment.kt b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/controller/ExternalCredentialControllerFragment.kt index 744994403b..9c6f7dda13 100644 --- a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/controller/ExternalCredentialControllerFragment.kt +++ b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/controller/ExternalCredentialControllerFragment.kt @@ -33,7 +33,10 @@ internal class ExternalCredentialControllerFragment : Fragment(R.layout.fragment private val currentlyDisplayedInternalFragment: Fragment? get() = hostFragment?.childFragmentManager?.fragments?.first() - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + override fun onViewCreated( + view: View, + savedInstanceState: Bundle?, + ) { super.onViewCreated(view, savedInstanceState) viewModel.init(params) @@ -49,7 +52,7 @@ internal class ExternalCredentialControllerFragment : Fragment(R.layout.fragment } else { internalNavController?.navigateSafely( currentlyDisplayedInternalFragment, - GraphExternalCredentialInternalDirections.actionGlobalExternalCredentialSelect() + GraphExternalCredentialInternalDirections.actionGlobalExternalCredentialSelect(), ) } } @@ -66,7 +69,7 @@ internal class ExternalCredentialControllerFragment : Fragment(R.layout.fragment viewLifecycleOwner, LiveDataEventWithContentObserver { result -> findNavController().finishWithResult(this, result) - } + }, ) } diff --git a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/controller/ExternalCredentialViewModel.kt b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/controller/ExternalCredentialViewModel.kt index 7b8cd1cfa0..751dd4b5db 100644 --- a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/controller/ExternalCredentialViewModel.kt +++ b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/controller/ExternalCredentialViewModel.kt @@ -14,7 +14,6 @@ import com.simprints.infra.resources.R as IDR @HiltViewModel internal class ExternalCredentialViewModel @Inject internal constructor() : ViewModel() { - private var isInitialized = false lateinit var params: ExternalCredentialParams private set @@ -49,20 +48,6 @@ internal class ExternalCredentialViewModel @Inject internal constructor() : View } } - - fun mapTypeToStringResource(type: ExternalCredentialType?) = when (type) { - ExternalCredentialType.NHISCard -> IDR.string.mfid_type_nhis_card - ExternalCredentialType.GhanaIdCard -> IDR.string.mfid_type_ghana_id_card - ExternalCredentialType.QRCode -> IDR.string.mfid_type_qr_code - null -> IDR.string.mfid_type_any_document - } - - fun mapTypeToCredentialFieldResource(type: ExternalCredentialType) = when (type) { - ExternalCredentialType.NHISCard -> IDR.string.mfid_nhis_card_credential_field - ExternalCredentialType.GhanaIdCard -> IDR.string.mfid_ghana_id_credential_field - ExternalCredentialType.QRCode -> IDR.string.mfid_qr_credential_field - } - fun finish(result: ExternalCredentialSearchResult) { _finishEvent.send(result) } diff --git a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/ExternalCredentialScanOcrFragment.kt b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/ExternalCredentialScanOcrFragment.kt index c305b67cc8..eb438a8bcf 100644 --- a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/ExternalCredentialScanOcrFragment.kt +++ b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/ExternalCredentialScanOcrFragment.kt @@ -29,8 +29,6 @@ import com.simprints.core.tools.extentions.getCurrentPermissionStatus import com.simprints.core.tools.extentions.permissionFromResult import com.simprints.feature.externalcredential.R import com.simprints.feature.externalcredential.databinding.FragmentExternalCredentialScanOcrBinding -import com.simprints.feature.externalcredential.ext.animateIn -import com.simprints.feature.externalcredential.ext.animateOut import com.simprints.feature.externalcredential.screens.controller.ExternalCredentialViewModel import com.simprints.feature.externalcredential.screens.scanocr.model.OcrCropConfig import com.simprints.feature.externalcredential.screens.scanocr.usecase.BuildOcrCropConfigUseCase @@ -39,6 +37,8 @@ import com.simprints.feature.externalcredential.screens.search.model.ScannedCred import com.simprints.infra.logging.LoggingConstants.CrashReportTag.MULTI_FACTOR_ID import com.simprints.infra.logging.Simber import com.simprints.infra.uibase.navigation.navigateSafely +import com.simprints.infra.uibase.view.animateIn +import com.simprints.infra.uibase.view.animateOut import com.simprints.infra.uibase.view.applySystemBarInsets import com.simprints.infra.uibase.viewbinding.viewBinding import dagger.hilt.android.AndroidEntryPoint @@ -96,7 +96,10 @@ internal class ExternalCredentialScanOcrFragment : Fragment(R.layout.fragment_ex @DispatcherBG lateinit var bgDispatcher: CoroutineDispatcher - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + override fun onViewCreated( + view: View, + savedInstanceState: Bundle?, + ) { super.onViewCreated(view, savedInstanceState) applySystemBarInsets(view) Simber.i("ExternalCredentialScanOcrFragment started", tag = MULTI_FACTOR_ID) @@ -124,7 +127,6 @@ internal class ExternalCredentialScanOcrFragment : Fragment(R.layout.fragment_ex renderNoPermission(shouldOpenPhoneSettings = true) } } - } override fun onDestroy() { @@ -148,7 +150,6 @@ internal class ExternalCredentialScanOcrFragment : Fragment(R.layout.fragment_ex startOcr() } }) - } private fun initObservers() { @@ -171,7 +172,7 @@ internal class ExternalCredentialScanOcrFragment : Fragment(R.layout.fragment_ex viewLifecycleOwner, LiveDataEventWithContentObserver { scannedCredential -> scheduleFinish(scannedCredential) - } + }, ) } @@ -189,7 +190,7 @@ internal class ExternalCredentialScanOcrFragment : Fragment(R.layout.fragment_ex onImageAnalysisReady = { imageAnalysis = it onComplete() - } + }, ) cameraProviderFuture.addListener(cameraListener, ContextCompat.getMainExecutor(requireContext())) } @@ -260,7 +261,7 @@ internal class ExternalCredentialScanOcrFragment : Fragment(R.layout.fragment_ex "package:${requireActivity().packageName}".toUri(), ), ) - } + }, ) } else { permissionRequestView.init( @@ -269,7 +270,7 @@ internal class ExternalCredentialScanOcrFragment : Fragment(R.layout.fragment_ex buttonText = IDR.string.face_capture_permission_action, onClickListener = { launchPermissionRequest.launch(CAMERA) - } + }, ) } permissionRequestView.isVisible = true @@ -289,7 +290,7 @@ internal class ExternalCredentialScanOcrFragment : Fragment(R.layout.fragment_ex val cropConfig: OcrCropConfig = buildOcrCropConfigUseCase( rotationDegrees = imageInfo.rotationDegrees, cameraPreview = binding.preview, - documentScannerArea = binding.documentScannerArea + documentScannerArea = binding.documentScannerArea, ) viewModel.runOcrOnFrame(frame = bitmap, cropConfig) } finally { @@ -323,7 +324,7 @@ internal class ExternalCredentialScanOcrFragment : Fragment(R.layout.fragment_ex val navigationAction = { findNavController().navigateSafely( this@ExternalCredentialScanOcrFragment, - ExternalCredentialScanOcrFragmentDirections.actionExternalCredentialScanOcrToExternalCredentialSearch(credential) + ExternalCredentialScanOcrFragmentDirections.actionExternalCredentialScanOcrToExternalCredentialSearch(credential), ) } if (isAnimatingCompletion) { @@ -332,5 +333,4 @@ internal class ExternalCredentialScanOcrFragment : Fragment(R.layout.fragment_ex navigationAction.invoke() } } - } diff --git a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/ExternalCredentialScanOcrViewModel.kt b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/ExternalCredentialScanOcrViewModel.kt index 475eb3450e..7993ff0492 100644 --- a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/ExternalCredentialScanOcrViewModel.kt +++ b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/ExternalCredentialScanOcrViewModel.kt @@ -46,7 +46,7 @@ internal class ExternalCredentialScanOcrViewModel @AssistedInject constructor( private val tokenizationProcessor: TokenizationProcessor, private val authStore: AuthStore, private val configManager: ConfigManager, - @DispatcherBG private val bgDispatcher: CoroutineDispatcher + @DispatcherBG private val bgDispatcher: CoroutineDispatcher, ) : ViewModel() { @AssistedFactory interface Factory { @@ -83,12 +83,15 @@ internal class ExternalCredentialScanOcrViewModel @AssistedInject constructor( ScanOcrState.ScanningInProgress( ocrDocumentType = ocrDocumentType, successfulCaptures = 0, - scansRequired = SUCCESSFUL_SCANS_REQUIRED + scansRequired = SUCCESSFUL_SCANS_REQUIRED, ) } } - fun runOcrOnFrame(frame: Bitmap, cropConfig: OcrCropConfig) { + fun runOcrOnFrame( + frame: Bitmap, + cropConfig: OcrCropConfig, + ) { viewModelScope.launch(bgDispatcher) { try { Simber.d("started OCR") @@ -101,7 +104,7 @@ internal class ExternalCredentialScanOcrViewModel @AssistedInject constructor( ScanOcrState.ScanningInProgress( ocrDocumentType = ocrDocumentType, successfulCaptures = detectedBlocks.size, - scansRequired = SUCCESSFUL_SCANS_REQUIRED + scansRequired = SUCCESSFUL_SCANS_REQUIRED, ) } } finally { @@ -128,28 +131,26 @@ internal class ExternalCredentialScanOcrViewModel @AssistedInject constructor( credentialType = credentialType, documentImagePath = detectedBlock.imagePath, zoomedCredentialImagePath = zoomedCredentialImagePath, - credentialBoundingBox = blockBoundingBox + credentialBoundingBox = blockBoundingBox, ) _finishOcrEvent.send(scannedCredential) detectedBlocks = emptyList() } } - private fun buildZoomedImagePath(detectedBlock: DetectedOcrBlock): String? { - return try { - saveScannedImageUseCase( - bitmap = zoomOntoCredentialUseCase(detectedBlock.imagePath, detectedBlock.blockBoundingBox), - documentType = detectedBlock.documentType, - imageType = ZoomedInCredential - ) - } catch (e: Exception) { - Simber.e( - "Unable to zoom into bounding box [${detectedBlock.blockBoundingBox}] of ${detectedBlock.documentType} image ${detectedBlock.imagePath}", - e, - MULTI_FACTOR_ID - ) - null - } + private fun buildZoomedImagePath(detectedBlock: DetectedOcrBlock): String? = try { + saveScannedImageUseCase( + bitmap = zoomOntoCredentialUseCase(detectedBlock.imagePath, detectedBlock.blockBoundingBox), + documentType = detectedBlock.documentType, + imageType = ZoomedInCredential, + ) + } catch (e: Exception) { + Simber.e( + "Unable to zoom into bounding box [${detectedBlock.blockBoundingBox}] of ${detectedBlock.documentType} image ${detectedBlock.imagePath}", + e, + MULTI_FACTOR_ID, + ) + null } fun ocrOnFrameStarted() { diff --git a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanqr/ExternalCredentialScanQrFragment.kt b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanqr/ExternalCredentialScanQrFragment.kt index 818b5d66b3..2f02b6e221 100644 --- a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanqr/ExternalCredentialScanQrFragment.kt +++ b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanqr/ExternalCredentialScanQrFragment.kt @@ -48,7 +48,6 @@ import com.simprints.infra.resources.R as IDR @AndroidEntryPoint internal class ExternalCredentialScanQrFragment : Fragment(R.layout.fragment_external_credential_scan_qr) { - private val binding by viewBinding(FragmentExternalCredentialScanQrBinding::bind) private val crashReportTag = MULTI_FACTOR_ID private val mainViewModel: ExternalCredentialViewModel by activityViewModels() @@ -74,12 +73,14 @@ internal class ExternalCredentialScanQrFragment : Fragment(R.layout.fragment_ext viewModel.updateCameraPermissionStatus(cameraPermissionStatus) } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + override fun onViewCreated( + view: View, + savedInstanceState: Bundle?, + ) { super.onViewCreated(view, savedInstanceState) applySystemBarInsets(view) Simber.i("ExternalCredentialScanQrFragment started", tag = MULTI_FACTOR_ID) - initObservers() if (!requireActivity().hasPermission(CAMERA)) { @@ -146,7 +147,7 @@ internal class ExternalCredentialScanQrFragment : Fragment(R.layout.fragment_ext ) findNavController().navigateSafely( this@ExternalCredentialScanQrFragment, - ExternalCredentialScanQrFragmentDirections.actionExternalCredentialSelectScanQrToExternalCredentialSearch(args) + ExternalCredentialScanQrFragmentDirections.actionExternalCredentialSelectScanQrToExternalCredentialSearch(args), ) } else { showInvalidQrCodeFormatDialog( @@ -154,7 +155,7 @@ internal class ExternalCredentialScanQrFragment : Fragment(R.layout.fragment_ext onDismiss = { dismissDialog() viewModel.updateCapturedValue(null) - } + }, ) } } @@ -166,7 +167,8 @@ internal class ExternalCredentialScanQrFragment : Fragment(R.layout.fragment_ext ) { dismissDialog() dialog = BottomSheetDialog(requireContext()).also { - val view = layoutInflater.inflate(R.layout.dialog_qr_wrong_value, null) + val view = layoutInflater + .inflate(R.layout.dialog_qr_wrong_value, null) .also { view -> val qrValueTextView = view.findViewById(R.id.qrValue) val buttonRescan = view.findViewById