aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/common/MomentTags.tsx44
-rw-r--r--src/screens/moments/TagFriendsScreen.tsx235
-rw-r--r--src/screens/profile/MomentCommentsScreen.tsx5
3 files changed, 211 insertions, 73 deletions
diff --git a/src/components/common/MomentTags.tsx b/src/components/common/MomentTags.tsx
index d8a70353..37069e18 100644
--- a/src/components/common/MomentTags.tsx
+++ b/src/components/common/MomentTags.tsx
@@ -10,6 +10,13 @@ interface MomentTagsProps {
setTags: (tag: MomentTagType[]) => void;
imageRef: RefObject<Image>;
deleteFromList?: (user: ProfilePreviewType) => void;
+ boundaries?: DraggableBoundaries;
+}
+interface DraggableBoundaries {
+ top?: number;
+ bottom?: number;
+ left?: number;
+ right?: number;
}
const MomentTags: React.FC<MomentTagsProps> = ({
@@ -18,11 +25,14 @@ const MomentTags: React.FC<MomentTagsProps> = ({
setTags,
imageRef,
deleteFromList,
+ boundaries,
}) => {
const [offset, setOffset] = useState([0, 0]);
const [imageDimensions, setImageDimensions] = useState([0, 0]);
const [maxZIndex, setMaxZIndex] = useState(1);
const [draggableRefs, setDraggableRefs] = useState<RefObject<View>[]>([]);
+ // [minXBoundary, maxXBoundary, minYBoundary, maxYBoundary]
+ const [boundariesList, setBoundariesList] = useState<number[]>([0, 0, 0, 0]);
const updateTagPosition = (ref: RefObject<Image>, userId: string) => {
if (ref !== null && ref.current !== null) {
@@ -77,6 +87,24 @@ const MomentTags: React.FC<MomentTagsProps> = ({
},
);
}
+
+ // Checks for and adds boundaries
+ if (boundaries) {
+ const newBounds = [...boundariesList];
+ if (boundaries.top) {
+ newBounds[2] = boundaries.top;
+ }
+ if (boundaries.bottom) {
+ newBounds[3] = boundaries.bottom;
+ }
+ if (boundaries.left) {
+ newBounds[0] = boundaries.left;
+ }
+ if (boundaries.right) {
+ newBounds[1] = boundaries.right;
+ }
+ setBoundariesList(newBounds);
+ }
},
editing ? 100 : 0,
);
@@ -94,10 +122,10 @@ const MomentTags: React.FC<MomentTagsProps> = ({
x={(imageDimensions[0] * tag.x) / 100 + offset[0]}
y={(imageDimensions[1] * tag.y) / 100 + offset[1]}
z={tag.z}
- minX={offset[0]}
- minY={offset[1]}
- maxX={imageDimensions[0] + offset[0]}
- maxY={imageDimensions[1] + offset[1]}
+ minX={offset[0] + boundariesList[0]}
+ minY={offset[1] + boundariesList[2]}
+ maxX={imageDimensions[0] + offset[0] - boundariesList[1]}
+ maxY={imageDimensions[1] + offset[1] - boundariesList[3]}
onDragStart={() => {
const currZIndex = maxZIndex;
setMaxZIndex(currZIndex + 1);
@@ -123,10 +151,10 @@ const MomentTags: React.FC<MomentTagsProps> = ({
x={(imageDimensions[0] * tag.x) / 100 + offset[0]}
y={(imageDimensions[1] * tag.y) / 100 + offset[1]}
z={tag.z}
- minX={offset[0]}
- minY={offset[1]}
- maxX={imageDimensions[0] + offset[0]}
- maxY={imageDimensions[1] + offset[1]}
+ minX={offset[0] + boundariesList[0]}
+ minY={offset[1] + boundariesList[2]}
+ maxX={imageDimensions[0] + offset[0] - boundariesList[1]}
+ maxY={imageDimensions[1] + offset[1] - boundariesList[3]}
disabled={true}>
<TaggDraggable
draggableRef={draggableRefs[index]}
diff --git a/src/screens/moments/TagFriendsScreen.tsx b/src/screens/moments/TagFriendsScreen.tsx
index 201caf49..6c982936 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 {
+ SCREEN_WIDTH,
+ SCREEN_HEIGHT,
+ HeaderHeight,
+ isIPhoneX,
+ normalize,
+} 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={{
+ position: 'absolute',
+ 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,138 @@ 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
+ {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,
},
});
diff --git a/src/screens/profile/MomentCommentsScreen.tsx b/src/screens/profile/MomentCommentsScreen.tsx
index 402e5f44..7dfe8ae9 100644
--- a/src/screens/profile/MomentCommentsScreen.tsx
+++ b/src/screens/profile/MomentCommentsScreen.tsx
@@ -48,8 +48,9 @@ const MomentCommentsScreen: React.FC<MomentCommentsScreenProps> = ({route}) => {
React.useState(true);
//Keeps track of the current comments object in focus so that the application knows which comment to post a reply to
- const [commentTapped, setCommentTapped] =
- useState<CommentType | CommentThreadType | undefined>();
+ const [commentTapped, setCommentTapped] = useState<
+ CommentType | CommentThreadType | undefined
+ >();
useEffect(() => {
navigation.setOptions({