react-native-okaycam 3.0.4 → 3.0.5
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/README.md +42 -131
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/innov8tif/rnokaycam/RNOkayCamModule.java +18 -5
- package/index.ts +20 -10
- package/ios/RNOkayCam.swift +65 -51
- package/package.json +1 -1
- package/react-native-okaycam.podspec +1 -1
package/README.md
CHANGED
|
@@ -46,22 +46,25 @@ use_frameworks!
|
|
|
46
46
|
|
|
47
47
|
post_install do |installer|
|
|
48
48
|
installer.pods_project.targets.each do |target|
|
|
49
|
-
if target.name == "CryptoSwift"
|
|
50
|
-
puts "Enable module stability for CryptoSwift"
|
|
51
|
-
target.build_configurations.each do |config|
|
|
52
|
-
config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
49
|
if (target.name&.eql?('FBReactNativeSpec'))
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
50
|
+
target.build_phases.each do |build_phase|
|
|
51
|
+
if (build_phase.respond_to?(:name) && build_phase.name.eql?('[CP-User] Generate Specs'))
|
|
52
|
+
target.build_phases.move(build_phase, 0)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
61
55
|
end
|
|
62
56
|
target.build_configurations.each do |config|
|
|
63
57
|
config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
|
|
64
58
|
config.build_settings["ONLY_ACTIVE_ARCH"] = "NO"
|
|
59
|
+
if target.name == "CryptoSwift"
|
|
60
|
+
puts "Enable module stability for CryptoSwift"
|
|
61
|
+
config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
if target.name == 'fmt'
|
|
65
|
+
puts "Enable module stability for fmt"
|
|
66
|
+
config.build_settings['CLANG_CXX_LANGUAGE_STANDARD'] = 'c++17'
|
|
67
|
+
end
|
|
65
68
|
end
|
|
66
69
|
end
|
|
67
70
|
end
|
|
@@ -106,134 +109,42 @@ const license = Platform.select({
|
|
|
106
109
|
|
|
107
110
|
### Configuration
|
|
108
111
|
|
|
109
|
-
| -
|
|
110
|
-
|
|
|
111
|
-
|
|
|
112
|
-
|
|
|
113
|
-
|
|
|
114
|
-
|
|
|
115
|
-
|
|
|
116
|
-
|
|
|
117
|
-
|
|
|
118
|
-
| - | showOverlay | transparent black overlay | true |
|
|
119
|
-
| topLabel | text | text of the top label | ""(empty string) |
|
|
120
|
-
| topLabel | color | color of the top label | #ffffff |
|
|
121
|
-
| topLabel | size | text size of the top label | 20 |
|
|
122
|
-
| bottomLabel | text | text of the bottom label | ""(empty string) |
|
|
123
|
-
| bottomLabel | color | color of the bottom label | #ffffff |
|
|
124
|
-
| bottomLabel | size | text size of the bottom label | 20 |
|
|
125
|
-
| timer | backgroundColor | background of the count down timer | #ffa500 |
|
|
126
|
-
| timer | textColor | text color of the count down timer | #ffffff |
|
|
127
|
-
| confirmBtnConfig | backgroundColor | background color of the confirm button | #ffa500 |
|
|
128
|
-
| confirmBtnConfig | contentColor | content color of the confirm button | #ffffff |
|
|
129
|
-
| retakeBtnConfig | backgroundColor | background color of the retake button | #ffa500 |
|
|
130
|
-
| retakeBtnConfig | contentColor | content color of the retake button | #ffffff |
|
|
131
|
-
| - | captureBtnColor | color of the capture button | #ffffff |
|
|
132
|
-
| - | firstPhotoConfig | config for the first capture | delay:0s,onFlash:false,outputPath: null |
|
|
133
|
-
| - | secondPhotoConfig | config for the second capture | null |
|
|
134
|
-
| preview | title | title on preview screen | ""(empty string) |
|
|
135
|
-
| preview | refImg | ref image on preview screen | null |
|
|
136
|
-
| preview | instruction1 | instruction on preview screen | ""(empty string) |
|
|
137
|
-
| preview | instruction2 | instruction on preview screen | ""(empty string) |
|
|
138
|
-
| preview | instruction3 | instruction on preview screen | ""(empty string) |
|
|
139
|
-
| preview | backgroundColor | background color of preview screen | null |
|
|
140
|
-
| instruction <sup>**New**</sup> | title | Instruction's title on camera caputre screen | ""(empty string) |
|
|
141
|
-
| instruction <sup>**New**</sup> | refImage1 | Instruction's reference image 1 | null |
|
|
142
|
-
| instruction <sup>**New**</sup> | refImage2 | Instruction's reference image 2 | null |
|
|
143
|
-
| - | showPreviewInstruction | Show or hide preview instruction for captured photos | false |
|
|
144
|
-
| - | autoCapture <sup>**New**</sup> | Boolean to auto capture document | false |
|
|
112
|
+
| - | Property name | Description | Default value |
|
|
113
|
+
| ----------------------- | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
|
|
114
|
+
| | width | width to resize the image | 2000 |
|
|
115
|
+
| | imageQuality | quality of cropped image | 1.0f |
|
|
116
|
+
| | **<sup>New</sup>** autoCapture | When set to `true`, the system will automatically capture the document once it is properly detected and aligned. When set to `false`, the user must manually trigger the capture instead. | true |
|
|
117
|
+
| **<sup>New</sup>** mode | FULL | Captures front of document, front of document with flash, and back of document automatically. This is the default mode for complete document capture. | ✅ |
|
|
118
|
+
| | FRONT_ONLY | Captures only the front of document. | ❌ |
|
|
119
|
+
| | FRONT_BACK | Captures both front and back of document automatically without flash. | ❌ |
|
|
120
|
+
| | FRONT_WITH_FLASH | Captures the front of document with flash enabled | ❌ |
|
|
145
121
|
|
|
146
122
|
## Usage
|
|
147
123
|
|
|
148
124
|
```
|
|
149
|
-
import { captureDocument } from "react-native-okaycam"
|
|
150
|
-
|
|
151
|
-
captureDocument(
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
size: 20
|
|
163
|
-
},
|
|
164
|
-
frame: {
|
|
165
|
-
size: {
|
|
166
|
-
width: 1000,
|
|
167
|
-
height: 300,
|
|
168
|
-
},
|
|
169
|
-
color: "#4287f5",
|
|
170
|
-
content: require('./images/content.svg')
|
|
171
|
-
},
|
|
172
|
-
showOverlay: true,
|
|
173
|
-
timer: {
|
|
174
|
-
backgroundColor: "#4287f5",
|
|
175
|
-
textColor: "#ffffff"
|
|
176
|
-
},
|
|
177
|
-
torchBtnEnabled: true,
|
|
178
|
-
confirmBtnConfig: {
|
|
179
|
-
backgroundColor: "#4287f5",
|
|
180
|
-
contentColor: "#000000"
|
|
181
|
-
},
|
|
182
|
-
retakeBtnConfig: {
|
|
183
|
-
backgroundColor: "#4287f5",
|
|
184
|
-
contentColor: "#000000"
|
|
185
|
-
},
|
|
186
|
-
captureBtnColor: "#4287f5",
|
|
187
|
-
firstPhotoConfig: {
|
|
188
|
-
delay: 0,
|
|
189
|
-
onFlash: false,
|
|
190
|
-
outputPath: null
|
|
191
|
-
},
|
|
192
|
-
secondPhotoConfig: {
|
|
193
|
-
delay: 5,
|
|
194
|
-
onFlash: true,
|
|
195
|
-
outputPath: null
|
|
196
|
-
},
|
|
197
|
-
crop: true,
|
|
198
|
-
width: 2000,
|
|
199
|
-
imageQuality: 1.0,
|
|
200
|
-
preview: {
|
|
201
|
-
title: {text: 'testing', color: '#000000', size: 25},
|
|
202
|
-
refImage: require('./images/ref.png'),
|
|
203
|
-
instruction1: {text: 'instr1', color: '#000000', size: 14},
|
|
204
|
-
instruction2: {text: 'instr2', color: '#000000', size: 14},
|
|
205
|
-
instruction3: {text: 'instr3', color: '#000000', size: 14},
|
|
206
|
-
backgroundColor: '#374fff',
|
|
207
|
-
},
|
|
208
|
-
instruction: {
|
|
209
|
-
title: {text: 'instr1', color: '#ffffff', size: 14},
|
|
210
|
-
refImage1: {
|
|
211
|
-
title: {text: 'ref1', color: '#ffffff', size: 14},
|
|
212
|
-
img: require('./images/ref.png'),
|
|
213
|
-
},
|
|
214
|
-
refImage2: {
|
|
215
|
-
title: {text: 'ref2', color: '#ffffff', size: 14},
|
|
216
|
-
img: require('./images/ref.png'),
|
|
217
|
-
},
|
|
218
|
-
},
|
|
219
|
-
showPreviewInstruction: false,
|
|
220
|
-
autoCapture: true
|
|
221
|
-
}
|
|
222
|
-
)
|
|
223
|
-
.then(result => {
|
|
224
|
-
console.log(result)
|
|
225
|
-
})
|
|
226
|
-
.catch(error => {
|
|
227
|
-
console.log(error)
|
|
228
|
-
})
|
|
125
|
+
import { captureDocument, DocumentCaptureMode } from "react-native-okaycam"
|
|
126
|
+
|
|
127
|
+
captureDocument(license, false, {
|
|
128
|
+
width: 2000,
|
|
129
|
+
imageQuality: 0.8,
|
|
130
|
+
mode: DocumentCaptureMode.FULL,
|
|
131
|
+
})
|
|
132
|
+
.then(result => {
|
|
133
|
+
console.log(JSON.stringify(result));
|
|
134
|
+
})
|
|
135
|
+
.catch(error => {
|
|
136
|
+
console.log(JSON.stringify(error));
|
|
137
|
+
});
|
|
229
138
|
```
|
|
230
139
|
|
|
231
140
|
### Result
|
|
232
141
|
|
|
233
|
-
| Result | Description
|
|
234
|
-
| ------------------ |
|
|
235
|
-
| fullDocumentImage | Result of
|
|
236
|
-
| fullDocumentImage2 | Result of
|
|
142
|
+
| Result | Description |
|
|
143
|
+
| ------------------ | ------------------------------ |
|
|
144
|
+
| fullDocumentImage | Result of first photo |
|
|
145
|
+
| fullDocumentImage2 | Result of first photo cropped |
|
|
146
|
+
| fullDocumentImage3 | Result of second photo |
|
|
147
|
+
| fullDocumentImage4 | Result of second photo cropped |
|
|
237
148
|
|
|
238
149
|
## OkayCam Selfie
|
|
239
150
|
|
package/android/build.gradle
CHANGED
|
@@ -44,7 +44,7 @@ repositories {
|
|
|
44
44
|
|
|
45
45
|
dependencies {
|
|
46
46
|
compileOnly "com.facebook.react:react-android"
|
|
47
|
-
implementation('com.innov8tif.okaycam:OkayCam:3.0.
|
|
47
|
+
implementation('com.innov8tif.okaycam:OkayCam:3.0.11@aar') {
|
|
48
48
|
transitive = true
|
|
49
49
|
exclude group: "junit", module: "junit"
|
|
50
50
|
exclude group: "org.hamcrest", module: "hamcrest-core"
|
|
@@ -7,6 +7,7 @@ import android.graphics.BitmapFactory;
|
|
|
7
7
|
import android.graphics.Canvas;
|
|
8
8
|
import android.graphics.Color;
|
|
9
9
|
import android.util.Size;
|
|
10
|
+
import android.util.Log;
|
|
10
11
|
|
|
11
12
|
import com.caverock.androidsvg.PreserveAspectRatio;
|
|
12
13
|
import com.caverock.androidsvg.RenderOptions;
|
|
@@ -62,12 +63,24 @@ public class RNOkayCamModule extends ReactContextBaseJavaModule {
|
|
|
62
63
|
ReadableMap userConfig = configs.getMap("config");
|
|
63
64
|
OkayCamAutoCaptureConfig config = OkayCamAutoCaptureConfig.init();
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
// config.setWidth(userConfig.getInt("width"));
|
|
67
|
-
// }
|
|
66
|
+
Log.d("OkayCam", "userConfig: " + userConfig.toString());
|
|
68
67
|
|
|
69
|
-
if (userConfig.
|
|
70
|
-
|
|
68
|
+
if (userConfig.hasKey("width") && !userConfig.isNull("width")) {
|
|
69
|
+
int width = userConfig.getInt("width");
|
|
70
|
+
if (width != -1) {
|
|
71
|
+
config.setWidth(width);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (userConfig.hasKey("imageQuality") && !userConfig.isNull("imageQuality")) {
|
|
76
|
+
double quality = userConfig.getDouble("imageQuality");
|
|
77
|
+
if (quality > 0.0) {
|
|
78
|
+
config.setImageQuality((float) quality);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (userConfig.hasKey("autoCapture") && !userConfig.isNull("autoCapture")) {
|
|
83
|
+
config.setAutoCapture(userConfig.getBoolean("autoCapture"));
|
|
71
84
|
}
|
|
72
85
|
|
|
73
86
|
config.setMode(parseMode(userConfig.getString("mode")));
|
package/index.ts
CHANGED
|
@@ -22,7 +22,7 @@ interface OkayCamBtnConfig {
|
|
|
22
22
|
|
|
23
23
|
interface SwitchBtnConfig {
|
|
24
24
|
color: string;
|
|
25
|
-
show:
|
|
25
|
+
show: boolean;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
type cameraFacingType = "front" | "back";
|
|
@@ -46,14 +46,23 @@ const okayCamBtnConfig: OkayCamBtnConfig = {
|
|
|
46
46
|
// cal native capture document
|
|
47
47
|
export const captureDocument = (
|
|
48
48
|
license: string,
|
|
49
|
-
base64:
|
|
50
|
-
{
|
|
49
|
+
base64: boolean,
|
|
50
|
+
config: {
|
|
51
|
+
width?: number;
|
|
52
|
+
imageQuality?: number;
|
|
53
|
+
mode?: string;
|
|
54
|
+
autoCapture?: boolean;
|
|
55
|
+
} = {},
|
|
56
|
+
) => {
|
|
57
|
+
const {
|
|
51
58
|
width = imageResizedWidth,
|
|
52
59
|
imageQuality = 1.0,
|
|
53
60
|
mode = DocumentCaptureMode.FULL,
|
|
54
|
-
|
|
55
|
-
|
|
61
|
+
autoCapture = true,
|
|
62
|
+
} = config;
|
|
56
63
|
return new Promise(function (resolve, reject) {
|
|
64
|
+
console.log(`autoCapture: ${autoCapture}`);
|
|
65
|
+
console.log(`mode: ${mode}`);
|
|
57
66
|
RNOkayCam.captureDocument({
|
|
58
67
|
license: license,
|
|
59
68
|
base64: base64,
|
|
@@ -61,12 +70,13 @@ export const captureDocument = (
|
|
|
61
70
|
width: width,
|
|
62
71
|
imageQuality: imageQuality,
|
|
63
72
|
mode: mode,
|
|
73
|
+
autoCapture: autoCapture,
|
|
64
74
|
},
|
|
65
75
|
})
|
|
66
|
-
.then((result) => {
|
|
76
|
+
.then((result: string) => {
|
|
67
77
|
resolve(JSON.parse(result));
|
|
68
78
|
})
|
|
69
|
-
.catch((error) => {
|
|
79
|
+
.catch((error: any) => {
|
|
70
80
|
reject(error);
|
|
71
81
|
});
|
|
72
82
|
});
|
|
@@ -82,7 +92,7 @@ const cameraFacing: cameraFacingType = "front";
|
|
|
82
92
|
// call native capture selfie
|
|
83
93
|
export const captureSelfie = (
|
|
84
94
|
license: string,
|
|
85
|
-
base64:
|
|
95
|
+
base64: boolean,
|
|
86
96
|
{
|
|
87
97
|
topLabel = labelConfig,
|
|
88
98
|
bottomFrameColor = defaultColor2,
|
|
@@ -111,10 +121,10 @@ export const captureSelfie = (
|
|
|
111
121
|
imageQuality: imageQuality,
|
|
112
122
|
},
|
|
113
123
|
})
|
|
114
|
-
.then((result) => {
|
|
124
|
+
.then((result: string) => {
|
|
115
125
|
resolve(JSON.parse(result));
|
|
116
126
|
})
|
|
117
|
-
.catch((error) => {
|
|
127
|
+
.catch((error: any) => {
|
|
118
128
|
reject(error);
|
|
119
129
|
});
|
|
120
130
|
});
|
package/ios/RNOkayCam.swift
CHANGED
|
@@ -15,75 +15,89 @@ class RNOkayCam: NSObject {
|
|
|
15
15
|
var promiseResolve: RCTPromiseResolveBlock?
|
|
16
16
|
var promiseReject: RCTPromiseRejectBlock?
|
|
17
17
|
|
|
18
|
-
@objc func captureDocument(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
let
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
@objc func captureDocument(
|
|
19
|
+
_ configs: NSDictionary,
|
|
20
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
21
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
22
|
+
) {
|
|
23
|
+
|
|
24
|
+
guard let license = configs["license"] as? String else {
|
|
25
|
+
reject("invalid_license", "Missing license", nil)
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let base64 = configs["base64"] as? Bool ?? false
|
|
30
|
+
let rnOkayCamConfig = configs["config"] as? NSDictionary ?? [:]
|
|
31
|
+
|
|
32
|
+
let width = rnOkayCamConfig["width"] as? Int
|
|
33
|
+
let imageQuality = rnOkayCamConfig["imageQuality"] as? CGFloat
|
|
34
|
+
let mode = rnOkayCamConfig["mode"] as? String
|
|
35
|
+
let autoCapture = rnOkayCamConfig["autoCapture"] as? Bool
|
|
36
|
+
|
|
28
37
|
DispatchQueue.main.async {
|
|
29
38
|
guard let rootViewController = UIApplication.shared.windows.first?.rootViewController else {
|
|
30
39
|
reject("no_root_view_controller", "Root view controller not found", nil)
|
|
31
40
|
return
|
|
32
41
|
}
|
|
33
|
-
|
|
42
|
+
|
|
34
43
|
let config = OkayCamAutoCaptureConfig(viewController: rootViewController)
|
|
35
|
-
|
|
36
|
-
// if (width != -1) {
|
|
37
|
-
// config.width = width
|
|
38
|
-
// }
|
|
39
44
|
|
|
40
|
-
|
|
45
|
+
// width
|
|
46
|
+
if let width = width, width != -1 {
|
|
47
|
+
config.width = width
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// image quality
|
|
51
|
+
if let imageQuality = imageQuality, imageQuality > 0.0 {
|
|
41
52
|
config.imageQuality = imageQuality
|
|
42
53
|
}
|
|
43
54
|
|
|
55
|
+
// ✅ FIX: allow false
|
|
56
|
+
if let autoCapture = autoCapture {
|
|
57
|
+
config.autoCapture = autoCapture
|
|
58
|
+
}
|
|
59
|
+
|
|
44
60
|
config.mode = self.parseMode(mode)
|
|
45
61
|
|
|
46
|
-
// start the SDK
|
|
47
62
|
OkayCamDocAutoCapture.start(
|
|
48
63
|
okayCamConfig: config,
|
|
49
|
-
license: license
|
|
50
|
-
|
|
51
|
-
// handle error
|
|
52
|
-
do {
|
|
53
|
-
if let failed = error {
|
|
54
|
-
print(failed)
|
|
55
|
-
self.handleError(failed, rejecter: reject)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// handle success
|
|
59
|
-
if let urls = filePaths {
|
|
60
|
-
let okayCamObject:NSMutableDictionary = NSMutableDictionary()
|
|
61
|
-
|
|
62
|
-
okayCamObject.setValue(self.convertImgToBase64(base64: base64, image: urls[0]), forKey: "fullDocumentImage")
|
|
63
|
-
|
|
64
|
-
if (filePaths!.count > 1) {
|
|
65
|
-
okayCamObject.setValue(self.convertImgToBase64(base64: base64, image: urls[1]), forKey: "fullDocumentImage2")
|
|
66
|
-
}
|
|
64
|
+
license: license
|
|
65
|
+
) { filePaths, error in
|
|
67
66
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
67
|
+
if let error = error {
|
|
68
|
+
self.handleError(error, rejecter: reject)
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
guard let urls = filePaths else {
|
|
73
|
+
reject("no_result", "No images returned", nil)
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
do {
|
|
78
|
+
let result: NSMutableDictionary = [:]
|
|
79
|
+
|
|
80
|
+
result["fullDocumentImage"] = self.convertImgToBase64(base64: base64, image: urls[0])
|
|
81
|
+
|
|
82
|
+
if urls.count > 1 {
|
|
83
|
+
result["fullDocumentImage2"] = self.convertImgToBase64(base64: base64, image: urls[1])
|
|
81
84
|
}
|
|
82
|
-
|
|
83
|
-
|
|
85
|
+
if urls.count > 2 {
|
|
86
|
+
result["fullDocumentImage3"] = self.convertImgToBase64(base64: base64, image: urls[2])
|
|
84
87
|
}
|
|
88
|
+
if urls.count > 3 {
|
|
89
|
+
result["fullDocumentImage4"] = self.convertImgToBase64(base64: base64, image: urls[3])
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
let jsonData = try JSONSerialization.data(withJSONObject: result)
|
|
93
|
+
let jsonString = String(data: jsonData, encoding: .utf8)!
|
|
94
|
+
|
|
95
|
+
resolve(jsonString)
|
|
96
|
+
|
|
97
|
+
} catch {
|
|
98
|
+
reject("json_error", error.localizedDescription, error)
|
|
85
99
|
}
|
|
86
|
-
|
|
100
|
+
}
|
|
87
101
|
}
|
|
88
102
|
}
|
|
89
103
|
|
package/package.json
CHANGED