aboutsummaryrefslogtreecommitdiff
path: root/src/screens/moments/CameraScreen.tsx
diff options
context:
space:
mode:
authorIvan Chen <ivan@tagg.id>2021-06-30 13:55:28 -0400
committerIvan Chen <ivan@tagg.id>2021-06-30 13:55:28 -0400
commit2f3244dfa11cc23b804930ad448222bbff4f022a (patch)
tree5b2d2705c2885f9432f94f876009561e757a8786 /src/screens/moments/CameraScreen.tsx
parent5480267b285812c094246bb941c6deaf83f53ff5 (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.tsx215
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;