diff --git a/native/media/camera-modal.react.js b/native/media/camera-modal.react.js --- a/native/media/camera-modal.react.js +++ b/native/media/camera-modal.react.js @@ -252,10 +252,11 @@ +changeFlashMode: () => void, +useFrontCamera: boolean, +switchCamera: () => void, + +hasCamerasOnBothSides: boolean, + +fetchCameraIDs: (camera: RNCamera) => Promise, }; type State = { +zoom: number, - +hasCamerasOnBothSides: boolean, +autoFocusPointOfInterest: ?{ x: number, y: number, @@ -304,8 +305,6 @@ cancelIndicatorAnimation: Value = new Value(0); - cameraIDsFetched = false; - stagingModeProgress: Value = new Value(0); sendButtonProgress: Animated.Value = new Animated.Value(0); sendButtonStyle: ViewStyle; @@ -316,7 +315,6 @@ this.state = { zoom: 0, - hasCamerasOnBothSides: props.deviceCameraInfo.hasCamerasOnBothSides, autoFocusPointOfInterest: undefined, stagingMode: false, pendingPhotoCapture: undefined, @@ -508,7 +506,7 @@ } componentDidUpdate(prevProps: Props, prevState: State) { - if (!this.state.hasCamerasOnBothSides && prevState.hasCamerasOnBothSides) { + if (!this.props.hasCamerasOnBothSides && prevProps.hasCamerasOnBothSides) { this.switchCameraButtonX.setValue(-1); this.switchCameraButtonY.setValue(-1); this.switchCameraButtonWidth.setValue(0); @@ -593,7 +591,7 @@ ... }): React.Node => { if (camera && camera._cameraHandle) { - void this.fetchCameraIDs(camera); + void this.props.fetchCameraIDs(camera); } if (this.state.stagingMode) { return this.renderStagingView(); @@ -663,7 +661,7 @@ } let switchCameraButton = null; - if (this.state.hasCamerasOnBothSides) { + if (this.props.hasCamerasOnBothSides) { switchCameraButton = ( { - if (this.cameraIDsFetched) { - return; - } - this.cameraIDsFetched = true; - - const deviceCameras = await camera.getCameraIdsAsync(); - - let hasFront = false, - hasBack = false, - i = 0; - while ((!hasFront || !hasBack) && i < deviceCameras.length) { - const deviceCamera = deviceCameras[i]; - if (deviceCamera.type === RNCamera.Constants.Type.front) { - hasFront = true; - } else if (deviceCamera.type === RNCamera.Constants.Type.back) { - hasBack = true; - } - i++; - } - - const hasCamerasOnBothSides = hasFront && hasBack; - const defaultUseFrontCamera = !hasBack && hasFront; - if (hasCamerasOnBothSides !== this.state.hasCamerasOnBothSides) { - this.setState({ hasCamerasOnBothSides }); - } - const { - hasCamerasOnBothSides: oldHasCamerasOnBothSides, - defaultUseFrontCamera: oldDefaultUseFrontCamera, - } = this.props.deviceCameraInfo; - if ( - hasCamerasOnBothSides !== oldHasCamerasOnBothSides || - defaultUseFrontCamera !== oldDefaultUseFrontCamera - ) { - this.props.dispatch({ - type: updateDeviceCameraInfoActionType, - payload: { hasCamerasOnBothSides, defaultUseFrontCamera }, - }); - } - }; } const styles = StyleSheet.create({ @@ -1199,6 +1156,59 @@ setUseFrontCamera(prevUseFrontCamera => !prevUseFrontCamera); }, []); + const [hasCamerasOnBothSides, setHasCamerasOnBothSides] = React.useState( + deviceCameraInfo.hasCamerasOnBothSides, + ); + + const cameraIDsFetched = React.useRef(false); + + const fetchCameraIDs = React.useCallback( + async (camera: RNCamera) => { + if (cameraIDsFetched.current) { + return; + } + cameraIDsFetched.current = true; + + const deviceCameras = await camera.getCameraIdsAsync(); + + let hasFront = false, + hasBack = false, + i = 0; + while ((!hasFront || !hasBack) && i < deviceCameras.length) { + const deviceCamera = deviceCameras[i]; + if (deviceCamera.type === RNCamera.Constants.Type.front) { + hasFront = true; + } else if (deviceCamera.type === RNCamera.Constants.Type.back) { + hasBack = true; + } + i++; + } + + const nextHasCamerasOnBothSides = hasFront && hasBack; + const defaultUseFrontCamera = !hasBack && hasFront; + if (nextHasCamerasOnBothSides !== hasCamerasOnBothSides) { + setHasCamerasOnBothSides(nextHasCamerasOnBothSides); + } + const { + hasCamerasOnBothSides: oldHasCamerasOnBothSides, + defaultUseFrontCamera: oldDefaultUseFrontCamera, + } = deviceCameraInfo; + if ( + nextHasCamerasOnBothSides !== oldHasCamerasOnBothSides || + defaultUseFrontCamera !== oldDefaultUseFrontCamera + ) { + dispatch({ + type: updateDeviceCameraInfoActionType, + payload: { + hasCamerasOnBothSides: nextHasCamerasOnBothSides, + defaultUseFrontCamera, + }, + }); + } + }, + [deviceCameraInfo, dispatch, hasCamerasOnBothSides], + ); + return ( ); });