Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for New Architecture #672

Merged
merged 8 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions ReactNativeCameraKit.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,22 @@ Pod::Spec.new do |s|
s.platform = :ios, "11.0"

s.source = { :git => "https://github.com/teslamotors/react-native-camera-kit.git", :tag => "v#{s.version}" }
s.source_files = "ios/**/*.{h,m,swift}"
s.source_files = "ios/**/*.{h,m,mm,swift}"
s.private_header_files = 'ios/ReactNativeCameraKit/ReactNativeCameraKit-Swift.pre.h'

if ENV['USE_FRAMEWORKS']
exisiting_flags = s.attributes_hash["compiler_flags"]
if exisiting_flags.present?
s.compiler_flags = exisiting_flags + "-DCK_USE_FRAMEWORKS=1"
else
s.compiler_flags = "-DCK_USE_FRAMEWORKS=1"
end
end

if defined?(install_modules_dependencies()) != nil
install_modules_dependencies(s)
else
s.dependency 'React-Core'
end

s.dependency 'React-Core'
end
22 changes: 21 additions & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

def isNewArchitectureEnabled() {
// To opt-in for the New Architecture, you can either:
// - Set `newArchEnabled` to true inside the `gradle.properties` file
// - Invoke gradle with `-newArchEnabled=true`
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
}

if (isNewArchitectureEnabled()) {
apply plugin: 'com.facebook.react'
}

android {
def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
if (agpVersion.tokenize('.')[0].toInteger() >= 7) {
namespace "com.rncamerakit"
}

compileSdkVersion = 34
defaultConfig {
minSdkVersion = 24
Expand All @@ -17,10 +28,19 @@ android {
ndk {
abiFilters "arm64-v8a", "x86"
}
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
}
lintOptions {
warning 'InvalidPackage'
}

if (!isNewArchitectureEnabled()) {
sourceSets {
main {
java.srcDirs += 'src/paper/java'
}
}
}
}

dependencies {
Expand Down
58 changes: 22 additions & 36 deletions android/src/main/java/com/rncamerakit/CKCamera.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ import kotlin.math.min
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
import com.facebook.react.uimanager.UIManagerHelper
import com.google.mlkit.vision.barcode.common.Barcode
import com.rncamerakit.events.*

class RectOverlay constructor(context: Context) :
View(context) {
Expand Down Expand Up @@ -330,13 +332,10 @@ class CKCamera(context: ThemedReactContext) : FrameLayout(context), LifecycleObs
} catch (exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)

val event: WritableMap = Arguments.createMap()
event.putString("errorMessage", exc.message)
currentContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(
id,
"onError",
event
)
val surfaceId = UIManagerHelper.getSurfaceId(currentContext)
UIManagerHelper
.getEventDispatcherForReactTag(currentContext, id)
?.dispatchEvent(ErrorEvent(surfaceId, id, exc.message))
}
}

Expand Down Expand Up @@ -459,15 +458,11 @@ class CKCamera(context: ThemedReactContext) : FrameLayout(context), LifecycleObs
}

private fun onBarcodeRead(barcodes: List<Barcode>) {
val event: WritableMap = Arguments.createMap()
event.putString("codeStringValue", barcodes.first().rawValue)
val codeFormat = CodeFormat.fromBarcodeType(barcodes.first().format);
event.putString("codeFormat",codeFormat.code );
currentContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(
id,
"onReadCode",
event
)
val surfaceId = UIManagerHelper.getSurfaceId(currentContext)
UIManagerHelper
.getEventDispatcherForReactTag(currentContext, id)
?.dispatchEvent(ReadCodeEvent(surfaceId, id, barcodes.first().rawValue, codeFormat.code))
}

private fun onOrientationChange(orientation: Int) {
Expand All @@ -482,23 +477,17 @@ class CKCamera(context: ThemedReactContext) : FrameLayout(context), LifecycleObs
}
}

val event: WritableMap = Arguments.createMap()
event.putInt("orientation", remappedOrientation)
currentContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(
id,
"onOrientationChange",
event
)
val surfaceId = UIManagerHelper.getSurfaceId(currentContext)
UIManagerHelper
.getEventDispatcherForReactTag(currentContext, id)
?.dispatchEvent(OrientationChangeEvent(surfaceId, id, remappedOrientation))
}

private fun onPictureTaken(uri: String) {
val event: WritableMap = Arguments.createMap()
event.putString("uri", uri)
currentContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(
id,
"onPictureTaken",
event
)
val surfaceId = UIManagerHelper.getSurfaceId(currentContext)
UIManagerHelper
.getEventDispatcherForReactTag(currentContext, id)
?.dispatchEvent(PictureTakenEvent(surfaceId, id, uri))
}

fun setFlashMode(mode: String?) {
Expand Down Expand Up @@ -569,13 +558,10 @@ class CKCamera(context: ThemedReactContext) : FrameLayout(context), LifecycleObs
}

lastOnZoom = desiredOrCameraZoom
val event: WritableMap = Arguments.createMap()
event.putDouble("zoom", desiredOrCameraZoom)
currentContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(
id,
"onZoom",
event
)
val surfaceId = UIManagerHelper.getSurfaceId(currentContext)
UIManagerHelper
.getEventDispatcherForReactTag(currentContext, id)
?.dispatchEvent(ZoomEvent(surfaceId, id, desiredOrCameraZoom))
}

fun setMaxZoom(factor: Double?) {
Expand Down
71 changes: 45 additions & 26 deletions android/src/main/java/com/rncamerakit/CKCameraManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,20 @@ import com.facebook.react.common.MapBuilder
import com.facebook.react.common.ReactConstants.TAG
import com.facebook.react.uimanager.SimpleViewManager
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.ViewManagerDelegate
import com.facebook.react.uimanager.annotations.ReactProp
import com.facebook.react.viewmanagers.CKCameraManagerDelegate
import com.facebook.react.viewmanagers.CKCameraManagerInterface
import com.rncamerakit.events.*

class CKCameraManager : SimpleViewManager<CKCamera>(), CKCameraManagerInterface<CKCamera> {

class CKCameraManager : SimpleViewManager<CKCamera>() {
private val delegate: ViewManagerDelegate<CKCamera> = CKCameraManagerDelegate(this)

override fun getDelegate(): ViewManagerDelegate<CKCamera> = delegate

override fun getName() : String {
return "CKCameraManager"
return "CKCamera"
}

override fun createViewInstance(context: ThemedReactContext): CKCamera {
Expand Down Expand Up @@ -44,81 +51,93 @@ class CKCameraManager : SimpleViewManager<CKCamera>() {

override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any> {
return MapBuilder.of(
"onOrientationChange", MapBuilder.of("registrationName", "onOrientationChange"),
"onReadCode", MapBuilder.of("registrationName", "onReadCode"),
"onPictureTaken", MapBuilder.of("registrationName", "onPictureTaken"),
"onZoom", MapBuilder.of("registrationName", "onZoom"),
"onError", MapBuilder.of("registrationName", "onError")
OrientationChangeEvent.EVENT_NAME, MapBuilder.of("registrationName", "onOrientationChange"),
ReadCodeEvent.EVENT_NAME, MapBuilder.of("registrationName", "onReadCode"),
PictureTakenEvent.EVENT_NAME, MapBuilder.of("registrationName", "onPictureTaken"),
ZoomEvent.EVENT_NAME, MapBuilder.of("registrationName", "onZoom"),
ErrorEvent.EVENT_NAME, MapBuilder.of("registrationName", "onError")
)
}

@ReactProp(name = "cameraType")
fun setCameraType(view: CKCamera, type: String) {
view.setCameraType(type)
override fun setCameraType(view: CKCamera, type: String?) {
view.setCameraType(type ?: "back")
}

@ReactProp(name = "flashMode")
fun setFlashMode(view: CKCamera, mode: String?) {
override fun setFlashMode(view: CKCamera, mode: String?) {
view.setFlashMode(mode)
}

@ReactProp(name = "torchMode")
fun setTorchMode(view: CKCamera, mode: String?) {
override fun setTorchMode(view: CKCamera, mode: String?) {
view.setTorchMode(mode)
}

@ReactProp(name = "focusMode")
fun setFocusMode(view: CKCamera, mode: String) {
view.setAutoFocus(mode)
override fun setFocusMode(view: CKCamera, mode: String?) {
view.setAutoFocus(mode ?: "on")
}

@ReactProp(name = "zoomMode")
fun setZoomMode(view: CKCamera, mode: String?) {
override fun setZoomMode(view: CKCamera, mode: String?) {
view.setZoomMode(mode)
}

@ReactProp(name = "zoom", defaultDouble = -1.0)
fun setZoom(view: CKCamera, factor: Double) {
override fun setZoom(view: CKCamera, factor: Double) {
view.setZoom(if (factor == -1.0) null else factor)
}

@ReactProp(name = "maxZoom", defaultDouble = 420.0)
fun setMaxZoom(view: CKCamera, factor: Double) {
override fun setMaxZoom(view: CKCamera, factor: Double) {
view.setMaxZoom(factor)
}

@ReactProp(name = "scanBarcode")
fun setScanBarcode(view: CKCamera, enabled: Boolean) {
override fun setScanBarcode(view: CKCamera, enabled: Boolean) {
view.setScanBarcode(enabled)
}

@ReactProp(name = "showFrame")
fun setShowFrame(view: CKCamera, enabled: Boolean) {
override fun setShowFrame(view: CKCamera, enabled: Boolean) {
view.setShowFrame(enabled)
}

@ReactProp(name = "laserColor", defaultInt = Color.RED)
fun setLaserColor(view: CKCamera, @ColorInt color: Int) {
view.setLaserColor(color)
override fun setLaserColor(view: CKCamera, @ColorInt color: Int?) {
view.setLaserColor(color ?: Color.RED)
}

@ReactProp(name = "frameColor", defaultInt = Color.GREEN)
fun setFrameColor(view: CKCamera, @ColorInt color: Int) {
view.setFrameColor(color)
override fun setFrameColor(view: CKCamera, @ColorInt color: Int?) {
view.setFrameColor(color ?: Color.GREEN)
}

@ReactProp(name = "outputPath")
fun setOutputPath(view: CKCamera, path: String) {
view.setOutputPath(path)
override fun setOutputPath(view: CKCamera, path: String?) {
view.setOutputPath(path ?: "")
}

@ReactProp(name = "shutterAnimationDuration")
fun setShutterAnimationDuration(view: CKCamera, duration: Int) {
override fun setShutterAnimationDuration(view: CKCamera, duration: Int) {
view.setShutterAnimationDuration(duration)
}

@ReactProp(name = "shutterPhotoSound")
fun setShutterPhotoSound(view: CKCamera, enabled: Boolean) {
override fun setShutterPhotoSound(view: CKCamera, enabled: Boolean) {
view.setShutterPhotoSound(enabled);
}

override fun setRatioOverlay(view: CKCamera?, value: String?) = Unit

override fun setRatioOverlayColor(view: CKCamera?, value: Int?) = Unit

override fun setResetFocusTimeout(view: CKCamera?, value: Int) = Unit

override fun setResetFocusWhenMotionDetected(view: CKCamera?, value: Boolean) = Unit

override fun setResizeMode(view: CKCamera?, value: String?) = Unit

override fun setScanThrottleDelay(view: CKCamera?, value: Int) = Unit
WoLewicki marked this conversation as resolved.
Show resolved Hide resolved
}
25 changes: 17 additions & 8 deletions android/src/main/java/com/rncamerakit/RNCameraKitModule.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.rncamerakit

import com.facebook.react.bridge.*
import com.facebook.react.uimanager.UIManagerModule
import com.facebook.react.uimanager.UIManagerHelper

/**
* Native module for interacting with the camera in React Native applications.
Expand All @@ -11,7 +11,7 @@ import com.facebook.react.uimanager.UIManagerModule
*
* @param reactContext The application's ReactApplicationContext.
*/
class RNCameraKitModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
class RNCameraKitModule(private val reactContext: ReactApplicationContext) : NativeCameraKitModuleSpec(reactContext) {

companion object {
// Constants for camera orientation
Expand All @@ -34,10 +34,12 @@ class RNCameraKitModule(private val reactContext: ReactApplicationContext) : Rea
* Represents the landscape orientation with the right side of the device up.
*/
const val LANDSCAPE_RIGHT = 3 // ➡️

const val REACT_CLASS = "RNCameraKitModule"
}

override fun getName(): String {
return "RNCameraKitModule"
return REACT_CLASS
}

/**
Expand All @@ -54,6 +56,10 @@ class RNCameraKitModule(private val reactContext: ReactApplicationContext) : Rea
)
}

override fun requestDeviceCameraAuthorization(promise: Promise?) = Unit

override fun checkDeviceCameraAuthorizationStatus(promise: Promise?) = Unit

/**
* Captures a photo using the camera.
*
Expand All @@ -62,13 +68,16 @@ class RNCameraKitModule(private val reactContext: ReactApplicationContext) : Rea
* @param promise The promise to resolve the capture result.
*/
@ReactMethod
fun capture(options: ReadableMap, viewTag: Int, promise: Promise) {
override fun capture(options: ReadableMap?, tag: Double?, promise: Promise) {
// CameraManager does not allow us to return values
val context = reactContext
val uiManager = context.getNativeModule(UIManagerModule::class.java)
context.runOnUiQueueThread {
val view = uiManager?.resolveView(viewTag) as CKCamera
view.capture(options.toHashMap(), promise)
val viewTag = tag?.toInt()
if (viewTag != null && options != null) {
val uiManager = UIManagerHelper.getUIManagerForReactTag(reactContext, viewTag)
context.runOnUiQueueThread {
val camera = uiManager?.resolveView(viewTag) as CKCamera
camera.capture(options.toHashMap(), promise)
}
}
WoLewicki marked this conversation as resolved.
Show resolved Hide resolved
}
}
Loading