Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fix camera not working on the second time opening it #53194

Merged
merged 9 commits into from
Dec 5, 2024
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
import {useIsFocused} from '@react-navigation/native';
import React from 'react';
import React, {useState} from 'react';
import type {ForwardedRef} from 'react';
import {View} from 'react-native';
import type {Camera} from 'react-native-vision-camera';
import Webcam from 'react-webcam';
import useThemeStyles from '@hooks/useThemeStyles';
import type {NavigationAwareCameraProps} from './types';

// Wraps a camera that will only be active when the tab is focused or as soon as it starts to become focused.
function WebCamera({torchOn, onTorchAvailability, cameraTabIndex, ...props}: NavigationAwareCameraProps, ref: ForwardedRef<Webcam | Camera>) {
function WebCamera(props: NavigationAwareCameraProps, ref: ForwardedRef<Webcam | Camera>) {
const [isInitialized, setIsInitialized] = useState(false);
const shouldShowCamera = useIsFocused();
const styles = useThemeStyles();

if (!shouldShowCamera) {
return null;
}

return (
<View>
// Hide the camera during initialization to prevent random failures on some iOS versions.
<View style={isInitialized ? styles.dFlex : styles.dNone}>
<Webcam
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
onResize={() => setIsInitialized(true)}
ref={ref as unknown as ForwardedRef<Webcam>}
/>
</View>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
import type {CameraProps} from 'react-native-vision-camera';
import type {WebcamProps} from 'react-webcam';

type NavigationAwareCameraProps = WebcamProps & {
/** Flag to turn on/off the torch/flashlight - if available */
torchOn?: boolean;

/** The index of the tab that contains this camera */
onTorchAvailability?: (torchAvailable: boolean) => void;

/** Callback function when media stream becomes available - user granted camera permissions and camera starts to work */
cameraTabIndex: number;
};
type NavigationAwareCameraProps = WebcamProps;

type NavigationAwareCameraNativeProps = Omit<CameraProps, 'isActive'> & {
cameraTabIndex: number;
Expand Down
8 changes: 3 additions & 5 deletions src/pages/iou/request/step/IOURequestStepScan/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ function IOURequestStepScan({
const [isLoadingReceipt, setIsLoadingReceipt] = useState(false);

const [videoConstraints, setVideoConstraints] = useState<MediaTrackConstraints>();
const tabIndex = 1;
const isTabActive = useIsFocused();

const isEditing = action === CONST.IOU.ACTION.EDIT;
Expand All @@ -118,7 +117,7 @@ function IOURequestStepScan({
* The last deviceId is of regular len camera.
*/
const requestCameraPermission = useCallback(() => {
if (!isEmptyObject(videoConstraints) || !Browser.isMobile()) {
if (!Browser.isMobile()) {
return;
}

Expand All @@ -129,7 +128,7 @@ function IOURequestStepScan({
setCameraPermissionState('granted');
stream.getTracks().forEach((track) => track.stop());
// Only Safari 17+ supports zoom constraint
if (Browser.isMobileSafari() && stream.getTracks().length > 0) {
if (Browser.isMobileWebKit() && stream.getTracks().length > 0) {
let deviceId;
for (const track of stream.getTracks()) {
const setting = track.getSettings();
Expand Down Expand Up @@ -167,11 +166,11 @@ function IOURequestStepScan({
setVideoConstraints(defaultConstraints);
setCameraPermissionState('denied');
});
// eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
}, []);

useEffect(() => {
if (!Browser.isMobile() || !isTabActive) {
setVideoConstraints(undefined);
return;
}
navigator.permissions
Expand Down Expand Up @@ -665,7 +664,6 @@ function IOURequestStepScan({
screenshotFormat="image/png"
videoConstraints={videoConstraints}
forceScreenshotSourceSize
cameraTabIndex={tabIndex}
audio={false}
disablePictureInPicture={false}
imageSmoothing={false}
Expand Down
Loading