@regulaforensics/face-sdk 7.2.408-rc → 7.2.414-beta

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.
Files changed (168) hide show
  1. package/README.md +2 -3
  2. package/RNFaceSDK.podspec +2 -2
  3. package/android/build.gradle +2 -2
  4. package/android/cordova.gradle +2 -2
  5. package/android/src/main/java/com/regula/plugin/facesdk/JSONConstructor.kt +2 -0
  6. package/android/src/main/java/com/regula/plugin/facesdk/Main.kt +18 -0
  7. package/examples/capacitor/android/app/src/main/AndroidManifest.xml +2 -2
  8. package/examples/capacitor/index.html +2 -7
  9. package/examples/capacitor/index.tsx +53 -0
  10. package/examples/capacitor/package.json +3 -3
  11. package/examples/capacitor/scripts/setup.sh +4 -2
  12. package/examples/capacitor/src/main.css +60 -6
  13. package/examples/capacitor/src/main.html +1 -1
  14. package/examples/capacitor/src/main.tsx +51 -87
  15. package/examples/ionic/angular.json +3 -3
  16. package/examples/ionic/config.xml +1 -1
  17. package/examples/ionic/index.tsx +68 -0
  18. package/examples/ionic/package.json +2 -2
  19. package/examples/ionic/src/main.css +60 -6
  20. package/examples/ionic/src/main.html +1 -1
  21. package/examples/ionic/src/{main.ts → main.tsx} +52 -97
  22. package/examples/ionic/tsconfig.json +3 -2
  23. package/examples/react_native/index.tsx +49 -7
  24. package/examples/react_native/package.json +9 -9
  25. package/examples/react_native/src/main.css +60 -6
  26. package/examples/react_native/src/main.html +1 -1
  27. package/examples/react_native/src/main.tsx +54 -77
  28. package/ios/RFSWJSONConstructor.h +0 -1
  29. package/ios/RFSWJSONConstructor.m +5 -14
  30. package/ios/RFSWMain.m +30 -0
  31. package/package.json +1 -1
  32. package/plugin.xml +2 -2
  33. package/test/json.tsx +375 -0
  34. package/test/package-lock.json +584 -0
  35. package/test/package.json +9 -0
  36. package/test/test.tsx +61 -0
  37. package/test/utils.tsx +38 -0
  38. package/www/capacitor/customization/customization_fonts.js +1 -1
  39. package/www/capacitor/customization/customization_images.js +1 -1
  40. package/www/capacitor/customization/font.js +8 -0
  41. package/www/capacitor/detect_faces/detect_face_result.js +12 -0
  42. package/www/capacitor/detect_faces/detect_faces_attribute_result.js +9 -0
  43. package/www/capacitor/detect_faces/detect_faces_backend_exception.js +7 -0
  44. package/www/capacitor/detect_faces/detect_faces_config.js +34 -0
  45. package/www/capacitor/detect_faces/detect_faces_exception.js +8 -0
  46. package/www/capacitor/detect_faces/detect_faces_request.js +22 -0
  47. package/www/capacitor/detect_faces/detect_faces_response.js +9 -0
  48. package/www/capacitor/face_capture/face_capture_config.js +37 -0
  49. package/www/capacitor/face_capture/face_capture_exception.js +7 -0
  50. package/www/capacitor/face_capture/face_capture_image.js +8 -0
  51. package/www/capacitor/face_capture/face_capture_response.js +7 -0
  52. package/www/capacitor/image_params/output_image_crop.js +23 -0
  53. package/www/capacitor/image_params/output_image_params.js +19 -0
  54. package/www/capacitor/image_params/point.js +7 -0
  55. package/www/capacitor/image_params/rect.js +9 -0
  56. package/www/capacitor/image_params/size.js +12 -0
  57. package/www/capacitor/image_quality/image_quality_characteristic.js +22 -0
  58. package/www/capacitor/image_quality/image_quality_range.js +7 -0
  59. package/www/capacitor/image_quality/image_quality_result.js +10 -0
  60. package/www/capacitor/index.js +48 -0
  61. package/www/capacitor/init/face_sdk_version.js +8 -0
  62. package/www/capacitor/init/init_config.js +19 -0
  63. package/www/capacitor/init/init_exception.js +8 -0
  64. package/www/capacitor/init/license_exception.js +7 -0
  65. package/www/capacitor/internal/bridge.js +20 -1
  66. package/www/capacitor/liveness/liveness_backend_exception.js +7 -0
  67. package/www/capacitor/liveness/liveness_config.js +43 -0
  68. package/www/capacitor/liveness/liveness_exception.js +8 -0
  69. package/www/capacitor/liveness/liveness_notification.js +7 -0
  70. package/www/capacitor/liveness/liveness_response.js +11 -0
  71. package/www/capacitor/match_faces/compared_face.js +9 -0
  72. package/www/capacitor/match_faces/compared_faces_pair.js +10 -0
  73. package/www/capacitor/match_faces/compared_faces_split.js +7 -0
  74. package/www/capacitor/match_faces/match_faces_backend_exception.js +7 -0
  75. package/www/capacitor/match_faces/match_faces_config.js +19 -0
  76. package/www/capacitor/match_faces/match_faces_detection.js +9 -0
  77. package/www/capacitor/match_faces/match_faces_detection_face.js +11 -0
  78. package/www/capacitor/match_faces/match_faces_exception.js +8 -0
  79. package/www/capacitor/match_faces/match_faces_image.js +9 -0
  80. package/www/capacitor/match_faces/match_faces_request.js +27 -0
  81. package/www/capacitor/match_faces/match_faces_response.js +9 -0
  82. package/www/capacitor/person_database/edit_group_persons_request.js +15 -0
  83. package/www/capacitor/person_database/image_upload.js +17 -0
  84. package/www/capacitor/person_database/pageable_item_list.js +8 -0
  85. package/www/capacitor/person_database/person.js +13 -0
  86. package/www/capacitor/person_database/person_group.js +11 -0
  87. package/www/capacitor/person_database/person_image.js +13 -0
  88. package/www/capacitor/person_database/search_person.js +14 -0
  89. package/www/capacitor/person_database/search_person_detection.js +9 -0
  90. package/www/capacitor/person_database/search_person_image.js +15 -0
  91. package/www/capacitor/person_database/search_person_request.js +29 -0
  92. package/www/cordova.js +753 -6
  93. package/www/react-native/customization/customization_fonts.js +1 -1
  94. package/www/react-native/customization/customization_images.js +1 -1
  95. package/www/react-native/customization/font.js +8 -0
  96. package/www/react-native/detect_faces/detect_face_result.js +12 -0
  97. package/www/react-native/detect_faces/detect_faces_attribute_result.js +9 -0
  98. package/www/react-native/detect_faces/detect_faces_backend_exception.js +7 -0
  99. package/www/react-native/detect_faces/detect_faces_config.js +34 -0
  100. package/www/react-native/detect_faces/detect_faces_exception.js +8 -0
  101. package/www/react-native/detect_faces/detect_faces_request.js +22 -0
  102. package/www/react-native/detect_faces/detect_faces_response.js +9 -0
  103. package/www/react-native/face_capture/face_capture_config.js +37 -0
  104. package/www/react-native/face_capture/face_capture_exception.js +7 -0
  105. package/www/react-native/face_capture/face_capture_image.js +8 -0
  106. package/www/react-native/face_capture/face_capture_response.js +7 -0
  107. package/www/react-native/image_params/output_image_crop.js +23 -0
  108. package/www/react-native/image_params/output_image_params.js +19 -0
  109. package/www/react-native/image_params/point.js +7 -0
  110. package/www/react-native/image_params/rect.js +9 -0
  111. package/www/react-native/image_params/size.js +12 -0
  112. package/www/react-native/image_quality/image_quality_characteristic.js +22 -0
  113. package/www/react-native/image_quality/image_quality_range.js +7 -0
  114. package/www/react-native/image_quality/image_quality_result.js +10 -0
  115. package/www/react-native/index.js +48 -0
  116. package/www/react-native/init/face_sdk_version.js +8 -0
  117. package/www/react-native/init/init_config.js +19 -0
  118. package/www/react-native/init/init_exception.js +8 -0
  119. package/www/react-native/init/license_exception.js +7 -0
  120. package/www/react-native/internal/bridge.js +20 -1
  121. package/www/react-native/liveness/liveness_backend_exception.js +7 -0
  122. package/www/react-native/liveness/liveness_config.js +43 -0
  123. package/www/react-native/liveness/liveness_exception.js +8 -0
  124. package/www/react-native/liveness/liveness_notification.js +7 -0
  125. package/www/react-native/liveness/liveness_response.js +11 -0
  126. package/www/react-native/match_faces/compared_face.js +9 -0
  127. package/www/react-native/match_faces/compared_faces_pair.js +10 -0
  128. package/www/react-native/match_faces/compared_faces_split.js +7 -0
  129. package/www/react-native/match_faces/match_faces_backend_exception.js +7 -0
  130. package/www/react-native/match_faces/match_faces_config.js +19 -0
  131. package/www/react-native/match_faces/match_faces_detection.js +9 -0
  132. package/www/react-native/match_faces/match_faces_detection_face.js +11 -0
  133. package/www/react-native/match_faces/match_faces_exception.js +8 -0
  134. package/www/react-native/match_faces/match_faces_image.js +9 -0
  135. package/www/react-native/match_faces/match_faces_request.js +27 -0
  136. package/www/react-native/match_faces/match_faces_response.js +9 -0
  137. package/www/react-native/person_database/edit_group_persons_request.js +15 -0
  138. package/www/react-native/person_database/image_upload.js +17 -0
  139. package/www/react-native/person_database/pageable_item_list.js +8 -0
  140. package/www/react-native/person_database/person.js +13 -0
  141. package/www/react-native/person_database/person_group.js +11 -0
  142. package/www/react-native/person_database/person_image.js +13 -0
  143. package/www/react-native/person_database/search_person.js +14 -0
  144. package/www/react-native/person_database/search_person_detection.js +9 -0
  145. package/www/react-native/person_database/search_person_image.js +15 -0
  146. package/www/react-native/person_database/search_person_request.js +29 -0
  147. package/www/types/index.d.ts +12 -0
  148. package/www/types/match_faces/match_faces_config.d.ts +2 -0
  149. package/www/types/person_database/search_person_request.d.ts +4 -0
  150. package/examples/cordova/.vscode/launch.json +0 -28
  151. package/examples/cordova/README.md +0 -25
  152. package/examples/cordova/config.xml +0 -26
  153. package/examples/cordova/package-lock.json +0 -1327
  154. package/examples/cordova/package.json +0 -30
  155. package/examples/cordova/scripts/android.sh +0 -8
  156. package/examples/cordova/scripts/ios.sh +0 -8
  157. package/examples/cordova/scripts/setup.sh +0 -8
  158. package/examples/cordova/www/images/logo.png +0 -0
  159. package/examples/cordova/www/index.html +0 -21
  160. package/examples/cordova/www/src/main.css +0 -83
  161. package/examples/cordova/www/src/main.html +0 -25
  162. package/examples/cordova/www/src/main.js +0 -152
  163. package/examples/ionic/index.ts +0 -17
  164. package/examples/ionic/src/images/portrait.png +0 -0
  165. package/examples/react_native/package-lock.json +0 -9296
  166. /package/examples/ionic/{src/assets → assets}/.gitkeep +0 -0
  167. /package/examples/ionic/{src/images → images}/icon.png +0 -0
  168. /package/examples/{cordova/www → ionic}/images/portrait.png +0 -0
@@ -1,15 +1,19 @@
1
1
  html,
2
2
  body {
3
- width: 99%;
3
+ margin: 0;
4
+ width: 100%;
4
5
  height: 99vh;
5
6
  display: flex;
7
+ overflow: hidden;
6
8
  flex-direction: column;
7
9
  }
8
10
 
9
- .page {
10
- height: 100%;
11
- display: flex;
12
- flex-direction: column;
11
+ /* Prevent text selection */
12
+ * {
13
+ user-select: none !important;
14
+ -webkit-user-select: none !important;
15
+ -webkit-user-drag: none !important;
16
+ -webkit-touch-callout: none !important;
13
17
  }
14
18
 
15
19
  .column {
@@ -52,10 +56,14 @@ body {
52
56
  margin-top: 13px;
53
57
  }
54
58
 
59
+ .scroll {
60
+ flex-grow: 1;
61
+ overflow-y: auto;
62
+ }
63
+
55
64
  .no-scroll {
56
65
  flex-grow: 1;
57
66
  overflow-y: hidden;
58
- overflow-x: hidden;
59
67
  }
60
68
 
61
69
  .button {
@@ -67,6 +75,7 @@ body {
67
75
  color: white;
68
76
  border: none;
69
77
  padding: 10px 20px;
78
+ justify-content: center;
70
79
  font-size: 16px;
71
80
  border-radius: 100px;
72
81
  cursor: pointer;
@@ -80,4 +89,49 @@ body {
80
89
  .button:active {
81
90
  position: relative;
82
91
  top: 1px;
92
+ }
93
+
94
+ .text-button {
95
+ background: none;
96
+ border: none;
97
+ color: #2196f3;
98
+ font-size: 20px;
99
+ font-weight: bold;
100
+ padding: 5px;
101
+ }
102
+
103
+ .text-button:active {
104
+ position: relative;
105
+ top: 1px;
106
+ }
107
+
108
+ .radio {
109
+ align-items: baseline;
110
+ padding: 15px;
111
+ }
112
+
113
+ input[type="checkbox"] {
114
+ width: 20px;
115
+ height: 20px;
116
+ border: 2px solid black;
117
+ background-color: white;
118
+ display: inline-block;
119
+ position: relative;
120
+ cursor: pointer;
121
+ }
122
+
123
+ .progress-bar {
124
+ width: 75%;
125
+ padding: 3px;
126
+ margin-top: 40px;
127
+ background-color: #eee;
128
+ border-radius: 8px;
129
+ box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
130
+ }
131
+
132
+ #progress {
133
+ width: 0%;
134
+ height: 20px;
135
+ background-color: #4285F4;
136
+ border-radius: 5px;
83
137
  }
@@ -1,4 +1,4 @@
1
- <div class="page">
1
+ <div class="column" style="height: 100%">
2
2
  <div class="column header">
3
3
  <span id="status">Loading...</span>
4
4
  <div class="column divider"></div>
@@ -1,15 +1,21 @@
1
- import { Component } from '@angular/core'
2
- import { Dialogs } from '@awesome-cordova-plugins/dialogs/ngx'
3
- import { File } from '@awesome-cordova-plugins/file'
4
- import { Camera, DestinationType, MediaType, PictureSourceType } from '@awesome-cordova-plugins/camera/ngx'
5
- import { Platform } from '@ionic/angular'
6
1
  import { FaceSDK, MatchFacesRequest, MatchFacesImage, InitConfig, LivenessSkipStep, ImageType, LivenessStatus, LivenessConfig } from '@regulaforensics/face-sdk'
2
+ import { loadAssetIfExists, chooseOption, pickImage } from '../index'
3
+
4
+ var faceSdk = FaceSDK.instance
5
+ var image1: MatchFacesImage | null
6
+ var image2: MatchFacesImage | null
7
7
 
8
8
  async function init() {
9
- if (!await initialize()) return
9
+ if (!await initializeReader()) return
10
10
  setStatus("Ready")
11
11
  }
12
12
 
13
+ async function startFaceCapture(position: number) {
14
+ var image = (await faceSdk.startFaceCapture()).image
15
+ if (image == null) return
16
+ setImage("data:image/png;base64," + image.image, image.imageType, position)
17
+ }
18
+
13
19
  async function startLiveness() {
14
20
  var response = await faceSdk.startLiveness({
15
21
  config: new LivenessConfig({
@@ -40,30 +46,15 @@ async function matchFaces() {
40
46
  setStatus("Ready")
41
47
  }
42
48
 
43
- function clearResults() {
44
- setStatus("Ready")
45
- setSimilarityStatus("null")
46
- setLivenessStatus("null")
47
- resetImages()
48
- image1 = null
49
- image2 = null
50
- }
51
-
52
- // If 'regula.license' exists, init using license(enables offline match)
53
- // otherwise init without license.
54
- async function initialize() {
55
- setStatus("Initializing...")
56
-
57
- var license = await loadAssetIfExists("regula.license")
58
- var config: InitConfig | undefined
59
- if (license != null) config = new InitConfig(license)
60
- var [success, error] = await faceSdk.initialize({ config: config })
61
-
62
- if (!success && error != null) {
63
- setStatus(error.message)
64
- console.log(error.code + ": " + error.message)
49
+ async function getImage(position: number) {
50
+ var source = await chooseOption()
51
+ if (source == null) return
52
+ if (source) startFaceCapture(position)
53
+ else {
54
+ var image = await pickImage()
55
+ if (image == null) return
56
+ setImage(image, ImageType.PRINTED, position)
65
57
  }
66
- return success
67
58
  }
68
59
 
69
60
  function setImage(base64: string, type: number, position: number) {
@@ -80,82 +71,46 @@ function setImage(base64: string, type: number, position: number) {
80
71
  }
81
72
  }
82
73
 
83
- async function useCamera(position: number) {
84
- var response = await faceSdk.startFaceCapture()
85
- if (response.image == null) return
86
- var image = response.image
87
- setImage("data:image/png;base64," + image.image, image.imageType, position)
88
- }
89
-
90
- async function useGallery(position: number) {
91
- var image = await app.camera.getPicture({
92
- destinationType: DestinationType.DATA_URL,
93
- mediaType: MediaType.PICTURE,
94
- sourceType: PictureSourceType.PHOTOLIBRARY
95
- })
96
- setImage(image, ImageType.PRINTED, position)
97
- }
74
+ // If 'regula.license' exists, init using license(enables offline match)
75
+ // otherwise init without license.
76
+ async function initializeReader() {
77
+ setStatus("Initializing...")
98
78
 
99
- async function pickImage(position: number) {
100
- var option = await app.dialogs.confirm("", "Select option", ["Use gallery", "Use camera"])
101
- if (option == 1) useGallery(position)
102
- else useCamera(position)
103
- }
79
+ var license = await loadAssetIfExists("regula.license")
80
+ var config: InitConfig | undefined
81
+ if (license != null) config = new InitConfig(license)
82
+ var [success, error] = await faceSdk.initialize({ config: config })
104
83
 
105
- async function loadAssetIfExists(path: string): Promise<string | null> {
106
- try {
107
- var dir = await File.resolveDirectoryUrl(File.applicationDirectory + "www/assets")
108
- var fileEntry = await File.getFile(dir, path, null)
109
- var result = await new Promise<string | null>((resolve, _) => {
110
- fileEntry.file(file => {
111
- var reader = new FileReader()
112
- reader.onloadend = (_) => resolve(reader.result as string)
113
- reader.readAsDataURL(file)
114
- }, _ => resolve(null))
115
- })
116
- return result
117
- } catch (_) {
118
- return null
84
+ if (error != null) {
85
+ setStatus(error.message)
86
+ console.log(error.code + ": " + error.message)
119
87
  }
88
+ return success
120
89
  }
121
90
 
122
- var app: Main
123
- var faceSdk = FaceSDK.instance
124
- var image1: MatchFacesImage | null
125
- var image2: MatchFacesImage | null
91
+ // --------------------------------------------------------------------------------------------------------------------
92
+
93
+ export function main() {
94
+ document.getElementById("first-image")!.onclick = () => getImage(1)
95
+ document.getElementById("second-image")!.onclick = () => getImage(2)
96
+ document.getElementById("match-faces")!.onclick = () => matchFaces()
97
+ document.getElementById("start-liveness")!.onclick = () => startLiveness()
98
+ document.getElementById("clear-results")!.onclick = () => clearResults()
99
+
100
+ init()
101
+ }
126
102
 
127
- var setStatus = (data: string) => document.getElementById("status").innerHTML = data
128
- var setLivenessStatus = (data: string) => document.getElementById("liveness-status").innerHTML = data
129
- var setSimilarityStatus = (data: string) => document.getElementById("similarity-status").innerHTML = data
103
+ var setStatus = (data: string) => document.getElementById("status")!.innerHTML = data
104
+ var setLivenessStatus = (data: string) => document.getElementById("liveness-status")!.innerHTML = data
105
+ var setSimilarityStatus = (data: string) => document.getElementById("similarity-status")!.innerHTML = data
130
106
  var setUiImage1 = (data: string) => (document.getElementById("first-image") as HTMLImageElement).src = data
131
107
  var setUiImage2 = (data: string) => (document.getElementById("second-image") as HTMLImageElement).src = data
132
- var resetImages = () => {
108
+ var clearResults = () => {
109
+ setStatus("Ready")
110
+ setSimilarityStatus("null")
111
+ setLivenessStatus("null")
133
112
  setUiImage1("images/portrait.png")
134
113
  setUiImage2("images/portrait.png")
135
- }
136
-
137
- @Component({
138
- selector: 'app-root',
139
- templateUrl: 'main.html',
140
- styleUrl: 'main.css'
141
- })
142
- export class Main {
143
- dialogs: Dialogs
144
- camera: Camera
145
-
146
- constructor(platform: Platform, dialogs: Dialogs, camera: Camera) {
147
- platform.ready().then(() => {
148
- this.dialogs = dialogs
149
- this.camera = camera
150
- app = this
151
-
152
- document.getElementById("first-image").onclick = () => pickImage(1)
153
- document.getElementById("second-image").onclick = () => pickImage(2)
154
- document.getElementById("match-faces").onclick = () => matchFaces()
155
- document.getElementById("start-liveness").onclick = () => startLiveness()
156
- document.getElementById("clear-results").onclick = () => clearResults()
157
-
158
- init()
159
- });
160
- }
114
+ image1 = null
115
+ image2 = null
161
116
  }
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "include": [
3
- "*.ts"
3
+ "*.tsx"
4
4
  ],
5
5
  "compilerOptions": {
6
6
  "types": [],
7
7
  "module": "esnext",
8
8
  "moduleResolution": "node",
9
9
  "experimentalDecorators": true,
10
- "target": "es2022"
10
+ "target": "es2022",
11
+ "jsx": "react-jsx"
11
12
  }
12
13
  }
@@ -1,18 +1,22 @@
1
1
  import { registerRootComponent } from 'expo'
2
2
  import WebView from 'react-native-webview'
3
- import { onload } from './src/main'
3
+ import React from 'react'
4
+ import * as RNFS from 'react-native-fs'
5
+ import { Alert, Platform } from 'react-native'
6
+ import { launchImageLibrary } from 'react-native-image-picker'
7
+ import { main } from './src/main'
4
8
 
5
9
  var webViewRef: any
6
10
  const onclicks: any = {}
7
11
  const onMessage = (json: any) => {
8
12
  const event = JSON.parse(json.nativeEvent.data)
9
- if (event.id === "ready") onload()
13
+ if (event.id === "ready") main()
10
14
  if (event.id === "onclick") {
11
15
  onclicks[event.value]()
12
16
  }
13
17
  }
14
18
 
15
- export const document = {
19
+ const document = {
16
20
  getElementById(id: string): any {
17
21
  return new Proxy({}, {
18
22
  set(_, prop: string, value) {
@@ -24,29 +28,67 @@ export const document = {
24
28
  }; true
25
29
  `)
26
30
  } else
27
- webViewRef.injectJavaScript(`document.getElementById("${id}").${prop} = "${value}"; true`)
31
+ webViewRef.injectJavaScript(`document.getElementById("${id}").${prop} = ${parseValue(value)}; true`)
28
32
  return true
29
33
  },
30
34
  get(_, prop: string) {
31
35
  if (prop === "style") return new Proxy({}, {
32
36
  set(_, styleProp: string, value) {
33
- webViewRef.injectJavaScript(`document.getElementById("${id}").style.${styleProp} = "${value}"; true`)
37
+ webViewRef.injectJavaScript(`document.getElementById("${id}").style.${styleProp} = ${parseValue(value)}; true`)
34
38
  return true
35
39
  }
36
40
  })
41
+ if (prop === "insertAdjacentHTML") return (position: string, html: string) => {
42
+ webViewRef.injectJavaScript(`document.getElementById("${id}").insertAdjacentHTML('${position}', \`${html}\`); true`)
43
+ return true
44
+ }
37
45
  return undefined
38
- },
46
+ }
39
47
  }
40
48
  )
41
49
  }
42
50
  }
43
51
 
52
+ function parseValue(value: any) {
53
+ if (value !== true && value !== false) return `"${value}"`
54
+ return value
55
+ }
56
+
57
+ (globalThis as any).document = document;
44
58
  registerRootComponent(() =>
45
59
  <WebView
46
60
  ref={ref => { webViewRef = ref }}
47
61
  onMessage={onMessage}
48
62
  source={require("./index.html")}
49
63
  scrollEnabled={false}
50
- injectedJavaScript="document.body.addEventListener('touchmove', function(e) { e.preventDefault() }, { passive: false })"
64
+ overScrollMode={'content'}
51
65
  />
52
66
  )
67
+
68
+ export async function loadAssetIfExists(path: string): Promise<string | null> {
69
+ if (Platform.OS === 'ios') path = RNFS.MainBundlePath + "/" + path
70
+ var readFile = Platform.OS === 'ios' ? RNFS.readFile : RNFS.readFileRes
71
+ try {
72
+ return await readFile(path, 'base64')
73
+ } catch {
74
+ return null
75
+ }
76
+ }
77
+
78
+ export async function pickImage(): Promise<string | null> {
79
+ var response = await launchImageLibrary({
80
+ mediaType: 'photo',
81
+ selectionLimit: 1,
82
+ includeBase64: true
83
+ })
84
+ return "data:image/png;base64," + response?.assets?.[0].base64!
85
+ }
86
+
87
+ export async function chooseOption(): Promise<boolean | null> {
88
+ return new Promise<boolean | null>((resolve) => {
89
+ Alert.alert("Select option", "", [
90
+ { text: "Use gallery", onPress: () => { resolve(false) } },
91
+ { text: "Use camera", onPress: () => { resolve(true) } }
92
+ ], { cancelable: true, onDismiss: () => resolve(null) })
93
+ })
94
+ }
@@ -8,19 +8,19 @@
8
8
  "start": "expo start"
9
9
  },
10
10
  "dependencies": {
11
- "@regulaforensics/face-sdk": "7.2.408-rc",
12
- "@regulaforensics/face-core-basic": "7.2.241-rc",
13
- "react-native": "0.79.2",
11
+ "@regulaforensics/face-sdk": "7.2.414-beta",
12
+ "@regulaforensics/face-core-basic": "7.1.240-nightly",
13
+ "react-native": "0.79.5",
14
14
  "react-native-fs": "2.20.0",
15
15
  "react-native-image-picker": "8.2.1",
16
- "react-native-webview": "13.13.5",
17
- "@react-native/metro-config": "0.79.2",
16
+ "react-native-webview": "13.15.0",
17
+ "@react-native/metro-config": "0.79.5",
18
18
  "react": "19.1.0",
19
- "@types/react": "19.1.4",
20
- "expo": "53.0.9",
21
- "expo-dev-client": "5.1.8",
19
+ "@types/react": "19.1.8",
20
+ "expo": "53.0.20",
21
+ "expo-dev-client": "5.2.4",
22
22
  "expo-custom-assets": "1.4.1",
23
- "expo-build-properties": "0.14.6",
23
+ "expo-build-properties": "0.14.8",
24
24
  "typescript": "5.8.3"
25
25
  }
26
26
  }
@@ -1,15 +1,19 @@
1
1
  html,
2
2
  body {
3
- width: 99%;
3
+ margin: 0;
4
+ width: 100%;
4
5
  height: 99vh;
5
6
  display: flex;
7
+ overflow: hidden;
6
8
  flex-direction: column;
7
9
  }
8
10
 
9
- .page {
10
- height: 100%;
11
- display: flex;
12
- flex-direction: column;
11
+ /* Prevent text selection */
12
+ * {
13
+ user-select: none !important;
14
+ -webkit-user-select: none !important;
15
+ -webkit-user-drag: none !important;
16
+ -webkit-touch-callout: none !important;
13
17
  }
14
18
 
15
19
  .column {
@@ -52,10 +56,14 @@ body {
52
56
  margin-top: 13px;
53
57
  }
54
58
 
59
+ .scroll {
60
+ flex-grow: 1;
61
+ overflow-y: auto;
62
+ }
63
+
55
64
  .no-scroll {
56
65
  flex-grow: 1;
57
66
  overflow-y: hidden;
58
- overflow-x: hidden;
59
67
  }
60
68
 
61
69
  .button {
@@ -67,6 +75,7 @@ body {
67
75
  color: white;
68
76
  border: none;
69
77
  padding: 10px 20px;
78
+ justify-content: center;
70
79
  font-size: 16px;
71
80
  border-radius: 100px;
72
81
  cursor: pointer;
@@ -80,4 +89,49 @@ body {
80
89
  .button:active {
81
90
  position: relative;
82
91
  top: 1px;
92
+ }
93
+
94
+ .text-button {
95
+ background: none;
96
+ border: none;
97
+ color: #2196f3;
98
+ font-size: 20px;
99
+ font-weight: bold;
100
+ padding: 5px;
101
+ }
102
+
103
+ .text-button:active {
104
+ position: relative;
105
+ top: 1px;
106
+ }
107
+
108
+ .radio {
109
+ align-items: baseline;
110
+ padding: 15px;
111
+ }
112
+
113
+ input[type="checkbox"] {
114
+ width: 20px;
115
+ height: 20px;
116
+ border: 2px solid black;
117
+ background-color: white;
118
+ display: inline-block;
119
+ position: relative;
120
+ cursor: pointer;
121
+ }
122
+
123
+ .progress-bar {
124
+ width: 75%;
125
+ padding: 3px;
126
+ margin-top: 40px;
127
+ background-color: #eee;
128
+ border-radius: 8px;
129
+ box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
130
+ }
131
+
132
+ #progress {
133
+ width: 0%;
134
+ height: 20px;
135
+ background-color: #4285F4;
136
+ border-radius: 5px;
83
137
  }
@@ -1,4 +1,4 @@
1
- <div class="page">
1
+ <div class="column" style="height: 100%">
2
2
  <div class="column header">
3
3
  <span id="status">Loading...</span>
4
4
  <div class="column divider"></div>