Merge pull request 'ivan/react-native-vision-camera-submodule' (#68) from ivan/react-native-vision-camera-submodule into master
Reviewed-on: railbird/rn-playground#68 Reviewed-by: Kat Huang <kkathuang@gmail.com>
This commit is contained in:
		
							
								
								
									
										9
									
								
								.editorconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								.editorconfig
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					root = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[*.json]
 | 
				
			||||||
 | 
					end_of_line = lf
 | 
				
			||||||
 | 
					charset = utf-8
 | 
				
			||||||
 | 
					indent_style = space
 | 
				
			||||||
 | 
					indent_size =  2
 | 
				
			||||||
 | 
					trim_trailing_whitespace = true
 | 
				
			||||||
 | 
					insert_final_newline = true
 | 
				
			||||||
							
								
								
									
										1
									
								
								.eslintignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.eslintignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					/react-native-vision-camera/
 | 
				
			||||||
							
								
								
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					[submodule "react-native-vision-camera"]
 | 
				
			||||||
 | 
						path = react-native-vision-camera
 | 
				
			||||||
 | 
						url = https://dev.railbird.ai/railbird/react-native-vision-camera.git
 | 
				
			||||||
@@ -174,6 +174,8 @@ dependencies {
 | 
				
			|||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        implementation jscFlavor
 | 
					        implementation jscFlavor
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    implementation project(':react-native-vision-camera')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
 | 
					apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,7 @@ import com.facebook.soloader.SoLoader;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import expo.modules.ApplicationLifecycleDispatcher;
 | 
					import expo.modules.ApplicationLifecycleDispatcher;
 | 
				
			||||||
import expo.modules.ReactNativeHostWrapper;
 | 
					import expo.modules.ReactNativeHostWrapper;
 | 
				
			||||||
 | 
					import com.mrousavy.camera.CameraPackage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -33,6 +34,7 @@ public class MainApplication extends Application implements ReactApplication {
 | 
				
			|||||||
        List<ReactPackage> packages = new PackageList(this).getPackages();
 | 
					        List<ReactPackage> packages = new PackageList(this).getPackages();
 | 
				
			||||||
        // Packages that cannot be autolinked yet can be added manually here, for example:
 | 
					        // Packages that cannot be autolinked yet can be added manually here, for example:
 | 
				
			||||||
            // packages.add(new MyReactNativePackage());
 | 
					            // packages.add(new MyReactNativePackage());
 | 
				
			||||||
 | 
					        packages.add(new CameraPackage());
 | 
				
			||||||
        return packages;
 | 
					        return packages;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,7 @@ buildscript {
 | 
				
			|||||||
        classpath 'com.google.gms:google-services:4.3.3'
 | 
					        classpath 'com.google.gms:google-services:4.3.3'
 | 
				
			||||||
        classpath('com.android.tools.build:gradle:7.4.2')
 | 
					        classpath('com.android.tools.build:gradle:7.4.2')
 | 
				
			||||||
        classpath('com.facebook.react:react-native-gradle-plugin')
 | 
					        classpath('com.facebook.react:react-native-gradle-plugin')
 | 
				
			||||||
 | 
					        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.22")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,17 @@
 | 
				
			|||||||
rootProject.name = 'Railbird'
 | 
					rootProject.name = 'Railbird'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle");
 | 
					apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
useExpoModules()
 | 
					useExpoModules()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
 | 
					apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
applyNativeModulesSettingsGradle(settings)
 | 
					applyNativeModulesSettingsGradle(settings)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include ':react-native-vision-camera'
 | 
				
			||||||
 | 
					project(':react-native-vision-camera').projectDir = new File(rootProject.projectDir, '../react-native-vision-camera/package/android')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include ':app'
 | 
					include ':app'
 | 
				
			||||||
includeBuild(new File(["node", "--print", "require.resolve('@react-native/gradle-plugin/package.json')"].execute(null, rootDir).text.trim()).getParentFile())
 | 
					includeBuild(new File(["node", "--print", "require.resolve('@react-native/gradle-plugin/package.json')"].execute(null, rootDir).text.trim()).getParentFile())
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								app.json
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								app.json
									
									
									
									
									
								
							@@ -11,9 +11,7 @@
 | 
				
			|||||||
      "resizeMode": "contain",
 | 
					      "resizeMode": "contain",
 | 
				
			||||||
      "backgroundColor": "#ffffff"
 | 
					      "backgroundColor": "#ffffff"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "assetBundlePatterns": [
 | 
					    "assetBundlePatterns": ["**/*"],
 | 
				
			||||||
      "**/*"
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "plugins": [
 | 
					    "plugins": [
 | 
				
			||||||
      "@react-native-firebase/app",
 | 
					      "@react-native-firebase/app",
 | 
				
			||||||
      "@react-native-firebase/auth",
 | 
					      "@react-native-firebase/auth",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,16 +1,34 @@
 | 
				
			|||||||
 | 
					const path = require("path");
 | 
				
			||||||
 | 
					const pak = require("./react-native-vision-camera/package/package.json");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = function (api) {
 | 
					module.exports = function (api) {
 | 
				
			||||||
  api.cache(true);
 | 
					  api.cache(true);
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
    presets: ["babel-preset-expo"],
 | 
					    presets: ["babel-preset-expo"],
 | 
				
			||||||
    plugins: [
 | 
					    plugins: [
 | 
				
			||||||
            ["module:react-native-dotenv", {
 | 
					      [
 | 
				
			||||||
                "moduleName": "@env",
 | 
					        "module:react-native-dotenv",
 | 
				
			||||||
                "path": ".env",
 | 
					        {
 | 
				
			||||||
                "safe": false,
 | 
					          moduleName: "@env",
 | 
				
			||||||
                "allowUndefined": true,
 | 
					          path: ".env",
 | 
				
			||||||
                "verbose": false,
 | 
					          safe: false,
 | 
				
			||||||
            }],
 | 
					          allowUndefined: true,
 | 
				
			||||||
            'react-native-reanimated/plugin',
 | 
					          verbose: false,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "react-native-reanimated/plugin",
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        "module-resolver",
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          alias: {
 | 
				
			||||||
 | 
					            [pak.name]: path.join(
 | 
				
			||||||
 | 
					              __dirname,
 | 
				
			||||||
 | 
					              "./react-native-vision-camera/package",
 | 
				
			||||||
 | 
					              pak.source,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,57 +1,69 @@
 | 
				
			|||||||
import React, { useCallback, useRef, useState } from 'react'
 | 
					import React, { useCallback, useRef, useState } from "react";
 | 
				
			||||||
import { Button, StyleSheet, Text, View } from 'react-native'
 | 
					import { Button, StyleSheet, Text, View } from "react-native";
 | 
				
			||||||
import { Camera, useCameraPermission, useCameraDevice, useCameraFormat, PhotoFile, VideoFile, CameraRuntimeError, Orientation } from 'react-native-vision-camera'
 | 
					import {
 | 
				
			||||||
import { RecordingButton } from './capture-button'
 | 
					  Camera,
 | 
				
			||||||
import { useIsForeground } from './is-foreground'
 | 
					  useCameraPermission,
 | 
				
			||||||
 | 
					  useCameraDevice,
 | 
				
			||||||
 | 
					  useCameraFormat,
 | 
				
			||||||
 | 
					  PhotoFile,
 | 
				
			||||||
 | 
					  VideoFile,
 | 
				
			||||||
 | 
					  CameraRuntimeError,
 | 
				
			||||||
 | 
					  Orientation,
 | 
				
			||||||
 | 
					  // @ts-ignore
 | 
				
			||||||
 | 
					} from "react-native-vision-camera";
 | 
				
			||||||
 | 
					import { RecordingButton } from "./capture-button";
 | 
				
			||||||
 | 
					import { useIsForeground } from "./is-foreground";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function CameraScreen(): React.ReactElement {
 | 
					export default function CameraScreen(): React.ReactElement {
 | 
				
			||||||
  const camera = useRef<Camera>(null)
 | 
					  const camera = useRef<Camera>(null);
 | 
				
			||||||
  const { hasPermission, requestPermission } = useCameraPermission()
 | 
					  const { hasPermission, requestPermission } = useCameraPermission();
 | 
				
			||||||
  const [isCameraInitialized, setIsCameraInitialized] = useState<boolean>(false)
 | 
					  const [isCameraInitialized, setIsCameraInitialized] =
 | 
				
			||||||
 | 
					    useState<boolean>(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const isForeground: boolean = useIsForeground()
 | 
					  const isForeground: boolean = useIsForeground();
 | 
				
			||||||
  const isActive: boolean = isForeground // Should be combined with isFocused hook
 | 
					  const isActive: boolean = isForeground; // Should be combined with isFocused hook
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const onError = useCallback((error: CameraRuntimeError) => {
 | 
					  const onError = useCallback((error: CameraRuntimeError) => {
 | 
				
			||||||
    console.error(error)
 | 
					    console.error(error);
 | 
				
			||||||
  }, [])
 | 
					  }, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const onInitialized = useCallback(() => {
 | 
					  const onInitialized = useCallback(() => {
 | 
				
			||||||
    console.log('Camera initialized!')
 | 
					    console.log("Camera initialized!");
 | 
				
			||||||
    setIsCameraInitialized(true)
 | 
					    setIsCameraInitialized(true);
 | 
				
			||||||
  }, [])
 | 
					  }, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const onMediaCaptured = useCallback(
 | 
					  const onMediaCaptured = useCallback((media: PhotoFile | VideoFile) => {
 | 
				
			||||||
    (media: PhotoFile | VideoFile) => {
 | 
					    console.log(`Media captured! ${JSON.stringify(media)}`);
 | 
				
			||||||
      console.log(`Media captured! ${JSON.stringify(media)}`)
 | 
					  }, []);
 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    [],
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!hasPermission) {
 | 
					  if (!hasPermission) {
 | 
				
			||||||
    requestPermission()
 | 
					    requestPermission();
 | 
				
			||||||
    // Error handling in case they refuse to give permission
 | 
					    // Error handling in case they refuse to give permission
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const device = useCameraDevice('back')
 | 
					  const device = useCameraDevice("back");
 | 
				
			||||||
  const format = useCameraFormat(device, [
 | 
					  const format = useCameraFormat(device, [
 | 
				
			||||||
    { videoResolution: { width: 3048, height: 2160 } },
 | 
					    { videoResolution: { width: 3048, height: 2160 } },
 | 
				
			||||||
    { fps: 60 }
 | 
					    { fps: 60 },
 | 
				
			||||||
  ]) // this sets as a target
 | 
					  ]); // this sets as a target
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //Orientation detection
 | 
					  //Orientation detection
 | 
				
			||||||
  const [orientation, setOrientation] = useState<Orientation>('portrait');
 | 
					  const [orientation, setOrientation] = useState<Orientation>("portrait");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const toggleOrientation = () => {
 | 
					  const toggleOrientation = () => {
 | 
				
			||||||
    setOrientation(currentOrientation => 
 | 
					    setOrientation(
 | 
				
			||||||
      currentOrientation === 'landscape-left' ? 'portrait' : 'landscape-left' // Can adjust this and the type to match what we want
 | 
					      (currentOrientation) =>
 | 
				
			||||||
 | 
					        currentOrientation === "landscape-left" ? "portrait" : "landscape-left", // Can adjust this and the type to match what we want
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (device === null) {
 | 
					  if (device === null) {
 | 
				
			||||||
    return <Text>Camera not available. Does user have permissions:  {hasPermission}</Text>
 | 
					    return (
 | 
				
			||||||
 | 
					      <Text>
 | 
				
			||||||
 | 
					        Camera not available. Does user have permissions: {hasPermission}
 | 
				
			||||||
 | 
					      </Text>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    hasPermission && (
 | 
					    hasPermission && (
 | 
				
			||||||
      <View style={styles.container}>
 | 
					      <View style={styles.container}>
 | 
				
			||||||
@@ -67,12 +79,22 @@ export default function CameraScreen(): React.ReactElement {
 | 
				
			|||||||
          isActive={isActive}
 | 
					          isActive={isActive}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
        <RecordingButton
 | 
					        <RecordingButton
 | 
				
			||||||
          style={[styles.captureButton, orientation === 'portrait' ? styles.portrait : styles.landscape ]}
 | 
					          style={[
 | 
				
			||||||
 | 
					            styles.captureButton,
 | 
				
			||||||
 | 
					            orientation === "portrait" ? styles.portrait : styles.landscape,
 | 
				
			||||||
 | 
					          ]}
 | 
				
			||||||
          camera={camera}
 | 
					          camera={camera}
 | 
				
			||||||
          onMediaCaptured={onMediaCaptured}
 | 
					          onMediaCaptured={onMediaCaptured}
 | 
				
			||||||
          enabled={isCameraInitialized}
 | 
					          enabled={isCameraInitialized}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
        <View style={[styles.button, orientation === 'portrait' ? styles.togglePortrait : styles.toggleLandscape ]}>
 | 
					        <View
 | 
				
			||||||
 | 
					          style={[
 | 
				
			||||||
 | 
					            styles.button,
 | 
				
			||||||
 | 
					            orientation === "portrait"
 | 
				
			||||||
 | 
					              ? styles.togglePortrait
 | 
				
			||||||
 | 
					              : styles.toggleLandscape,
 | 
				
			||||||
 | 
					          ]}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
          <Button
 | 
					          <Button
 | 
				
			||||||
            title="Toggle Orientation"
 | 
					            title="Toggle Orientation"
 | 
				
			||||||
            onPress={toggleOrientation}
 | 
					            onPress={toggleOrientation}
 | 
				
			||||||
@@ -82,35 +104,35 @@ export default function CameraScreen(): React.ReactElement {
 | 
				
			|||||||
        </View>
 | 
					        </View>
 | 
				
			||||||
      </View>
 | 
					      </View>
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
  )
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const styles = StyleSheet.create({
 | 
					const styles = StyleSheet.create({
 | 
				
			||||||
  container: {
 | 
					  container: {
 | 
				
			||||||
    flex: 1,
 | 
					    flex: 1,
 | 
				
			||||||
    backgroundColor: 'black',
 | 
					    backgroundColor: "black",
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  captureButton: {
 | 
					  captureButton: {
 | 
				
			||||||
    position: 'absolute',
 | 
					    position: "absolute",
 | 
				
			||||||
    alignSelf: 'center',
 | 
					    alignSelf: "center",
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  button: {
 | 
					  button: {
 | 
				
			||||||
    position: 'absolute',
 | 
					    position: "absolute",
 | 
				
			||||||
    alignSelf: 'center',
 | 
					    alignSelf: "center",
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  togglePortrait: {
 | 
					  togglePortrait: {
 | 
				
			||||||
    bottom: 110, // needs refined
 | 
					    bottom: 110, // needs refined
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  toggleLandscape: {
 | 
					  toggleLandscape: {
 | 
				
			||||||
    transform: [{ rotate: '90deg' }],
 | 
					    transform: [{ rotate: "90deg" }],
 | 
				
			||||||
    bottom: '43%', // Should come from SafeAreaProvider, hardcoded right now, should roughly appear above the button
 | 
					    bottom: "43%", // Should come from SafeAreaProvider, hardcoded right now, should roughly appear above the button
 | 
				
			||||||
    left: 50 // needs refined
 | 
					    left: 50, // needs refined
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  portrait: {
 | 
					  portrait: {
 | 
				
			||||||
    bottom: 20 // needs refined
 | 
					    bottom: 20, // needs refined
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  landscape: {
 | 
					  landscape: {
 | 
				
			||||||
    bottom: '40%', // Should come from SafeAreaProvider
 | 
					    bottom: "40%", // Should come from SafeAreaProvider
 | 
				
			||||||
    left: 20 // needs refined
 | 
					    left: 20, // needs refined
 | 
				
			||||||
  }
 | 
					  },
 | 
				
			||||||
})
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,16 @@
 | 
				
			|||||||
import React, { useCallback, useRef, useState } from 'react';
 | 
					import React, { useCallback, useRef, useState } from "react";
 | 
				
			||||||
import { TouchableOpacity, StyleSheet, View, StyleProp, ViewStyle } from 'react-native';
 | 
					import {
 | 
				
			||||||
 | 
						TouchableOpacity,
 | 
				
			||||||
 | 
						StyleSheet,
 | 
				
			||||||
 | 
						View,
 | 
				
			||||||
 | 
						StyleProp,
 | 
				
			||||||
 | 
						ViewStyle,
 | 
				
			||||||
 | 
					} from "react-native";
 | 
				
			||||||
import { CameraRoll } from "@react-native-camera-roll/camera-roll";
 | 
					import { CameraRoll } from "@react-native-camera-roll/camera-roll";
 | 
				
			||||||
import { Camera } from 'react-native-vision-camera/lib/typescript/Camera';
 | 
					// @ts-ignore
 | 
				
			||||||
import { VideoFile } from 'react-native-vision-camera/lib/typescript/VideoFile';
 | 
					import { Camera } from "react-native-vision-camera/lib/typescript/Camera";
 | 
				
			||||||
 | 
					// @ts-ignore
 | 
				
			||||||
 | 
					import { VideoFile } from "react-native-vision-camera/lib/typescript/VideoFile";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface RecordingButtonProps {
 | 
					interface RecordingButtonProps {
 | 
				
			||||||
	style: StyleProp<ViewStyle>;
 | 
						style: StyleProp<ViewStyle>;
 | 
				
			||||||
@@ -12,58 +20,62 @@ interface RecordingButtonProps {
 | 
				
			|||||||
	enabled: boolean;
 | 
						enabled: boolean;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const RecordingButton: React.FC<RecordingButtonProps> = ({
 | 
				
			||||||
export const RecordingButton: React.FC<RecordingButtonProps> = ({ style, camera, onMediaCaptured, enabled }) => {
 | 
						style,
 | 
				
			||||||
	const isRecording = useRef(false)
 | 
						camera,
 | 
				
			||||||
 | 
						onMediaCaptured,
 | 
				
			||||||
 | 
						enabled,
 | 
				
			||||||
 | 
					}) => {
 | 
				
			||||||
 | 
						const isRecording = useRef(false);
 | 
				
			||||||
	// UseRef won't trigger a re-render
 | 
						// UseRef won't trigger a re-render
 | 
				
			||||||
	const [, setRecordingState] = useState(false);
 | 
						const [, setRecordingState] = useState(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const onStoppedRecording = useCallback(() => {
 | 
						const onStoppedRecording = useCallback(() => {
 | 
				
			||||||
		isRecording.current = false
 | 
							isRecording.current = false;
 | 
				
			||||||
		setRecordingState(false)
 | 
							setRecordingState(false);
 | 
				
			||||||
		console.log('stopped recording video!')
 | 
							console.log("stopped recording video!");
 | 
				
			||||||
	}, [])
 | 
						}, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const stopRecording = useCallback(async () => {
 | 
						const stopRecording = useCallback(async () => {
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			if (camera.current === null) {
 | 
								if (camera.current === null) {
 | 
				
			||||||
				throw new Error('Camera ref is null!') // Error handling could be more graceful
 | 
									throw new Error("Camera ref is null!"); // Error handling could be more graceful
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			console.log('calling stopRecording()...')
 | 
								console.log("calling stopRecording()...");
 | 
				
			||||||
			await camera.current.stopRecording()
 | 
								await camera.current.stopRecording();
 | 
				
			||||||
			console.log('called stopRecording()!')
 | 
								console.log("called stopRecording()!");
 | 
				
			||||||
		} catch (e) {
 | 
							} catch (e) {
 | 
				
			||||||
			console.error('failed to stop recording!', e)
 | 
								console.error("failed to stop recording!", e);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}, [camera])
 | 
						}, [camera]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const startRecording = useCallback(() => {
 | 
						const startRecording = useCallback(() => {
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			if (camera.current === null) {
 | 
								if (camera.current === null) {
 | 
				
			||||||
			throw new Error('Camera ref is null!') // Error handling could be more graceful
 | 
									throw new Error("Camera ref is null!"); // Error handling could be more graceful
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		console.log('calling startRecording()...')
 | 
								console.log("calling startRecording()...");
 | 
				
			||||||
			camera.current.startRecording({
 | 
								camera.current.startRecording({
 | 
				
			||||||
				onRecordingError: (error) => {
 | 
									onRecordingError: (error) => {
 | 
				
			||||||
				console.error('Recording failed!', error)
 | 
										console.error("Recording failed!", error);
 | 
				
			||||||
				onStoppedRecording()
 | 
										onStoppedRecording();
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				onRecordingFinished: async (video) => {
 | 
									onRecordingFinished: async (video) => {
 | 
				
			||||||
				onMediaCaptured(video, 'video')
 | 
										onMediaCaptured(video, "video");
 | 
				
			||||||
				const path = video.path
 | 
										const path = video.path;
 | 
				
			||||||
					await CameraRoll.saveAsset(`file://${path}`, {
 | 
										await CameraRoll.saveAsset(`file://${path}`, {
 | 
				
			||||||
					type: 'video',
 | 
											type: "video",
 | 
				
			||||||
				})
 | 
										});
 | 
				
			||||||
				onStoppedRecording()
 | 
										onStoppedRecording();
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
		})
 | 
								});
 | 
				
			||||||
		console.log('called startRecording()!')
 | 
								console.log("called startRecording()!");
 | 
				
			||||||
		isRecording.current = true
 | 
								isRecording.current = true;
 | 
				
			||||||
		setRecordingState(true)
 | 
								setRecordingState(true);
 | 
				
			||||||
		} catch (e) {
 | 
							} catch (e) {
 | 
				
			||||||
		console.error('failed to start recording!', e, 'camera')
 | 
								console.error("failed to start recording!", e, "camera");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
}, [camera, onMediaCaptured, onStoppedRecording])
 | 
						}, [camera, onMediaCaptured, onStoppedRecording]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const handlePress = () => {
 | 
						const handlePress = () => {
 | 
				
			||||||
		if (isRecording.current) {
 | 
							if (isRecording.current) {
 | 
				
			||||||
@@ -79,7 +91,11 @@ const handlePress = () => {
 | 
				
			|||||||
			onPress={handlePress}
 | 
								onPress={handlePress}
 | 
				
			||||||
			disabled={!enabled}
 | 
								disabled={!enabled}
 | 
				
			||||||
		>
 | 
							>
 | 
				
			||||||
			<View style={isRecording.current ? styles.recordingSquare : styles.innerCircle} />
 | 
								<View
 | 
				
			||||||
 | 
									style={
 | 
				
			||||||
 | 
										isRecording.current ? styles.recordingSquare : styles.innerCircle
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
		</TouchableOpacity>
 | 
							</TouchableOpacity>
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -90,22 +106,22 @@ const styles = StyleSheet.create({
 | 
				
			|||||||
		width: 80,
 | 
							width: 80,
 | 
				
			||||||
		borderRadius: 40,
 | 
							borderRadius: 40,
 | 
				
			||||||
		borderWidth: 3,
 | 
							borderWidth: 3,
 | 
				
			||||||
			borderColor: 'white',
 | 
							borderColor: "white",
 | 
				
			||||||
			backgroundColor: 'transparent',
 | 
							backgroundColor: "transparent",
 | 
				
			||||||
			justifyContent: 'center',
 | 
							justifyContent: "center",
 | 
				
			||||||
			alignItems: 'center',
 | 
							alignItems: "center",
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	innerCircle: {
 | 
						innerCircle: {
 | 
				
			||||||
		height: 70,
 | 
							height: 70,
 | 
				
			||||||
		width: 70,
 | 
							width: 70,
 | 
				
			||||||
		borderRadius: 35,
 | 
							borderRadius: 35,
 | 
				
			||||||
			backgroundColor: '#FF3B30',
 | 
							backgroundColor: "#FF3B30",
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	recordingSquare: {
 | 
						recordingSquare: {
 | 
				
			||||||
		height: 40,
 | 
							height: 40,
 | 
				
			||||||
		width: 40,
 | 
							width: 40,
 | 
				
			||||||
		borderRadius: 10,
 | 
							borderRadius: 10,
 | 
				
			||||||
			backgroundColor: '#FF3B30',
 | 
							backgroundColor: "#FF3B30",
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										20
									
								
								flake.nix
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								flake.nix
									
									
									
									
									
								
							@@ -11,9 +11,15 @@
 | 
				
			|||||||
      url = "github:tadfisher/android-nixpkgs";
 | 
					      url = "github:tadfisher/android-nixpkgs";
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  outputs = { self, nixpkgs, flake-utils, gitignore, android-nixpkgs, ... }:
 | 
					  outputs = {
 | 
				
			||||||
  flake-utils.lib.eachDefaultSystem (system:
 | 
					    self,
 | 
				
			||||||
  let
 | 
					    nixpkgs,
 | 
				
			||||||
 | 
					    flake-utils,
 | 
				
			||||||
 | 
					    gitignore,
 | 
				
			||||||
 | 
					    android-nixpkgs,
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					  }:
 | 
				
			||||||
 | 
					    flake-utils.lib.eachDefaultSystem (system: let
 | 
				
			||||||
      pkgs = import nixpkgs {inherit system;};
 | 
					      pkgs = import nixpkgs {inherit system;};
 | 
				
			||||||
      nodejs = pkgs.nodejs-18_x;
 | 
					      nodejs = pkgs.nodejs-18_x;
 | 
				
			||||||
      # NOTE: this does not work
 | 
					      # NOTE: this does not work
 | 
				
			||||||
@@ -38,7 +44,8 @@
 | 
				
			|||||||
          runHook postInstall
 | 
					          runHook postInstall
 | 
				
			||||||
        '';
 | 
					        '';
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
    android-sdk = android-nixpkgs.sdk.${system} (sdkPkgs: with sdkPkgs; [
 | 
					      android-sdk = android-nixpkgs.sdk.${system} (sdkPkgs:
 | 
				
			||||||
 | 
					        with sdkPkgs; [
 | 
				
			||||||
          cmdline-tools-latest
 | 
					          cmdline-tools-latest
 | 
				
			||||||
          build-tools-30-0-3
 | 
					          build-tools-30-0-3
 | 
				
			||||||
          build-tools-33-0-0
 | 
					          build-tools-33-0-0
 | 
				
			||||||
@@ -50,7 +57,8 @@
 | 
				
			|||||||
          system-images-android-33-google-apis-x86-64
 | 
					          system-images-android-33-google-apis-x86-64
 | 
				
			||||||
          system-images-android-34-google-apis-x86-64
 | 
					          system-images-android-34-google-apis-x86-64
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
  in with pkgs; {
 | 
					    in
 | 
				
			||||||
 | 
					      with pkgs; {
 | 
				
			||||||
        defaultPackage = appBuild;
 | 
					        defaultPackage = appBuild;
 | 
				
			||||||
        devShell = mkShell {
 | 
					        devShell = mkShell {
 | 
				
			||||||
          buildInputs = [nodejs yarn watchman gradle_7 alejandra nodePackages.prettier];
 | 
					          buildInputs = [nodejs yarn watchman gradle_7 alejandra nodePackages.prettier];
 | 
				
			||||||
@@ -58,7 +66,7 @@
 | 
				
			|||||||
          shellHook = ''
 | 
					          shellHook = ''
 | 
				
			||||||
            export JAVA_HOME=${pkgs.jdk17.home}
 | 
					            export JAVA_HOME=${pkgs.jdk17.home}
 | 
				
			||||||
            source ${android-sdk.out}/nix-support/setup-hook
 | 
					            source ${android-sdk.out}/nix-support/setup-hook
 | 
				
			||||||
        export PATH=${android-sdk}/bin:$PATH
 | 
					            export PATH=${android-sdk}/bin:${android-sdk}/share/android-sdk/build-tools/33.0.0/:$PATH
 | 
				
			||||||
            ORG_GRADLE_PROJECT_ANDROID_HOME="$ANDROID_HOME"
 | 
					            ORG_GRADLE_PROJECT_ANDROID_HOME="$ANDROID_HOME"
 | 
				
			||||||
          '';
 | 
					          '';
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -384,7 +384,7 @@
 | 
				
			|||||||
				);
 | 
									);
 | 
				
			||||||
				OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
 | 
									OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
 | 
				
			||||||
				PRODUCT_BUNDLE_IDENTIFIER = ai.railbird.railbird;
 | 
									PRODUCT_BUNDLE_IDENTIFIER = ai.railbird.railbird;
 | 
				
			||||||
				PRODUCT_NAME = Railbird;
 | 
									PRODUCT_NAME = "Railbird";
 | 
				
			||||||
				PROVISIONING_PROFILE_SPECIFIER = "";
 | 
									PROVISIONING_PROFILE_SPECIFIER = "";
 | 
				
			||||||
				SWIFT_OBJC_BRIDGING_HEADER = "Railbird/Railbird-Bridging-Header.h";
 | 
									SWIFT_OBJC_BRIDGING_HEADER = "Railbird/Railbird-Bridging-Header.h";
 | 
				
			||||||
				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
 | 
									SWIFT_OPTIMIZATION_LEVEL = "-Onone";
 | 
				
			||||||
@@ -419,7 +419,7 @@
 | 
				
			|||||||
				);
 | 
									);
 | 
				
			||||||
				OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
 | 
									OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
 | 
				
			||||||
				PRODUCT_BUNDLE_IDENTIFIER = ai.railbird.railbird;
 | 
									PRODUCT_BUNDLE_IDENTIFIER = ai.railbird.railbird;
 | 
				
			||||||
				PRODUCT_NAME = Railbird;
 | 
									PRODUCT_NAME = "Railbird";
 | 
				
			||||||
				PROVISIONING_PROFILE_SPECIFIER = "";
 | 
									PROVISIONING_PROFILE_SPECIFIER = "";
 | 
				
			||||||
				SWIFT_OBJC_BRIDGING_HEADER = "Railbird/Railbird-Bridging-Header.h";
 | 
									SWIFT_OBJC_BRIDGING_HEADER = "Railbird/Railbird-Bridging-Header.h";
 | 
				
			||||||
				SWIFT_VERSION = 5.0;
 | 
									SWIFT_VERSION = 5.0;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,53 @@
 | 
				
			|||||||
// Learn more https://docs.expo.io/guides/customizing-metro
 | 
					const { getDefaultConfig } = require("expo/metro-config");
 | 
				
			||||||
const { getDefaultConfig } = require('expo/metro-config');
 | 
					const { mergeConfig } = require("@react-native/metro-config");
 | 
				
			||||||
 | 
					const path = require("path");
 | 
				
			||||||
 | 
					const escape = require("escape-string-regexp");
 | 
				
			||||||
 | 
					const exclusionList = require("metro-config/src/defaults/exclusionList");
 | 
				
			||||||
 | 
					const pak = require("./react-native-vision-camera/package/package.json");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** @type {import('expo/metro-config').MetroConfig} */
 | 
					const root = path.resolve(__dirname, "./react-native-vision-camera/package");
 | 
				
			||||||
const config = getDefaultConfig(__dirname);
 | 
					const modules = Object.keys({ ...pak.peerDependencies });
 | 
				
			||||||
 | 
					const localPackagePath = path.resolve(
 | 
				
			||||||
 | 
					  __dirname,
 | 
				
			||||||
 | 
					  "./react-native-vision-camera/package/src/index",
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = config;
 | 
					/**
 | 
				
			||||||
 | 
					 * Metro configuration
 | 
				
			||||||
 | 
					 * https://facebook.github.io/metro/docs/configuration
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @type {import('metro-config').MetroConfig}
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const config = {
 | 
				
			||||||
 | 
					  watchFolders: [root],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // We need to make sure that only one version is loaded for peerDependencies
 | 
				
			||||||
 | 
					  // So we block them at the root, and alias them to the versions in example's node_modules
 | 
				
			||||||
 | 
					  resolver: {
 | 
				
			||||||
 | 
					    blacklistRE: exclusionList(
 | 
				
			||||||
 | 
					      modules.map(
 | 
				
			||||||
 | 
					        (m) =>
 | 
				
			||||||
 | 
					          new RegExp(`^${escape(path.join(root, "node_modules", m))}\\/.*$`),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    extraNodeModules: modules.reduce(
 | 
				
			||||||
 | 
					      (acc, name) => {
 | 
				
			||||||
 | 
					        acc[name] = path.join(__dirname, "node_modules", name);
 | 
				
			||||||
 | 
					        return acc;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      { "react-native-vision-camera": localPackagePath },
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  transformer: {
 | 
				
			||||||
 | 
					    getTransformOptions: async () => ({
 | 
				
			||||||
 | 
					      transform: {
 | 
				
			||||||
 | 
					        experimentalImportSupport: false,
 | 
				
			||||||
 | 
					        inlineRequires: true,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = mergeConfig(getDefaultConfig(__dirname), config);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								package.json
									
									
									
									
									
								
							@@ -4,10 +4,10 @@
 | 
				
			|||||||
  "main": "node_modules/expo/AppEntry.js",
 | 
					  "main": "node_modules/expo/AppEntry.js",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
    "start": "cp .env.development .env && expo start",
 | 
					    "start": "cp .env.development .env && expo start",
 | 
				
			||||||
    "android": "expo start --android",
 | 
					    "android": "expo run:android",
 | 
				
			||||||
    "ios": "expo start --ios",
 | 
					    "ios": "expo run:ios",
 | 
				
			||||||
    "run:android": "expo run:android",
 | 
					    "run:android": "expo start --android",
 | 
				
			||||||
    "run:ios": "expo run:ios",
 | 
					    "run:ios": "expo start --android",
 | 
				
			||||||
    "web": "expo start --web",
 | 
					    "web": "expo start --web",
 | 
				
			||||||
    "lint": "eslint . --ext .js,.ts,.tsx",
 | 
					    "lint": "eslint . --ext .js,.ts,.tsx",
 | 
				
			||||||
    "lint:fix": "eslint . --ext .ts,.tsx --fix",
 | 
					    "lint:fix": "eslint . --ext .ts,.tsx --fix",
 | 
				
			||||||
@@ -28,6 +28,7 @@
 | 
				
			|||||||
    "@typescript-eslint/eslint-plugin": "^6.17.0",
 | 
					    "@typescript-eslint/eslint-plugin": "^6.17.0",
 | 
				
			||||||
    "@typescript-eslint/parser": "^6.17.0",
 | 
					    "@typescript-eslint/parser": "^6.17.0",
 | 
				
			||||||
    "babel-plugin-inline-dotenv": "^1.7.0",
 | 
					    "babel-plugin-inline-dotenv": "^1.7.0",
 | 
				
			||||||
 | 
					    "expo-constants": "15.4.5",
 | 
				
			||||||
    "d3-path": "^3.1.0",
 | 
					    "d3-path": "^3.1.0",
 | 
				
			||||||
    "d3-scale": "^1.0.6",
 | 
					    "d3-scale": "^1.0.6",
 | 
				
			||||||
    "eslint": "^8.56.0",
 | 
					    "eslint": "^8.56.0",
 | 
				
			||||||
@@ -48,15 +49,16 @@
 | 
				
			|||||||
    "react-native-static-safe-area-insets": "^2.2.0",
 | 
					    "react-native-static-safe-area-insets": "^2.2.0",
 | 
				
			||||||
    "react-native-svg": "13.9.0",
 | 
					    "react-native-svg": "13.9.0",
 | 
				
			||||||
    "react-native-svg-charts": "^5.4.0",
 | 
					    "react-native-svg-charts": "^5.4.0",
 | 
				
			||||||
    "react-native-vision-camera": "^3.8.2",
 | 
					 | 
				
			||||||
    "typescript": "^5.3.3"
 | 
					    "typescript": "^5.3.3"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "@babel/core": "^7.20.0",
 | 
					    "@babel/core": "^7.20.0",
 | 
				
			||||||
    "@testing-library/jest-native": "^5.4.3",
 | 
					    "@testing-library/jest-native": "^5.4.3",
 | 
				
			||||||
    "@testing-library/react-native": "^12.4.3",
 | 
					    "@testing-library/react-native": "^12.4.3",
 | 
				
			||||||
 | 
					    "@react-native/metro-config": "^0.72.9",
 | 
				
			||||||
    "@types/d3-path": "^3.0.2",
 | 
					    "@types/d3-path": "^3.0.2",
 | 
				
			||||||
    "@types/jest": "^29.5.11",
 | 
					    "@types/jest": "^29.5.11",
 | 
				
			||||||
 | 
					    "metro-react-native-babel-preset": "^0.77.0",
 | 
				
			||||||
    "@types/react-native-svg-charts": "^5.0.16",
 | 
					    "@types/react-native-svg-charts": "^5.0.16",
 | 
				
			||||||
    "eslint-config-prettier": "^9.1.0"
 | 
					    "eslint-config-prettier": "^9.1.0"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								react-native-vision-camera
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								react-native-vision-camera
									
									
									
									
									
										Submodule
									
								
							 Submodule react-native-vision-camera added at fb42545890
									
								
							@@ -1,4 +1,5 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "compilerOptions": {},
 | 
					  "include": ["."],
 | 
				
			||||||
  "extends": "expo/tsconfig.base"
 | 
					  "exclude": ["node_modules", "./react-native-vision-camera/package"],
 | 
				
			||||||
 | 
					  "extends": ["expo/tsconfig.base"]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										60
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								yarn.lock
									
									
									
									
									
								
							@@ -2487,6 +2487,16 @@
 | 
				
			|||||||
    hermes-parser "0.15.0"
 | 
					    hermes-parser "0.15.0"
 | 
				
			||||||
    nullthrows "^1.1.1"
 | 
					    nullthrows "^1.1.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"@react-native/metro-config@^0.72.9":
 | 
				
			||||||
 | 
					  version "0.72.11"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/@react-native/metro-config/-/metro-config-0.72.11.tgz#c775a22fbb138cedd4513ca46c06bfd6a9dad316"
 | 
				
			||||||
 | 
					  integrity sha512-661EyQnDdVelyc0qP/ew7kKkGAh6N6KlkuPLC2SQ8sxaXskVU6fSuNlpLW4bUTBUDFKG8gEOU2hp6rzk4wQnGQ==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    "@react-native/js-polyfills" "^0.72.1"
 | 
				
			||||||
 | 
					    metro-config "0.76.8"
 | 
				
			||||||
 | 
					    metro-react-native-babel-transformer "0.76.8"
 | 
				
			||||||
 | 
					    metro-runtime "0.76.8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"@react-native/normalize-color@^2.0.0":
 | 
					"@react-native/normalize-color@^2.0.0":
 | 
				
			||||||
  version "2.1.0"
 | 
					  version "2.1.0"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.1.0.tgz#939b87a9849e81687d3640c5efa2a486ac266f91"
 | 
					  resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.1.0.tgz#939b87a9849e81687d3640c5efa2a486ac266f91"
 | 
				
			||||||
@@ -7214,6 +7224,51 @@ metro-react-native-babel-preset@0.76.8:
 | 
				
			|||||||
    babel-plugin-transform-flow-enums "^0.0.2"
 | 
					    babel-plugin-transform-flow-enums "^0.0.2"
 | 
				
			||||||
    react-refresh "^0.4.0"
 | 
					    react-refresh "^0.4.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					metro-react-native-babel-preset@^0.77.0:
 | 
				
			||||||
 | 
					  version "0.77.0"
 | 
				
			||||||
 | 
					  resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.77.0.tgz#47457eca8e36b77156afbe790247a70dbb40faaa"
 | 
				
			||||||
 | 
					  integrity sha512-HPPD+bTxADtoE4y/4t1txgTQ1LVR6imOBy7RMHUsqMVTbekoi8Ph5YI9vKX2VMPtVWeFt0w9YnCSLPa76GcXsA==
 | 
				
			||||||
 | 
					  dependencies:
 | 
				
			||||||
 | 
					    "@babel/core" "^7.20.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-proposal-async-generator-functions" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-proposal-class-properties" "^7.18.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-proposal-export-default-from" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-proposal-numeric-separator" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-proposal-object-rest-spread" "^7.20.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-proposal-optional-catch-binding" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-proposal-optional-chaining" "^7.20.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-syntax-dynamic-import" "^7.8.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-syntax-export-default-from" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-syntax-flow" "^7.18.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-syntax-optional-chaining" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-arrow-functions" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-async-to-generator" "^7.20.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-block-scoping" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-classes" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-computed-properties" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-destructuring" "^7.20.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-flow-strip-types" "^7.20.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-function-name" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-literals" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-modules-commonjs" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-named-capturing-groups-regex" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-parameters" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-react-display-name" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-react-jsx" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-react-jsx-self" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-react-jsx-source" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-runtime" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-shorthand-properties" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-spread" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-sticky-regex" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-typescript" "^7.5.0"
 | 
				
			||||||
 | 
					    "@babel/plugin-transform-unicode-regex" "^7.0.0"
 | 
				
			||||||
 | 
					    "@babel/template" "^7.0.0"
 | 
				
			||||||
 | 
					    babel-plugin-transform-flow-enums "^0.0.2"
 | 
				
			||||||
 | 
					    react-refresh "^0.4.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
metro-react-native-babel-transformer@0.76.8:
 | 
					metro-react-native-babel-transformer@0.76.8:
 | 
				
			||||||
  version "0.76.8"
 | 
					  version "0.76.8"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.76.8.tgz#c3a98e1f4cd5faf1e21eba8e004b94a90c4db69b"
 | 
					  resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.76.8.tgz#c3a98e1f4cd5faf1e21eba8e004b94a90c4db69b"
 | 
				
			||||||
@@ -8417,11 +8472,6 @@ react-native-svg@^6.2.1:
 | 
				
			|||||||
    lodash "^4.16.6"
 | 
					    lodash "^4.16.6"
 | 
				
			||||||
    pegjs "^0.10.0"
 | 
					    pegjs "^0.10.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
react-native-vision-camera@^3.8.2:
 | 
					 | 
				
			||||||
  version "3.8.2"
 | 
					 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/react-native-vision-camera/-/react-native-vision-camera-3.8.2.tgz#f4f75f84c6a19e1c3474ddc0f7f785b5a526739b"
 | 
					 | 
				
			||||||
  integrity sha512-MY39l2e3hNRPUefn2JPShOFExcw0PblbAcUGvJrIfS9pMzdIyceo0umRAx8lOGXzDUAdb+xy/tFWb8zGxKimCQ==
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
react-native@*:
 | 
					react-native@*:
 | 
				
			||||||
  version "0.73.2"
 | 
					  version "0.73.2"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.73.2.tgz#74ee163c8189660d41d1da6560411da7ce41a608"
 | 
					  resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.73.2.tgz#74ee163c8189660d41d1da6560411da7ce41a608"
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user