From 80f52fa900817d614680a60f0c35592cf48310b0 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Fri, 2 Jul 2021 15:59:07 -0400 Subject: Add long press to take video --- src/screens/moments/CameraScreen.tsx | 39 +++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 14 deletions(-) (limited to 'src/screens') diff --git a/src/screens/moments/CameraScreen.tsx b/src/screens/moments/CameraScreen.tsx index 37b37264..0f2e3b5d 100644 --- a/src/screens/moments/CameraScreen.tsx +++ b/src/screens/moments/CameraScreen.tsx @@ -16,7 +16,7 @@ import { } from '../../components'; 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; export type CameraScreenNavigationProps = StackNavigationProp< @@ -33,7 +33,7 @@ const CameraScreen: React.FC = ({route, navigation}) => { const tabBarHeight = useBottomTabBarHeight(); const [cameraType, setCameraType] = useState('front'); const [flashMode, setFlashMode] = useState('off'); - const [capturedImage, setCapturedImage] = useState(''); + const [mediaFromGallery, setMediaFromGallery] = useState(''); const [mostRecentPhoto, setMostRecentPhoto] = useState(''); const [showSaveButton, setShowSaveButton] = useState(false); @@ -64,7 +64,7 @@ const CameraScreen: React.FC = ({route, navigation}) => { .catch((_err) => console.log('Unable to fetch preview photo for gallery'), ); - }, [capturedImage]); + }, [mediaFromGallery]); const navigateToCropper = (uri: string) => { navigation.navigate('ZoomInCropper', { @@ -77,13 +77,13 @@ const CameraScreen: React.FC = ({route, navigation}) => { }); }; - const navigateToCaptionScreen = () => { + const navigateToCaptionScreen = (isVideo: boolean, uri: string) => { navigation.navigate('CaptionScreen', { screenType, title, media: { - uri: capturedImage, - isVideo: false, + uri, + isVideo, }, }); }; @@ -96,7 +96,7 @@ const CameraScreen: React.FC = ({route, navigation}) => { if (showSaveButton) { cameraRef.current?.resumePreview(); setShowSaveButton(false); - setCapturedImage(''); + setMediaFromGallery(''); } else { navigation.goBack(); } @@ -116,24 +116,35 @@ const CameraScreen: React.FC = ({route, navigation}) => { /> {showSaveButton ? ( - + ) : ( )} + onLongPress={() => { + takeVideo(cameraRef, (vid) => { + navigateToCaptionScreen(true, vid.uri); + }); + }} + onPressOut={async () => { + if (await cameraRef.current?.isRecording()) { + cameraRef.current?.stopRecording(); + } else { + } + }} + onPress={() => { takePicture(cameraRef, (pic) => { setShowSaveButton(true); - setCapturedImage(pic.uri); - }) - } + setMediaFromGallery(pic.uri); + }); + }} style={styles.captureButtonContainer}> - {capturedImage ? ( + {mediaFromGallery ? ( navigateToCaptionScreen(false, mediaFromGallery)} title={'Next'} buttonStyle={'large'} buttonColor={'blue'} -- cgit v1.2.3-70-g09d2 From f62eaec4f70ffaf1c5bf82a831acff542eec4957 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Fri, 2 Jul 2021 16:14:30 -0400 Subject: Support picking video from gallery --- src/components/camera/GalleryIcon.tsx | 4 ++-- src/screens/moments/CameraScreen.tsx | 14 +++++++++----- src/utils/camera.ts | 16 +++++++++++----- 3 files changed, 22 insertions(+), 12 deletions(-) (limited to 'src/screens') diff --git a/src/components/camera/GalleryIcon.tsx b/src/components/camera/GalleryIcon.tsx index 8d396550..ca2d2559 100644 --- a/src/components/camera/GalleryIcon.tsx +++ b/src/components/camera/GalleryIcon.tsx @@ -1,12 +1,12 @@ import React from 'react'; import {Image, Text, TouchableOpacity, View} from 'react-native'; import {navigateToImagePicker} from '../../utils/camera'; -import {Image as ImageType} from 'react-native-image-crop-picker'; +import {ImageOrVideo} from 'react-native-image-crop-picker'; import {styles} from './styles'; interface GalleryIconProps { mostRecentPhotoUri: string; - callback: (pic: ImageType) => void; + callback: (media: ImageOrVideo) => void; } /* diff --git a/src/screens/moments/CameraScreen.tsx b/src/screens/moments/CameraScreen.tsx index 0f2e3b5d..c759e5db 100644 --- a/src/screens/moments/CameraScreen.tsx +++ b/src/screens/moments/CameraScreen.tsx @@ -129,7 +129,6 @@ const CameraScreen: React.FC = ({route, navigation}) => { onPressOut={async () => { if (await cameraRef.current?.isRecording()) { cameraRef.current?.stopRecording(); - } else { } }} onPress={() => { @@ -155,15 +154,20 @@ const CameraScreen: React.FC = ({route, navigation}) => { ) : ( { - 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); + } } }} /> diff --git a/src/utils/camera.ts b/src/utils/camera.ts index 7fa18b7c..d178fe94 100644 --- a/src/utils/camera.ts +++ b/src/utils/camera.ts @@ -8,7 +8,11 @@ import { TakePictureOptions, TakePictureResponse, } from 'react-native-camera'; -import ImagePicker, {Image, Video} from 'react-native-image-crop-picker'; +import ImagePicker, { + Image, + ImageOrVideo, + Video, +} from 'react-native-image-crop-picker'; import {ERROR_UPLOAD} from '../constants/strings'; /* @@ -52,7 +56,9 @@ export const saveImageToGallery = (capturedImageURI: string) => { .catch((_err) => Alert.alert('Failed to save to device!')); }; -export const navigateToImagePicker = (callback: (pic: Image) => void) => { +export const navigateToImagePicker = ( + callback: (media: ImageOrVideo) => void, +) => { ImagePicker.openPicker({ smartAlbums: [ 'Favorites', @@ -61,10 +67,10 @@ export const navigateToImagePicker = (callback: (pic: Image) => void) => { 'Screenshots', 'UserLibrary', ], - mediaType: 'photo', + mediaType: 'any', }) - .then((pic) => { - callback(pic); + .then((media) => { + callback(media); }) .catch((err) => { if (err.code && err.code !== 'E_PICKER_CANCELLED') { -- cgit v1.2.3-70-g09d2 From e15c4568aacc9551487b34b2ef9b7d7acb56ddba Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Fri, 2 Jul 2021 19:02:17 -0400 Subject: Add circular progress bar --- package.json | 7 ++++--- src/screens/moments/CameraScreen.tsx | 28 +++++++++++++++++++++++++++- yarn.lock | 9 ++++++++- 3 files changed, 39 insertions(+), 5 deletions(-) (limited to 'src/screens') diff --git a/package.json b/package.json index 63203775..42e94b39 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "react-native": "0.63.3", "react-native-animatable": "^1.3.3", "react-native-camera": "^3.44.1", + "react-native-circular-progress": "^1.3.7", "react-native-confirmation-code-field": "^6.5.0", "react-native-contacts": "^6.0.4", "react-native-controlled-mentions": "^2.2.5", @@ -47,8 +48,8 @@ "react-native-haptic-feedback": "^1.11.0", "react-native-hyperlink": "^0.0.19", "react-native-image-crop-picker": "^0.36.0", - "react-native-image-picker": "^4.0.4", "react-native-image-pan-zoom": "^2.1.12", + "react-native-image-picker": "^4.0.4", "react-native-image-resizer": "^1.4.4", "react-native-inappbrowser-reborn": "^3.5.0", "react-native-linear-gradient": "^2.5.6", @@ -61,7 +62,7 @@ "react-native-share": "^5.1.7", "react-native-snap-carousel": "^3.9.1", "react-native-splash-screen": "^3.2.0", - "react-native-svg": "^12.1.0", + "react-native-svg": "^12.1.1", "react-native-vector-icons": "^7.0.0", "react-native-video": "^5.1.1", "react-promise-tracker": "^2.1.0", @@ -111,4 +112,4 @@ "./node_modules/react-native-gesture-handler/jestSetup.js" ] } -} \ No newline at end of file +} diff --git a/src/screens/moments/CameraScreen.tsx b/src/screens/moments/CameraScreen.tsx index c759e5db..317a2b37 100644 --- a/src/screens/moments/CameraScreen.tsx +++ b/src/screens/moments/CameraScreen.tsx @@ -3,7 +3,13 @@ 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, { + createRef, + useCallback, + useEffect, + useRef, + useState, +} from 'react'; import {StyleSheet, TouchableOpacity, View} from 'react-native'; import {CameraType, FlashMode, RNCamera} from 'react-native-camera'; import CloseIcon from '../../assets/ionicons/close-outline.svg'; @@ -17,6 +23,9 @@ import { import {MainStackParams} from '../../routes'; import {HeaderHeight, normalize, SCREEN_WIDTH} from '../../utils'; import {showGIFFailureAlert, takePicture, takeVideo} from '../../utils/camera'; +import {AnimatedCircularProgress} from 'react-native-circular-progress'; +import {Easing} from 'react-native-reanimated'; +import {TAGG_LIGHT_PURPLE, TAGG_PURPLE} from '../../constants'; type CameraScreenRouteProps = RouteProp; export type CameraScreenNavigationProps = StackNavigationProp< @@ -30,12 +39,14 @@ interface CameraScreenProps { const CameraScreen: React.FC = ({route, navigation}) => { const {title, screenType} = route.params; const cameraRef = createRef(); + const circularProgress = createRef(); const tabBarHeight = useBottomTabBarHeight(); const [cameraType, setCameraType] = useState('front'); const [flashMode, setFlashMode] = useState('off'); const [mediaFromGallery, setMediaFromGallery] = useState(''); const [mostRecentPhoto, setMostRecentPhoto] = useState(''); const [showSaveButton, setShowSaveButton] = useState(false); + const [isRecording, setIsRecording] = useState(false); useFocusEffect( useCallback(() => { @@ -121,14 +132,17 @@ const CameraScreen: React.FC = ({route, navigation}) => { )} { takeVideo(cameraRef, (vid) => { navigateToCaptionScreen(true, vid.uri); }); + setIsRecording(true); }} onPressOut={async () => { if (await cameraRef.current?.isRecording()) { cameraRef.current?.stopRecording(); + setIsRecording(false); } }} onPress={() => { @@ -140,6 +154,18 @@ const CameraScreen: React.FC = ({route, navigation}) => { style={styles.captureButtonContainer}> + {isRecording && ( + + )} {mediaFromGallery ? ( Date: Fri, 2 Jul 2021 19:15:54 -0400 Subject: Adjust progress bar style --- src/screens/moments/CameraScreen.tsx | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'src/screens') diff --git a/src/screens/moments/CameraScreen.tsx b/src/screens/moments/CameraScreen.tsx index 317a2b37..36ce3999 100644 --- a/src/screens/moments/CameraScreen.tsx +++ b/src/screens/moments/CameraScreen.tsx @@ -151,13 +151,17 @@ const CameraScreen: React.FC = ({route, navigation}) => { setMediaFromGallery(pic.uri); }); }} - style={styles.captureButtonContainer}> + style={ + isRecording + ? styles.captureButtonVideoContainer + : styles.captureButtonContainer + }> {isRecording && ( Date: Fri, 2 Jul 2021 19:17:13 -0400 Subject: Lint --- src/screens/moments/CameraScreen.tsx | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'src/screens') diff --git a/src/screens/moments/CameraScreen.tsx b/src/screens/moments/CameraScreen.tsx index 36ce3999..8ec4ff98 100644 --- a/src/screens/moments/CameraScreen.tsx +++ b/src/screens/moments/CameraScreen.tsx @@ -3,15 +3,10 @@ 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, - useRef, - useState, -} from 'react'; +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, @@ -20,12 +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, takeVideo} from '../../utils/camera'; -import {AnimatedCircularProgress} from 'react-native-circular-progress'; -import {Easing} from 'react-native-reanimated'; -import {TAGG_LIGHT_PURPLE, TAGG_PURPLE} from '../../constants'; type CameraScreenRouteProps = RouteProp; export type CameraScreenNavigationProps = StackNavigationProp< -- cgit v1.2.3-70-g09d2 From c772d0491529b795cc2cb3d87f6dd2ecd1775116 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Fri, 2 Jul 2021 19:20:47 -0400 Subject: Lint --- src/screens/moments/CameraScreen.tsx | 1 - 1 file changed, 1 deletion(-) (limited to 'src/screens') diff --git a/src/screens/moments/CameraScreen.tsx b/src/screens/moments/CameraScreen.tsx index 8ec4ff98..75638c40 100644 --- a/src/screens/moments/CameraScreen.tsx +++ b/src/screens/moments/CameraScreen.tsx @@ -32,7 +32,6 @@ interface CameraScreenProps { const CameraScreen: React.FC = ({route, navigation}) => { const {title, screenType} = route.params; const cameraRef = createRef(); - const circularProgress = createRef(); const tabBarHeight = useBottomTabBarHeight(); const [cameraType, setCameraType] = useState('front'); const [flashMode, setFlashMode] = useState('off'); -- cgit v1.2.3-70-g09d2