aboutsummaryrefslogtreecommitdiff
path: root/src/screens
diff options
context:
space:
mode:
Diffstat (limited to 'src/screens')
-rw-r--r--src/screens/moments/CameraScreen.tsx87
1 files changed, 68 insertions, 19 deletions
diff --git a/src/screens/moments/CameraScreen.tsx b/src/screens/moments/CameraScreen.tsx
index 37b37264..75638c40 100644
--- a/src/screens/moments/CameraScreen.tsx
+++ b/src/screens/moments/CameraScreen.tsx
@@ -6,6 +6,7 @@ import {StackNavigationProp} from '@react-navigation/stack';
import React, {createRef, useCallback, useEffect, useState} from 'react';
import {StyleSheet, TouchableOpacity, View} from 'react-native';
import {CameraType, FlashMode, RNCamera} from 'react-native-camera';
+import {AnimatedCircularProgress} from 'react-native-circular-progress';
import CloseIcon from '../../assets/ionicons/close-outline.svg';
import {
FlashButton,
@@ -14,9 +15,10 @@ import {
SaveButton,
TaggSquareButton,
} from '../../components';
+import {TAGG_PURPLE} from '../../constants';
import {MainStackParams} from '../../routes';
import {HeaderHeight, normalize, SCREEN_WIDTH} from '../../utils';
-import {showGIFFailureAlert, takePicture} from '../../utils/camera';
+import {showGIFFailureAlert, takePicture, takeVideo} from '../../utils/camera';
type CameraScreenRouteProps = RouteProp<MainStackParams, 'CameraScreen'>;
export type CameraScreenNavigationProps = StackNavigationProp<
@@ -33,9 +35,10 @@ const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => {
const tabBarHeight = useBottomTabBarHeight();
const [cameraType, setCameraType] = useState<keyof CameraType>('front');
const [flashMode, setFlashMode] = useState<keyof FlashMode>('off');
- const [capturedImage, setCapturedImage] = useState<string>('');
+ const [mediaFromGallery, setMediaFromGallery] = useState<string>('');
const [mostRecentPhoto, setMostRecentPhoto] = useState<string>('');
const [showSaveButton, setShowSaveButton] = useState<boolean>(false);
+ const [isRecording, setIsRecording] = useState<boolean>(false);
useFocusEffect(
useCallback(() => {
@@ -64,7 +67,7 @@ const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => {
.catch((_err) =>
console.log('Unable to fetch preview photo for gallery'),
);
- }, [capturedImage]);
+ }, [mediaFromGallery]);
const navigateToCropper = (uri: string) => {
navigation.navigate('ZoomInCropper', {
@@ -77,13 +80,13 @@ const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => {
});
};
- const navigateToCaptionScreen = () => {
+ const navigateToCaptionScreen = (isVideo: boolean, uri: string) => {
navigation.navigate('CaptionScreen', {
screenType,
title,
media: {
- uri: capturedImage,
- isVideo: false,
+ uri,
+ isVideo,
},
});
};
@@ -96,7 +99,7 @@ const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => {
if (showSaveButton) {
cameraRef.current?.resumePreview();
setShowSaveButton(false);
- setCapturedImage('');
+ setMediaFromGallery('');
} else {
navigation.goBack();
}
@@ -116,24 +119,53 @@ const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => {
/>
<View style={[styles.bottomContainer, {bottom: tabBarHeight}]}>
{showSaveButton ? (
- <SaveButton capturedImageURI={capturedImage} />
+ <SaveButton capturedImageURI={mediaFromGallery} />
) : (
<FlipButton cameraType={cameraType} setCameraType={setCameraType} />
)}
<TouchableOpacity
- onPress={() =>
+ activeOpacity={1}
+ onLongPress={() => {
+ takeVideo(cameraRef, (vid) => {
+ navigateToCaptionScreen(true, vid.uri);
+ });
+ setIsRecording(true);
+ }}
+ onPressOut={async () => {
+ if (await cameraRef.current?.isRecording()) {
+ cameraRef.current?.stopRecording();
+ setIsRecording(false);
+ }
+ }}
+ onPress={() => {
takePicture(cameraRef, (pic) => {
setShowSaveButton(true);
- setCapturedImage(pic.uri);
- })
- }
- style={styles.captureButtonContainer}>
+ setMediaFromGallery(pic.uri);
+ });
+ }}
+ style={
+ isRecording
+ ? styles.captureButtonVideoContainer
+ : styles.captureButtonContainer
+ }>
<View style={styles.captureButton} />
</TouchableOpacity>
+ {isRecording && (
+ <AnimatedCircularProgress
+ size={95}
+ width={6}
+ fill={100}
+ rotation={0}
+ duration={60000 + 1000} // an extra second for UI to load
+ tintColor={TAGG_PURPLE}
+ style={styles.bottomContainer}
+ lineCap={'round'}
+ />
+ )}
<View style={styles.bottomRightContainer}>
- {capturedImage ? (
+ {mediaFromGallery ? (
<TaggSquareButton
- onPress={navigateToCaptionScreen}
+ onPress={() => navigateToCaptionScreen(false, mediaFromGallery)}
title={'Next'}
buttonStyle={'large'}
buttonColor={'blue'}
@@ -144,15 +176,20 @@ const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => {
) : (
<GalleryIcon
mostRecentPhotoUri={mostRecentPhoto}
- callback={(pic) => {
- const filename = pic.filename;
+ callback={(media) => {
+ const filename = media.filename;
if (
filename &&
(filename.endsWith('gif') || filename.endsWith('GIF'))
) {
- showGIFFailureAlert(() => navigateToCropper(pic.path));
+ showGIFFailureAlert(() => navigateToCropper(media.path));
} else {
- navigateToCropper(pic.path);
+ // is this a video?
+ if (media.duration !== null) {
+ navigateToCaptionScreen(true, media.path);
+ } else {
+ navigateToCropper(media.path);
+ }
}
}}
/>
@@ -173,6 +210,18 @@ const styles = StyleSheet.create({
flexDirection: 'column',
backgroundColor: 'black',
},
+ captureButtonVideoContainer: {
+ alignSelf: 'center',
+ backgroundColor: 'transparent',
+ borderRadius: 100,
+ borderWidth: 15,
+ borderColor: 'rgba(255,255,255,0.3)',
+ width: 93,
+ height: 93,
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
captureButtonContainer: {
alignSelf: 'center',
backgroundColor: 'transparent',