diff --git a/ios/Podfile.lock b/ios/Podfile.lock index bc92a0ed7..e82e9d640 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1475,19 +1475,19 @@ PODS: - ReactCommon/turbomodule/core - Yoga - SocketRocket (0.7.0) - - VisionCamera (4.0.5): - - VisionCamera/Core (= 4.0.5) - - VisionCamera/FrameProcessors (= 4.0.5) - - VisionCamera/React (= 4.0.5) - - VisionCamera/Core (4.0.5) - - VisionCamera/FrameProcessors (4.0.5): + - VisionCamera (4.5.2): + - VisionCamera/Core (= 4.5.2) + - VisionCamera/FrameProcessors (= 4.5.2) + - VisionCamera/React (= 4.5.2) + - VisionCamera/Core (4.5.2) + - VisionCamera/FrameProcessors (4.5.2): - React - React-callinvoker - react-native-worklets-core - - VisionCamera/React (4.0.5): + - VisionCamera/React (4.5.2): - React-Core - VisionCamera/FrameProcessors - - VisionCameraPluginInatVision (5.2.0): + - VisionCameraPluginInatVision (5.3.0-rc.0): - React-Core - Yoga (0.0.0) @@ -1915,8 +1915,8 @@ SPEC CHECKSUMS: RNSVG: a31e321979e3001f56ba9331d10ac917f8ad1851 RNVectorIcons: 6c795cacc9276decc31d8e1a139b9cc6fc0479ca SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d - VisionCamera: f02de0b1b6b1516b327bd8215237a97e7386db8a - VisionCameraPluginInatVision: 9562479ff3360026c99b2dc2013127950ea31bbe + VisionCamera: 25a205cf335599192d84171d0925d5bd45433608 + VisionCameraPluginInatVision: 6eace74efbce44b4df258b2c2a45232c76846cdc Yoga: 272dddd3c0e1e23d09ba81ed55ddfa7fdd3caa17 PODFILE CHECKSUM: c92c85936cdaceff02009b29b05bbb2fe1d7b943 diff --git a/package-lock.json b/package-lock.json index 140d02ef5..4bcdabb3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -94,14 +94,14 @@ "react-native-svg-transformer": "^1.3.0", "react-native-url-polyfill": "^2.0.0", "react-native-vector-icons": "^10.2.0", - "react-native-vision-camera": "4.0.5", + "react-native-vision-camera": "4.5.2", "react-native-volume-manager": "^1.10.0", "react-native-webview": "^13.8.4", - "react-native-worklets-core": "^1.3.3", + "react-native-worklets-core": "1.3.3", "realm": "^20.1.0", "sanitize-html": "^2.13.0", "uuid": "^11.0.5", - "vision-camera-plugin-inatvision": "github:inaturalist/vision-camera-plugin-inatvision#924a801b224be6243679c8237fbe0ec58ece0ac9", + "vision-camera-plugin-inatvision": "github:inaturalist/vision-camera-plugin-inatvision#be7e5faed370bf307a062e728b5cf80b9c7292fe", "zustand": "^4.5.2" }, "devDependencies": { @@ -12181,9 +12181,10 @@ "dev": true }, "node_modules/h3-js": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/h3-js/-/h3-js-4.1.0.tgz", - "integrity": "sha512-LQhmMl1dRQQjMXPzJc7MpZ/CqPOWWuAvVEoVJM9n/s7vHypj+c3Pd5rLQCkAsOgAoAYKbNCsYFE++LF7MvSfCQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/h3-js/-/h3-js-4.2.1.tgz", + "integrity": "sha512-HYiUrq5qTRFqMuQu3jEHqxXLk1zsSJiby9Lja/k42wHjabZG7tN9rOuzT/PEFf+Wa7rsnHLMHRWIu0mgcJ0ewQ==", + "license": "Apache-2.0", "engines": { "node": ">=4", "npm": ">=3", @@ -18320,9 +18321,10 @@ } }, "node_modules/react-native-vision-camera": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/react-native-vision-camera/-/react-native-vision-camera-4.0.5.tgz", - "integrity": "sha512-MaNQPnRLf6RfWOvhrPb+qiwhOAQIhtWhXJck6UU5Xj0ehoC3SsZjbdPZ39V5BD1KifK1n2YnuS0tzGw/zfrBzg==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/react-native-vision-camera/-/react-native-vision-camera-4.5.2.tgz", + "integrity": "sha512-k5iITx10jmAPofVnz8S5/ZHyJYgHw/7MQ58M6S3z7TBlCqRu7D9dz4HSJrQcCpV8rBE3a5xyMqxTZ4Hth/h+2g==", + "license": "MIT", "peerDependencies": { "@shopify/react-native-skia": "*", "react": "*", @@ -20948,9 +20950,9 @@ } }, "node_modules/vision-camera-plugin-inatvision": { - "version": "5.2.0", - "resolved": "git+ssh://git@github.com/inaturalist/vision-camera-plugin-inatvision.git#924a801b224be6243679c8237fbe0ec58ece0ac9", - "integrity": "sha512-+8ZqYFRpmsIaSR4VDGJg8lKJ8iVo8JYBFGPxoWHlzUzeComffvCDDYX/zJCiyw7Z6dCka4y0wySQMdvlNiXQ7g==", + "version": "5.3.0-rc.0", + "resolved": "git+ssh://git@github.com/inaturalist/vision-camera-plugin-inatvision.git#be7e5faed370bf307a062e728b5cf80b9c7292fe", + "integrity": "sha512-KerEC93NqxLvfLgdbMD2KMl2NlGd92T6YyZ5M8ClsHjFT/jcIkYblTyB6e6eov48BGsApX55f4Q7fDchKG78eA==", "license": "MIT", "dependencies": { "h3-js": "^4.1.0" @@ -20960,9 +20962,9 @@ }, "peerDependencies": { "react": "*", - "react-native": "*", - "react-native-vision-camera": ">=4.0.1", - "react-native-worklets-core": ">=1.2.0" + "react-native": ">=0.73.0", + "react-native-vision-camera": ">=4.1.0", + "react-native-worklets-core": ">=1.3.3" } }, "node_modules/vlq": { diff --git a/package.json b/package.json index d46d2ea41..26d307827 100644 --- a/package.json +++ b/package.json @@ -128,14 +128,14 @@ "react-native-svg-transformer": "^1.3.0", "react-native-url-polyfill": "^2.0.0", "react-native-vector-icons": "^10.2.0", - "react-native-vision-camera": "4.0.5", + "react-native-vision-camera": "4.5.2", "react-native-volume-manager": "^1.10.0", "react-native-webview": "^13.8.4", - "react-native-worklets-core": "^1.3.3", + "react-native-worklets-core": "1.3.3", "realm": "^20.1.0", "sanitize-html": "^2.13.0", "uuid": "^11.0.5", - "vision-camera-plugin-inatvision": "github:inaturalist/vision-camera-plugin-inatvision#924a801b224be6243679c8237fbe0ec58ece0ac9", + "vision-camera-plugin-inatvision": "github:inaturalist/vision-camera-plugin-inatvision#be7e5faed370bf307a062e728b5cf80b9c7292fe", "zustand": "^4.5.2" }, "devDependencies": { diff --git a/patches/react-native-vision-camera+4.0.5.patch b/patches/react-native-vision-camera+4.5.2.patch similarity index 64% rename from patches/react-native-vision-camera+4.0.5.patch rename to patches/react-native-vision-camera+4.5.2.patch index 179ee692c..05c69ed97 100644 --- a/patches/react-native-vision-camera+4.0.5.patch +++ b/patches/react-native-vision-camera+4.5.2.patch @@ -1,22 +1,3 @@ -diff --git a/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/frameprocessors/VisionCameraProxy.kt b/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/frameprocessors/VisionCameraProxy.kt -index d697bef..8de418b 100644 ---- a/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/frameprocessors/VisionCameraProxy.kt -+++ b/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/frameprocessors/VisionCameraProxy.kt -@@ -7,12 +7,14 @@ import com.facebook.jni.HybridData - import com.facebook.proguard.annotations.DoNotStrip - import com.facebook.react.bridge.ReactApplicationContext - import com.facebook.react.bridge.UiThreadUtil -+import com.facebook.react.common.annotations.FrameworkAPI - import com.facebook.react.turbomodule.core.CallInvokerHolderImpl - import com.facebook.react.uimanager.UIManagerHelper - import com.mrousavy.camera.core.ViewNotFoundError - import com.mrousavy.camera.react.CameraView - import java.lang.ref.WeakReference - -+@OptIn(FrameworkAPI::class) - @Suppress("KotlinJniMissingFunction") // we use fbjni. - class VisionCameraProxy(private val reactContext: ReactApplicationContext) { - companion object { diff --git a/node_modules/react-native-vision-camera/ios/Core/MetadataProvider.swift b/node_modules/react-native-vision-camera/ios/Core/MetadataProvider.swift index 4855d31..ece8024 100644 --- a/node_modules/react-native-vision-camera/ios/Core/MetadataProvider.swift diff --git a/src/components/Camera/AICamera/FrameProcessorCamera.js b/src/components/Camera/AICamera/FrameProcessorCamera.js index 79d8d46dc..43cce2a46 100644 --- a/src/components/Camera/AICamera/FrameProcessorCamera.js +++ b/src/components/Camera/AICamera/FrameProcessorCamera.js @@ -19,11 +19,8 @@ import { taxonomyPath } from "sharedHelpers/mlModel.ts"; import { logStage } from "sharedHelpers/sentinelFiles.ts"; -import { - orientationPatchFrameProcessor, - usePatchedRunAsync -} from "sharedHelpers/visionCameraPatches"; -import { useDeviceOrientation, useLayoutPrefs } from "sharedHooks"; +import usePatchedRunAsync from "sharedHelpers/visionCameraPatches"; +import { useLayoutPrefs } from "sharedHooks"; import useStore from "stores/useStore"; type Props = { @@ -81,7 +78,6 @@ const FrameProcessorCamera = ( { }: Props ): Node => { const sentinelFileName = useStore( state => state.sentinelFileName ); const { isDefaultMode } = useLayoutPrefs( ); - const { deviceOrientation } = useDeviceOrientation(); const [lastTimestamp, setLastTimestamp] = useState( undefined ); const navigation = useNavigation(); @@ -139,7 +135,6 @@ const FrameProcessorCamera = ( { onClassifierError( error ); } ); - const patchedOrientationAndroid = orientationPatchFrameProcessor( deviceOrientation ); const patchedRunAsync = usePatchedRunAsync( ); const hasUserLocation = userLocation?.latitude != null && userLocation?.longitude != null; const useGeomodel = isDefaultMode @@ -182,7 +177,6 @@ const FrameProcessorCamera = ( { confidenceThreshold, numStoredResults, cropRatio, - patchedOrientationAndroid, useGeomodel, geomodelPath, location: { @@ -205,7 +199,6 @@ const FrameProcessorCamera = ( { modelVersion, confidenceThreshold, takingPhoto, - patchedOrientationAndroid, numStoredResults, cropRatio, lastTimestamp, diff --git a/src/components/Camera/CameraContainer.tsx b/src/components/Camera/CameraContainer.tsx index e1680eb9c..291c67853 100644 --- a/src/components/Camera/CameraContainer.tsx +++ b/src/components/Camera/CameraContainer.tsx @@ -15,15 +15,13 @@ import type { } from "react-native-vision-camera"; import fetchAccurateUserLocation from "sharedHelpers/fetchAccurateUserLocation.ts"; import { createSentinelFile, deleteSentinelFile, logStage } from "sharedHelpers/sentinelFiles.ts"; -import { - useDeviceOrientation, useTranslation -} from "sharedHooks"; +import { useTranslation } from "sharedHooks"; import useLocationPermission from "sharedHooks/useLocationPermission.tsx"; import useStore from "stores/useStore"; import CameraWithDevice from "./CameraWithDevice"; import savePhotosToPhotoLibrary from "./helpers/savePhotosToPhotoLibrary"; -import saveRotatedPhotoToDocumentsDirectory from "./helpers/saveRotatedPhotoToDocumentsDirectory"; +import savePhotoToDocumentsDirectory from "./helpers/savePhotoToDocumentsDirectory"; import usePrepareStoreAndNavigate from "./hooks/usePrepareStoreAndNavigate"; import useSavePhotoPermission from "./hooks/useSavePhotoPermission"; @@ -79,8 +77,6 @@ const CameraContainer = ( ) => { await deleteSentinelFile( sentinelFileName ); }, [cameraType, sentinelFileName] ); - const { deviceOrientation } = useDeviceOrientation( ); - const { hasPermissions: hasLocationPermissions, renderPermissionsGate: renderLocationPermissionsGate, @@ -248,7 +244,7 @@ const CameraContainer = ( ) => { await logStageIfAICamera( "take_photo_error" ); throw new Error( "Failed to take photo: missing camera" ); } - const uri = await saveRotatedPhotoToDocumentsDirectory( cameraPhoto, deviceOrientation ); + const uri = await savePhotoToDocumentsDirectory( cameraPhoto ); const newPhotoState = await updateTakePhotoStore( uri, options ); if ( cameraType !== "AI" ) { setTakingPhoto( false ); } if ( options?.navigateImmediately ) { diff --git a/src/components/Camera/CameraView.tsx b/src/components/Camera/CameraView.tsx index 4be93f020..239ceb0d8 100644 --- a/src/components/Camera/CameraView.tsx +++ b/src/components/Camera/CameraView.tsx @@ -5,7 +5,6 @@ import { useCameraFormat } from "components/Camera/helpers/visionCameraWrapper"; import useFocusTap from "components/Camera/hooks/useFocusTap.ts"; -import VeryBadIpadRotator from "components/SharedComponents/VeryBadIpadRotator"; import React, { useCallback } from "react"; @@ -17,8 +16,6 @@ import Reanimated from "react-native-reanimated"; import type { CameraDevice, CameraDeviceFormat, CameraProps, CameraRuntimeError } from "react-native-vision-camera"; -import { orientationPatch } from "sharedHelpers/visionCameraPatches"; -import useDeviceOrientation from "sharedHooks/useDeviceOrientation.ts"; import FocusSquare from "./FocusSquare"; @@ -100,8 +97,6 @@ const CameraView = ( { // Set the exposure to the middle of the min and max exposure const exposure = ( device.maxExposure + device.minExposure ) / 2; - const { deviceOrientation } = useDeviceOrientation(); - const onError = useCallback( ( error: CameraRuntimeError ) => { // { code: string, message: string, cause?: {} } @@ -154,19 +149,14 @@ const CameraView = ( { ] ); - // react-native-vision-camera v3.9.0: - // iPad camera preview is wrong in anything else than portrait, hence the - // VeryBadIpadRotator, which will rotate its contents us a style transform - // and adjust position accordingly - // Note that overflow-hidden handles what seems to be a bug in android in // which the Camera overflows its view return ( - - + <> + - - - + + + ); }; diff --git a/src/components/Camera/helpers/savePhotoToDocumentsDirectory.ts b/src/components/Camera/helpers/savePhotoToDocumentsDirectory.ts new file mode 100644 index 000000000..48b361d74 --- /dev/null +++ b/src/components/Camera/helpers/savePhotoToDocumentsDirectory.ts @@ -0,0 +1,31 @@ +import { + rotatedOriginalPhotosPath +} from "appConstants/paths.ts"; +import RNFS from "react-native-fs"; +import type { + PhotoFile +} from "react-native-vision-camera"; +import resizeImage from "sharedHelpers/resizeImage.ts"; +import { unlink } from "sharedHelpers/util.ts"; + +const savePhotoToDocumentsDirectory = async ( + cameraPhoto: PhotoFile +) => { + const path = rotatedOriginalPhotosPath; + await RNFS.mkdir( path ); + // Move the image with ImageResizer (for legacy reasons, because we + // used to use it to rotate the photo) + const image = await resizeImage( + cameraPhoto.path, + { + width: cameraPhoto.width, + height: cameraPhoto.height, + outputPath: path + } + ); + // Remove original photo + await unlink( cameraPhoto.path ); + return image; +}; + +export default savePhotoToDocumentsDirectory; diff --git a/src/components/Camera/helpers/saveRotatedPhotoToDocumentsDirectory.ts b/src/components/Camera/helpers/saveRotatedPhotoToDocumentsDirectory.ts deleted file mode 100644 index 2c3aee893..000000000 --- a/src/components/Camera/helpers/saveRotatedPhotoToDocumentsDirectory.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { - PhotoFile -} from "react-native-vision-camera"; -import { - rotatePhotoPatch -} from "sharedHelpers/visionCameraPatches"; - -// Rotate the original photo depending on device orientation -const saveRotatedPhotoToDocumentsDirectory = async ( - cameraPhoto: PhotoFile, - deviceOrientation: string -) => rotatePhotoPatch( cameraPhoto, deviceOrientation ); - -export default saveRotatedPhotoToDocumentsDirectory; diff --git a/src/components/Camera/hooks/useRotation.ts b/src/components/Camera/hooks/useRotation.ts index 98100f2d1..12c56465b 100644 --- a/src/components/Camera/hooks/useRotation.ts +++ b/src/components/Camera/hooks/useRotation.ts @@ -3,8 +3,24 @@ import { useSharedValue, withTiming } from "react-native-reanimated"; -import { rotationValue } from "sharedHelpers/visionCameraPatches"; -import useDeviceOrientation from "sharedHooks/useDeviceOrientation.ts"; +import useDeviceOrientation, { + LANDSCAPE_LEFT, + LANDSCAPE_RIGHT, + PORTRAIT_UPSIDE_DOWN +} from "sharedHooks/useDeviceOrientation.ts"; + +const rotationValue = ( deviceOrientation: string | undefined ) => { + switch ( deviceOrientation ) { + case LANDSCAPE_LEFT: + return -90; + case LANDSCAPE_RIGHT: + return 90; + case PORTRAIT_UPSIDE_DOWN: + return 180; + default: + return 0; + } +}; const useRotation = ( ) => { const { deviceOrientation } = useDeviceOrientation( ); diff --git a/src/components/SharedComponents/VeryBadIpadRotator.js b/src/components/SharedComponents/VeryBadIpadRotator.js deleted file mode 100644 index b81f4e844..000000000 --- a/src/components/SharedComponents/VeryBadIpadRotator.js +++ /dev/null @@ -1,58 +0,0 @@ -// This assumes that its contents are not rotated correctly on an iPad... for -// whatever reason, and rotates them using a CSS transform and some munging -// of the position. This is very much a kludge. It would be far preferrable -// to fix whatever is causing the incorrect rotation. Originally a workaround -// for https://github.com/mrousavy/react-native-vision-camera/issues/1891 -import { View } from "components/styledComponents"; -import React, { useRef, useState } from "react"; -import { iPadStylePatch } from "sharedHelpers/visionCameraPatches"; -import useDeviceOrientation from "sharedHooks/useDeviceOrientation.ts"; - -const VeryBadIpadRotator = ( { children } ) => { - const [dims, setDims] = useState( {} ); - const { deviceOrientation } = useDeviceOrientation(); - const containerRef = useRef( ); - - const innerStyle = iPadStylePatch( deviceOrientation ); - innerStyle.flex = 1; - // courtesy of - // https://github.com/mrousavy/react-native-vision-camera/issues/1891#issuecomment-1746222690 - if ( - innerStyle.transform - && dims.width - && dims.height - ) { - innerStyle.position = "absolute"; - innerStyle.width = dims.height; - innerStyle.height = dims.width; - innerStyle.left = dims.width / 2 - dims.height / 2; - innerStyle.top = dims.height / 2 - dims.width / 2; - } - return ( - containerRef?.current?.measure( - ( x, y, w, h, pageX, pageY ) => setDims( { - x, - y, - width: w, - height: h, - pageX, - pageY - } ) - ) - } - > - - {children} - - - ); -}; - -export default VeryBadIpadRotator; diff --git a/src/sharedHelpers/visionCameraPatches.js b/src/sharedHelpers/visionCameraPatches.js index 662d01f66..80f039962 100644 --- a/src/sharedHelpers/visionCameraPatches.js +++ b/src/sharedHelpers/visionCameraPatches.js @@ -1,160 +1,11 @@ /* - This file contains various patches for handling the react-native-vision-camera library. + This file contains patches for handling the react-native-vision-camera library. */ -import { - rotatedOriginalPhotosPath -} from "appConstants/paths.ts"; -import { Platform } from "react-native"; -import { isTablet } from "react-native-device-info"; -import RNFS from "react-native-fs"; import { useSharedValue as useWorkletSharedValue, Worklets } from "react-native-worklets-core"; -import resizeImage from "sharedHelpers/resizeImage.ts"; -import { unlink } from "sharedHelpers/util.ts"; -import { - LANDSCAPE_LEFT, - LANDSCAPE_RIGHT, - PORTRAIT, - PORTRAIT_UPSIDE_DOWN -} from "sharedHooks/useDeviceOrientation.ts"; - -// Needed for react-native-vision-camera v3.9.0 -// This patch is used to determine the orientation prop for the Camera component. -// On Android, the orientation prop is not used, so we return null. -// On iOS, the orientation prop is undocumented, but it does get used in a sense that the -// photo metadata shows the correct Orientation only if this prop is set. -export const orientationPatch = deviceOrientation => ( Platform.OS === "android" - ? null - : deviceOrientation ); - -// Needed for react-native-vision-camera v3.9.0 in combination -// with our vision-camera-plugin-inatvision -// This patch is used to determine the orientation prop for the FrameProcessor. -// This is only needed for Android, so on iOS we return null. -export const orientationPatchFrameProcessor = deviceOrientation => ( Platform.OS === "android" - ? deviceOrientation - : null ); - -// Needed for react-native-vision-camera v3.9.0 -// As of this version the photo from takePhoto is not oriented coming from the native side. -// E.g. if you take a photo in landscape-right and save it to camera roll directly from the -// vision camera, it will be tilted in the native photo app. So, on iOS, depending on the -// metadata of the photo the rotation needs to be set to 0 or 180. -// On Android, the rotation is derived from the device orientation at the time of taking the -// photo, because orientation is not yet supported in the library. -export const rotationTempPhotoPatch = ( photo, deviceOrientation ) => { - let photoRotation = 0; - if ( Platform.OS === "ios" ) { - switch ( photo.metadata?.Orientation ) { - case 1: - case 3: - photoRotation = 180; - break; - case 6: - case 8: - photoRotation = 0; - break; - default: - photoRotation = 0; - } - } else { - switch ( deviceOrientation ) { - case PORTRAIT: - photoRotation = 90; - break; - case LANDSCAPE_RIGHT: - photoRotation = 180; - break; - case LANDSCAPE_LEFT: - photoRotation = 0; - break; - case PORTRAIT_UPSIDE_DOWN: - photoRotation = 270; - break; - default: - photoRotation = 90; - } - } - return photoRotation; -}; - -// Needed for react-native-vision-camera v3.9.0 -// This patch is used to rotate the photo taken with the vision camera. -// Because the photos coming from the vision camera are not oriented correctly, we -// rotate them with image-resizer as a first step, replacing the original photo. -export const rotatePhotoPatch = async ( photo, deviceOrientation ) => { - const rotation = rotationTempPhotoPatch( photo, deviceOrientation ); - const path = rotatedOriginalPhotosPath; - await RNFS.mkdir( path ); - // Rotate the image with ImageResizer - const image = await resizeImage( - photo.path, - { - width: photo.width, - height: photo.height, - rotation, - outputPath: path - } - ); - // Remove original photo - await unlink( photo.path ); - return image; -}; - -// Needed for react-native-vision-camera v3.9.0 -// This patch is here to remember to replace the rotation used when resizing the original -// photo to a smaller local copy we keep in the app cache. Previously we had a flow where -// we would resize the original photo to a smaller version including rotation. Now, we -// rotate the original photo first with image-resizer separately to save to camera roll, -// and then resize this copy to a smaller version. In case the first step is redundant -// in the future, we keep this patch here to remind us to put the rotation back to resizing -// the smaller photo. -export const rotationLocalPhotoPatch = () => 0; - -export const rotationValue = deviceOrientation => { - switch ( deviceOrientation ) { - case LANDSCAPE_LEFT: - return -90; - case LANDSCAPE_RIGHT: - return 90; - case PORTRAIT_UPSIDE_DOWN: - return 180; - default: - return 0; - } -}; - -// Needed for react-native-vision-camera v3.3.1 -// This patch is used to rotate the camera view on iPads. -// The only thing to do there is to rotate the camera view component -// depending on the device orientation. The resulting photo is already rotated in other places. -export const iPadStylePatch = deviceOrientation => { - // Do nothing on Android - if ( Platform.OS === "android" ) { - return {}; - } - // Do nothing on phones - if ( !isTablet() ) { - return {}; - } - if ( deviceOrientation === LANDSCAPE_RIGHT ) { - return { - transform: [{ rotate: "90deg" }] - }; - } if ( deviceOrientation === LANDSCAPE_LEFT ) { - return { - transform: [{ rotate: "-90deg" }] - }; - } if ( deviceOrientation === PORTRAIT_UPSIDE_DOWN ) { - return { - transform: [{ rotate: "180deg" }] - }; - } - return {}; -}; // This patch is currently required because we are using react-native-vision-camera v4.0.3 // together wit react-native-reanimated. The problem is that the runAsync function @@ -162,7 +13,7 @@ export const iPadStylePatch = deviceOrientation => { // Uses this workaround: https://gist.github.com/nonam4/7a6409cd1273e8ed7466ba3a48dd1ecc but adapted it to // version 4 of vision-camera. // Originally, posted on this currently open issue: https://github.com/mrousavy/react-native-vision-camera/issues/2589 -export const usePatchedRunAsync = ( ) => { +const usePatchedRunAsync = ( ) => { /** * Print worklets logs/errors on js thread */ @@ -199,3 +50,5 @@ export const usePatchedRunAsync = ( ) => { return customRunAsync; }; + +export default usePatchedRunAsync;