package io.scanbot.barcodesdk.plugin.reactnative import android.app.Activity import android.app.Application import android.content.Intent import com.facebook.react.bridge.ActivityEventListener import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.ReactContextBaseJavaModule import com.facebook.react.bridge.ReactMethod import com.facebook.react.bridge.ReadableMap import com.facebook.react.modules.core.DeviceEventManagerModule import io.scanbot.barcodesdk.plugin.reactnative.extensions.toJSON import io.scanbot.barcodesdk.plugin.reactnative.extensions.toWritableMap import io.scanbot.sdk_wrapper.barcode.operations.detection.SBBDetectBarcodes import io.scanbot.sdk_wrapper.barcode.operations.image_operations.SBBImageOperations import io.scanbot.sdk_wrapper.barcode.operations.license.SBBLicenseOperations import io.scanbot.sdk_wrapper.barcode.operations.mock.SBBMock import io.scanbot.sdk_wrapper.barcode.operations.parsing.SBBBarcodeDocumentParser import io.scanbot.sdk_wrapper.barcode.operations.setup.SBBSetupOperations import io.scanbot.sdk_wrapper.barcode.rtuui.SBBRtuUi import io.scanbot.sdk_wrapper.exceptions.SBWrapperError import org.json.JSONException import org.json.JSONObject class ScanbotBarcodeSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext), ActivityEventListener { companion object { const val NAME = "ScanbotBarcodeSdk" const val BARCODE_ITEM_MAPPER_EVENT = "barcodeItemMapperEvent" } override fun getName(): String { return NAME } @ReactMethod fun initialize(configuration: ReadableMap, promise: Promise) = runOperationWithJSONParam( configuration, promise ) { configurationAsJSON -> reactApplicationContextIfActiveOrWarn?.let { SBBSetupOperations.initializeSdk( it.applicationContext as Application, configurationAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise) ) it.addActivityEventListener(this) } ?: run { SBWrapperError( SBWrapperError.OperationError( "initialize", "React Native Instance has already disappeared." ) ).let { error -> promise.reject(error.code.toString(), error.message) } } } @ReactMethod fun getLicenseInfo(promise: Promise) { SBBLicenseOperations.getLicenseInfo( ScanbotBarcodeSdkPluginResultDelegate( promise ) ) } @ReactMethod fun cleanupStorage(promise: Promise) { SBBSetupOperations.cleanup(ScanbotBarcodeSdkPluginResultDelegate(promise)) } @ReactMethod fun startBarcodeScanner( configuration: ReadableMap, barcodeItemMapperImplemented: Boolean, promise: Promise ) = runOperationWithJSONParamAndSafeActivity( configuration, promise ) { configurationAsJSON, currentActivity -> if (barcodeItemMapperImplemented) { SBBRtuUi.startBarcodeScanner( currentActivity, configurationAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise) ) { reactApplicationContextIfActiveOrWarn?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) ?.emit(BARCODE_ITEM_MAPPER_EVENT, it.toWritableMap()) } } else { SBBRtuUi.startBarcodeScanner( currentActivity, configurationAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise), null ) } } @ReactMethod fun onBarcodeItemMapper(barcodeItemUuid: String, barcodeMappedData: ReadableMap?) { SBBRtuUi.onBarcodeItemMapper(barcodeItemUuid, barcodeMappedData?.toJSON()) } @ReactMethod fun scanBarcodesFromImage(args: ReadableMap, promise: Promise) = runOperationWithJSONParam(args, promise) { argsAsJSON -> SBBDetectBarcodes.detectOnImage( argsAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise) ) } @ReactMethod fun scanBarcodesFromPdf(args: ReadableMap, promise: Promise) = runOperationWithJSONParam(args, promise) { argsAsJSON -> SBBDetectBarcodes.detectOnPdf( argsAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise) ) } @ReactMethod fun parseBarcodeDocument(args: ReadableMap, promise: Promise) = runOperationWithJSONParam(args, promise) { argsAsJSON -> SBBBarcodeDocumentParser.parseDocument( argsAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise) ) } @ReactMethod fun readImageData(args: ReadableMap, promise: Promise) { runOperationWithJSONParam(args, promise) { argsAsJSON -> SBBImageOperations.getImageData( argsAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise) ) } } @ReactMethod fun mockCamera(configuration: ReadableMap, promise: Promise) = runOperationWithJSONParam(configuration, promise) { configurationAsJSON -> SBBMock.camera(configurationAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise)) } //region ImageRefs @ReactMethod fun imageRefDeserialize(args: ReadableMap, promise: Promise) { runOperationWithJSONParam(args, promise) { argsAsJSON -> SBBImageOperations.imageRefDeserialize( argsAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise) ) } } @ReactMethod fun imageRefSerialize(args: ReadableMap, promise: Promise) { runOperationWithJSONParam(args, promise) { argsAsJSON -> SBBImageOperations.imageRefSerialize( argsAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise) ) } } @ReactMethod fun imageRefFromImageFileUri(args: ReadableMap, promise: Promise) { runOperationWithJSONParam(args, promise) { argsAsJSON -> SBBImageOperations.imageRefFromImageFileUri( argsAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise) ) } } @ReactMethod fun imageRefFromEncodedBuffer(args: ReadableMap, promise: Promise) { runOperationWithJSONParam(args, promise) { argsAsJSON -> SBBImageOperations.imageRefFromEncodedBuffer( argsAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise) ) } } @ReactMethod fun imageRefHibernate(args: ReadableMap, promise: Promise) { runOperationWithJSONParam(args, promise) { argsAsJSON -> SBBImageOperations.imageRefHibernate( argsAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise) ) } } @ReactMethod fun imageRefClear(args: ReadableMap, promise: Promise) { runOperationWithJSONParam(args, promise) { argsAsJSON -> SBBImageOperations.imageRefClear( argsAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise) ) } } @ReactMethod fun imageRefInfo(args: ReadableMap, promise: Promise) { runOperationWithJSONParam(args, promise) { argsAsJSON -> SBBImageOperations.imageRefInfo( argsAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise) ) } } @ReactMethod fun imageRefSaveImage(args: ReadableMap, promise: Promise) { runOperationWithJSONParam(args, promise) { argsAsJSON -> SBBImageOperations.imageRefSaveImage( argsAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise) ) } } @ReactMethod fun imageRefEncodeImage(args: ReadableMap, promise: Promise) { runOperationWithJSONParam(args, promise) { argsAsJSON -> SBBImageOperations.imageRefEncodeImage( argsAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise) ) } } @ReactMethod fun imageRefRelease(args: ReadableMap, promise: Promise) { runOperationWithJSONParam(args, promise) { argsAsJSON -> SBBImageOperations.imageRefRelease( argsAsJSON, ScanbotBarcodeSdkPluginResultDelegate(promise) ) } } @ReactMethod fun makeSnapshot(promise: Promise) { SBBImageOperations.makeSnapshot( ScanbotBarcodeSdkPluginResultDelegate( promise ) ) } @ReactMethod fun imageRefReleaseAll(promise: Promise) { SBBImageOperations.releaseAllImageRefs( ScanbotBarcodeSdkPluginResultDelegate( promise ) ) } //endregion ImageRefs override fun onActivityResult( activity: Activity, requestCode: Int, resultCode: Int, intent: Intent? ) { SBBRtuUi.onActivityResult(requestCode, resultCode, intent) } override fun onNewIntent(intent: Intent) { // NO-OP } //region Helpers @Suppress("UNUSED_PARAMETER") @ReactMethod fun addListener(type: String?) { // Keep: Required for RN built in Event Emitter Calls, otherwise warnings are thrown in the console log. } @Suppress("UNUSED_PARAMETER") @ReactMethod fun removeListeners(type: Int?) { // Keep: Required for RN built in Event Emitter Calls, otherwise warnings are thrown in the console log. } private fun runOperationWithJSONParam( configuration: ReadableMap, promise: Promise, operation: (configurationAsJSON: JSONObject) -> Unit ) { val configurationAsJSON: JSONObject try { configurationAsJSON = configuration.toJSON() } catch (ex: JSONException) { SBWrapperError( SBWrapperError.ArgumentError( ex.message ?: "Input parameter is not a valid JSON" ) ).let { error -> promise.reject(error.code.toString(), error.message) } return } operation(configurationAsJSON) } private fun runOperationWithJSONParamAndSafeActivity( configuration: ReadableMap, promise: Promise, operation: (configurationAsJSON: JSONObject, currentActivity: Activity) -> Unit ) { val configurationAsJSON: JSONObject try { configurationAsJSON = configuration.toJSON() } catch (ex: JSONException) { SBWrapperError( SBWrapperError.ArgumentError( ex.message ?: "Input parameter is not a valid JSON" ) ).let { error -> promise.reject(error.code.toString(), error.message) } return } reactApplicationContext?.currentActivity?.let { operation(configurationAsJSON, it) } ?: run { SBWrapperError( SBWrapperError.OperationError( "RTU UI", "ScanbotBarcodeSdkModule is not attached to activity" ) ).let { error -> promise.reject(error.code.toString(), error.message) } } } //endregion Helpers }