expo-camera 13.8.0 → 14.0.0

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 (113) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/android/build.gradle +18 -5
  3. package/android/src/main/AndroidManifest.xml +1 -0
  4. package/android/src/main/java/expo/modules/camera/CameraViewModule.kt +1 -1
  5. package/android/src/main/java/expo/modules/camera/Events.kt +1 -1
  6. package/android/src/main/java/expo/modules/camera/ExpoCameraView.kt +2 -2
  7. package/android/src/main/java/expo/modules/camera/Options.kt +2 -2
  8. package/android/src/main/java/expo/modules/camera/next/CameraExceptions.kt +9 -0
  9. package/android/src/main/java/expo/modules/camera/next/CameraViewHelper.kt +40 -0
  10. package/android/src/main/java/expo/modules/camera/next/CameraViewNextModule.kt +167 -0
  11. package/android/src/main/java/expo/modules/camera/next/ExpoCameraView.kt +447 -0
  12. package/android/src/main/java/expo/modules/camera/next/Options.kt +22 -0
  13. package/android/src/main/java/expo/modules/camera/next/analyzers/BarcodeAnalyzer.kt +77 -0
  14. package/android/src/main/java/expo/modules/camera/next/records/CameraRecords.kt +94 -0
  15. package/android/src/main/java/expo/modules/camera/next/tasks/PictureSavedDelegate.kt +7 -0
  16. package/android/src/main/java/expo/modules/camera/next/tasks/ResolveTakenPicture.kt +248 -0
  17. package/android/src/main/java/expo/modules/camera/next/utils/FileSystemUtils.kt +22 -0
  18. package/android/src/main/java/expo/modules/camera/next/utils/ImageDimensions.kt +16 -0
  19. package/android/src/main/java/expo/modules/camera/utils/FileSystemUtils.kt +8 -0
  20. package/build/Camera.d.ts +4 -4
  21. package/build/Camera.d.ts.map +1 -1
  22. package/build/Camera.js +9 -9
  23. package/build/Camera.js.map +1 -1
  24. package/build/{ExponentCamera.d.ts → ExpoCamera.d.ts} +1 -1
  25. package/build/ExpoCamera.d.ts.map +1 -0
  26. package/build/ExpoCamera.js +4 -0
  27. package/build/ExpoCamera.js.map +1 -0
  28. package/build/ExponentCamera.web.js +5 -3
  29. package/build/ExponentCamera.web.js.map +1 -1
  30. package/build/ExponentCameraManager.d.ts.map +1 -1
  31. package/build/ExponentCameraManager.js +1 -1
  32. package/build/ExponentCameraManager.js.map +1 -1
  33. package/build/next/Camera.types.d.ts +404 -0
  34. package/build/next/Camera.types.d.ts.map +1 -0
  35. package/build/next/Camera.types.js +3 -0
  36. package/build/next/Camera.types.js.map +1 -0
  37. package/build/next/CameraView.d.ts +95 -0
  38. package/build/next/CameraView.d.ts.map +1 -0
  39. package/build/next/CameraView.js +187 -0
  40. package/build/next/CameraView.js.map +1 -0
  41. package/build/next/ExpoCamera.d.ts +5 -0
  42. package/build/next/ExpoCamera.d.ts.map +1 -0
  43. package/build/next/ExpoCamera.js +4 -0
  44. package/build/next/ExpoCamera.js.map +1 -0
  45. package/build/next/ExpoCamera.web.d.ts +13 -0
  46. package/build/next/ExpoCamera.web.d.ts.map +1 -0
  47. package/build/next/ExpoCamera.web.js +106 -0
  48. package/build/next/ExpoCamera.web.js.map +1 -0
  49. package/build/next/ExpoCameraManager.d.ts +3 -0
  50. package/build/next/ExpoCameraManager.d.ts.map +1 -0
  51. package/build/next/ExpoCameraManager.js +3 -0
  52. package/build/next/ExpoCameraManager.js.map +1 -0
  53. package/build/next/ExpoCameraManager.web.d.ts +42 -0
  54. package/build/next/ExpoCameraManager.web.d.ts.map +1 -0
  55. package/build/next/ExpoCameraManager.web.js +216 -0
  56. package/build/next/ExpoCameraManager.web.js.map +1 -0
  57. package/build/next/index.d.ts +52 -0
  58. package/build/next/index.d.ts.map +1 -0
  59. package/build/next/index.js +73 -0
  60. package/build/next/index.js.map +1 -0
  61. package/build/next/utils/props.d.ts +8 -0
  62. package/build/next/utils/props.d.ts.map +1 -0
  63. package/build/next/utils/props.js +33 -0
  64. package/build/next/utils/props.js.map +1 -0
  65. package/expo-module.config.json +5 -2
  66. package/ios/CameraEnums.swift +98 -0
  67. package/ios/CameraExceptions.swift +55 -0
  68. package/ios/CameraPermissionsRequester.swift +125 -0
  69. package/ios/CameraRecordingOptions.swift +56 -0
  70. package/ios/CameraView.swift +978 -0
  71. package/ios/{EXCamera/CameraViewModule.swift → CameraViewModule.swift} +97 -91
  72. package/ios/CameraViewNextModule.swift +284 -0
  73. package/ios/{EXCamera.podspec → ExpoCamera.podspec} +7 -4
  74. package/ios/ExpoCameraUtils.swift +175 -0
  75. package/ios/Next/BarcodeRecord.swift +75 -0
  76. package/ios/Next/BarcodeScanner.swift +226 -0
  77. package/ios/Next/BarcodeScannerUtils.swift +117 -0
  78. package/ios/Next/CameraEnumsNext.swift +29 -0
  79. package/ios/Next/CameraRecordingOptionsNext.swift +55 -0
  80. package/ios/Next/CameraViewNext.swift +794 -0
  81. package/ios/Next/ExpoCameraUtilsNext.swift +175 -0
  82. package/ios/Next/PreviewView.swift +24 -0
  83. package/ios/Next/TakePictureOptionsNext.swift +23 -0
  84. package/ios/Next/VisionScannerDelegate.swift +25 -0
  85. package/next.d.ts +1 -0
  86. package/next.js +1 -0
  87. package/package.json +2 -2
  88. package/src/Camera.tsx +9 -9
  89. package/src/{ExponentCamera.ts → ExpoCamera.ts} +1 -1
  90. package/src/ExponentCamera.web.tsx +4 -3
  91. package/src/ExponentCameraManager.ts +1 -1
  92. package/src/next/Camera.types.ts +455 -0
  93. package/src/next/CameraView.tsx +258 -0
  94. package/src/next/ExpoCamera.ts +9 -0
  95. package/src/next/ExpoCamera.web.tsx +164 -0
  96. package/src/next/ExpoCameraManager.ts +3 -0
  97. package/src/next/ExpoCameraManager.web.ts +239 -0
  98. package/src/next/index.ts +83 -0
  99. package/src/next/utils/props.ts +45 -0
  100. package/build/ExponentCamera.d.ts.map +0 -1
  101. package/build/ExponentCamera.js +0 -4
  102. package/build/ExponentCamera.js.map +0 -1
  103. package/ios/EXCamera/EXCamera.h +0 -112
  104. package/ios/EXCamera/EXCamera.m +0 -1046
  105. package/ios/EXCamera/EXCameraCameraPermissionRequester.h +0 -7
  106. package/ios/EXCamera/EXCameraCameraPermissionRequester.m +0 -54
  107. package/ios/EXCamera/EXCameraMicrophonePermissionRequester.h +0 -7
  108. package/ios/EXCamera/EXCameraMicrophonePermissionRequester.m +0 -54
  109. package/ios/EXCamera/EXCameraPermissionRequester.h +0 -7
  110. package/ios/EXCamera/EXCameraPermissionRequester.m +0 -54
  111. package/ios/EXCamera/Utilities/EXCameraUtils.h +0 -35
  112. package/ios/EXCamera/Utilities/EXCameraUtils.m +0 -228
  113. /package/ios/{EXCamera/TakePictureOptions.swift → TakePictureOptions.swift} +0 -0
package/CHANGELOG.md CHANGED
@@ -10,6 +10,35 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 14.0.0 — 2023-12-12
14
+
15
+ ### 🎉 New features
16
+
17
+ - Methods `stopRecording`, `pausePreview` and `resumePreview` have been updated to return promises. ([#25737](https://github.com/expo/expo/pull/25737) by [@lukmccall](https://github.com/lukmccall))
18
+
19
+ ### 💡 Others
20
+
21
+ - [iOS] Replace legacy `FileSystem` interfaces usage with core `FileSystemUtilities`. ([#25495](https://github.com/expo/expo/pull/25495) by [@alanhughes](https://github.com/alanjhughes))
22
+
23
+ ## 13.9.0 — 2023-11-14
24
+
25
+ ### 🛠 Breaking changes
26
+
27
+ - Bumped iOS deployment target to 13.4. ([#25063](https://github.com/expo/expo/pull/25063) by [@gabrieldonadel](https://github.com/gabrieldonadel))
28
+ - On `Android` bump `compileSdkVersion` and `targetSdkVersion` to `34`. ([#24708](https://github.com/expo/expo/pull/24708) by [@alanjhughes](https://github.com/alanjhughes))
29
+
30
+ ### 🎉 New features
31
+
32
+ - [iOS] Rewrote Objective-C classes to Swift. ([#22604](https://github.com/expo/expo/pull/22604) by [@alanjhughes](https://github.com/alanjhughes))
33
+
34
+ ### 🐛 Bug fixes
35
+
36
+ - [iOS] Fix a regression from ([#22604](https://github.com/expo/expo/pull/22604) that prevented the barcode scanner from starting.([#25053](https://github.com/expo/expo/pull/25053) by [@alanjhughes](https://github.com/alanjhughes))
37
+
38
+ ### 💡 Others
39
+
40
+ - Use `pointerEvent` style instead of prop. ([#24931](https://github.com/expo/expo/pull/24931) by [@EvanBacon](https://github.com/EvanBacon))
41
+
13
42
  ## 13.8.0 — 2023-10-17
14
43
 
15
44
  ### 🛠 Breaking changes
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
3
3
  apply plugin: 'maven-publish'
4
4
 
5
5
  group = 'host.exp.exponent'
6
- version = '13.8.0'
6
+ version = '14.0.0'
7
7
 
8
8
  def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
9
9
  if (expoModulesCorePlugin.exists()) {
@@ -61,11 +61,11 @@ if (!safeExtGet("expoProvidesDefaultConfig", false)) {
61
61
  android {
62
62
  // Remove this if and it's contents, when support for SDK49 is dropped
63
63
  if (!safeExtGet("expoProvidesDefaultConfig", false)) {
64
- compileSdkVersion safeExtGet("compileSdkVersion", 33)
64
+ compileSdkVersion safeExtGet("compileSdkVersion", 34)
65
65
 
66
66
  defaultConfig {
67
67
  minSdkVersion safeExtGet("minSdkVersion", 23)
68
- targetSdkVersion safeExtGet("targetSdkVersion", 33)
68
+ targetSdkVersion safeExtGet("targetSdkVersion", 34)
69
69
  }
70
70
 
71
71
  publishing {
@@ -94,7 +94,7 @@ android {
94
94
  namespace "expo.modules.camera"
95
95
  defaultConfig {
96
96
  versionCode 32
97
- versionName "13.8.0"
97
+ versionName "14.0.0"
98
98
  }
99
99
  }
100
100
 
@@ -111,7 +111,20 @@ dependencies {
111
111
  implementation project(':expo-modules-core')
112
112
  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
113
113
  }
114
+ def camerax_version = "1.4.0-alpha02"
115
+
116
+ api "androidx.exifinterface:exifinterface:1.3.6"
117
+ api 'com.google.android:cameraview:1.0.0'
118
+
119
+ implementation "androidx.camera:camera-core:${camerax_version}"
120
+ implementation "androidx.camera:camera-camera2:${camerax_version}"
121
+ implementation "androidx.camera:camera-lifecycle:${camerax_version}"
122
+ implementation "androidx.camera:camera-video:${camerax_version}"
123
+
124
+ implementation "androidx.camera:camera-view:${camerax_version}"
125
+ implementation "androidx.camera:camera-extensions:${camerax_version}"
126
+ implementation "com.google.mlkit:barcode-scanning:17.2.0"
127
+ implementation 'androidx.camera:camera-mlkit-vision:1.4.0-alpha02'
114
128
 
115
- api "androidx.exifinterface:exifinterface:1.0.0"
116
129
  api 'com.google.android:cameraview:1.0.0'
117
130
  }
@@ -1,3 +1,4 @@
1
1
  <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
2
  <uses-permission android:name="android.permission.CAMERA" />
3
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
3
4
  </manifest>
@@ -17,7 +17,7 @@ import java.io.File
17
17
 
18
18
  class CameraViewModule : Module() {
19
19
  override fun definition() = ModuleDefinition {
20
- Name("ExponentCamera")
20
+ Name("ExpoCamera")
21
21
 
22
22
  Constants(
23
23
  "Type" to mapOf(
@@ -4,7 +4,7 @@ import android.os.Bundle
4
4
  import expo.modules.kotlin.records.Field
5
5
  import expo.modules.kotlin.records.Record
6
6
 
7
- data class BarCodeScannedEvent(
7
+ data class BarcodeScannedEvent(
8
8
  @Field val target: Int,
9
9
  @Field val data: String,
10
10
  @Field val type: Int,
@@ -63,7 +63,7 @@ class ExpoCameraView(
63
63
 
64
64
  private val onCameraReady by EventDispatcher<Unit>()
65
65
  private val onMountError by EventDispatcher<CameraMountErrorEvent>()
66
- private val onBarCodeScanned by EventDispatcher<BarCodeScannedEvent>(
66
+ private val onBarCodeScanned by EventDispatcher<BarcodeScannedEvent>(
67
67
  /**
68
68
  * We want every distinct barcode to be reported to the JS listener.
69
69
  * If we return some static value as a coalescing key there may be two barcode events
@@ -273,7 +273,7 @@ class ExpoCameraView(
273
273
  transformBarCodeScannerResultToViewCoordinates(barCode)
274
274
  val (cornerPoints, boundingBox) = getCornerPointsAndBoundingBox(barCode.cornerPoints, barCode.boundingBox)
275
275
  onBarCodeScanned(
276
- BarCodeScannedEvent(
276
+ BarcodeScannedEvent(
277
277
  target = id,
278
278
  data = barCode.value,
279
279
  type = barCode.type,
@@ -16,8 +16,8 @@ class PictureOptions : Record {
16
16
  }
17
17
 
18
18
  class RecordingOptions : Record {
19
- @Field val maxDuration: Int = -1
20
- @Field val maxFileSize: Int = -1
19
+ @Field val maxDuration: Int = 0
20
+ @Field val maxFileSize: Int = 0
21
21
  @Field val quality: Int = CamcorderProfile.QUALITY_HIGH
22
22
  @Field val mute: Boolean = false
23
23
  @Field val videoBitrate: Int? = null
@@ -0,0 +1,9 @@
1
+ package expo.modules.camera.next
2
+
3
+ import expo.modules.kotlin.exception.CodedException
4
+
5
+ class CameraExceptions {
6
+ class ImageCaptureFailed : CodedException(message = "Failed to capture image")
7
+
8
+ class VideoRecordingFailed(cause: String?) : CodedException("Video recording failed: $cause")
9
+ }
@@ -0,0 +1,40 @@
1
+ package expo.modules.camera.next
2
+
3
+ import android.graphics.Bitmap
4
+ import android.graphics.Canvas
5
+ import android.graphics.Color
6
+ import android.graphics.Paint
7
+ import expo.modules.camera.next.records.CameraType
8
+ import java.io.ByteArrayOutputStream
9
+ import java.text.SimpleDateFormat
10
+ import java.util.Calendar
11
+ import java.util.Locale
12
+
13
+ object CameraViewHelper {
14
+ // Utilities
15
+ @JvmStatic
16
+ fun getCorrectCameraRotation(rotation: Int, facing: CameraType) =
17
+ if (facing == CameraType.FRONT) (rotation - 90 + 360) % 360
18
+ else (-rotation + 90 + 360) % 360
19
+
20
+ fun generateSimulatorPhoto(width: Int, height: Int): ByteArray {
21
+ val fakePhotoBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
22
+ val canvas = Canvas(fakePhotoBitmap)
23
+ val background = Paint().apply {
24
+ color = Color.BLACK
25
+ }
26
+ canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), background)
27
+ val textPaint = Paint().apply {
28
+ color = Color.YELLOW
29
+ textSize = 35f
30
+ }
31
+ val calendar = Calendar.getInstance()
32
+ val simpleDateFormat = SimpleDateFormat("dd.MM.yy HH:mm:ss", Locale.US)
33
+ canvas.drawText(simpleDateFormat.format(calendar.time), width * 0.1f, height * 0.9f, textPaint)
34
+
35
+ val stream = ByteArrayOutputStream()
36
+ fakePhotoBitmap.compress(Bitmap.CompressFormat.PNG, 90, stream)
37
+ val fakePhotoByteArray = stream.toByteArray()
38
+ return fakePhotoByteArray
39
+ }
40
+ }
@@ -0,0 +1,167 @@
1
+ package expo.modules.camera.next
2
+
3
+ import android.Manifest
4
+ import android.util.Log
5
+ import expo.modules.camera.next.records.BarcodeSettings
6
+ import expo.modules.camera.next.records.CameraMode
7
+ import expo.modules.camera.next.records.CameraType
8
+ import expo.modules.camera.next.records.FlashMode
9
+ import expo.modules.camera.next.records.VideoQuality
10
+ import expo.modules.camera.next.tasks.ResolveTakenPicture
11
+ import expo.modules.core.errors.ModuleDestroyedException
12
+ import expo.modules.core.utilities.EmulatorUtilities
13
+ import expo.modules.interfaces.permissions.Permissions
14
+ import expo.modules.kotlin.Promise
15
+ import expo.modules.kotlin.exception.Exceptions
16
+ import expo.modules.kotlin.functions.Queues
17
+ import expo.modules.kotlin.modules.Module
18
+ import expo.modules.kotlin.modules.ModuleDefinition
19
+ import kotlinx.coroutines.CoroutineScope
20
+ import kotlinx.coroutines.Dispatchers
21
+ import kotlinx.coroutines.cancel
22
+ import kotlinx.coroutines.launch
23
+ import java.io.File
24
+
25
+ val cameraEvents = arrayOf(
26
+ "onCameraReady",
27
+ "onMountError",
28
+ "onBarcodeScanned",
29
+ "onFacesDetected",
30
+ "onFaceDetectionError",
31
+ "onPictureSaved"
32
+ )
33
+
34
+ class CameraViewNextModule : Module() {
35
+ private val moduleScope = CoroutineScope(Dispatchers.Main)
36
+ override fun definition() = ModuleDefinition {
37
+ Name("ExpoCameraNext")
38
+
39
+ Events("onModernBarcodeScanned")
40
+
41
+ AsyncFunction("requestCameraPermissionsAsync") { promise: Promise ->
42
+ Permissions.askForPermissionsWithPermissionsManager(
43
+ permissionsManager,
44
+ promise,
45
+ Manifest.permission.CAMERA
46
+ )
47
+ }
48
+
49
+ AsyncFunction("requestMicrophonePermissionsAsync") { promise: Promise ->
50
+ Permissions.askForPermissionsWithPermissionsManager(
51
+ permissionsManager,
52
+ promise,
53
+ Manifest.permission.RECORD_AUDIO
54
+ )
55
+ }
56
+
57
+ AsyncFunction("getCameraPermissionsAsync") { promise: Promise ->
58
+ Permissions.getPermissionsWithPermissionsManager(
59
+ permissionsManager,
60
+ promise,
61
+ Manifest.permission.CAMERA
62
+ )
63
+ }
64
+
65
+ AsyncFunction("getMicrophonePermissionsAsync") { promise: Promise ->
66
+ Permissions.getPermissionsWithPermissionsManager(
67
+ permissionsManager,
68
+ promise,
69
+ Manifest.permission.RECORD_AUDIO
70
+ )
71
+ }
72
+
73
+ OnDestroy {
74
+ try {
75
+ moduleScope.cancel(ModuleDestroyedException())
76
+ } catch (e: IllegalStateException) {
77
+ Log.e(TAG, "The scope does not have a job in it")
78
+ }
79
+ }
80
+
81
+ View(ExpoCameraView::class) {
82
+ Events(cameraEvents)
83
+
84
+ Prop("type") { view, type: CameraType ->
85
+ view.lenFacing = type
86
+ }
87
+
88
+ Prop("flashMode") { view, flashMode: FlashMode ->
89
+ view.setCameraFlashMode(flashMode)
90
+ }
91
+
92
+ Prop("enableTorch") { view, enabled: Boolean ->
93
+ view.setTorchEnabled(enabled)
94
+ }
95
+
96
+ Prop("zoom") { view, zoom: Float ->
97
+ view.camera?.cameraControl?.setLinearZoom(zoom)
98
+ }
99
+
100
+ Prop("mode") { view, mode: CameraMode ->
101
+ view.cameraMode = mode
102
+ }
103
+
104
+ Prop("mute") { view, muted: Boolean? ->
105
+ view.mute = muted ?: false
106
+ }
107
+
108
+ Prop("videoQuality") { view, quality: VideoQuality? ->
109
+ if (quality != null) {
110
+ view.videoQuality = quality
111
+ } else {
112
+ view.videoQuality = VideoQuality.VIDEO1080P
113
+ }
114
+ }
115
+
116
+ Prop("barcodeScannerSettings") { view, settings: BarcodeSettings? ->
117
+ if (settings == null) {
118
+ return@Prop
119
+ }
120
+ view.setBarCodeScannerSettings(settings)
121
+ }
122
+
123
+ Prop("barcodeScannerEnabled") { view, barCodeScannerEnabled: Boolean? ->
124
+ view.setShouldScanBarcodes(barCodeScannerEnabled ?: false)
125
+ }
126
+
127
+ AsyncFunction("takePicture") { view: ExpoCameraView, options: PictureOptions, promise: Promise ->
128
+ if (!EmulatorUtilities.isRunningOnEmulator()) {
129
+ view.takePicture(options, promise, cacheDirectory)
130
+ } else {
131
+ val image = CameraViewHelper.generateSimulatorPhoto(view.width, view.height)
132
+ moduleScope.launch {
133
+ ResolveTakenPicture(image, promise, options, cacheDirectory) { response ->
134
+ view.onPictureSaved(response)
135
+ }.resolve()
136
+ }
137
+ }
138
+ }.runOnQueue(Queues.MAIN)
139
+
140
+ AsyncFunction("record") { view: ExpoCameraView, options: RecordingOptions, promise: Promise ->
141
+ if (!view.mute && !permissionsManager.hasGrantedPermissions(Manifest.permission.RECORD_AUDIO)) {
142
+ throw Exceptions.MissingPermissions(Manifest.permission.RECORD_AUDIO)
143
+ }
144
+
145
+ view.record(options, promise, cacheDirectory)
146
+ }.runOnQueue(Queues.MAIN)
147
+
148
+ AsyncFunction("stopRecording") { view: ExpoCameraView ->
149
+ view.activeRecording?.close()
150
+ }.runOnQueue(Queues.MAIN)
151
+
152
+ OnViewDestroys { view ->
153
+ view.cancelCoroutineScope()
154
+ }
155
+ }
156
+ }
157
+
158
+ private val cacheDirectory: File
159
+ get() = appContext.cacheDirectory
160
+
161
+ private val permissionsManager: Permissions
162
+ get() = appContext.permissions ?: throw Exceptions.PermissionsModuleNotFound()
163
+
164
+ companion object {
165
+ internal val TAG = CameraViewNextModule::class.java.simpleName
166
+ }
167
+ }