diff --git a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js index 9289fc6a2434..a419af5768b5 100644 --- a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js +++ b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js @@ -13,6 +13,9 @@ const propTypes = { /* Callback function passing torch/flashlight capability as bool param of the browser */ onTorchAvailability: PropTypes.func, + + /* Whether we're in a tab navigator */ + isInTabNavigator: PropTypes.bool.isRequired, }; const defaultProps = { diff --git a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.native.js b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.native.js index 8fa153550cbe..56fc311f0d46 100644 --- a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.native.js +++ b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.native.js @@ -11,19 +11,29 @@ const propTypes = { /* Forwarded ref */ forwardedRef: refPropTypes.isRequired, + + /* Whether we're in a tab navigator */ + isInTabNavigator: PropTypes.bool.isRequired, }; // Wraps a camera that will only be active when the tab is focused or as soon as it starts to become focused. -function NavigationAwareCamera({cameraTabIndex, forwardedRef, ...props}) { +function NavigationAwareCamera({cameraTabIndex, forwardedRef, isInTabNavigator, ...props}) { // Get navigation to get initial isFocused value (only needed once during init!) const navigation = useNavigation(); const [isCameraActive, setIsCameraActive] = useState(navigation.isFocused()); // Retrieve the animation value from the tab navigator, which ranges from 0 to the total number of pages displayed. // Even a minimal scroll towards the camera page (e.g., a value of 0.001 at start) should activate the camera for immediate responsiveness. - const tabPositionAnimation = useTabAnimation(); + + // STOP!!!!!!! This is not a pattern to be followed! We are conditionally rendering this hook becase when used in the edit flow we'll never be inside a tab navigator. + // eslint-disable-next-line react-hooks/rules-of-hooks + const tabPositionAnimation = isInTabNavigator ? useTabAnimation() : null; useEffect(() => { + if (!isInTabNavigator) { + return; + } + const listenerId = tabPositionAnimation.addListener(({value}) => { // Activate camera as soon the index is animating towards the `cameraTabIndex` setIsCameraActive(value > cameraTabIndex - 1 && value < cameraTabIndex + 1); @@ -32,7 +42,7 @@ function NavigationAwareCamera({cameraTabIndex, forwardedRef, ...props}) { return () => { tabPositionAnimation.removeListener(listenerId); }; - }, [cameraTabIndex, tabPositionAnimation]); + }, [cameraTabIndex, tabPositionAnimation, isInTabNavigator]); // Note: The useEffect can be removed once VisionCamera V3 is used. // Its only needed for android, because there is a native cameraX android bug. With out this flow would break the camera: diff --git a/src/pages/iou/ReceiptSelector/TabNavigationAwareCamera.js b/src/pages/iou/ReceiptSelector/TabNavigationAwareCamera.js deleted file mode 100644 index 744a10376237..000000000000 --- a/src/pages/iou/ReceiptSelector/TabNavigationAwareCamera.js +++ /dev/null @@ -1,77 +0,0 @@ -import React, {useEffect, useState} from 'react'; -import {Camera} from 'react-native-vision-camera'; -import {useTabAnimation} from '@react-navigation/material-top-tabs'; -import {useNavigation} from '@react-navigation/native'; -import PropTypes from 'prop-types'; -import refPropTypes from '../../../components/refPropTypes'; - -const propTypes = { - /* The index of the tab that contains this camera */ - cameraTabIndex: PropTypes.number.isRequired, - - /* Forwarded ref */ - forwardedRef: refPropTypes.isRequired, -}; - -// Wraps a camera that will only be active when the tab is focused or as soon as it starts to become focused. -function TabNavigationAwareCamera({cameraTabIndex, forwardedRef, ...props}) { - // Get navigation to get initial isFocused value (only needed once during init!) - const navigation = useNavigation(); - const [isCameraActive, setIsCameraActive] = useState(navigation.isFocused()); - - // Get the animation value from the tab navigator. Its a value between 0 and the - // number of pages we render in the tab navigator. When we even just slightly start to scroll to the camera page, - // (value is e.g. 0.001 on animation start) we want to activate the camera, so its as fast as possible active. - const tabPositionAnimation = useTabAnimation(); - - useEffect(() => { - const listenerId = tabPositionAnimation.addListener(({value}) => { - // Activate camera as soon the index is animating towards the `cameraTabIndex` - setIsCameraActive(value > cameraTabIndex - 1 && value < cameraTabIndex + 1); - }); - - return () => { - tabPositionAnimation.removeListener(listenerId); - }; - }, [cameraTabIndex, tabPositionAnimation]); - - // Note: The useEffect can be removed once VisionCamera V3 is used. - // Its only needed for android, because there is a native cameraX android bug. With out this flow would break the camera: - // 1. Open camera tab - // 2. Take a picture - // 3. Go back from the opened screen - // 4. The camera is not working anymore - useEffect(() => { - const removeBlurListener = navigation.addListener('blur', () => { - setIsCameraActive(false); - }); - const removeFocusListener = navigation.addListener('focus', () => { - setIsCameraActive(true); - }); - - return () => { - removeBlurListener(); - removeFocusListener(); - }; - }, [navigation]); - - return ( - - ); -} - -TabNavigationAwareCamera.propTypes = propTypes; -TabNavigationAwareCamera.displayName = 'TabNavigationAwareCamera'; - -export default React.forwardRef((props, ref) => ( - -)); diff --git a/src/pages/iou/ReceiptSelector/index.native.js b/src/pages/iou/ReceiptSelector/index.native.js index f2654a9faefb..6503d488e805 100644 --- a/src/pages/iou/ReceiptSelector/index.native.js +++ b/src/pages/iou/ReceiptSelector/index.native.js @@ -25,7 +25,6 @@ import {iouPropTypes, iouDefaultProps} from '../propTypes'; import NavigationAwareCamera from './NavigationAwareCamera'; import Navigation from '../../../libs/Navigation/Navigation'; import * as FileUtils from '../../../libs/fileDownload/FileUtils'; -import TabNavigationAwareCamera from './TabNavigationAwareCamera'; const propTypes = { /** React Navigation route */ @@ -76,8 +75,6 @@ function ReceiptSelector({route, report, iou, transactionID, isInTabNavigator}) const {translate} = useLocalize(); - const CameraComponent = isInTabNavigator ? TabNavigationAwareCamera : NavigationAwareCamera; - useEffect(() => { const refreshCameraPermissionStatus = () => { CameraPermission.getCameraPermissionStatus() @@ -190,13 +187,14 @@ function ReceiptSelector({route, report, iou, transactionID, isInTabNavigator}) )} {cameraPermissionStatus === RESULTS.GRANTED && device != null && ( - )}