diff options
-rw-r--r-- | src/screens/moments/CameraScreen.tsx | 156 |
1 files changed, 88 insertions, 68 deletions
diff --git a/src/screens/moments/CameraScreen.tsx b/src/screens/moments/CameraScreen.tsx index 07b697d0..b14e1dfe 100644 --- a/src/screens/moments/CameraScreen.tsx +++ b/src/screens/moments/CameraScreen.tsx @@ -3,7 +3,7 @@ import {useBottomTabBarHeight} from '@react-navigation/bottom-tabs'; import {RouteProp} from '@react-navigation/core'; import {useFocusEffect} from '@react-navigation/native'; import {StackNavigationProp} from '@react-navigation/stack'; -import React, {createRef, useCallback, useEffect, useState} from 'react'; +import React, {useRef, useCallback, useEffect, useState} from 'react'; import {Modal, StyleSheet, TouchableOpacity, View} from 'react-native'; import {CameraType, FlashMode, RNCamera} from 'react-native-camera'; import {AnimatedCircularProgress} from 'react-native-circular-progress'; @@ -25,18 +25,29 @@ interface CameraScreenProps { } const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => { const {screenType, selectedCategory} = route.params; - const cameraRef = createRef<RNCamera>(); + const cameraRef = useRef<RNCamera>(null); const tabBarHeight = useBottomTabBarHeight(); const [cameraType, setCameraType] = useState<keyof CameraType>('back'); const [flashMode, setFlashMode] = useState<keyof FlashMode>('off'); const [mostRecentPhoto, setMostRecentPhoto] = useState<string>(''); const [isRecording, setIsRecording] = useState<boolean>(false); + const [pictureProcessing, setpictureProcessing] = useState<boolean>(false); + const [mounted, setMounted] = useState<boolean>(false); useFocusEffect( useCallback(() => { navigation.dangerouslyGetParent()?.setOptions({ tabBarVisible: false, }); + + // reset in case we have returned to this screen + setpictureProcessing(false); + + // in case the preview image gets stuck + if (mounted) { + cameraRef?.current?.resumePreview(); + } + return () => setIsRecording(false); }, [navigation]), ); @@ -55,10 +66,12 @@ const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => { .catch((_err) => console.log('Unable to fetch preview photo for gallery'), ); + + setMounted(true); }, []); const navigateToEditMedia = (uri: string) => { - cameraRef.current?.resumePreview(); + cameraRef?.current?.resumePreview(); navigation.navigate('EditMedia', { screenType, media: { @@ -104,76 +117,83 @@ const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => { : flashMode } onDoubleTap={() => { - setCameraType(cameraType === 'front' ? 'back' : 'front'); + if (!pictureProcessing) { + setCameraType(cameraType === 'front' ? 'back' : 'front'); + } }} /> - <View style={[styles.bottomContainer, {bottom: tabBarHeight}]}> - <FlipButton cameraType={cameraType} setCameraType={setCameraType} /> - <TouchableOpacity - style={ - isRecording - ? styles.captureButtonVideoContainer - : styles.captureButtonContainer - } - activeOpacity={1} - onLongPress={() => { - takeVideo(cameraRef, (vid) => navigateToEditMedia(vid.uri)); - setIsRecording(true); - }} - onPressOut={async () => { - const cancelRecording = async () => { - if (await cameraRef.current?.isRecording()) { - cameraRef.current?.stopRecording(); - setIsRecording(false); - } - }; - cancelRecording(); - // tmp fix for when the animation glitches during the beginning of - // recording causing onPressOut to not be detected. - setTimeout(() => { - cancelRecording(); - }, 500); - setTimeout(() => { - cancelRecording(); - }, 1000); - setTimeout(() => { + {!pictureProcessing && ( + <View style={[styles.bottomContainer, {bottom: tabBarHeight}]}> + <FlipButton cameraType={cameraType} setCameraType={setCameraType} /> + <TouchableOpacity + style={ + isRecording + ? styles.captureButtonVideoContainer + : styles.captureButtonContainer + } + activeOpacity={1} + onLongPress={() => { + takeVideo(cameraRef, (vid) => navigateToEditMedia(vid.uri)); + setIsRecording(true); + }} + onPressOut={async () => { + const cancelRecording = async () => { + if (await cameraRef.current?.isRecording()) { + cameraRef.current?.stopRecording(); + setIsRecording(false); + } + }; cancelRecording(); - }, 1500); - }} - onPress={() => { - takePicture(cameraRef, (pic) => navigateToEditMedia(pic.uri)); - }}> - <View style={styles.captureButton} /> - </TouchableOpacity> - {isRecording && ( - <AnimatedCircularProgress - size={95} - width={6} - fill={100} - rotation={0} - duration={(MAX_VIDEO_RECORDING_DURATION + 1) * 1000} // an extra second for UI to load - tintColor={TAGG_PURPLE} - style={styles.bottomContainer} - lineCap={'round'} - /> - )} - <View style={styles.bottomRightContainer}> - <GalleryIcon - mostRecentPhotoUri={mostRecentPhoto} - callback={(media) => { - const filename = media.filename; - if ( - filename && - (filename.endsWith('gif') || filename.endsWith('GIF')) - ) { - showGIFFailureAlert(() => navigateToEditMedia(media.path)); - } else { - navigateToEditMedia(media.path); - } + // tmp fix for when the animation glitches during the beginning of + // recording causing onPressOut to not be detected. + setTimeout(() => { + cancelRecording(); + }, 500); + setTimeout(() => { + cancelRecording(); + }, 1000); + setTimeout(() => { + cancelRecording(); + }, 1500); }} - /> + onPress={() => { + if (!pictureProcessing) { + setpictureProcessing(true); + } + takePicture(cameraRef, (pic) => navigateToEditMedia(pic.uri)); + }}> + <View style={styles.captureButton} /> + </TouchableOpacity> + {isRecording && ( + <AnimatedCircularProgress + size={95} + width={6} + fill={100} + rotation={0} + duration={(MAX_VIDEO_RECORDING_DURATION + 1) * 1000} // an extra second for UI to load + tintColor={TAGG_PURPLE} + style={styles.bottomContainer} + lineCap={'round'} + /> + )} + <View style={styles.bottomRightContainer}> + <GalleryIcon + mostRecentPhotoUri={mostRecentPhoto} + callback={(media) => { + const filename = media.filename; + if ( + filename && + (filename.endsWith('gif') || filename.endsWith('GIF')) + ) { + showGIFFailureAlert(() => navigateToEditMedia(media.path)); + } else { + navigateToEditMedia(media.path); + } + }} + /> + </View> </View> - </View> + )} </View> ); }; |