@smileid/usesmileid 12.0.0-beta01 → 12.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +701 -89
- package/dist/camera/camera_defaults.d.ts +14 -9
- package/dist/camera/camera_defaults.d.ts.map +1 -1
- package/dist/camera/camera_defaults.js +11 -9
- package/dist/camera/camera_defaults.js.map +1 -1
- package/dist/camera/orientation_degrees.d.ts +5 -6
- package/dist/camera/orientation_degrees.d.ts.map +1 -1
- package/dist/camera/orientation_degrees.js +5 -6
- package/dist/camera/orientation_degrees.js.map +1 -1
- package/dist/core/exception/agent_mode_with_enhanced_liveness_exception.d.ts +11 -0
- package/dist/core/exception/agent_mode_with_enhanced_liveness_exception.d.ts.map +1 -0
- package/dist/core/exception/agent_mode_with_enhanced_liveness_exception.js +17 -0
- package/dist/core/exception/agent_mode_with_enhanced_liveness_exception.js.map +1 -0
- package/dist/core/exception/capture_validation_exceptions.d.ts +1 -0
- package/dist/core/exception/capture_validation_exceptions.d.ts.map +1 -1
- package/dist/core/exception/capture_validation_exceptions.js +1 -0
- package/dist/core/exception/capture_validation_exceptions.js.map +1 -1
- package/dist/core/exception/index.d.ts +1 -0
- package/dist/core/exception/index.d.ts.map +1 -1
- package/dist/core/exception/index.js +1 -0
- package/dist/core/exception/index.js.map +1 -1
- package/dist/core/exception/use_smile_id_error_code.d.ts +1 -0
- package/dist/core/exception/use_smile_id_error_code.d.ts.map +1 -1
- package/dist/core/exception/use_smile_id_error_code.js +1 -0
- package/dist/core/exception/use_smile_id_error_code.js.map +1 -1
- package/dist/core/models/config.d.ts +19 -0
- package/dist/core/models/config.d.ts.map +1 -1
- package/dist/core/models/document_capture_mode.d.ts +8 -0
- package/dist/core/models/document_capture_mode.d.ts.map +1 -1
- package/dist/core/models/document_capture_mode.js +24 -0
- package/dist/core/models/document_capture_mode.js.map +1 -1
- package/dist/core/models/document_type.d.ts +2 -2
- package/dist/core/models/document_type.d.ts.map +1 -1
- package/dist/core/models/document_type.js +7 -5
- package/dist/core/models/document_type.js.map +1 -1
- package/dist/core/models/global_privacy_control.d.ts +36 -0
- package/dist/core/models/global_privacy_control.d.ts.map +1 -0
- package/dist/core/models/global_privacy_control.js +39 -0
- package/dist/core/models/global_privacy_control.js.map +1 -0
- package/dist/core/models/network_config.d.ts +2 -2
- package/dist/core/models/network_config.js +2 -2
- package/dist/core/models/result.d.ts +9 -8
- package/dist/core/models/result.d.ts.map +1 -1
- package/dist/core/models/result.js +5 -6
- package/dist/core/models/result.js.map +1 -1
- package/dist/data/api/interceptors/smile_auth_interceptor.d.ts.map +1 -1
- package/dist/data/api/interceptors/smile_auth_interceptor.js +3 -17
- package/dist/data/api/interceptors/smile_auth_interceptor.js.map +1 -1
- package/dist/data/api/interceptors/smile_integrity_interceptor.d.ts +11 -0
- package/dist/data/api/interceptors/smile_integrity_interceptor.d.ts.map +1 -1
- package/dist/data/api/interceptors/smile_integrity_interceptor.js +13 -0
- package/dist/data/api/interceptors/smile_integrity_interceptor.js.map +1 -1
- package/dist/data/api/interceptors/smile_request_mac_interceptor.d.ts +8 -0
- package/dist/data/api/interceptors/smile_request_mac_interceptor.d.ts.map +1 -1
- package/dist/data/api/interceptors/smile_request_mac_interceptor.js +11 -0
- package/dist/data/api/interceptors/smile_request_mac_interceptor.js.map +1 -1
- package/dist/data/api/smile_id_api.d.ts +1 -1
- package/dist/data/api/smile_id_api.d.ts.map +1 -1
- package/dist/data/compression/compressible_asset.d.ts +41 -0
- package/dist/data/compression/compressible_asset.d.ts.map +1 -0
- package/dist/data/compression/compressible_asset.js +34 -0
- package/dist/data/compression/compressible_asset.js.map +1 -0
- package/dist/data/compression/payload_compression_config.d.ts +36 -0
- package/dist/data/compression/payload_compression_config.d.ts.map +1 -0
- package/dist/data/compression/payload_compression_config.js +52 -0
- package/dist/data/compression/payload_compression_config.js.map +1 -0
- package/dist/data/compression/payload_compression_runner.d.ts +29 -0
- package/dist/data/compression/payload_compression_runner.d.ts.map +1 -0
- package/dist/data/compression/payload_compression_runner.js +55 -0
- package/dist/data/compression/payload_compression_runner.js.map +1 -0
- package/dist/data/compression/payload_compressor.d.ts +40 -0
- package/dist/data/compression/payload_compressor.d.ts.map +1 -0
- package/dist/data/compression/payload_compressor.js +126 -0
- package/dist/data/compression/payload_compressor.js.map +1 -0
- package/dist/data/compression/uri_compressible_asset.d.ts +23 -0
- package/dist/data/compression/uri_compressible_asset.d.ts.map +1 -0
- package/dist/data/compression/uri_compressible_asset.js +77 -0
- package/dist/data/compression/uri_compressible_asset.js.map +1 -0
- package/dist/data/dsl/builder/cache_config_builder.d.ts +2 -1
- package/dist/data/dsl/builder/cache_config_builder.d.ts.map +1 -1
- package/dist/data/dsl/builder/cache_config_builder.js +2 -1
- package/dist/data/dsl/builder/cache_config_builder.js.map +1 -1
- package/dist/data/dsl/builder/config_builder.d.ts +40 -14
- package/dist/data/dsl/builder/config_builder.d.ts.map +1 -1
- package/dist/data/dsl/builder/config_builder.js +40 -14
- package/dist/data/dsl/builder/config_builder.js.map +1 -1
- package/dist/data/dsl/builder/interceptor_config_builder.d.ts +9 -7
- package/dist/data/dsl/builder/interceptor_config_builder.d.ts.map +1 -1
- package/dist/data/dsl/builder/interceptor_config_builder.js +9 -7
- package/dist/data/dsl/builder/interceptor_config_builder.js.map +1 -1
- package/dist/data/dsl/builder/retry_config_builder.d.ts +19 -4
- package/dist/data/dsl/builder/retry_config_builder.d.ts.map +1 -1
- package/dist/data/dsl/builder/retry_config_builder.js +21 -6
- package/dist/data/dsl/builder/retry_config_builder.js.map +1 -1
- package/dist/data/dsl/builder/timeout_config_builder.d.ts +4 -0
- package/dist/data/dsl/builder/timeout_config_builder.d.ts.map +1 -1
- package/dist/data/dsl/builder/timeout_config_builder.js +4 -0
- package/dist/data/dsl/builder/timeout_config_builder.js.map +1 -1
- package/dist/data/dsl/use_smile_id_network_builder.d.ts +17 -0
- package/dist/data/dsl/use_smile_id_network_builder.d.ts.map +1 -1
- package/dist/data/dsl/use_smile_id_network_builder.js +17 -0
- package/dist/data/dsl/use_smile_id_network_builder.js.map +1 -1
- package/dist/data/factory/networking_factory.d.ts.map +1 -1
- package/dist/data/factory/networking_factory.js +11 -1
- package/dist/data/factory/networking_factory.js.map +1 -1
- package/dist/data/repository/use_smile_id_repository_impl.d.ts +6 -0
- package/dist/data/repository/use_smile_id_repository_impl.d.ts.map +1 -1
- package/dist/data/repository/use_smile_id_repository_impl.js +82 -8
- package/dist/data/repository/use_smile_id_repository_impl.js.map +1 -1
- package/dist/data/security/request_canonicalizer.d.ts.map +1 -1
- package/dist/data/security/request_canonicalizer.js +14 -2
- package/dist/data/security/request_canonicalizer.js.map +1 -1
- package/dist/data/security/security_policy.d.ts +43 -0
- package/dist/data/security/security_policy.d.ts.map +1 -0
- package/dist/data/security/security_policy.js +61 -0
- package/dist/data/security/security_policy.js.map +1 -0
- package/dist/data/smile_id_urls.d.ts +1 -1
- package/dist/data/smile_id_urls.js +1 -1
- package/dist/data/smile_id_urls.js.map +1 -1
- package/dist/data/util/retry_util.d.ts +2 -2
- package/dist/data/util/retry_util.d.ts.map +1 -1
- package/dist/data/util/retry_util.js +7 -1
- package/dist/data/util/retry_util.js.map +1 -1
- package/dist/data/util/use_smile_id_token_decoder.d.ts +22 -0
- package/dist/data/util/use_smile_id_token_decoder.d.ts.map +1 -1
- package/dist/data/util/use_smile_id_token_decoder.js +58 -24
- package/dist/data/util/use_smile_id_token_decoder.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/l10n/strings_en.d.ts +2 -1
- package/dist/l10n/strings_en.d.ts.map +1 -1
- package/dist/l10n/strings_en.js +2 -1
- package/dist/l10n/strings_en.js.map +1 -1
- package/dist/l10n/use_smile_id_localizations.d.ts +1 -0
- package/dist/l10n/use_smile_id_localizations.d.ts.map +1 -1
- package/dist/l10n/use_smile_id_localizations.js +3 -0
- package/dist/l10n/use_smile_id_localizations.js.map +1 -1
- package/dist/metadata/builder_configuration.d.ts +44 -0
- package/dist/metadata/builder_configuration.d.ts.map +1 -0
- package/dist/metadata/builder_configuration.js +35 -0
- package/dist/metadata/builder_configuration.js.map +1 -0
- package/dist/metadata/captured_image_properties.d.ts +11 -0
- package/dist/metadata/captured_image_properties.d.ts.map +1 -0
- package/dist/metadata/captured_image_properties.js +11 -0
- package/dist/metadata/captured_image_properties.js.map +1 -0
- package/dist/metadata/device_orientation_collector.d.ts +17 -0
- package/dist/metadata/device_orientation_collector.d.ts.map +1 -0
- package/dist/metadata/device_orientation_collector.js +66 -0
- package/dist/metadata/device_orientation_collector.js.map +1 -0
- package/dist/metadata/geolocation.d.ts +20 -0
- package/dist/metadata/geolocation.d.ts.map +1 -0
- package/dist/metadata/geolocation.js +40 -0
- package/dist/metadata/geolocation.js.map +1 -0
- package/dist/metadata/metadata_configuration_mappers.d.ts +47 -0
- package/dist/metadata/metadata_configuration_mappers.d.ts.map +1 -0
- package/dist/metadata/metadata_configuration_mappers.js +178 -0
- package/dist/metadata/metadata_configuration_mappers.js.map +1 -0
- package/dist/metadata/model_configuration.d.ts +41 -0
- package/dist/metadata/model_configuration.d.ts.map +1 -0
- package/dist/metadata/model_configuration.js +44 -0
- package/dist/metadata/model_configuration.js.map +1 -0
- package/dist/metadata/optional_native_modules.d.ts +79 -3
- package/dist/metadata/optional_native_modules.d.ts.map +1 -1
- package/dist/metadata/optional_native_modules.js +108 -3
- package/dist/metadata/optional_native_modules.js.map +1 -1
- package/dist/metadata/use_smile_id_metadata.d.ts +45 -7
- package/dist/metadata/use_smile_id_metadata.d.ts.map +1 -1
- package/dist/metadata/use_smile_id_metadata.js +85 -13
- package/dist/metadata/use_smile_id_metadata.js.map +1 -1
- package/dist/metadata/use_smile_id_metadata_factory.d.ts +37 -0
- package/dist/metadata/use_smile_id_metadata_factory.d.ts.map +1 -1
- package/dist/metadata/use_smile_id_metadata_factory.js +197 -16
- package/dist/metadata/use_smile_id_metadata_factory.js.map +1 -1
- package/dist/presentation/assets/svg/document_shimmer_strings.d.ts +14 -0
- package/dist/presentation/assets/svg/document_shimmer_strings.d.ts.map +1 -0
- package/dist/presentation/assets/svg/document_shimmer_strings.js +14 -0
- package/dist/presentation/assets/svg/document_shimmer_strings.js.map +1 -0
- package/dist/presentation/assets/svg/instruction_svg_strings.d.ts +12 -4
- package/dist/presentation/assets/svg/instruction_svg_strings.d.ts.map +1 -1
- package/dist/presentation/assets/svg/instruction_svg_strings.js +19 -8
- package/dist/presentation/assets/svg/instruction_svg_strings.js.map +1 -1
- package/dist/presentation/components/helpers/enhanced_smart_selfie_animation_frames.d.ts +0 -5
- package/dist/presentation/components/helpers/enhanced_smart_selfie_animation_frames.d.ts.map +1 -1
- package/dist/presentation/components/helpers/enhanced_smart_selfie_animation_frames.js +0 -5
- package/dist/presentation/components/helpers/enhanced_smart_selfie_animation_frames.js.map +1 -1
- package/dist/presentation/components/icons/index.d.ts +24 -8
- package/dist/presentation/components/icons/index.d.ts.map +1 -1
- package/dist/presentation/components/icons/index.js +31 -11
- package/dist/presentation/components/icons/index.js.map +1 -1
- package/dist/presentation/components/use_smile_id_attribution.d.ts +1 -1
- package/dist/presentation/components/use_smile_id_button.d.ts +2 -2
- package/dist/presentation/components/use_smile_id_button.js +4 -4
- package/dist/presentation/components/use_smile_id_button.js.map +1 -1
- package/dist/presentation/components/use_smile_id_capture_content.d.ts +13 -0
- package/dist/presentation/components/use_smile_id_capture_content.d.ts.map +1 -1
- package/dist/presentation/components/use_smile_id_capture_content.js +15 -9
- package/dist/presentation/components/use_smile_id_capture_content.js.map +1 -1
- package/dist/presentation/components/use_smile_id_captured_document_image.d.ts +2 -3
- package/dist/presentation/components/use_smile_id_captured_document_image.d.ts.map +1 -1
- package/dist/presentation/components/use_smile_id_captured_document_image.js +1 -3
- package/dist/presentation/components/use_smile_id_captured_document_image.js.map +1 -1
- package/dist/presentation/components/use_smile_id_document_capture_controls.d.ts +12 -6
- package/dist/presentation/components/use_smile_id_document_capture_controls.d.ts.map +1 -1
- package/dist/presentation/components/use_smile_id_document_capture_controls.js +59 -16
- package/dist/presentation/components/use_smile_id_document_capture_controls.js.map +1 -1
- package/dist/presentation/components/use_smile_id_document_overlay.d.ts +22 -5
- package/dist/presentation/components/use_smile_id_document_overlay.d.ts.map +1 -1
- package/dist/presentation/components/use_smile_id_document_overlay.js +80 -40
- package/dist/presentation/components/use_smile_id_document_overlay.js.map +1 -1
- package/dist/presentation/components/use_smile_id_document_shimmer.d.ts +15 -0
- package/dist/presentation/components/use_smile_id_document_shimmer.d.ts.map +1 -0
- package/dist/presentation/components/use_smile_id_document_shimmer.js +23 -0
- package/dist/presentation/components/use_smile_id_document_shimmer.js.map +1 -0
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_clip.d.ts +5 -2
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_clip.d.ts.map +1 -1
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_clip.js +9 -6
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_clip.js.map +1 -1
- package/dist/presentation/components/use_smile_id_guideline_thumbnail.d.ts.map +1 -1
- package/dist/presentation/components/use_smile_id_guideline_thumbnail.js +84 -1
- package/dist/presentation/components/use_smile_id_guideline_thumbnail.js.map +1 -1
- package/dist/presentation/components/use_smile_id_instructions_hero.d.ts +3 -1
- package/dist/presentation/components/use_smile_id_instructions_hero.d.ts.map +1 -1
- package/dist/presentation/components/use_smile_id_instructions_hero.js +25 -5
- package/dist/presentation/components/use_smile_id_instructions_hero.js.map +1 -1
- package/dist/presentation/components/use_smile_id_oval_border_palette.d.ts.map +1 -1
- package/dist/presentation/components/use_smile_id_oval_border_palette.js +7 -3
- package/dist/presentation/components/use_smile_id_oval_border_palette.js.map +1 -1
- package/dist/presentation/flow/dsl/builder/config_builder.d.ts +28 -0
- package/dist/presentation/flow/dsl/builder/config_builder.d.ts.map +1 -1
- package/dist/presentation/flow/dsl/builder/config_builder.js +30 -0
- package/dist/presentation/flow/dsl/builder/config_builder.js.map +1 -1
- package/dist/presentation/flow/dsl/builder/ml_builder.d.ts +13 -4
- package/dist/presentation/flow/dsl/builder/ml_builder.d.ts.map +1 -1
- package/dist/presentation/flow/dsl/builder/ml_builder.js +3 -2
- package/dist/presentation/flow/dsl/builder/ml_builder.js.map +1 -1
- package/dist/presentation/flow/dsl/builder/screens_builder.d.ts +110 -12
- package/dist/presentation/flow/dsl/builder/screens_builder.d.ts.map +1 -1
- package/dist/presentation/flow/dsl/builder/screens_builder.js +110 -12
- package/dist/presentation/flow/dsl/builder/screens_builder.js.map +1 -1
- package/dist/presentation/flow/dsl/builder/theme_builder.d.ts +15 -2
- package/dist/presentation/flow/dsl/builder/theme_builder.d.ts.map +1 -1
- package/dist/presentation/flow/dsl/builder/theme_builder.js +15 -2
- package/dist/presentation/flow/dsl/builder/theme_builder.js.map +1 -1
- package/dist/presentation/flow/dsl/use_smile_id_builder.d.ts +6 -4
- package/dist/presentation/flow/dsl/use_smile_id_builder.d.ts.map +1 -1
- package/dist/presentation/flow/dsl/use_smile_id_builder.js.map +1 -1
- package/dist/presentation/flow/dsl/use_smile_id_flow_builder.d.ts +62 -36
- package/dist/presentation/flow/dsl/use_smile_id_flow_builder.d.ts.map +1 -1
- package/dist/presentation/flow/dsl/use_smile_id_flow_builder.js +62 -36
- package/dist/presentation/flow/dsl/use_smile_id_flow_builder.js.map +1 -1
- package/dist/presentation/flow/flow_navigation_manager.d.ts +44 -5
- package/dist/presentation/flow/flow_navigation_manager.d.ts.map +1 -1
- package/dist/presentation/flow/flow_navigation_manager.js +148 -11
- package/dist/presentation/flow/flow_navigation_manager.js.map +1 -1
- package/dist/presentation/flow/model/instruction_guideline.d.ts +9 -0
- package/dist/presentation/flow/model/instruction_guideline.d.ts.map +1 -1
- package/dist/presentation/flow/model/instructions_defaults.d.ts +11 -2
- package/dist/presentation/flow/model/instructions_defaults.d.ts.map +1 -1
- package/dist/presentation/flow/model/instructions_defaults.js +74 -26
- package/dist/presentation/flow/model/instructions_defaults.js.map +1 -1
- package/dist/presentation/flow/screen/orchestrated_capture_screen.d.ts.map +1 -1
- package/dist/presentation/flow/screen/orchestrated_capture_screen.js +48 -14
- package/dist/presentation/flow/screen/orchestrated_capture_screen.js.map +1 -1
- package/dist/presentation/flow/screen/orchestrated_consent_screen.d.ts.map +1 -1
- package/dist/presentation/flow/screen/orchestrated_consent_screen.js +3 -1
- package/dist/presentation/flow/screen/orchestrated_consent_screen.js.map +1 -1
- package/dist/presentation/flow/screen/orchestrated_instructions_screen.js +1 -1
- package/dist/presentation/flow/screen/orchestrated_instructions_screen.js.map +1 -1
- package/dist/presentation/flow/screen/orchestrated_preview_screen.d.ts.map +1 -1
- package/dist/presentation/flow/screen/orchestrated_preview_screen.js +3 -9
- package/dist/presentation/flow/screen/orchestrated_preview_screen.js.map +1 -1
- package/dist/presentation/flow/screen/orchestrated_processing_screen.js +3 -3
- package/dist/presentation/flow/screen/orchestrated_processing_screen.js.map +1 -1
- package/dist/presentation/flow/use_smile_id_flow.d.ts.map +1 -1
- package/dist/presentation/flow/use_smile_id_flow.js +10 -4
- package/dist/presentation/flow/use_smile_id_flow.js.map +1 -1
- package/dist/presentation/flow/validation/flow_validator.d.ts.map +1 -1
- package/dist/presentation/flow/validation/flow_validator.js +42 -20
- package/dist/presentation/flow/validation/flow_validator.js.map +1 -1
- package/dist/presentation/flow/validation/job_type_validator.d.ts.map +1 -1
- package/dist/presentation/flow/validation/job_type_validator.js +14 -0
- package/dist/presentation/flow/validation/job_type_validator.js.map +1 -1
- package/dist/presentation/screen/helpers/capture_screen_helpers.d.ts.map +1 -1
- package/dist/presentation/screen/helpers/capture_screen_helpers.js +1 -0
- package/dist/presentation/screen/helpers/capture_screen_helpers.js.map +1 -1
- package/dist/presentation/screen/helpers/capture_ui_state.d.ts +6 -6
- package/dist/presentation/screen/helpers/capture_ui_state.d.ts.map +1 -1
- package/dist/presentation/screen/helpers/capture_ui_state.js +19 -19
- package/dist/presentation/screen/helpers/capture_ui_state.js.map +1 -1
- package/dist/presentation/screen/helpers/ess_turn_haptics.d.ts +2 -2
- package/dist/presentation/screen/helpers/ess_turn_haptics.d.ts.map +1 -1
- package/dist/presentation/screen/helpers/ess_turn_haptics.js +6 -6
- package/dist/presentation/screen/helpers/ess_turn_haptics.js.map +1 -1
- package/dist/presentation/screen/helpers/instructions_screen_helpers.d.ts +1 -0
- package/dist/presentation/screen/helpers/instructions_screen_helpers.d.ts.map +1 -1
- package/dist/presentation/screen/helpers/instructions_screen_helpers.js +6 -2
- package/dist/presentation/screen/helpers/instructions_screen_helpers.js.map +1 -1
- package/dist/presentation/screen/helpers/scan_state_to_overlay_state.d.ts +5 -5
- package/dist/presentation/screen/helpers/scan_state_to_overlay_state.d.ts.map +1 -1
- package/dist/presentation/screen/helpers/scan_state_to_overlay_state.js +14 -11
- package/dist/presentation/screen/helpers/scan_state_to_overlay_state.js.map +1 -1
- package/dist/presentation/screen/helpers/use_capture_orientation_lock.d.ts +13 -3
- package/dist/presentation/screen/helpers/use_capture_orientation_lock.d.ts.map +1 -1
- package/dist/presentation/screen/helpers/use_capture_orientation_lock.js +48 -6
- package/dist/presentation/screen/helpers/use_capture_orientation_lock.js.map +1 -1
- package/dist/presentation/screen/use_smile_id_capture_screen.d.ts +21 -3
- package/dist/presentation/screen/use_smile_id_capture_screen.d.ts.map +1 -1
- package/dist/presentation/screen/use_smile_id_capture_screen.js +188 -32
- package/dist/presentation/screen/use_smile_id_capture_screen.js.map +1 -1
- package/dist/presentation/screen/use_smile_id_consent_screen.d.ts +7 -0
- package/dist/presentation/screen/use_smile_id_consent_screen.d.ts.map +1 -1
- package/dist/presentation/screen/use_smile_id_consent_screen.js +6 -5
- package/dist/presentation/screen/use_smile_id_consent_screen.js.map +1 -1
- package/dist/presentation/screen/use_smile_id_document_back_instructions.d.ts.map +1 -1
- package/dist/presentation/screen/use_smile_id_document_back_instructions.js +5 -13
- package/dist/presentation/screen/use_smile_id_document_back_instructions.js.map +1 -1
- package/dist/presentation/screen/use_smile_id_document_preview_screen.d.ts +2 -3
- package/dist/presentation/screen/use_smile_id_document_preview_screen.d.ts.map +1 -1
- package/dist/presentation/screen/use_smile_id_document_preview_screen.js +17 -12
- package/dist/presentation/screen/use_smile_id_document_preview_screen.js.map +1 -1
- package/dist/presentation/screen/use_smile_id_instructions_screen.d.ts +2 -0
- package/dist/presentation/screen/use_smile_id_instructions_screen.d.ts.map +1 -1
- package/dist/presentation/screen/use_smile_id_instructions_screen.js +2 -1
- package/dist/presentation/screen/use_smile_id_instructions_screen.js.map +1 -1
- package/dist/presentation/screen/use_smile_id_preview_screen.d.ts +7 -26
- package/dist/presentation/screen/use_smile_id_preview_screen.d.ts.map +1 -1
- package/dist/presentation/screen/use_smile_id_preview_screen.js +10 -20
- package/dist/presentation/screen/use_smile_id_preview_screen.js.map +1 -1
- package/dist/presentation/screen/use_smile_id_processing_screen.d.ts +2 -3
- package/dist/presentation/screen/use_smile_id_processing_screen.d.ts.map +1 -1
- package/dist/presentation/screen/use_smile_id_processing_screen.js +4 -3
- package/dist/presentation/screen/use_smile_id_processing_screen.js.map +1 -1
- package/dist/presentation/theme/theme.d.ts +1 -1
- package/dist/presentation/theme/theme.d.ts.map +1 -1
- package/dist/presentation/theme/theme.js +20 -18
- package/dist/presentation/theme/theme.js.map +1 -1
- package/dist/presentation/utils/force_max_brightness.d.ts +4 -4
- package/dist/presentation/utils/locale_utils.d.ts +10 -4
- package/dist/presentation/utils/locale_utils.d.ts.map +1 -1
- package/dist/presentation/utils/locale_utils.js +13 -5
- package/dist/presentation/utils/locale_utils.js.map +1 -1
- package/dist/testing/fake_face_analyzer.d.ts +43 -0
- package/dist/testing/fake_face_analyzer.d.ts.map +1 -0
- package/dist/testing/fake_face_analyzer.js +52 -0
- package/dist/testing/fake_face_analyzer.js.map +1 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +7 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/scenario_expectations.d.ts +28 -0
- package/dist/testing/scenario_expectations.d.ts.map +1 -0
- package/dist/testing/scenario_expectations.js +65 -0
- package/dist/testing/scenario_expectations.js.map +1 -0
- package/dist/testing/scenario_loader.d.ts +11 -0
- package/dist/testing/scenario_loader.d.ts.map +1 -0
- package/dist/testing/scenario_loader.js +64 -0
- package/dist/testing/scenario_loader.js.map +1 -0
- package/dist/testing/scripted_scan_results.d.ts +17 -0
- package/dist/testing/scripted_scan_results.d.ts.map +1 -0
- package/dist/testing/scripted_scan_results.js +52 -0
- package/dist/testing/scripted_scan_results.js.map +1 -0
- package/package.json +34 -7
- package/src/__tests__/dsl.test.ts +51 -1
- package/src/__tests__/react_native_mock.tsx +8 -0
- package/src/__tests__/setup_react_native.ts +17 -2
- package/src/__tests__/snapshots/__snapshots__/screens_structural.test.tsx.snap +5261 -0
- package/src/__tests__/snapshots/screens_structural.test.tsx +230 -0
- package/src/camera/__tests__/use_smile_id_camera_system.test.ts +103 -0
- package/src/camera/camera_defaults.ts +11 -9
- package/src/camera/orientation_degrees.ts +5 -6
- package/src/core/exception/__tests__/builder_validation_exceptions.test.ts +67 -0
- package/src/core/exception/agent_mode_with_enhanced_liveness_exception.ts +20 -0
- package/src/core/exception/capture_validation_exceptions.ts +1 -0
- package/src/core/exception/index.ts +1 -0
- package/src/core/exception/use_smile_id_error_code.ts +1 -0
- package/src/core/models/__tests__/document_type.test.ts +7 -5
- package/src/core/models/__tests__/flow_models.test.ts +26 -0
- package/src/core/models/config.ts +22 -0
- package/src/core/models/document_capture_mode.ts +27 -0
- package/src/core/models/document_type.ts +7 -5
- package/src/core/models/global_privacy_control.ts +45 -0
- package/src/core/models/network_config.ts +2 -2
- package/src/core/models/result.ts +9 -8
- package/src/data/api/__tests__/smile_id_api.test.ts +1 -1
- package/src/data/api/interceptors/__tests__/gzip_interceptor.test.ts +83 -0
- package/src/data/api/interceptors/__tests__/smile_integrity_interceptor.test.ts +37 -1
- package/src/data/api/interceptors/__tests__/smile_request_mac_interceptor.test.ts +59 -1
- package/src/data/api/interceptors/smile_auth_interceptor.ts +3 -18
- package/src/data/api/interceptors/smile_integrity_interceptor.ts +20 -0
- package/src/data/api/interceptors/smile_request_mac_interceptor.ts +13 -0
- package/src/data/compression/__tests__/payload_compressor.test.ts +200 -0
- package/src/data/compression/__tests__/payload_compressor_real_jpeg.test.ts +226 -0
- package/src/data/compression/compressible_asset.ts +62 -0
- package/src/data/compression/payload_compression_config.ts +53 -0
- package/src/data/compression/payload_compression_runner.ts +102 -0
- package/src/data/compression/payload_compressor.ts +164 -0
- package/src/data/compression/uri_compressible_asset.ts +85 -0
- package/src/data/dsl/builder/__tests__/config_builders.test.ts +62 -0
- package/src/data/dsl/builder/cache_config_builder.ts +3 -1
- package/src/data/dsl/builder/config_builder.ts +45 -14
- package/src/data/dsl/builder/interceptor_config_builder.ts +9 -7
- package/src/data/dsl/builder/retry_config_builder.ts +27 -6
- package/src/data/dsl/builder/timeout_config_builder.ts +7 -0
- package/src/data/dsl/use_smile_id_network_builder.ts +17 -0
- package/src/data/factory/__tests__/retry_gzip_mac_composition.test.ts +163 -0
- package/src/data/factory/__tests__/signed_job_submission_headers.test.ts +1 -1
- package/src/data/factory/networking_factory.ts +14 -1
- package/src/data/repository/__tests__/network_retries.test.ts +117 -0
- package/src/data/repository/__tests__/use_smile_id_repository.test.ts +1 -1
- package/src/data/repository/use_smile_id_repository_impl.ts +96 -9
- package/src/data/security/__tests__/request_canonicalizer.test.ts +132 -0
- package/src/data/security/__tests__/security_policy.test.ts +96 -0
- package/src/data/security/__tests__/smile_id_crypto_manager.test.ts +18 -0
- package/src/data/security/request_canonicalizer.ts +15 -2
- package/src/data/security/security_policy.ts +70 -0
- package/src/data/smile_id_urls.ts +1 -1
- package/src/data/util/__tests__/retry_util.test.ts +25 -0
- package/src/data/util/__tests__/use_smile_id_token_decoder.test.ts +57 -1
- package/src/data/util/retry_util.ts +12 -3
- package/src/data/util/use_smile_id_token_decoder.ts +76 -28
- package/src/index.ts +6 -4
- package/src/l10n/strings_en.ts +2 -1
- package/src/l10n/use_smile_id_localizations.ts +3 -0
- package/src/metadata/__tests__/device_orientation_collector.test.ts +15 -0
- package/src/metadata/__tests__/metadata_configuration_mappers.test.ts +254 -0
- package/src/metadata/__tests__/metadata_configuration_objects.test.ts +86 -0
- package/src/metadata/__tests__/metadata_device_context.test.ts +147 -0
- package/src/metadata/__tests__/metadata_device_os_android.test.ts +18 -0
- package/src/metadata/__tests__/metadata_golden_fixture.json +13 -0
- package/src/metadata/__tests__/metadata_payload_golden.test.ts +193 -0
- package/src/metadata/__tests__/use_smile_id_metadata.test.ts +19 -25
- package/src/metadata/builder_configuration.ts +69 -0
- package/src/metadata/captured_image_properties.ts +10 -0
- package/src/metadata/device_orientation_collector.ts +75 -0
- package/src/metadata/geolocation.ts +46 -0
- package/src/metadata/metadata_configuration_mappers.ts +248 -0
- package/src/metadata/model_configuration.ts +68 -0
- package/src/metadata/optional_native_modules.ts +157 -3
- package/src/metadata/use_smile_id_metadata.ts +140 -17
- package/src/metadata/use_smile_id_metadata_factory.ts +211 -16
- package/src/presentation/assets/si_document_green_book_hero_animation.json +1 -4668
- package/src/presentation/assets/si_document_hero_animation.json +1 -4799
- package/src/presentation/assets/si_document_hero_back_animation.json +1 -2039
- package/src/presentation/assets/si_document_passport_hero_animation.json +1 -14491
- package/src/presentation/assets/si_ess_all_directions_hero_animation.json +1 -0
- package/src/presentation/assets/si_ess_animation_all_directions.json +1 -5575
- package/src/presentation/assets/si_selfie_hero_animation.json +1 -1439
- package/src/presentation/assets/si_smile_to_capture_animation.json +1 -1439
- package/src/presentation/assets/svg/document_shimmer_strings.ts +17 -0
- package/src/presentation/assets/svg/instruction_svg_strings.ts +34 -12
- package/src/presentation/components/__tests__/enhanced_smart_selfie_animation_frames.test.ts +1 -3
- package/src/presentation/components/__tests__/use_smile_id_enhanced_smart_selfie_clip.test.tsx +12 -8
- package/src/presentation/components/__tests__/use_smile_id_guideline_thumbnail.test.tsx +34 -1
- package/src/presentation/components/__tests__/use_smile_id_instructions_hero.test.tsx +71 -0
- package/src/presentation/components/__tests__/use_smile_id_oval_border_palette.test.ts +7 -5
- package/src/presentation/components/helpers/enhanced_smart_selfie_animation_frames.ts +0 -6
- package/src/presentation/components/icons/index.tsx +65 -18
- package/src/presentation/components/use_smile_id_attribution.tsx +1 -1
- package/src/presentation/components/use_smile_id_button.tsx +4 -4
- package/src/presentation/components/use_smile_id_capture_content.tsx +36 -12
- package/src/presentation/components/use_smile_id_captured_document_image.tsx +3 -8
- package/src/presentation/components/use_smile_id_document_capture_controls.tsx +103 -39
- package/src/presentation/components/use_smile_id_document_overlay.tsx +134 -44
- package/src/presentation/components/use_smile_id_document_shimmer.tsx +51 -0
- package/src/presentation/components/use_smile_id_enhanced_smart_selfie_clip.tsx +9 -6
- package/src/presentation/components/use_smile_id_guideline_thumbnail.tsx +131 -2
- package/src/presentation/components/use_smile_id_instructions_hero.tsx +111 -60
- package/src/presentation/components/use_smile_id_oval_border_palette.ts +7 -3
- package/src/presentation/flow/__tests__/document_flow_navigation.test.ts +203 -4
- package/src/presentation/flow/__tests__/flow_navigation_manager.test.ts +49 -0
- package/src/presentation/flow/dsl/builder/__tests__/config_builder.test.ts +25 -0
- package/src/presentation/flow/dsl/builder/config_builder.ts +35 -0
- package/src/presentation/flow/dsl/builder/ml_builder.ts +13 -4
- package/src/presentation/flow/dsl/builder/screens_builder.ts +110 -12
- package/src/presentation/flow/dsl/builder/theme_builder.ts +19 -2
- package/src/presentation/flow/dsl/use_smile_id_builder.tsx +6 -4
- package/src/presentation/flow/dsl/use_smile_id_flow_builder.ts +62 -36
- package/src/presentation/flow/flow_navigation_manager.ts +185 -14
- package/src/presentation/flow/model/instruction_guideline.ts +6 -0
- package/src/presentation/flow/model/instructions_defaults.ts +104 -26
- package/src/presentation/flow/screen/orchestrated_capture_screen.tsx +60 -12
- package/src/presentation/flow/screen/orchestrated_consent_screen.tsx +5 -0
- package/src/presentation/flow/screen/orchestrated_instructions_screen.tsx +1 -0
- package/src/presentation/flow/screen/orchestrated_preview_screen.tsx +4 -14
- package/src/presentation/flow/screen/orchestrated_processing_screen.tsx +3 -3
- package/src/presentation/flow/use_smile_id_flow.tsx +11 -4
- package/src/presentation/flow/validation/__tests__/flow_validator.test.ts +61 -1
- package/src/presentation/flow/validation/__tests__/job_type_validator.test.ts +64 -0
- package/src/presentation/flow/validation/flow_validator.ts +55 -26
- package/src/presentation/flow/validation/job_type_validator.ts +24 -0
- package/src/presentation/screen/__tests__/capture_ui_state.test.ts +66 -47
- package/src/presentation/screen/__tests__/ess_turn_haptics.test.ts +15 -11
- package/src/presentation/screen/__tests__/instructions_screen_helpers.test.ts +15 -3
- package/src/presentation/screen/__tests__/scan_state_to_overlay_state.test.ts +47 -27
- package/src/presentation/screen/__tests__/use_smile_id_capture_screen.test.tsx +182 -18
- package/src/presentation/screen/__tests__/use_smile_id_document_back_instructions.test.tsx +1 -1
- package/src/presentation/screen/__tests__/use_smile_id_preview_screen.test.tsx +10 -40
- package/src/presentation/screen/helpers/__tests__/use_capture_orientation_lock.test.tsx +212 -0
- package/src/presentation/screen/helpers/capture_screen_helpers.ts +1 -0
- package/src/presentation/screen/helpers/capture_ui_state.ts +27 -27
- package/src/presentation/screen/helpers/ess_turn_haptics.ts +9 -9
- package/src/presentation/screen/helpers/instructions_screen_helpers.ts +7 -2
- package/src/presentation/screen/helpers/scan_state_to_overlay_state.ts +16 -13
- package/src/presentation/screen/helpers/use_capture_orientation_lock.ts +69 -7
- package/src/presentation/screen/use_smile_id_capture_screen.tsx +280 -54
- package/src/presentation/screen/use_smile_id_consent_screen.tsx +16 -5
- package/src/presentation/screen/use_smile_id_document_back_instructions.tsx +14 -23
- package/src/presentation/screen/use_smile_id_document_preview_screen.tsx +33 -23
- package/src/presentation/screen/use_smile_id_instructions_screen.tsx +4 -0
- package/src/presentation/screen/use_smile_id_preview_screen.tsx +21 -53
- package/src/presentation/screen/use_smile_id_processing_screen.tsx +8 -8
- package/src/presentation/theme/theme.ts +21 -19
- package/src/presentation/utils/__tests__/locale_utils.test.ts +46 -5
- package/src/presentation/utils/force_max_brightness.tsx +4 -4
- package/src/presentation/utils/locale_utils.ts +13 -4
- package/src/testing/__tests__/fake_face_analyzer.test.ts +42 -0
- package/src/testing/__tests__/scenario_expectations.test.ts +110 -0
- package/src/testing/__tests__/scenario_loader.test.ts +64 -0
- package/src/testing/fake_face_analyzer.ts +82 -0
- package/src/testing/index.ts +15 -0
- package/src/testing/scenario_expectations.ts +87 -0
- package/src/testing/scenario_loader.ts +83 -0
- package/src/testing/scripted_scan_results.ts +66 -0
- package/dist/camera/frame_processor_plugin.d.ts +0 -28
- package/dist/camera/frame_processor_plugin.d.ts.map +0 -1
- package/dist/camera/frame_processor_plugin.js +0 -21
- package/dist/camera/frame_processor_plugin.js.map +0 -1
- package/dist/camera/use_smile_id_frame_processor.d.ts +0 -38
- package/dist/camera/use_smile_id_frame_processor.d.ts.map +0 -1
- package/dist/camera/use_smile_id_frame_processor.js +0 -2
- package/dist/camera/use_smile_id_frame_processor.js.map +0 -1
- package/dist/presentation/components/use_smile_id_document_frame_glyph.d.ts +0 -17
- package/dist/presentation/components/use_smile_id_document_frame_glyph.d.ts.map +0 -1
- package/dist/presentation/components/use_smile_id_document_frame_glyph.js +0 -17
- package/dist/presentation/components/use_smile_id_document_frame_glyph.js.map +0 -1
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_animation.d.ts +0 -24
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_animation.d.ts.map +0 -1
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_animation.js +0 -91
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_animation.js.map +0 -1
- package/dist/presentation/components/use_smile_id_face_silhouette_overlay.d.ts +0 -15
- package/dist/presentation/components/use_smile_id_face_silhouette_overlay.d.ts.map +0 -1
- package/dist/presentation/components/use_smile_id_face_silhouette_overlay.js +0 -19
- package/dist/presentation/components/use_smile_id_face_silhouette_overlay.js.map +0 -1
- package/dist/presentation/components/use_smile_id_instruction_card.d.ts +0 -31
- package/dist/presentation/components/use_smile_id_instruction_card.d.ts.map +0 -1
- package/dist/presentation/components/use_smile_id_instruction_card.js +0 -43
- package/dist/presentation/components/use_smile_id_instruction_card.js.map +0 -1
- package/dist/presentation/screen/helpers/use_document_orientation_lock.d.ts +0 -24
- package/dist/presentation/screen/helpers/use_document_orientation_lock.d.ts.map +0 -1
- package/dist/presentation/screen/helpers/use_document_orientation_lock.js +0 -47
- package/dist/presentation/screen/helpers/use_document_orientation_lock.js.map +0 -1
- package/src/presentation/components/use_smile_id_document_frame_glyph.tsx +0 -162
- package/src/presentation/components/use_smile_id_face_silhouette_overlay.tsx +0 -27
|
@@ -3,6 +3,14 @@ import * as ScreenOrientation from "expo-screen-orientation";
|
|
|
3
3
|
import { UseSmileIDCrashReporting } from "@smileid/usesmileid_bridge";
|
|
4
4
|
import type { DocumentOrientation } from "../../../core/models/document_type";
|
|
5
5
|
|
|
6
|
+
export type CaptureOrientationOptions = {
|
|
7
|
+
/**
|
|
8
|
+
* Lock applied when the capture screen unmounts. Defaults to portrait-up;
|
|
9
|
+
* threaded from the builder's `exitOrientations`.
|
|
10
|
+
*/
|
|
11
|
+
readonly exitLock?: ScreenOrientation.OrientationLock;
|
|
12
|
+
};
|
|
13
|
+
|
|
6
14
|
/**
|
|
7
15
|
* Lock device orientation for a capture screen, scoped to its lifetime
|
|
8
16
|
* (`"Landscape"` → landscape, `"Portrait"` → portrait-up).
|
|
@@ -10,26 +18,76 @@ import type { DocumentOrientation } from "../../../core/models/document_type";
|
|
|
10
18
|
* Each screen asserts its OWN orientation on mount, so document → selfie
|
|
11
19
|
* reverts deterministically rather than depending on the previous
|
|
12
20
|
* screen's teardown winning a race against the next camera initialising.
|
|
13
|
-
* Unmount restores portrait-up as a safety net.
|
|
14
21
|
*
|
|
15
22
|
* Locks are global: the host app must permit the locked orientations at
|
|
16
23
|
* the OS level (iOS `UISupportedInterfaceOrientations`, Android activity
|
|
17
|
-
* `screenOrientation`) for the lock to take effect
|
|
24
|
+
* `screenOrientation`) for the lock to take effect — a host that does not
|
|
25
|
+
* is warned about and reported rather than silently staying upright.
|
|
18
26
|
*/
|
|
19
27
|
export function useCaptureOrientationLock(
|
|
20
28
|
orientation: DocumentOrientation,
|
|
29
|
+
{
|
|
30
|
+
exitLock = ScreenOrientation.OrientationLock.PORTRAIT_UP,
|
|
31
|
+
}: CaptureOrientationOptions = {},
|
|
21
32
|
): void {
|
|
22
33
|
useEffect(() => {
|
|
23
34
|
const target =
|
|
24
35
|
orientation === "Landscape"
|
|
25
36
|
? ScreenOrientation.OrientationLock.LANDSCAPE
|
|
26
37
|
: ScreenOrientation.OrientationLock.PORTRAIT_UP;
|
|
38
|
+
void reportIfLockUnsupported(target);
|
|
27
39
|
void lockOrientation(target);
|
|
28
40
|
|
|
29
41
|
return () => {
|
|
30
|
-
void lockOrientation(
|
|
42
|
+
void lockOrientation(exitLock);
|
|
31
43
|
};
|
|
32
|
-
}, [orientation]);
|
|
44
|
+
}, [orientation, exitLock]);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Surface a host build that cannot honour `target`. `lockAsync` resolves
|
|
49
|
+
* successfully in that case, so without this preflight the capture screen
|
|
50
|
+
* just stays in the wrong orientation with no signal. (Expo's `app.json`
|
|
51
|
+
* `orientation` value is not such a case: the module's app-delegate hook
|
|
52
|
+
* outranks the baked `Info.plist` on iOS — device-verified.)
|
|
53
|
+
*/
|
|
54
|
+
async function reportIfLockUnsupported(
|
|
55
|
+
target: ScreenOrientation.OrientationLock,
|
|
56
|
+
): Promise<void> {
|
|
57
|
+
let supported: boolean;
|
|
58
|
+
try {
|
|
59
|
+
supported = await ScreenOrientation.supportsOrientationLockAsync(target);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
reportOrientationFailure(error);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (supported) return;
|
|
65
|
+
|
|
66
|
+
// `typeof` guard: `__DEV__` is bundler-injected and absent outside Metro-like
|
|
67
|
+
// environments, where a bare reference throws rather than reading falsy.
|
|
68
|
+
const isDevBuild = typeof __DEV__ !== "undefined" && __DEV__;
|
|
69
|
+
if (isDevBuild && !warnedUnsupportedTargets.has(target)) {
|
|
70
|
+
warnedUnsupportedTargets.add(target);
|
|
71
|
+
console.warn(
|
|
72
|
+
"[UseSmileID] The capture screen needs to lock the device orientation, " +
|
|
73
|
+
"but this build does not permit it. Allow the required orientations " +
|
|
74
|
+
"in your app's iOS Info.plist / Android manifest.",
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
reportOrientationFailure(
|
|
78
|
+
new Error(`orientation lock unsupported by host build: ${target}`),
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Dedupes the dev warning per target: a flow remounts the capture screen for the back
|
|
84
|
+
* side and interstitial, and the misconfiguration can't change mid-session.
|
|
85
|
+
*/
|
|
86
|
+
const warnedUnsupportedTargets = new Set<ScreenOrientation.OrientationLock>();
|
|
87
|
+
|
|
88
|
+
/** Test seam: clears the once-per-target dev-warning dedupe. */
|
|
89
|
+
export function resetUnsupportedLockWarningsForTesting(): void {
|
|
90
|
+
warnedUnsupportedTargets.clear();
|
|
33
91
|
}
|
|
34
92
|
|
|
35
93
|
/** Lock to `target`, routing a native failure through crash reporting. */
|
|
@@ -39,8 +97,12 @@ async function lockOrientation(
|
|
|
39
97
|
try {
|
|
40
98
|
await ScreenOrientation.lockAsync(target);
|
|
41
99
|
} catch (error) {
|
|
42
|
-
|
|
43
|
-
error instanceof Error ? error : new Error(String(error)),
|
|
44
|
-
);
|
|
100
|
+
reportOrientationFailure(error);
|
|
45
101
|
}
|
|
46
102
|
}
|
|
103
|
+
|
|
104
|
+
function reportOrientationFailure(error: unknown): void {
|
|
105
|
+
UseSmileIDCrashReporting.captureException(
|
|
106
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
107
|
+
);
|
|
108
|
+
}
|
|
@@ -6,7 +6,13 @@ import {
|
|
|
6
6
|
useState,
|
|
7
7
|
type ReactNode,
|
|
8
8
|
} from "react";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
Platform,
|
|
11
|
+
StatusBar,
|
|
12
|
+
StyleSheet,
|
|
13
|
+
View,
|
|
14
|
+
useWindowDimensions,
|
|
15
|
+
} from "react-native";
|
|
10
16
|
import {
|
|
11
17
|
Camera,
|
|
12
18
|
useCameraDevice,
|
|
@@ -22,25 +28,35 @@ import type {
|
|
|
22
28
|
DocumentAnalyzer,
|
|
23
29
|
FaceAnalyzer,
|
|
24
30
|
} from "@smileid/usesmileid_platform_interface";
|
|
25
|
-
import type {
|
|
31
|
+
import type {
|
|
32
|
+
CaptureReadyEvent,
|
|
33
|
+
UseSmileIDScanState,
|
|
34
|
+
} from "@smileid/usesmileid_bridge";
|
|
26
35
|
import {
|
|
27
36
|
CaptureReadyEventKind,
|
|
28
37
|
DocumentSide,
|
|
29
|
-
|
|
38
|
+
UseSmileIDScanStateType,
|
|
30
39
|
} from "@smileid/usesmileid_bridge";
|
|
31
40
|
import { CaptureType } from "../../core/models/ml_config";
|
|
32
41
|
import type { DocumentCaptureMode } from "../../core/models/document_capture_mode";
|
|
42
|
+
import type { DocumentType } from "../../core/models/document_type";
|
|
33
43
|
import { resampleImportedDocument } from "../../camera/document_image_pipeline";
|
|
34
44
|
import { defaultLightTheme, type UseSmileIDTheme } from "../theme/theme";
|
|
45
|
+
import { UseSmileIDThemeProvider } from "../theme/theme_context";
|
|
35
46
|
import {
|
|
36
47
|
UseSmileIDCaptureContent,
|
|
37
48
|
type UseSmileIDCaptureContentState,
|
|
38
49
|
} from "../components/use_smile_id_capture_content";
|
|
50
|
+
import {
|
|
51
|
+
DEFAULT_DOCUMENT_ASPECT,
|
|
52
|
+
documentGuideRect,
|
|
53
|
+
} from "../components/use_smile_id_document_overlay";
|
|
39
54
|
import { UseSmileIDCrashReporting } from "@smileid/usesmileid_bridge";
|
|
40
55
|
import { ForceMaxBrightness } from "../utils/force_max_brightness";
|
|
41
56
|
import { CameraDefaults } from "../../camera/camera_defaults";
|
|
42
57
|
import type { SiKey } from "../../l10n/strings_en";
|
|
43
58
|
import { DocumentImageOrigin } from "../../metadata/document_image_origin";
|
|
59
|
+
import { DeviceOrientationCollector } from "../../metadata/device_orientation_collector";
|
|
44
60
|
import { useSmileIDFrameStream } from "../../camera/use_smile_id_frame_stream";
|
|
45
61
|
import { orientationToDegrees } from "../../camera/orientation_degrees";
|
|
46
62
|
import {
|
|
@@ -55,6 +71,20 @@ import {
|
|
|
55
71
|
triggerEssTurnHaptic,
|
|
56
72
|
} from "./helpers/ess_turn_haptics";
|
|
57
73
|
|
|
74
|
+
/** Capture telemetry surfaced alongside the captured artifacts at completion. */
|
|
75
|
+
export interface CaptureTelemetry {
|
|
76
|
+
/** Elapsed time in ms from the first analyzed frame to completion. */
|
|
77
|
+
readonly durationMs: number;
|
|
78
|
+
/** Count of face/document-lost resets (rising edges of `unsatisfied`). */
|
|
79
|
+
readonly retries: number;
|
|
80
|
+
/** Identifier of the camera used for capture (`CameraDevice.id`); `undefined` until resolved. */
|
|
81
|
+
readonly cameraName?: string;
|
|
82
|
+
/** Accelerometer `"epochMs,x,y,z"` samples collected during capture. */
|
|
83
|
+
readonly devicePositions: readonly string[];
|
|
84
|
+
/** Span of movement magnitude during capture; `null` when no samples ran. */
|
|
85
|
+
readonly deviceMovementDetected: number | null;
|
|
86
|
+
}
|
|
87
|
+
|
|
58
88
|
export type UseSmileIDCaptureScreenProps = {
|
|
59
89
|
readonly captureType: CaptureType;
|
|
60
90
|
|
|
@@ -73,12 +103,15 @@ export type UseSmileIDCaptureScreenProps = {
|
|
|
73
103
|
* settled, with every `CaptureReadyEvent` of the session (one
|
|
74
104
|
* `"selfie"` + N `"liveness"` for face, one `"document"` for document).
|
|
75
105
|
*/
|
|
76
|
-
readonly onCaptureComplete?: (
|
|
106
|
+
readonly onCaptureComplete?: (
|
|
107
|
+
events: readonly CaptureReadyEvent[],
|
|
108
|
+
telemetry: CaptureTelemetry,
|
|
109
|
+
) => void;
|
|
77
110
|
/** Records how a document side was produced (auto/manual/gallery), fired just before delivery. */
|
|
78
111
|
readonly onDocumentOrigin?: (origin: DocumentImageOrigin) => void;
|
|
79
112
|
|
|
80
113
|
/** Fires when the state machine reaches `"timeout"`; the screen stops streaming. */
|
|
81
|
-
readonly onCaptureTimeout?: (state:
|
|
114
|
+
readonly onCaptureTimeout?: (state: UseSmileIDScanState) => void;
|
|
82
115
|
|
|
83
116
|
readonly onBack?: () => void;
|
|
84
117
|
readonly showAttribution?: boolean;
|
|
@@ -86,6 +119,9 @@ export type UseSmileIDCaptureScreenProps = {
|
|
|
86
119
|
/** Keeps the oval rim neutral through CAPTURING/PROCESSING — ESS has no green oval treatment. */
|
|
87
120
|
readonly enableEnhancedLiveness?: boolean;
|
|
88
121
|
|
|
122
|
+
/** Runs a selfie capture on the rear camera. Ignored for document capture. */
|
|
123
|
+
readonly allowAgentMode?: boolean;
|
|
124
|
+
|
|
89
125
|
/**
|
|
90
126
|
* Document aspect ratio (width / height) for the document capture
|
|
91
127
|
* guide cutout. Ignored for selfie capture. Omitted ⇒ the overlay's
|
|
@@ -106,6 +142,8 @@ export type UseSmileIDCaptureScreenProps = {
|
|
|
106
142
|
* `document_front.jpg` / `document_back.jpg`. Ignored for selfie capture.
|
|
107
143
|
*/
|
|
108
144
|
readonly documentSide?: DocumentSide;
|
|
145
|
+
/** Document type — selects the in-frame capture shimmer skeleton. Ignored for selfie. */
|
|
146
|
+
readonly documentTypeKind?: DocumentType["kind"];
|
|
109
147
|
/** Close/cancel the whole flow (document capture chrome — top-right X). */
|
|
110
148
|
readonly onClose?: () => void;
|
|
111
149
|
|
|
@@ -130,9 +168,12 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
130
168
|
const theme = props.theme ?? defaultLightTheme;
|
|
131
169
|
const showAttribution = props.showAttribution ?? true;
|
|
132
170
|
const enableEnhancedLiveness = props.enableEnhancedLiveness ?? false;
|
|
171
|
+
const allowAgentMode = props.allowAgentMode ?? false;
|
|
133
172
|
// Literal union — useCameraDevice takes the lowercase string directly.
|
|
134
173
|
const cameraFacing: "front" | "back" =
|
|
135
|
-
props.captureType === CaptureType.selfie
|
|
174
|
+
props.captureType === CaptureType.selfie && !allowAgentMode
|
|
175
|
+
? "front"
|
|
176
|
+
: "back";
|
|
136
177
|
|
|
137
178
|
const { hasPermission, requestPermission } = useCameraPermission();
|
|
138
179
|
const device = useCameraDevice(cameraFacing);
|
|
@@ -140,15 +181,24 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
140
181
|
const cameraRef = useRef<Camera>(null);
|
|
141
182
|
// Pin an explicit format: the "highest supported" heuristic can pick 4K,
|
|
142
183
|
// stalling the frame-processor thread and stuttering the pipeline.
|
|
184
|
+
// Document capture uses 16:9 so the analysis FOV matches the visible 16:9
|
|
185
|
+
// preview — keeping the guide-rectangle crop aligned with the framed document
|
|
186
|
+
// (mirrors the native Android SDK's RATIO_16_9 + 1280×720 pin). Selfie keeps
|
|
187
|
+
// 4:3: the face geometry + smile heuristic are calibrated on 4:3, and 16:9
|
|
188
|
+
// skews normalized landmark ratios and shifts every threshold.
|
|
189
|
+
const isDocumentFormat = props.captureType === CaptureType.document;
|
|
143
190
|
const format = useCameraFormat(device, [
|
|
144
|
-
|
|
145
|
-
// 16:9 skews normalized landmark ratios and shifts every threshold.
|
|
146
|
-
{ videoAspectRatio: 4 / 3 },
|
|
191
|
+
{ videoAspectRatio: isDocumentFormat ? 16 / 9 : 4 / 3 },
|
|
147
192
|
{
|
|
148
|
-
videoResolution:
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
193
|
+
videoResolution: isDocumentFormat
|
|
194
|
+
? {
|
|
195
|
+
width: CameraDefaults.documentAnalysisResolution.width,
|
|
196
|
+
height: CameraDefaults.documentAnalysisResolution.height,
|
|
197
|
+
}
|
|
198
|
+
: {
|
|
199
|
+
width: CameraDefaults.analysisTargetResolution.width,
|
|
200
|
+
height: CameraDefaults.analysisTargetResolution.height,
|
|
201
|
+
},
|
|
152
202
|
},
|
|
153
203
|
{ fps: CameraDefaults.analysisTargetFps },
|
|
154
204
|
]);
|
|
@@ -161,8 +211,8 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
161
211
|
}, [hasPermission, requestPermission]);
|
|
162
212
|
|
|
163
213
|
// Per-frame scan state drives the overlay + feedback bubble.
|
|
164
|
-
const [scanState, setScanState] = useState<
|
|
165
|
-
type:
|
|
214
|
+
const [scanState, setScanState] = useState<UseSmileIDScanState>({
|
|
215
|
+
type: UseSmileIDScanStateType.Initial,
|
|
166
216
|
});
|
|
167
217
|
const [streaming, setStreaming] = useState<boolean>(false);
|
|
168
218
|
// Bumped on every Start tap to reset the feedback debouncer.
|
|
@@ -172,6 +222,11 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
172
222
|
const [hasAnalyzedFrame, setHasAnalyzedFrame] = useState<boolean>(false);
|
|
173
223
|
// Fallback shutter, revealed after activateManualAfterMs. Resets per mount.
|
|
174
224
|
const [manualShutterRevealed, setManualShutterRevealed] = useState(false);
|
|
225
|
+
// Set when a document scan times out, so the recovery controls stay on screen
|
|
226
|
+
// after the scan (and `streaming`) stops. `timedOutRef` keeps the terminal
|
|
227
|
+
// branch idempotent without latching the one-shot delivery gate.
|
|
228
|
+
const [captureTimedOut, setCaptureTimedOut] = useState(false);
|
|
229
|
+
const timedOutRef = useRef(false);
|
|
175
230
|
// True while a manual/gallery delivery is in flight — disables the controls.
|
|
176
231
|
const [deliveringDocument, setDeliveringDocument] = useState(false);
|
|
177
232
|
// Transient gallery-import error; overrides the live chip, self-clears so the user can re-pick.
|
|
@@ -191,7 +246,34 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
191
246
|
const completedRef = useRef<boolean>(false);
|
|
192
247
|
// Raw (not committed) frame state for the session-boundary check, so
|
|
193
248
|
// transitions the 1% bucketing skips committing are still seen.
|
|
194
|
-
const previousScanStateRef = useRef<
|
|
249
|
+
const previousScanStateRef = useRef<UseSmileIDScanState | null>(null);
|
|
250
|
+
|
|
251
|
+
// Capture telemetry: wall-clock start (first analyzed frame) and a
|
|
252
|
+
// rising-edge `unsatisfied` retry counter, surfaced via onCaptureComplete.
|
|
253
|
+
const captureStartedAtRef = useRef<number | null>(null);
|
|
254
|
+
const captureRetriesRef = useRef<number>(0);
|
|
255
|
+
const wasUnsatisfiedRef = useRef<boolean>(false);
|
|
256
|
+
// Accelerometer sampler for device_positions / device_movement_detected, run only
|
|
257
|
+
// while the live capture loop is streaming.
|
|
258
|
+
const deviceOrientationRef = useRef<DeviceOrientationCollector>(
|
|
259
|
+
new DeviceOrientationCollector(),
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
const captureTelemetry = useCallback(
|
|
263
|
+
(): CaptureTelemetry => ({
|
|
264
|
+
durationMs:
|
|
265
|
+
captureStartedAtRef.current === null
|
|
266
|
+
? 0
|
|
267
|
+
: Date.now() - captureStartedAtRef.current,
|
|
268
|
+
retries: captureRetriesRef.current,
|
|
269
|
+
devicePositions: deviceOrientationRef.current.devicePositions,
|
|
270
|
+
deviceMovementDetected:
|
|
271
|
+
deviceOrientationRef.current.deviceMovementDetected,
|
|
272
|
+
// Omit (not set to undefined) when unresolved — exactOptionalPropertyTypes.
|
|
273
|
+
...(device?.id !== undefined ? { cameraName: device.id } : {}),
|
|
274
|
+
}),
|
|
275
|
+
[device],
|
|
276
|
+
);
|
|
195
277
|
|
|
196
278
|
const onStartCapture = props.onStartCapture;
|
|
197
279
|
const handleStart = useCallback(() => {
|
|
@@ -213,6 +295,23 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
213
295
|
const documentSide = props.documentSide ?? DocumentSide.Front;
|
|
214
296
|
const isDocumentCapture = props.captureType === CaptureType.document;
|
|
215
297
|
|
|
298
|
+
// Reset capture telemetry per side so each document side reports its own
|
|
299
|
+
// duration / retries (the screen instance is reused across the front→back flip).
|
|
300
|
+
useEffect(() => {
|
|
301
|
+
captureStartedAtRef.current = null;
|
|
302
|
+
captureRetriesRef.current = 0;
|
|
303
|
+
wasUnsatisfiedRef.current = false;
|
|
304
|
+
}, [documentSide]);
|
|
305
|
+
|
|
306
|
+
// Sample the accelerometer only while the live capture loop streams. start()
|
|
307
|
+
// clears prior samples, so a retry / side switch begins fresh; cleanup stops it.
|
|
308
|
+
useEffect(() => {
|
|
309
|
+
if (streaming) {
|
|
310
|
+
deviceOrientationRef.current.start();
|
|
311
|
+
}
|
|
312
|
+
return () => deviceOrientationRef.current.stop();
|
|
313
|
+
}, [streaming]);
|
|
314
|
+
|
|
216
315
|
// Reveal the fallback shutter after the delay once streaming begins.
|
|
217
316
|
// Bound to `streaming`: any capture clears it, tearing this effect down
|
|
218
317
|
// and clearing the timer, so it can't fire post-capture or leak.
|
|
@@ -249,13 +348,16 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
249
348
|
documentSide,
|
|
250
349
|
);
|
|
251
350
|
onDocumentOrigin?.(DocumentImageOrigin.CameraManualCapture);
|
|
252
|
-
onCaptureComplete?.(
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
351
|
+
onCaptureComplete?.(
|
|
352
|
+
[
|
|
353
|
+
{
|
|
354
|
+
kind: CaptureReadyEventKind.Document,
|
|
355
|
+
captureIndex: 0,
|
|
356
|
+
url: processedUri,
|
|
357
|
+
},
|
|
358
|
+
],
|
|
359
|
+
captureTelemetry(),
|
|
360
|
+
);
|
|
259
361
|
} catch (error) {
|
|
260
362
|
UseSmileIDCrashReporting.captureException(
|
|
261
363
|
error instanceof Error ? error : new Error(String(error)),
|
|
@@ -318,13 +420,16 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
318
420
|
documentSide,
|
|
319
421
|
);
|
|
320
422
|
onDocumentOrigin?.(DocumentImageOrigin.Gallery);
|
|
321
|
-
onCaptureComplete?.(
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
423
|
+
onCaptureComplete?.(
|
|
424
|
+
[
|
|
425
|
+
{
|
|
426
|
+
kind: CaptureReadyEventKind.Document,
|
|
427
|
+
captureIndex: 0,
|
|
428
|
+
url: processedUri,
|
|
429
|
+
},
|
|
430
|
+
],
|
|
431
|
+
captureTelemetry(),
|
|
432
|
+
);
|
|
328
433
|
} catch (error) {
|
|
329
434
|
UseSmileIDCrashReporting.captureException(
|
|
330
435
|
error instanceof Error ? error : new Error(String(error)),
|
|
@@ -379,7 +484,19 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
379
484
|
// Unsatisfied = native session reset; drop accumulated events so it
|
|
380
485
|
// can't leak stale liveness frames. `else` so a reset frame can't
|
|
381
486
|
// re-add its own stale events on the same pass.
|
|
382
|
-
|
|
487
|
+
// Capture telemetry: anchor the start clock on the first analyzed frame,
|
|
488
|
+
// and count rising edges of `unsatisfied` as retries.
|
|
489
|
+
if (captureStartedAtRef.current === null) {
|
|
490
|
+
captureStartedAtRef.current = Date.now();
|
|
491
|
+
}
|
|
492
|
+
const isUnsatisfied =
|
|
493
|
+
result.state.type === UseSmileIDScanStateType.Unsatisfied;
|
|
494
|
+
if (isUnsatisfied && !wasUnsatisfiedRef.current) {
|
|
495
|
+
captureRetriesRef.current += 1;
|
|
496
|
+
}
|
|
497
|
+
wasUnsatisfiedRef.current = isUnsatisfied;
|
|
498
|
+
|
|
499
|
+
if (result.state.type === UseSmileIDScanStateType.Unsatisfied) {
|
|
383
500
|
capturedEventsRef.current = [];
|
|
384
501
|
} else if (result.capturedEvents.length > 0) {
|
|
385
502
|
capturedEventsRef.current = [
|
|
@@ -405,7 +522,7 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
405
522
|
|
|
406
523
|
// Terminal states: finished → flush + complete; timeout → failure
|
|
407
524
|
// without flushing (no captured artifacts to wait on).
|
|
408
|
-
if (result.state.type ===
|
|
525
|
+
if (result.state.type === UseSmileIDScanStateType.Finished) {
|
|
409
526
|
if (completedRef.current) return;
|
|
410
527
|
completedRef.current = true;
|
|
411
528
|
setStreaming(false);
|
|
@@ -420,12 +537,20 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
420
537
|
.finally(() => {
|
|
421
538
|
// No-op for selfie (callback unset).
|
|
422
539
|
onDocumentOrigin?.(DocumentImageOrigin.CameraAutoCapture);
|
|
423
|
-
onCaptureComplete?.(capturedEventsRef.current);
|
|
540
|
+
onCaptureComplete?.(capturedEventsRef.current, captureTelemetry());
|
|
424
541
|
});
|
|
425
|
-
} else if (result.state.type ===
|
|
426
|
-
if (completedRef.current) return;
|
|
427
|
-
completedRef.current = true;
|
|
542
|
+
} else if (result.state.type === UseSmileIDScanStateType.Timeout) {
|
|
543
|
+
if (completedRef.current || timedOutRef.current) return;
|
|
428
544
|
setStreaming(false);
|
|
545
|
+
if (isDocumentCapture) {
|
|
546
|
+
// Document capture has no Start button, so a timeout must leave a way
|
|
547
|
+
// forward: reveal the manual shutter and keep the delivery gate open
|
|
548
|
+
// so the tap can still produce a capture.
|
|
549
|
+
timedOutRef.current = true;
|
|
550
|
+
setCaptureTimedOut(true);
|
|
551
|
+
} else {
|
|
552
|
+
completedRef.current = true;
|
|
553
|
+
}
|
|
429
554
|
onCaptureTimeout?.(result.state);
|
|
430
555
|
}
|
|
431
556
|
},
|
|
@@ -447,7 +572,7 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
447
572
|
sessionEpoch,
|
|
448
573
|
);
|
|
449
574
|
const isInstructionState =
|
|
450
|
-
scanState.type ===
|
|
575
|
+
scanState.type === UseSmileIDScanStateType.Initial && !streaming;
|
|
451
576
|
const canStart = !streaming && !completedRef.current;
|
|
452
577
|
|
|
453
578
|
const previewReady = hasPermission && device != null;
|
|
@@ -487,33 +612,116 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
487
612
|
});
|
|
488
613
|
}, [onFrameResult]);
|
|
489
614
|
|
|
490
|
-
// Physical device tilt (0 =
|
|
491
|
-
//
|
|
492
|
-
// never derived from `frame.orientation` (fixed sensor mounting).
|
|
615
|
+
// Physical device tilt (0 = portrait) for the native upright validator /
|
|
616
|
+
// head-pose math; gravity-sourced, never from `frame.orientation`.
|
|
493
617
|
const [deviceOrientationDegrees, setDeviceOrientationDegrees] = useState(0);
|
|
494
618
|
|
|
619
|
+
// Locked INTERFACE orientation (0/90/270) — the axis the preview and guide are
|
|
620
|
+
// drawn against, from VisionCamera's preview orientation, NOT device gravity
|
|
621
|
+
// (the document screen locks the interface while the phone is held flat, so
|
|
622
|
+
// gravity disagrees). iOS uprights the saved document to this axis.
|
|
623
|
+
const [previewOrientationDegrees, setPreviewOrientationDegrees] = useState(0);
|
|
624
|
+
|
|
625
|
+
// VisionCamera derives its iOS preview orientation from the interface
|
|
626
|
+
// orientation but only refreshes it on a PHYSICAL rotation — a programmatic
|
|
627
|
+
// lock (the document landscape lock) never fires that, so the preview stays
|
|
628
|
+
// portrait in the rotated UI. Remounting <Camera> when the interface flips
|
|
629
|
+
// forces a re-read. iOS only — Android's preview already tracks the lock.
|
|
630
|
+
const { width: windowWidth, height: windowHeight } = useWindowDimensions();
|
|
631
|
+
const cameraOrientationKey =
|
|
632
|
+
Platform.OS === "ios"
|
|
633
|
+
? windowWidth > windowHeight
|
|
634
|
+
? "landscape"
|
|
635
|
+
: "portrait"
|
|
636
|
+
: "camera";
|
|
637
|
+
|
|
638
|
+
// Camera viewport size, reported by the capture content on layout. Drives the
|
|
639
|
+
// document crop region so the saved capture matches the on-screen frame.
|
|
640
|
+
const [viewport, setViewport] = useState({ width: 0, height: 0 });
|
|
641
|
+
const handleViewportLayout = useCallback(
|
|
642
|
+
(size: { width: number; height: number }) => {
|
|
643
|
+
setViewport((previous) =>
|
|
644
|
+
previous.width === size.width && previous.height === size.height
|
|
645
|
+
? previous
|
|
646
|
+
: size,
|
|
647
|
+
);
|
|
648
|
+
},
|
|
649
|
+
[],
|
|
650
|
+
);
|
|
651
|
+
|
|
652
|
+
// The document guide rectangle as a native crop region — viewport fractions +
|
|
653
|
+
// size + cover scale — derived from the SAME geometry the overlay draws
|
|
654
|
+
// (documentGuideRect), so the native side crops the saved document to exactly
|
|
655
|
+
// the framed rectangle. undefined for selfie or before the viewport is known.
|
|
656
|
+
const documentCropRegion = useMemo(() => {
|
|
657
|
+
if (!isDocumentCapture || viewport.width <= 0 || viewport.height <= 0) {
|
|
658
|
+
return undefined;
|
|
659
|
+
}
|
|
660
|
+
const aspect = props.knownIdAspectRatio ?? DEFAULT_DOCUMENT_ASPECT;
|
|
661
|
+
const rect = documentGuideRect(aspect, viewport.width, viewport.height);
|
|
662
|
+
return {
|
|
663
|
+
left: rect.left / viewport.width,
|
|
664
|
+
top: rect.top / viewport.height,
|
|
665
|
+
width: rect.width / viewport.width,
|
|
666
|
+
height: rect.height / viewport.height,
|
|
667
|
+
viewportWidthPx: Math.round(viewport.width),
|
|
668
|
+
viewportHeightPx: Math.round(viewport.height),
|
|
669
|
+
};
|
|
670
|
+
}, [isDocumentCapture, viewport, props.knownIdAspectRatio]);
|
|
671
|
+
|
|
495
672
|
const frameProcessor = useFrameProcessor(
|
|
496
673
|
(frame) => {
|
|
497
674
|
"worklet";
|
|
498
675
|
if (!plugin) return;
|
|
676
|
+
// Crop region passed as FLAT numeric args — frame-processor arguments
|
|
677
|
+
// don't reliably accept nested objects. cropWidth <= 0 signals "no region"
|
|
678
|
+
// (selfie, or before the viewport is measured), leaving it uncropped.
|
|
679
|
+
//
|
|
680
|
+
// The saved document uprights to the LOCKED INTERFACE axis (what the
|
|
681
|
+
// preview and guide are drawn against), never device gravity (the phone is
|
|
682
|
+
// held flat): iOS uprights to `viewportOrientation`, Android via its
|
|
683
|
+
// display-tracking `rotationDegrees`. `rotation` stays the RAW gravity
|
|
684
|
+
// tilt the native upright validator needs.
|
|
499
685
|
const rawResult = plugin.call(frame, {
|
|
500
686
|
rotation: deviceOrientationDegrees,
|
|
687
|
+
viewportOrientation: previewOrientationDegrees,
|
|
688
|
+
cropLeft: documentCropRegion ? documentCropRegion.left : 0,
|
|
689
|
+
cropTop: documentCropRegion ? documentCropRegion.top : 0,
|
|
690
|
+
cropWidth: documentCropRegion ? documentCropRegion.width : 0,
|
|
691
|
+
cropHeight: documentCropRegion ? documentCropRegion.height : 0,
|
|
692
|
+
cropViewportWidth: documentCropRegion
|
|
693
|
+
? documentCropRegion.viewportWidthPx
|
|
694
|
+
: 0,
|
|
695
|
+
cropViewportHeight: documentCropRegion
|
|
696
|
+
? documentCropRegion.viewportHeightPx
|
|
697
|
+
: 0,
|
|
501
698
|
});
|
|
502
699
|
onFrameResultRunOnJS(rawResult);
|
|
503
700
|
},
|
|
504
|
-
[
|
|
701
|
+
[
|
|
702
|
+
plugin,
|
|
703
|
+
onFrameResultRunOnJS,
|
|
704
|
+
deviceOrientationDegrees,
|
|
705
|
+
previewOrientationDegrees,
|
|
706
|
+
documentCropRegion,
|
|
707
|
+
],
|
|
505
708
|
);
|
|
506
709
|
|
|
507
710
|
// Document controls — live capture only (after Start). Manual shutter
|
|
508
711
|
// follows the capture mode + fallback timer; gallery follows
|
|
509
712
|
// allowGalleryUpload. Renderer also hides both during CAPTURING/PROCESSING.
|
|
713
|
+
// A timeout offers the shutter in every capture mode — it is the recovery
|
|
714
|
+
// affordance, so it outranks `captureMode` and survives `streaming` going
|
|
715
|
+
// false with the scan.
|
|
510
716
|
const manualShutterAvailable =
|
|
511
717
|
isDocumentCapture &&
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
718
|
+
(captureTimedOut ||
|
|
719
|
+
(streaming &&
|
|
720
|
+
(captureMode?.kind === "manualCapture" ||
|
|
721
|
+
(captureMode?.kind === "autoCaptureWithManualFallback" &&
|
|
722
|
+
manualShutterRevealed))));
|
|
723
|
+
const galleryAvailable =
|
|
724
|
+
isDocumentCapture && (streaming || captureTimedOut) && allowGalleryUpload;
|
|
517
725
|
|
|
518
726
|
// Deps are scalar fields (mapCaptureUiState returns a fresh object per
|
|
519
727
|
// render). captureProgress intentionally stays a separate per-frame prop.
|
|
@@ -530,9 +738,13 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
530
738
|
showCaptureButton: isInstructionState && !isDocumentCapture,
|
|
531
739
|
showManualShutter: manualShutterAvailable,
|
|
532
740
|
showGalleryUpload: galleryAvailable,
|
|
741
|
+
isBackSide: documentSide === DocumentSide.Back,
|
|
533
742
|
...(props.knownIdAspectRatio !== undefined
|
|
534
743
|
? { knownIdAspectRatio: props.knownIdAspectRatio }
|
|
535
744
|
: {}),
|
|
745
|
+
...(props.documentTypeKind !== undefined
|
|
746
|
+
? { documentTypeKind: props.documentTypeKind }
|
|
747
|
+
: {}),
|
|
536
748
|
}),
|
|
537
749
|
[
|
|
538
750
|
props.captureType,
|
|
@@ -546,7 +758,9 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
546
758
|
isDocumentCapture,
|
|
547
759
|
manualShutterAvailable,
|
|
548
760
|
galleryAvailable,
|
|
761
|
+
documentSide,
|
|
549
762
|
props.knownIdAspectRatio,
|
|
763
|
+
props.documentTypeKind,
|
|
550
764
|
],
|
|
551
765
|
);
|
|
552
766
|
|
|
@@ -554,14 +768,14 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
554
768
|
const cameraPreview = useMemo(
|
|
555
769
|
() => (
|
|
556
770
|
<>
|
|
557
|
-
{/*
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
/>
|
|
771
|
+
{/* Every capture screen runs at max brightness with the screen kept
|
|
772
|
+
awake, restored on unmount. Selfie uses the front camera with the
|
|
773
|
+
screen as fill light; document capture keeps the same guarantee so
|
|
774
|
+
the preview never dims or auto-locks mid-scan. */}
|
|
775
|
+
<ForceMaxBrightness />
|
|
563
776
|
{previewReady ? (
|
|
564
777
|
<Camera
|
|
778
|
+
key={cameraOrientationKey}
|
|
565
779
|
ref={cameraRef}
|
|
566
780
|
style={StyleSheet.absoluteFill}
|
|
567
781
|
device={device}
|
|
@@ -576,6 +790,11 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
576
790
|
onOutputOrientationChanged={(orientation) => {
|
|
577
791
|
setDeviceOrientationDegrees(orientationToDegrees(orientation));
|
|
578
792
|
}}
|
|
793
|
+
// The LOCKED interface orientation (follows the screen even under a
|
|
794
|
+
// programmatic lock) — the axis the saved document uprights to.
|
|
795
|
+
onPreviewOrientationChanged={(orientation) => {
|
|
796
|
+
setPreviewOrientationDegrees(orientationToDegrees(orientation));
|
|
797
|
+
}}
|
|
579
798
|
// Attach the frame processor only while streaming (skip pre-Start
|
|
580
799
|
// preview). Spread idiom because exactOptionalPropertyTypes rejects
|
|
581
800
|
// passing `undefined` to an optional prop directly.
|
|
@@ -602,11 +821,17 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
602
821
|
streaming,
|
|
603
822
|
frameProcessor,
|
|
604
823
|
theme.colors.offBlack,
|
|
824
|
+
cameraOrientationKey,
|
|
605
825
|
],
|
|
606
826
|
);
|
|
607
827
|
|
|
608
828
|
return (
|
|
609
|
-
|
|
829
|
+
// The capture screen is always light, regardless of the system dark-mode
|
|
830
|
+
// setting (every other screen tracks the system). Providing the light theme
|
|
831
|
+
// here forces every descendant that reads it from context — not only the
|
|
832
|
+
// ones passing `forceLightMode` — to render light; partner colours still
|
|
833
|
+
// apply because `theme` carries the partner's resolved light tokens.
|
|
834
|
+
<UseSmileIDThemeProvider value={theme}>
|
|
610
835
|
{/* Translucent status bar → full-bleed window so the oval's reference
|
|
611
836
|
frame is the full screen (no-op on iOS). On-device-pending: residual
|
|
612
837
|
inset also depends on the host SafeAreaProvider config. */}
|
|
@@ -620,6 +845,7 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
620
845
|
onBack={props.onBack}
|
|
621
846
|
showAttribution={showAttribution}
|
|
622
847
|
startButton={props.startButton}
|
|
848
|
+
onViewportLayout={handleViewportLayout}
|
|
623
849
|
{...(isDocumentCapture
|
|
624
850
|
? {
|
|
625
851
|
onManualShutter: handleManualShutter,
|
|
@@ -630,6 +856,6 @@ export function UseSmileIDCaptureScreen(props: UseSmileIDCaptureScreenProps) {
|
|
|
630
856
|
: {})}
|
|
631
857
|
theme={theme}
|
|
632
858
|
/>
|
|
633
|
-
|
|
859
|
+
</UseSmileIDThemeProvider>
|
|
634
860
|
);
|
|
635
861
|
}
|