diff options
author | Ivan Chen <ivan@tagg.id> | 2021-06-30 13:55:28 -0400 |
---|---|---|
committer | Ivan Chen <ivan@tagg.id> | 2021-06-30 13:55:28 -0400 |
commit | 2f3244dfa11cc23b804930ad448222bbff4f022a (patch) | |
tree | 5b2d2705c2885f9432f94f876009561e757a8786 /src/screens/moments/CameraScreen.tsx | |
parent | 5480267b285812c094246bb941c6deaf83f53ff5 (diff) |
Squashed commit of the following:
commit 66c974161b59f1e3570e2a4a42334fabc16c2129
Merge: 53bdc94c d4b21051
Author: Ivan Chen <ivan@tagg.id>
Date: Tue Jun 29 17:06:19 2021 -0400
Merge pull request #476 from shravyaramesh/tma937-tagg-camera
[TMA-937] Tagg Camera
commit d4b210518eaffd3bf1320ca7ce7fa4a6d611528f
Author: Ivan Chen <ivan@tagg.id>
Date: Tue Jun 29 17:04:10 2021 -0400
Cleanup code, Update camera options
commit 3f826ec0741d3f0d0c85a17e5d0a09eef402dbf2
Author: Ivan Chen <ivan@tagg.id>
Date: Tue Jun 29 16:45:45 2021 -0400
Set to only allow photos
commit 9d30c0c211e6b0b1b87e5de93a043e6e9f06beb3
Author: Ivan Chen <ivan@tagg.id>
Date: Tue Jun 29 16:44:41 2021 -0400
Cleanup code, Fix gallery icon bug
commit f6fdd5d913c29855644f226d09d6cba60faf6e21
Author: Ivan Chen <ivan@tagg.id>
Date: Tue Jun 29 16:32:19 2021 -0400
Add error handling
commit 5fcffd40746b2074d523f53dc82c824d147444e5
Author: Ivan Chen <ivan@tagg.id>
Date: Tue Jun 29 16:29:06 2021 -0400
Refactor buttons
commit f273a7aa1c2e27692c2a03ae1e2fc9b81360558d
Author: Shravya Ramesh <shravs1208@gmail.com>
Date: Fri Jun 25 17:18:47 2021 -0700
Fix lint errors
commit 448e91ed0b6c7519c02bbe1ac32a9d51989679db
Author: Shravya Ramesh <shravs1208@gmail.com>
Date: Fri Jun 25 16:58:05 2021 -0700
Fix lint errors
commit 6f94f0bb6dbe12e23f4222a0d0e3ffb09af965d7
Author: Shravya Ramesh <shravs1208@gmail.com>
Date: Fri Jun 25 16:50:13 2021 -0700
Add missing description for permissions
commit 727c6384a2a07c42cd132d02da8c7dbb5757ea4f
Author: Shravya Ramesh <shravs1208@gmail.com>
Date: Fri Jun 25 16:50:00 2021 -0700
Refactor code, Fix orientation bug
commit f596a0246a9b9453df3a93c8c3fc5c9137bb50fc
Author: Shravya Ramesh <shravs1208@gmail.com>
Date: Fri Jun 25 03:26:00 2021 -0700
Create camera screen, Add to Navigator
commit 0646d38547319200f7f725cdd76b1ed9b531a188
Author: Shravya Ramesh <shravs1208@gmail.com>
Date: Fri Jun 25 03:24:54 2021 -0700
Navigate to camera screen, Move image picker funct
commit f0762b7a3171f99833eb3c3f5e723c472dbc4879
Author: Shravya Ramesh <shravs1208@gmail.com>
Date: Fri Jun 25 03:23:56 2021 -0700
Add assets for camera screen
commit 3c4676b7646fbddc43bf5d9796b7cbac185b6664
Author: Shravya Ramesh <shravs1208@gmail.com>
Date: Fri Jun 25 03:23:33 2021 -0700
Add package, install for camera lib
Diffstat (limited to 'src/screens/moments/CameraScreen.tsx')
-rw-r--r-- | src/screens/moments/CameraScreen.tsx | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/src/screens/moments/CameraScreen.tsx b/src/screens/moments/CameraScreen.tsx new file mode 100644 index 00000000..c6ed1116 --- /dev/null +++ b/src/screens/moments/CameraScreen.tsx @@ -0,0 +1,215 @@ +import CameraRoll from '@react-native-community/cameraroll'; +import {useBottomTabBarHeight} from '@react-navigation/bottom-tabs'; +import {RouteProp, useFocusEffect} from '@react-navigation/core'; +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 CloseIcon from '../../assets/ionicons/close-outline.svg'; +import { + FlashButton, + FlipButton, + GalleryIcon, + SaveButton, + TaggSquareButton, +} from '../../components'; +import {MainStackParams} from '../../routes'; +import {HeaderHeight, normalize, SCREEN_WIDTH} from '../../utils'; +import {takePicture} from '../../utils/camera'; + +type CameraScreenRouteProps = RouteProp<MainStackParams, 'CameraScreen'>; +export type CameraScreenNavigationProps = StackNavigationProp< + MainStackParams, + 'CameraScreen' +>; +interface CameraScreenProps { + route: CameraScreenRouteProps; + navigation: CameraScreenNavigationProps; +} +const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => { + const {title, screenType} = route.params; + const cameraRef = createRef<RNCamera>(); + const tabBarHeight = useBottomTabBarHeight(); + const [cameraType, setCameraType] = useState<keyof CameraType>('front'); + const [flashMode, setFlashMode] = useState<keyof FlashMode>('off'); + const [capturedImage, setCapturedImage] = useState<string>(''); + const [mostRecentPhoto, setMostRecentPhoto] = useState<string>(''); + const [showSaveButton, setShowSaveButton] = useState<boolean>(false); + + /* + * Removes bottom navigation bar on current screen and add it back when navigating away + */ + useFocusEffect( + useCallback(() => { + navigation.dangerouslyGetParent()?.setOptions({ + tabBarVisible: false, + }); + return () => { + navigation.dangerouslyGetParent()?.setOptions({ + tabBarVisible: true, + }); + }; + }, [navigation]), + ); + + /* + * Chooses the last picture from gallery to display as the gallery button icon + */ + useEffect(() => { + CameraRoll.getPhotos({first: 1}) + .then((lastPhoto) => { + if (lastPhoto.edges.length > 0) { + const image = lastPhoto.edges[0].node.image; + setMostRecentPhoto(image.uri); + } + }) + .catch((_err) => + console.log('Unable to fetch preview photo for gallery'), + ); + }, [capturedImage]); + + /* + * Appears once a picture has been captured to navigate to the caption screen + */ + const handleNext = () => { + navigation.navigate('CaptionScreen', { + screenType, + title, + image: { + filename: capturedImage, + path: capturedImage, + }, + }); + }; + + /* + * If picture is not taken yet, exists from camera screen to profile view + * If picture is taken, exists from captured image's preview to camera + * */ + const handleClose = () => { + if (showSaveButton) { + cameraRef.current?.resumePreview(); + setShowSaveButton(false); + setCapturedImage(''); + } else { + navigation.goBack(); + } + }; + + return ( + <View style={styles.container}> + <TouchableOpacity style={styles.closeButton} onPress={handleClose}> + <CloseIcon height={25} width={25} color={'white'} /> + </TouchableOpacity> + <FlashButton flashMode={flashMode} setFlashMode={setFlashMode} /> + <RNCamera + ref={cameraRef} + style={styles.camera} + type={cameraType} + flashMode={flashMode} + /> + <View style={[styles.bottomContainer, {bottom: tabBarHeight}]}> + {showSaveButton ? ( + <SaveButton capturedImageURI={capturedImage} /> + ) : ( + <FlipButton cameraType={cameraType} setCameraType={setCameraType} /> + )} + <TouchableOpacity + onPress={() => + takePicture(cameraRef, setShowSaveButton, setCapturedImage) + } + style={styles.captureButtonContainer}> + <View style={styles.captureButton} /> + </TouchableOpacity> + <View style={styles.bottomRightContainer}> + {capturedImage ? ( + <TaggSquareButton + onPress={handleNext} + title={'Next'} + buttonStyle={'large'} + buttonColor={'blue'} + labelColor={'white'} + style={styles.nextButton} + labelStyle={styles.nextButtonLabel} + /> + ) : ( + <GalleryIcon + mostRecentPhotoUri={mostRecentPhoto} + screenType={screenType} + title={title} + /> + )} + </View> + </View> + </View> + ); +}; + +const styles = StyleSheet.create({ + camera: { + flex: 1, + justifyContent: 'space-between', + }, + container: { + flex: 1, + flexDirection: 'column', + backgroundColor: 'black', + }, + preview: { + flex: 1, + justifyContent: 'flex-end', + alignItems: 'center', + }, + captureButtonContainer: { + alignSelf: 'center', + backgroundColor: 'transparent', + borderRadius: 100, + borderWidth: 4, + borderColor: '#fff', + width: 93, + height: 93, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + }, + captureButton: { + backgroundColor: '#fff', + width: 68, + height: 68, + borderRadius: 74, + }, + closeButton: { + position: 'absolute', + top: 0, + paddingTop: HeaderHeight, + zIndex: 1, + marginLeft: '5%', + }, + bottomContainer: { + position: 'absolute', + width: SCREEN_WIDTH, + flexDirection: 'row', + justifyContent: 'center', + }, + bottomRightContainer: { + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'center', + width: (SCREEN_WIDTH - 100) / 2, + }, + nextButton: { + zIndex: 1, + width: normalize(100), + height: normalize(37), + borderRadius: 10, + }, + nextButtonLabel: { + fontWeight: '700', + fontSize: normalize(15), + lineHeight: normalize(17.8), + letterSpacing: normalize(1.3), + textAlign: 'center', + }, +}); + +export default CameraScreen; |