diff options
Diffstat (limited to 'src/screens/moments/TagFriendsScreen.tsx')
-rw-r--r-- | src/screens/moments/TagFriendsScreen.tsx | 239 |
1 files changed, 176 insertions, 63 deletions
diff --git a/src/screens/moments/TagFriendsScreen.tsx b/src/screens/moments/TagFriendsScreen.tsx index 201caf49..fc3bccf2 100644 --- a/src/screens/moments/TagFriendsScreen.tsx +++ b/src/screens/moments/TagFriendsScreen.tsx @@ -1,19 +1,27 @@ import {RouteProp} from '@react-navigation/core'; import {useNavigation} from '@react-navigation/native'; import React, {useEffect, useRef, useState} from 'react'; -import {Image, StyleSheet, TouchableWithoutFeedback, View} from 'react-native'; -import {Button} from 'react-native-elements'; +import { + Image, + StyleSheet, + Text, + TouchableOpacity, + TouchableWithoutFeedback, + View, +} from 'react-native'; import Video from 'react-native-video'; import {MainStackParams} from 'src/routes'; -import { - CaptionScreenHeader, - MomentTags, - SearchBackground, -} from '../../components'; +import BackArrow from '../../assets/icons/back-arrow.svg'; +import {MomentTags} from '../../components'; import {TagFriendsFooter} from '../../components/moments'; -import {TAGG_LIGHT_BLUE_2} from '../../constants'; import {MomentTagType} from '../../types'; -import {SCREEN_WIDTH, StatusBarHeight} from '../../utils'; +import { + HeaderHeight, + isIPhoneX, + normalize, + SCREEN_HEIGHT, + SCREEN_WIDTH, +} from '../../utils'; type TagFriendsScreenRouteProps = RouteProp< MainStackParams, @@ -29,6 +37,9 @@ const TagFriendsScreen: React.FC<TagFriendsScreenProps> = ({route}) => { const [tags, setTags] = useState<MomentTagType[]>([]); const [imageWidth, setImageWidth] = useState<number>(0); const [imageHeight, setImageHeight] = useState<number>(0); + const [bottomBound, setBottomBound] = useState<number>(0); + const [topHeight, setTopHeight] = useState<number>(0); + const [topBound, setTopBound] = useState<number>(0); /* * Update list of tagged users from route params @@ -41,28 +52,57 @@ const TagFriendsScreen: React.FC<TagFriendsScreenProps> = ({route}) => { * Navigate back to Tag Users Screen, send selected users */ const handleDone = () => { - navigation.navigate('CaptionScreen', { - ...route.params, - selectedTags: tags, - }); + // Makes sure that this can only be pressed if there are tags + if (tags.length !== 0) { + navigation.navigate('CaptionScreen', { + ...route.params, + selectedTags: tags, + }); + } }; const setMediaDimensions = (width: number, height: number) => { const imageAspectRatio = width / height; + const screenRatio = SCREEN_WIDTH / SCREEN_HEIGHT; - // aspectRatio: >= 1 [Landscape] [1:1] - if (imageAspectRatio >= 1) { + // aspectRatio is wider than or equal to screen + if (imageAspectRatio >= screenRatio) { setImageWidth(SCREEN_WIDTH); setImageHeight(SCREEN_WIDTH / imageAspectRatio); } - // aspectRatio: < 1 [Portrait] - if (imageAspectRatio < 1) { - setImageHeight(SCREEN_WIDTH); - setImageWidth(SCREEN_WIDTH * imageAspectRatio); + // aspectRatio is taller than screen + if (imageAspectRatio < screenRatio) { + setImageHeight(SCREEN_HEIGHT); + setImageWidth(SCREEN_HEIGHT * imageAspectRatio); } }; /* + * Calculate boundary (if any) for drag from bottom and top + */ + useEffect(() => { + // Bottom dead zone + if (SCREEN_HEIGHT / 2 - imageHeight / 2 < SCREEN_HEIGHT * 0.15) { + if (SCREEN_HEIGHT / 2 - imageHeight / 2 < 0) { + setBottomBound(SCREEN_HEIGHT * 0.15); + } else { + setBottomBound( + SCREEN_HEIGHT * 0.15 - (SCREEN_HEIGHT / 2 - imageHeight / 2), + ); + } + } + + // Top dead zone + if (SCREEN_HEIGHT / 2 - imageHeight / 2 < topHeight) { + if (SCREEN_HEIGHT / 2 - imageHeight / 2 < 0) { + setTopBound(topHeight + 15); + } else { + setTopBound(topHeight - (SCREEN_HEIGHT / 2 - imageHeight / 2) + 15); + } + } + }, [imageHeight, imageWidth, topHeight]); + + /* * Calculating image width and height with respect to it's enclosing view's dimensions. Only works for images. */ useEffect(() => { @@ -78,25 +118,12 @@ const TagFriendsScreen: React.FC<TagFriendsScreenProps> = ({route}) => { }, []); return ( - <SearchBackground> - <View style={styles.contentContainer}> - <View style={styles.buttonsContainer}> - <Button - title="Cancel" - buttonStyle={styles.button} - onPress={() => navigation.goBack()} - /> - <Button - title="Done" - titleStyle={styles.shareButtonTitle} - buttonStyle={styles.button} - onPress={handleDone} - /> - </View> - <CaptionScreenHeader - style={styles.header} - title={'Tap on photo to tag friends!'} - /> + <View style={styles.contentContainer}> + <View + style={[ + styles.innerContainer, + {paddingTop: SCREEN_HEIGHT / 2 - imageHeight / 2}, + ]}> <TouchableWithoutFeedback onPress={() => navigation.navigate('TagSelectionScreen', { @@ -108,7 +135,6 @@ const TagFriendsScreen: React.FC<TagFriendsScreenProps> = ({route}) => { style={{ width: imageWidth, height: imageHeight, - marginVertical: (SCREEN_WIDTH - imageHeight) / 2, marginHorizontal: (SCREEN_WIDTH - imageWidth) / 2, }} ref={imageRef}> @@ -136,55 +162,142 @@ const TagFriendsScreen: React.FC<TagFriendsScreenProps> = ({route}) => { style={{ width: imageWidth, height: imageHeight, - marginVertical: (SCREEN_WIDTH - imageHeight) / 2, marginHorizontal: (SCREEN_WIDTH - imageWidth) / 2, }} source={{uri: media.uri}} /> )} </TouchableWithoutFeedback> - {tags.length !== 0 && ( - <MomentTags - tags={tags} - setTags={setTags} - editing={true} - imageRef={imageRef} - deleteFromList={(user) => - setTags(tags.filter((tag) => tag.user.id !== user.id)) - } - /> - )} + </View> + <View + style={styles.titleContainer} + onLayout={(event) => { + const {y, height} = event.nativeEvent.layout; + setTopHeight(y + height); + }}> + <TouchableOpacity + onPress={() => { + navigation.goBack(); + }} + style={styles.backArrow}> + <View style={styles.backArrowContainer}> + <BackArrow + height={normalize(18)} + width={normalize(18)} + color={'white'} + /> + </View> + </TouchableOpacity> + <TouchableWithoutFeedback style={styles.captionContainer}> + {tags.length === 0 ? ( + <Text style={styles.header}>Tap on photo to tag friends!</Text> + ) : ( + <Text style={styles.header}>Press and drag to move</Text> + )} + </TouchableWithoutFeedback> + <TouchableOpacity + style={styles.buttonContainer} + // Altering the opacity style of TouchableOpacity doesn't work, + // so the next two lines are needed + disabled={tags.length === 0} + activeOpacity={tags.length === 0 ? 0 : 1} + onPress={handleDone}> + <Text + style={[ + styles.shareButtonTitle, + // makes the Done buttomn invisible if there are no tags + // eslint-disable-next-line react-native/no-inline-styles + {opacity: tags.length !== 0 ? 1 : 0}, + ]}> + Done + </Text> + </TouchableOpacity> + </View> + {tags.length !== 0 && ( + <MomentTags + tags={tags} + setTags={setTags} + editing={true} + imageRef={imageRef} + deleteFromList={(user) => + setTags(tags.filter((tag) => tag.user.id !== user.id)) + } + boundaries={{top: topBound, bottom: bottomBound}} + /> + )} + {tags.length !== 0 && ( <View style={styles.footerContainer}> <TagFriendsFooter tags={tags} setTags={setTags} /> </View> - </View> - </SearchBackground> + )} + </View> ); }; const styles = StyleSheet.create({ contentContainer: { - paddingTop: StatusBarHeight, + backgroundColor: 'black', + height: SCREEN_HEIGHT, + alignContent: 'center', }, - buttonsContainer: { - flexDirection: 'row', - justifyContent: 'space-between', - marginLeft: '5%', - marginRight: '5%', + backArrow: { + marginTop: isIPhoneX() ? HeaderHeight : '10%', + zIndex: 9999, + }, + backArrowContainer: { + flex: 1, + flexDirection: 'column', + justifyContent: 'center', + alignContent: 'center', }, button: { - backgroundColor: 'transparent', + zIndex: 9999, + }, + buttonContainer: { + marginTop: isIPhoneX() ? HeaderHeight : '10%', + right: 0, + zIndex: 9999, + flexDirection: 'row', + justifyContent: 'flex-end', + }, + captionContainer: { + width: SCREEN_WIDTH, + flexDirection: 'row', + justifyContent: 'center', + zIndex: 9999, }, shareButtonTitle: { fontWeight: 'bold', - color: TAGG_LIGHT_BLUE_2, + fontSize: 18, + color: 'white', + }, + titleContainer: { + flexDirection: 'row', + justifyContent: 'space-evenly', + alignContent: 'center', + zIndex: 9999, }, header: { - marginVertical: 20, + marginTop: isIPhoneX() ? HeaderHeight : '10%', + fontSize: 18, + fontWeight: 'bold', + color: 'white', + textAlign: 'center', }, footerContainer: { - marginHorizontal: '5%', marginTop: '3%', + backgroundColor: 'black', + padding: '5%', + flexDirection: 'column', + justifyContent: 'center', + width: SCREEN_WIDTH, + position: 'absolute', + paddingBottom: 0, + bottom: 0, + height: SCREEN_HEIGHT * 0.15, + }, + innerContainer: { + position: 'absolute', }, }); |