react-native-scanbot-barcode-scanner-sdk 3.2.1-beta6 → 3.2.1-beta9

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 (37) hide show
  1. package/android/.project +6 -0
  2. package/android/build.gradle +2 -2
  3. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  4. package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  5. package/android/gradlew +185 -0
  6. package/android/gradlew.bat +89 -0
  7. package/android/src/main/java/com/reactlibrary/ScanbotBarcodeSdkPackage.java +17 -4
  8. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/ObjectMapper.java +6 -0
  9. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/ScanbotBarcodeSdkPackage.java +15 -5
  10. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/barcodecameraview/RNScanbotBarcodeCameraComponent.java +292 -0
  11. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/barcodecameraview/{ScanbotBarcodeCameraViewConfiguration.java → RNScanbotBarcodeCameraConfiguration.java} +54 -4
  12. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/barcodecameraview/RNScanbotBarcodeCameraUi.java +81 -0
  13. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/base/RNScanbotNativeComponent.java +90 -0
  14. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/base/RNScanbotNativeComponentManager.java +133 -0
  15. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/base/RNScanbotNativeComponentManagerFactory.java +40 -0
  16. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/base/RNScanbotNativeComponentUi.java +131 -0
  17. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/{EventEmitter.java → base/communication/RNScanbotEventEmitter.java} +27 -6
  18. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/base/communication/RNScanbotEventReceiver.java +108 -0
  19. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/{common/ScanbotComponentFrameLayout.java → base/views/RNScanbotNativeComponentFrameLayout.java} +4 -4
  20. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/{common/ScanbotComponentRootView.java → base/views/RNScanbotNativeComponentRootView.java} +43 -48
  21. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/utils/JSONUtils.java +25 -14
  22. package/android/src/main/res/layout/component_barcode_camera_view.xml +22 -5
  23. package/index.d.ts +7 -3
  24. package/ios/Components/BarcodeCameraView/RNScanbotBarcodeCameraView.h +7 -1
  25. package/ios/Components/BarcodeCameraView/RNScanbotBarcodeCameraView.m +18 -2
  26. package/ios/Components/BarcodeCameraView/RNScanbotBarcodeCameraViewManager.h +6 -0
  27. package/ios/Components/BarcodeCameraView/RNScanbotBarcodeCameraViewManager.m +41 -0
  28. package/ios/Utils/BarcodeMapping.h +3 -1
  29. package/package.json +1 -1
  30. package/src/components/barcode-camera-view/scanbot-barcode-camera-view-types.tsx +6 -0
  31. package/src/components/barcode-camera-view/scanbot-barcode-camera-view.tsx +42 -5
  32. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/BitmapHelper.java +0 -28
  33. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/JSONUtils.java +0 -272
  34. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/LogUtils.java +0 -40
  35. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/ResponseUtils.java +0 -41
  36. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/barcodecameraview/ScanbotBarcodeCameraViewFragment.java +0 -255
  37. package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/barcodecameraview/ScanbotBarcodeCameraViewManager.java +0 -160
@@ -0,0 +1,292 @@
1
+ package io.scanbot.barcodesdk.plugin.reactnative.components.barcodecameraview;;
2
+
3
+ import android.Manifest;
4
+ import android.app.Activity;
5
+ import android.content.pm.PackageManager;
6
+ import android.graphics.Color;
7
+ import android.view.View;
8
+
9
+ import androidx.annotation.ColorInt;
10
+ import androidx.annotation.NonNull;
11
+ import androidx.annotation.Nullable;
12
+ import androidx.core.app.ActivityCompat;
13
+ import androidx.core.content.ContextCompat;
14
+
15
+ import com.facebook.react.bridge.ReactContext;
16
+ import com.facebook.react.bridge.ReadableArray;
17
+ import com.facebook.react.bridge.ReadableMap;
18
+ import com.facebook.react.bridge.WritableArray;
19
+ import com.facebook.react.bridge.WritableMap;
20
+ import com.facebook.react.bridge.WritableNativeArray;
21
+
22
+ import org.jetbrains.annotations.NotNull;
23
+
24
+ import java.util.Collections;
25
+ import java.util.List;
26
+
27
+ import io.scanbot.sdk.SdkLicenseError;
28
+ import io.scanbot.sdk.barcode.BarcodeDetectorFrameHandler;
29
+ import io.scanbot.sdk.barcode.DefaultScanbotBarcodeDetector;
30
+ import io.scanbot.sdk.barcode.ScanbotBarcodeDetector;
31
+ import io.scanbot.sdk.barcode.entity.BarcodeItem;
32
+ import io.scanbot.sdk.barcode.entity.BarcodeScannerAdditionalConfig;
33
+ import io.scanbot.sdk.barcode.entity.BarcodeScanningResult;
34
+ import io.scanbot.sdk.camera.FrameHandlerResult;
35
+ import io.scanbot.barcodesdk.plugin.reactnative.utils.JSONUtils;
36
+ import io.scanbot.barcodesdk.plugin.reactnative.components.base.communication.RNScanbotEventEmitter;
37
+ import io.scanbot.barcodesdk.plugin.reactnative.components.base.communication.RNScanbotEventReceiver;
38
+ import io.scanbot.barcodesdk.plugin.reactnative.components.base.RNScanbotNativeComponent;
39
+ import io.scanbot.barcodesdk.plugin.reactnative.components.base.RNScanbotNativeComponentUi;
40
+ import io.scanbot.barcodesdk.plugin.reactnative.components.base.views.RNScanbotNativeComponentRootView;
41
+ import io.scanbot.sdk.ui.camera.FinderOverlayView;
42
+ import io.scanbot.sdk.ui.camera.ScanbotCameraXView;
43
+ import kotlin.Unit;
44
+
45
+ /*
46
+ * The core logic of the ScanbotBarcodeCameraView Component
47
+ */
48
+ public class RNScanbotBarcodeCameraComponent extends RNScanbotNativeComponent implements BarcodeDetectorFrameHandler.ResultHandler {
49
+
50
+ private static final int REQUEST_PERMISSION_CODE = 200;
51
+
52
+ // From Java to JavaScript
53
+ public enum NativeEvents implements RNScanbotEventEmitter.NativeEvent {
54
+ BARCODE_SCANNER_RESULT("onBarcodeScannerResult");
55
+
56
+ private final String name;
57
+ NativeEvents(final String name) {
58
+ this.name = name;
59
+ }
60
+
61
+ public String getName() {
62
+ return name;
63
+ }
64
+ }
65
+
66
+ // UI
67
+ private RNScanbotBarcodeCameraUi barcodeCameraUi;
68
+ private ScanbotBarcodeDetector barcodeDetector;
69
+ private BarcodeDetectorFrameHandler frameHandler;
70
+
71
+ // Communication
72
+ private RNScanbotEventEmitter eventEmitter;
73
+
74
+ // Configuration
75
+ private RNScanbotBarcodeCameraConfiguration configuration = new RNScanbotBarcodeCameraConfiguration();
76
+ private float userDefinedCameraZoomFactor = -1;
77
+
78
+ // Dependencies
79
+ private final ReactContext reactContext;
80
+
81
+ // State handling
82
+ private boolean isInitialized = false;
83
+
84
+ public RNScanbotBarcodeCameraComponent(@NonNull final ReactContext reactContext) {
85
+ super(reactContext);
86
+ this.reactContext = reactContext;
87
+ this.barcodeCameraUi = new RNScanbotBarcodeCameraUi(reactContext);
88
+ }
89
+
90
+ // ---------------------
91
+ // Component Lifecycle
92
+ // ---------------------
93
+ @Override
94
+ public void onComponentWillUnmount() {
95
+ super.onComponentWillUnmount();
96
+ final ScanbotCameraXView cameraView = this.barcodeCameraUi.getCameraView();
97
+ cameraView.stopPreview();
98
+ }
99
+
100
+ @Override
101
+ public void onOrientationChanged() {
102
+ super.onOrientationChanged();
103
+ }
104
+ // ---------------------
105
+
106
+ @Override
107
+ public void initializeComponent() {
108
+ final ScanbotCameraXView cameraView = this.barcodeCameraUi.getCameraView();
109
+ cameraView.startPreview();
110
+
111
+ this.barcodeDetector = new DefaultScanbotBarcodeDetector();
112
+
113
+ this.frameHandler = BarcodeDetectorFrameHandler.attach(cameraView, barcodeDetector);
114
+ this.frameHandler.setDetectionInterval(0);
115
+ this.frameHandler.addResultHandler(this);
116
+
117
+ cameraView.addFrameHandler(frameHandler);
118
+ cameraView.setCameraOpenCallback(cameraView::continuousFocus);
119
+
120
+ cameraView.post(this::checkPermissions);
121
+
122
+ this.eventEmitter = new RNScanbotEventEmitter(this.reactContext, this.barcodeCameraUi.getRootView());
123
+
124
+ applyConfiguration();
125
+
126
+ reactContext.runOnUiQueueThread(() -> isInitialized = true);
127
+ }
128
+
129
+ private void applyConfiguration() {
130
+ reactContext.runOnUiQueueThread(() -> {
131
+ final FinderOverlayView finderOverlayView = barcodeCameraUi.getFinderOverlayView();
132
+ final ScanbotCameraXView cameraView = barcodeCameraUi.getCameraView();
133
+
134
+ finderOverlayView.setVisibility(configuration.shouldUseFinderView() ? View.VISIBLE : View.INVISIBLE);
135
+ finderOverlayView.setStrokeWidth(configuration.getFinderLineWidth());
136
+ finderOverlayView.setStrokeColor(configuration.getFinderLineColor());
137
+ finderOverlayView.setOverlayColor(colorWithAlpha(
138
+ configuration.getFinderBackgroundColor(),
139
+ configuration.getFinderBackgroundOpacity()));
140
+ finderOverlayView.setMinFinderPadding(configuration.getFinderMinimumPadding());
141
+ finderOverlayView.setVerticalOffset(configuration.getFinderVerticalOffset());
142
+ finderOverlayView.setRequiredAspectRatios(Collections.singletonList(configuration.getFinderAspectRatio()));
143
+ finderOverlayView.requestLayout();
144
+
145
+ cameraView.useFlash(configuration.isFlashEnabled());
146
+
147
+ if (configuration.getCameraZoomFactor() != -1) {
148
+ if (configuration.getCameraZoomFactor() != userDefinedCameraZoomFactor || userDefinedCameraZoomFactor == -1) {
149
+ cameraView.setOpticalZoomLevel(configuration.getCameraZoomFactor());
150
+ userDefinedCameraZoomFactor = configuration.getCameraZoomFactor();
151
+ }
152
+ }
153
+ barcodeDetector.modifyConfig(b -> {
154
+ if(!configuration.barcodeFormats.isEmpty()) {
155
+ b.setBarcodeFormats(configuration.barcodeFormats);
156
+ }
157
+ if(!configuration.acceptedDocumentFormats.isEmpty()) {
158
+ b.setAcceptedDocumentFormats(configuration.acceptedDocumentFormats);
159
+ }
160
+ b.setEngineMode(configuration.engineMode);
161
+
162
+ if(configuration.additionalConfiguration != null) {
163
+ b.modifyAdditionalConfig(ab -> {
164
+ final BarcodeScannerAdditionalConfig config = configuration.additionalConfiguration;
165
+ ab.setMinimumTextLength(config.getMinimumTextLength());
166
+ ab.setMaximumTextLength(config.getMaximumTextLength());
167
+ ab.setMsiPlesseyChecksumAlgorithms(config.getMsiPlesseyChecksumAlgorithms());
168
+ ab.setStripCheckDigits(config.getStripCheckDigits());
169
+ ab.setGs1DecodingEnabled(config.getGs1DecodingEnabled());
170
+ ab.setMinimum1DQuietZoneSize(config.getMinimum1DQuietZoneSize());
171
+ return Unit.INSTANCE;
172
+ });
173
+ }
174
+ return Unit.INSTANCE;
175
+ });
176
+ });
177
+
178
+ }
179
+
180
+ // Barcode Detector Frame Handler - Result Handler
181
+ @Override
182
+ @SuppressWarnings("unchecked")
183
+ public boolean handle(@NotNull FrameHandlerResult<? extends BarcodeScanningResult, ? extends SdkLicenseError> frameHandlerResult) {
184
+ if (frameHandlerResult instanceof FrameHandlerResult.Success) {
185
+ handleSuccess((FrameHandlerResult.Success<BarcodeScanningResult>) frameHandlerResult);
186
+ }
187
+ return false;
188
+ }
189
+
190
+ private void handleSuccess(final FrameHandlerResult.Success<BarcodeScanningResult> result) {
191
+ if (result == null || result.getValue() == null) {
192
+ return;
193
+ }
194
+
195
+ List<BarcodeItem> barcodeItems;
196
+ if (configuration.barcodeFilter != null) {
197
+ barcodeItems = JSONUtils.getBarcodeItemsFromItemListWithFilter(result.getValue().getBarcodeItems(), configuration.barcodeFilter);
198
+ } else {
199
+ barcodeItems = result.getValue().getBarcodeItems();
200
+ }
201
+
202
+ sendResult(barcodeItems);
203
+ }
204
+
205
+ private void sendResult(final List<BarcodeItem> barcodeItems) {
206
+ if (barcodeItems == null || barcodeItems.size() == 0) {
207
+ return;
208
+ }
209
+
210
+ final WritableArray barcodes = new WritableNativeArray();
211
+
212
+ for (BarcodeItem item: barcodeItems) {
213
+ final WritableMap barcode = new JSONUtils.WritableMapBuilder()
214
+ .putString("text", item.getText())
215
+ .putString("type", item.getBarcodeFormat().name())
216
+ .putString("textWithExtension", item.getTextWithExtension())
217
+ .build();
218
+ barcodes.pushMap(barcode);
219
+ }
220
+
221
+ final WritableMap result = new JSONUtils.WritableMapBuilder()
222
+ .putString("status", "OK")
223
+ .putArray("barcodes", barcodes)
224
+ .build();
225
+
226
+ final WritableMap data = new JSONUtils.WritableMapBuilder()
227
+ .putMap("result", result)
228
+ .build();
229
+
230
+ eventEmitter.emitEvent(NativeEvents.BARCODE_SCANNER_RESULT, data);
231
+ }
232
+
233
+ @Override
234
+ public RNScanbotNativeComponentUi createNativeComponentUi(@NonNull ReactContext reactContext) {
235
+ this.barcodeCameraUi = new RNScanbotBarcodeCameraUi(reactContext);
236
+ return this.barcodeCameraUi;
237
+ }
238
+
239
+ /*
240
+ * Creates the root view for the component
241
+ */
242
+ @Override
243
+ public RNScanbotNativeComponentRootView getRootView() { return this.barcodeCameraUi.getRootView(); }
244
+
245
+ /*
246
+ * Returns the list of native events
247
+ */
248
+ @Override
249
+ public RNScanbotEventEmitter.NativeEvent[] getNativeEvents() { return NativeEvents.values(); }
250
+
251
+ @Override
252
+ public RNScanbotEventReceiver.JavaScriptEvent[] getJavascriptEvents() {
253
+ return new RNScanbotEventReceiver.JavaScriptEvent[] {};
254
+ }
255
+
256
+ /*
257
+ * Applies the given configuration to the component (JSON Configuration)
258
+ */
259
+ @Override
260
+ public void applyConfiguration(@NonNull final ReadableMap configuration) {
261
+ applyConfiguration(RNScanbotBarcodeCameraConfiguration.fromJsonMap(configuration));
262
+ }
263
+
264
+ /*
265
+ * Applies the given configuration to the component (Native Configuration)
266
+ */
267
+ public void applyConfiguration(@NonNull final RNScanbotBarcodeCameraConfiguration configuration) {
268
+ this.configuration = configuration;
269
+ if (isInitialized) {
270
+ applyConfiguration();
271
+ }
272
+ }
273
+
274
+ private void checkPermissions() {
275
+ if (this.reactContext == null) { return; }
276
+ Activity activity = reactContext.getCurrentActivity();
277
+
278
+ if (activity != null && ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
279
+ ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.CAMERA }, REQUEST_PERMISSION_CODE);
280
+ }
281
+ }
282
+
283
+ @ColorInt
284
+ public static int colorWithAlpha(@ColorInt int color, float factor) {
285
+ int alpha = Math.round(Color.alpha(color) * factor);
286
+ int red = Color.red(color);
287
+ int green = Color.green(color);
288
+ int blue = Color.blue(color);
289
+ return Color.argb(alpha, red, green, blue);
290
+ }
291
+
292
+ }
@@ -1,7 +1,11 @@
1
- package io.scanbot.barcodesdk.plugin.reactnative.components.barcodecameraview;
1
+ package io.scanbot.barcodesdk.plugin.reactnative.components.barcodecameraview;;
2
2
 
3
3
  import android.graphics.Color;
4
4
 
5
+ import androidx.annotation.NonNull;
6
+
7
+ import com.facebook.react.bridge.ReadableMap;
8
+
5
9
  import java.util.ArrayList;
6
10
  import java.util.List;
7
11
 
@@ -9,17 +13,21 @@ import io.scanbot.sdk.barcode.entity.BarcodeDocumentFormat;
9
13
  import io.scanbot.sdk.barcode.entity.BarcodeFormat;
10
14
  import io.scanbot.sdk.barcode.entity.BarcodeScannerAdditionalConfig;
11
15
  import io.scanbot.sdk.barcode.entity.EngineMode;
16
+ import io.scanbot.barcodesdk.plugin.reactnative.utils.JSONUtils;
17
+ import io.scanbot.barcodesdk.plugin.reactnative.ObjectMapper;
12
18
  import io.scanbot.sdk.ui.camera.FinderAspectRatio;
19
+ import io.scanbot.sdk.ui.view.barcode.configuration.BarcodeFilter;
13
20
 
14
21
  @SuppressWarnings("unused")
15
- public class ScanbotBarcodeCameraViewConfiguration {
16
-
22
+ public class RNScanbotBarcodeCameraConfiguration {
23
+ // Manually mapped properties (must NOT have a getter and setter)
17
24
  public List<BarcodeFormat> barcodeFormats = new ArrayList<>();
18
25
  public List<BarcodeDocumentFormat> acceptedDocumentFormats = new ArrayList<>();
19
26
  public EngineMode engineMode;
20
27
  public BarcodeScannerAdditionalConfig additionalConfiguration;
28
+ public BarcodeFilter barcodeFilter;
21
29
 
22
- // Automatically mapped properties
30
+ // Automatically mapped properties (must have a getter and a setter with the same name)
23
31
  private boolean shouldUseFinderView = false;
24
32
  private int finderLineWidth = 1;
25
33
  private int finderLineColor = Color.WHITE;
@@ -110,4 +118,46 @@ public class ScanbotBarcodeCameraViewConfiguration {
110
118
  public FinderAspectRatio getFinderAspectRatio() {
111
119
  return finderAspectRatio;
112
120
  }
121
+
122
+ @NonNull
123
+ public static RNScanbotBarcodeCameraConfiguration fromJsonMap(ReadableMap jsonConfig) {
124
+ final RNScanbotBarcodeCameraConfiguration nativeConfig = new RNScanbotBarcodeCameraConfiguration();
125
+
126
+ // Automatic Mapping
127
+ try {
128
+ ObjectMapper.map(jsonConfig, nativeConfig);
129
+ } catch (Exception e) {
130
+ final String msg = "Unexpected ERROR while parsing the given JSON configuration: " + e.getMessage();
131
+ throw new ObjectMapper.InvalidJSONException(msg);
132
+ }
133
+
134
+ // Custom Mapping
135
+ if (jsonConfig.hasKey("barcodeFormats")) {
136
+ nativeConfig.barcodeFormats = JSONUtils.extractBarcodeFormats(jsonConfig);
137
+ }
138
+
139
+ if (jsonConfig.hasKey("acceptedDocumentFormats")) {
140
+ nativeConfig.acceptedDocumentFormats = JSONUtils.extractBarcodeDocumentFormats(jsonConfig);
141
+ }
142
+
143
+ if (jsonConfig.hasKey("cameraZoomFactor")) {
144
+ float value = (float) jsonConfig.getDouble("cameraZoomFactor");
145
+ if (value != -1) {
146
+ nativeConfig.setCameraZoomFactor(value);
147
+ }
148
+ }
149
+
150
+ if (jsonConfig.hasKey("flashEnabled")) {
151
+ nativeConfig.setFlashEnabled(jsonConfig.getBoolean("flashEnabled"));
152
+ }
153
+
154
+ if (jsonConfig.hasKey("barcodeFilter")) {
155
+ nativeConfig.barcodeFilter = JSONUtils.extractBarcodeFilter(jsonConfig);
156
+ }
157
+
158
+ nativeConfig.additionalConfiguration = JSONUtils.extractBarcodeScannerAdditionalConfig(jsonConfig);
159
+ nativeConfig.engineMode = JSONUtils.extractEngineMode(jsonConfig);
160
+
161
+ return nativeConfig;
162
+ }
113
163
  }
@@ -0,0 +1,81 @@
1
+ package io.scanbot.barcodesdk.plugin.reactnative.components.barcodecameraview;
2
+
3
+ import android.app.Activity;
4
+ import android.util.Size;
5
+ import android.view.LayoutInflater;
6
+ import android.widget.FrameLayout;
7
+
8
+ import androidx.annotation.NonNull;
9
+
10
+ import com.facebook.react.bridge.ReactContext;
11
+
12
+ import io.scanbot.barcodesdk.plugin.reactnative.R;
13
+ import io.scanbot.barcodesdk.plugin.reactnative.components.base.RNScanbotNativeComponentUi;
14
+ import io.scanbot.barcodesdk.plugin.reactnative.components.base.views.RNScanbotNativeComponentFrameLayout;
15
+ import io.scanbot.barcodesdk.plugin.reactnative.components.base.views.RNScanbotNativeComponentRootView;
16
+ import io.scanbot.sdk.ui.camera.FinderOverlayView;
17
+ import io.scanbot.sdk.ui.camera.ScanbotCameraXView;
18
+
19
+ public class RNScanbotBarcodeCameraUi extends RNScanbotNativeComponentUi {
20
+
21
+ private FinderOverlayView finderOverlayView;
22
+ private ScanbotCameraXView cameraView;
23
+ private RNScanbotNativeComponentFrameLayout cameraLayout;
24
+
25
+ public RNScanbotBarcodeCameraUi(@NonNull final ReactContext reactContext) {
26
+ super(reactContext);
27
+ }
28
+
29
+ @Override
30
+ protected RNScanbotNativeComponentRootView createRootView(@NonNull final ReactContext reactContext) {
31
+ final Activity activity = reactContext.getCurrentActivity();
32
+ if (activity == null) {
33
+ throw new IllegalStateException("ERROR: Cannot retrieve current activity");
34
+ }
35
+ return setupUIAndGetRootView(activity);
36
+ }
37
+
38
+ public FinderOverlayView getFinderOverlayView() {
39
+ return this.finderOverlayView;
40
+ }
41
+ public ScanbotCameraXView getCameraView() {
42
+ return this.cameraView;
43
+ }
44
+
45
+ /*
46
+ * Takes care of inflating the XML layout, retrieving the views and configuring them (UI)
47
+ */
48
+ private RNScanbotNativeComponentRootView setupUIAndGetRootView(@NonNull final Activity activity) {
49
+ // Retrieves Root View from XML layout
50
+ final RNScanbotNativeComponentRootView rootView = (RNScanbotNativeComponentRootView) LayoutInflater
51
+ .from(activity)
52
+ .inflate(R.layout.component_barcode_camera_view, null, false);
53
+
54
+ // Retrieves the inner Camera Layout and configures it
55
+ cameraLayout = rootView.findViewById(R.id.barcode_camera_layout);
56
+ cameraLayout.setZ(-1.0f);
57
+ cameraLayout.setLayoutParams(new FrameLayout.LayoutParams(
58
+ FrameLayout.LayoutParams.MATCH_PARENT,
59
+ FrameLayout.LayoutParams.MATCH_PARENT));
60
+
61
+ finderOverlayView = rootView.findViewById(R.id.barcode_finder_overlay);
62
+ cameraView = rootView.findViewById(R.id.barcode_camera);
63
+
64
+ return rootView;
65
+ }
66
+
67
+ @Override
68
+ protected void onViewsRemeasured() {
69
+ cameraView.stopPreview();
70
+
71
+ final Size cameraViewSize = new Size(
72
+ cameraLayout.getWidth(),
73
+ cameraLayout.getHeight()
74
+ );
75
+
76
+ cameraView.setPreviewFrameSize(cameraViewSize);
77
+ cameraView.setAnalyzerFrameSize(cameraViewSize);
78
+
79
+ cameraView.startPreview();
80
+ }
81
+ }
@@ -0,0 +1,90 @@
1
+ package io.scanbot.barcodesdk.plugin.reactnative.components.base;
2
+
3
+ import androidx.annotation.NonNull;
4
+ import androidx.annotation.Nullable;
5
+
6
+ import com.facebook.react.bridge.ReactContext;
7
+ import com.facebook.react.bridge.ReadableArray;
8
+ import com.facebook.react.bridge.ReadableMap;
9
+
10
+ import io.scanbot.barcodesdk.plugin.reactnative.components.base.communication.RNScanbotEventEmitter;
11
+ import io.scanbot.barcodesdk.plugin.reactnative.components.base.communication.RNScanbotEventReceiver;
12
+ import io.scanbot.barcodesdk.plugin.reactnative.components.base.views.RNScanbotNativeComponentRootView;
13
+ import kotlin.NotImplementedError;
14
+
15
+ public abstract class RNScanbotNativeComponent {
16
+ // The UI layer of the native component
17
+ private RNScanbotNativeComponentUi nativeComponentUi;
18
+ // Internally set to true when the UI root view is recreated
19
+ private boolean isDirty;
20
+
21
+ public RNScanbotNativeComponent(@NonNull final ReactContext reactContext) {
22
+ this.nativeComponentUi = createNativeComponentUi(reactContext);
23
+ }
24
+ /*
25
+ * Every native component must have a UI component of type RNScanbotNativeComponentUi.
26
+ * You must override this method to provide your own custom implementation for it.
27
+ */
28
+ public RNScanbotNativeComponentUi createNativeComponentUi(@NonNull final ReactContext reactContext) {
29
+ throw new NotImplementedError("You must override createNativeComponentUi() in your Native Component implementation");
30
+ }
31
+ /*
32
+ * Initialize the component
33
+ */
34
+ public abstract void initializeComponent();
35
+ /*
36
+ * You must override this method to write your implementation mapping the JSON configuration
37
+ * that is passed to the component from the React Native JavaScript layer
38
+ */
39
+ public abstract void applyConfiguration(@NonNull final ReadableMap configuration);
40
+ /*
41
+ * This is called when a new view instance is requested to the ViewManager.
42
+ * It mostly disposes listeners and callbacks, and the .dispose() function of
43
+ * the UI Component can be overridden to add custom disposal methods.
44
+ */
45
+ public void recreateWithContext(final ReactContext reactContext) {
46
+ this.nativeComponentUi.dispose();
47
+ this.nativeComponentUi = createNativeComponentUi(reactContext);
48
+ this.nativeComponentUi._setOnViewRecreatedListener(() -> this.isDirty = true);
49
+ }
50
+
51
+ /*
52
+ * Called on componentDidMount
53
+ */
54
+ public void onComponentDidMount() {
55
+ this.initializeComponent();
56
+ }
57
+ /*
58
+ * Called on componentWillUnmount
59
+ */
60
+ public void onComponentWillUnmount() {}
61
+ /*
62
+ * Called on componentDidUpdate
63
+ */
64
+ public void onComponentDidUpdate() {
65
+ if (this.isDirty) {
66
+ initializeComponent();
67
+ this.isDirty = false;
68
+ }
69
+ }
70
+ /*
71
+ * Called on orientationChanged
72
+ */
73
+ public void onOrientationChanged() {}
74
+ /*
75
+ * Creates the root view for the component
76
+ */
77
+ public RNScanbotNativeComponentRootView getRootView() { return this.nativeComponentUi.getRootView(); }
78
+ /*
79
+ * Returns the list of Native events (from Native to JavaScript); default: empty
80
+ */
81
+ public RNScanbotEventEmitter.NativeEvent[] getNativeEvents() { return new RNScanbotEventEmitter.NativeEvent[] {}; }
82
+ /*
83
+ * Returns the list of JavaScript events (from JavaScript to Native); default: empty
84
+ */
85
+ public RNScanbotEventReceiver.JavaScriptEvent[] getJavascriptEvents() { return new RNScanbotEventReceiver.JavaScriptEvent[] {}; }
86
+ /*
87
+ * Override this to handle events defined in the getJavascriptEvents method; default: empty
88
+ */
89
+ public void handleJavascriptEvent(RNScanbotEventReceiver.JavaScriptEvent event, @Nullable ReadableArray args) {}
90
+ }
@@ -0,0 +1,133 @@
1
+ package io.scanbot.barcodesdk.plugin.reactnative.components.base;
2
+
3
+ import android.widget.FrameLayout;
4
+
5
+ import androidx.annotation.NonNull;
6
+ import androidx.annotation.Nullable;
7
+
8
+ import com.facebook.react.ReactRootView;
9
+ import com.facebook.react.bridge.ReactContext;
10
+ import com.facebook.react.bridge.ReadableArray;
11
+ import com.facebook.react.bridge.ReadableMap;
12
+ import com.facebook.react.uimanager.ThemedReactContext;
13
+ import com.facebook.react.uimanager.ViewGroupManager;
14
+ import com.facebook.react.uimanager.annotations.ReactProp;
15
+
16
+ import java.util.ArrayList;
17
+ import java.util.List;
18
+ import java.util.Map;
19
+
20
+ import io.scanbot.barcodesdk.plugin.reactnative.components.base.communication.RNScanbotEventEmitter;
21
+ import io.scanbot.barcodesdk.plugin.reactnative.components.base.communication.RNScanbotEventReceiver;
22
+
23
+ /**
24
+ * This class takes care of setting up a ViewManager that:
25
+ * - Returns the correct name for registering the view in React Native
26
+ * - Accepts a JSON configuration under the prop name 'configuration' and passes it to the native component
27
+ * - Sets up events (both JS -> Java and Java -> JS) and it handles common core events
28
+ * automatically (like componentDidMount, orientationChanged etc.)
29
+ * - Takes care of creating (and recreating) the root view and passing it to the React Native View Manager
30
+ * @param <T> Your custom type that extends RNScanbotNativeComponent
31
+ */
32
+ public abstract class RNScanbotNativeComponentManager<T extends RNScanbotNativeComponent> extends ViewGroupManager<ReactRootView> implements RNScanbotEventReceiver.IEventHandler {
33
+ protected final ReactContext reactContext;
34
+ protected final T nativeComponent;
35
+ protected RNScanbotEventReceiver eventReceiver;
36
+ private boolean isInitialized = false;
37
+
38
+ public RNScanbotNativeComponentManager(
39
+ @NonNull final ReactContext reactContext,
40
+ @NonNull final T nativeComponent
41
+ ) {
42
+ super();
43
+ this.reactContext = reactContext;
44
+ this.nativeComponent = nativeComponent;
45
+ this.eventReceiver = new RNScanbotEventReceiver(this, nativeComponent.getJavascriptEvents());
46
+ }
47
+
48
+ @ReactProp(name = "configuration")
49
+ public void setConfiguration(FrameLayout frameLayout, ReadableMap configuration) {
50
+ final RNScanbotNativeComponent component = nativeComponent;
51
+ if (component == null) {
52
+ return;
53
+ }
54
+ component.applyConfiguration(configuration);
55
+ }
56
+
57
+ protected void componentDidMount() { this.nativeComponent.onComponentDidMount(); }
58
+ protected void componentWillUnmount() { this.nativeComponent.onComponentWillUnmount(); }
59
+ protected void componentDidUpdate() { this.nativeComponent.onComponentDidUpdate(); }
60
+ protected void orientationChanged() { this.nativeComponent.onOrientationChanged(); }
61
+
62
+ /* --------------------------------------------------*/
63
+ /* Internal stuff you probably shouldn't worry about */
64
+ /* --------------------------------------------------*/
65
+
66
+ // Maps native events (from Native to JS)
67
+ @Nullable
68
+ @Override
69
+ public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
70
+ final RNScanbotEventEmitter.NativeEvent[] commonEvents = RNScanbotEventEmitter.CommonEvents.values();
71
+ final RNScanbotEventEmitter.NativeEvent[] customEvents = nativeComponent.getNativeEvents();
72
+ final RNScanbotEventEmitter.NativeEvent[] allEvents = RNScanbotEventEmitter.concatEvents(commonEvents, customEvents);
73
+ return RNScanbotEventEmitter.getMapForNativeEvents(allEvents);
74
+ }
75
+
76
+ // Creates the view instance when requested from the RN layer
77
+ @NonNull
78
+ @Override
79
+ protected ReactRootView createViewInstance(@NonNull final ThemedReactContext reactContext) {
80
+ if (isInitialized) {
81
+ this.nativeComponent.recreateWithContext(reactContext);
82
+ }
83
+ isInitialized = true;
84
+ return this.nativeComponent.getRootView();
85
+ }
86
+
87
+ // Parses notifications from the EventReceiver:
88
+ // - It handles common events and stops them from getting to the inheriting class
89
+ // - It sends non-common events to the handleJavascriptEvent delegate method in the inheriting class
90
+ @Override
91
+ public void eventHandler_eventReceived(RNScanbotEventReceiver.JavaScriptEvent event, @Nullable ReadableArray args) {
92
+ List<RNScanbotEventReceiver.JavaScriptEvent> handledEvents = new ArrayList<>();
93
+ RNScanbotEventReceiver.CommonEvents commonEvent = eventReceiver.getCommonEventFromName(event.getName());
94
+ if (commonEvent == null) {
95
+ this.nativeComponent.handleJavascriptEvent(event, args);
96
+ return;
97
+ }
98
+
99
+ this.handleCommonEvent(commonEvent, args);
100
+ }
101
+
102
+ // Calls the common events handlers
103
+ private void handleCommonEvent(RNScanbotEventReceiver.CommonEvents commonEvent, @Nullable ReadableArray args) {
104
+ switch (commonEvent) {
105
+ case COMPONENT_DID_UPDATE:
106
+ componentDidUpdate();
107
+ break;
108
+ case COMPONENT_DID_MOUNT:
109
+ componentDidMount();
110
+ break;
111
+ case COMPONENT_WILL_UNMOUNT:
112
+ componentWillUnmount();
113
+ break;
114
+ case ORIENTATION_CHANGED:
115
+ orientationChanged();
116
+ break;
117
+ }
118
+ }
119
+
120
+ // Maps JavaScript events (from JavaScript to Native)
121
+ @Nullable
122
+ @Override
123
+ public Map<String, Integer> getCommandsMap() {
124
+ return eventReceiver.getCommandsMap();
125
+ }
126
+
127
+ // Hands over JavaScript events to our beatufiul event receiver
128
+ @Override
129
+ public void receiveCommand(@NonNull ReactRootView root, String commandId, @Nullable ReadableArray args) {
130
+ super.receiveCommand(root, commandId, args);
131
+ eventReceiver.receiveCommand(commandId, args);
132
+ }
133
+ }