aboutsummaryrefslogtreecommitdiff
path: root/src/screens
diff options
context:
space:
mode:
authorIvan Chen <ivan@tagg.id>2021-07-09 18:50:15 -0400
committerGitHub <noreply@github.com>2021-07-09 18:50:15 -0400
commit1b2dbdefd7f0f188c3aae9f3fb862a690c123468 (patch)
treee9b88baa252155d3dcad90d6d7b68f195e81be2a /src/screens
parent70a9fbcd9aab15be060694fc751cda5f26a81e11 (diff)
parenta0f3288050ec1ea3b9b9fc1320fa54b7f3119bb2 (diff)
Merge pull request #491 from IvanIFChen/tma969-new-caption-screen
[TMA-969] New Caption Screen
Diffstat (limited to 'src/screens')
-rw-r--r--src/screens/moments/CameraScreen.tsx13
-rw-r--r--src/screens/moments/TagFriendsScreen.tsx16
-rw-r--r--src/screens/profile/CaptionScreen.tsx351
-rw-r--r--src/screens/profile/CategorySelection.tsx1
-rw-r--r--src/screens/profile/ChoosingCategoryScreen.tsx192
-rw-r--r--src/screens/profile/CreateCustomCategory.tsx4
-rw-r--r--src/screens/profile/index.ts1
7 files changed, 451 insertions, 127 deletions
diff --git a/src/screens/moments/CameraScreen.tsx b/src/screens/moments/CameraScreen.tsx
index dd3612ca..2282ecad 100644
--- a/src/screens/moments/CameraScreen.tsx
+++ b/src/screens/moments/CameraScreen.tsx
@@ -30,7 +30,7 @@ interface CameraScreenProps {
navigation: CameraScreenNavigationProps;
}
const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => {
- const {title, screenType} = route.params;
+ const {screenType, selectedCategory} = route.params;
const cameraRef = createRef<RNCamera>();
const tabBarHeight = useBottomTabBarHeight();
const [cameraType, setCameraType] = useState<keyof CameraType>('front');
@@ -45,11 +45,6 @@ const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => {
navigation.dangerouslyGetParent()?.setOptions({
tabBarVisible: false,
});
- return () => {
- navigation.dangerouslyGetParent()?.setOptions({
- tabBarVisible: true,
- });
- };
}, [navigation]),
);
@@ -72,18 +67,17 @@ const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => {
const navigateToCropper = (uri: string) => {
navigation.navigate('ZoomInCropper', {
screenType,
- title,
media: {
uri,
isVideo: false,
},
+ selectedCategory,
});
};
const navigateToCaptionScreen = (isVideo: boolean, uri: string) => {
navigation.navigate('CaptionScreen', {
screenType,
- title,
media: {
uri,
isVideo,
@@ -101,6 +95,9 @@ const CameraScreen: React.FC<CameraScreenProps> = ({route, navigation}) => {
setShowSaveButton(false);
setMediaFromGallery('');
} else {
+ navigation.dangerouslyGetParent()?.setOptions({
+ tabBarVisible: true,
+ });
navigation.goBack();
}
};
diff --git a/src/screens/moments/TagFriendsScreen.tsx b/src/screens/moments/TagFriendsScreen.tsx
index 6c982936..fc3bccf2 100644
--- a/src/screens/moments/TagFriendsScreen.tsx
+++ b/src/screens/moments/TagFriendsScreen.tsx
@@ -16,11 +16,11 @@ import {MomentTags} from '../../components';
import {TagFriendsFooter} from '../../components/moments';
import {MomentTagType} from '../../types';
import {
- SCREEN_WIDTH,
- SCREEN_HEIGHT,
HeaderHeight,
isIPhoneX,
normalize,
+ SCREEN_HEIGHT,
+ SCREEN_WIDTH,
} from '../../utils';
type TagFriendsScreenRouteProps = RouteProp<
@@ -120,10 +120,10 @@ const TagFriendsScreen: React.FC<TagFriendsScreenProps> = ({route}) => {
return (
<View style={styles.contentContainer}>
<View
- style={{
- position: 'absolute',
- paddingTop: SCREEN_HEIGHT / 2 - imageHeight / 2,
- }}>
+ style={[
+ styles.innerContainer,
+ {paddingTop: SCREEN_HEIGHT / 2 - imageHeight / 2},
+ ]}>
<TouchableWithoutFeedback
onPress={() =>
navigation.navigate('TagSelectionScreen', {
@@ -206,6 +206,7 @@ const TagFriendsScreen: React.FC<TagFriendsScreenProps> = ({route}) => {
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
@@ -295,6 +296,9 @@ const styles = StyleSheet.create({
bottom: 0,
height: SCREEN_HEIGHT * 0.15,
},
+ innerContainer: {
+ position: 'absolute',
+ },
});
export default TagFriendsScreen;
diff --git a/src/screens/profile/CaptionScreen.tsx b/src/screens/profile/CaptionScreen.tsx
index 7fef73db..1232eb66 100644
--- a/src/screens/profile/CaptionScreen.tsx
+++ b/src/screens/profile/CaptionScreen.tsx
@@ -1,9 +1,10 @@
import {RouteProp} from '@react-navigation/native';
import {StackNavigationProp} from '@react-navigation/stack';
-import React, {Fragment, useEffect, useState} from 'react';
+import React, {FC, useEffect, useMemo, useState} from 'react';
import {
Alert,
Image,
+ ImageSourcePropType,
Keyboard,
KeyboardAvoidingView,
Platform,
@@ -13,19 +14,25 @@ import {
TouchableWithoutFeedback,
View,
} from 'react-native';
-import {MentionInputControlled} from '../../components';
-import {Button, normalize} from 'react-native-elements';
+import {Button} from 'react-native-elements';
import Video from 'react-native-video';
import {useDispatch, useSelector} from 'react-redux';
import FrontArrow from '../../assets/icons/front-arrow.svg';
-import {SearchBackground} from '../../components';
+import {
+ MentionInputControlled,
+ SearchBackground,
+ TaggSquareButton,
+} from '../../components';
import {CaptionScreenHeader} from '../../components/';
import TaggLoadingIndicator from '../../components/common/TaggLoadingIndicator';
import {TAGG_LIGHT_BLUE_2} from '../../constants';
import {
+ ERROR_NO_MOMENT_CATEGORY,
ERROR_SOMETHING_WENT_WRONG_REFRESH,
ERROR_UPLOAD,
+ SUCCESS_PIC_UPLOAD,
} from '../../constants/strings';
+import * as RootNavigation from '../../RootNavigation';
import {MainStackParams} from '../../routes';
import {
handlePresignedURL,
@@ -40,34 +47,36 @@ import {
} from '../../store/actions';
import {RootState} from '../../store/rootReducer';
import {MomentTagType} from '../../types';
-import {SCREEN_WIDTH, StatusBarHeight} from '../../utils';
+import {isIPhoneX, normalize, SCREEN_WIDTH, StatusBarHeight} from '../../utils';
import {mentionPartTypes} from '../../utils/comments';
/**
* Upload Screen to allow users to upload posts to Tagg
*/
type CaptionScreenRouteProp = RouteProp<MainStackParams, 'CaptionScreen'>;
+
type CaptionScreenNavigationProp = StackNavigationProp<
MainStackParams,
'CaptionScreen'
>;
+
interface CaptionScreenProps {
route: CaptionScreenRouteProp;
navigation: CaptionScreenNavigationProp;
}
const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
- const {title, screenType, selectedTags, moment} = route.params;
+ // moment is only present when editing
+ const {moment} = route.params;
const {
user: {userId},
} = useSelector((state: RootState) => state.user);
const dispatch = useDispatch();
const [caption, setCaption] = useState(moment ? moment.caption : '');
const [loading, setLoading] = useState(false);
- const [tags, setTags] = useState<MomentTagType[]>(
- selectedTags ? selectedTags : [],
- );
- const [taggedList, setTaggedList] = useState<string>('');
+ const [tags, setTags] = useState<MomentTagType[]>([]);
+ const [taggedUsersText, setTaggedUsersText] = useState('');
+ const [momentCategory, setMomentCategory] = useState<string | undefined>();
const mediaUri = moment ? moment.moment_url : route.params.media!.uri;
// TODO: change this once moment refactor is done
const isMediaAVideo = moment
@@ -80,54 +89,68 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
: route.params.media?.isVideo ?? false;
useEffect(() => {
- setTags(selectedTags ? selectedTags : []);
- }, [selectedTags]);
+ setTags(route.params.selectedTags ?? []);
+ }, [route.params.selectedTags]);
useEffect(() => {
- const getTaggedUsersListString = () => {
- let listString = '';
- for (let i = 0; i < tags.length; i++) {
- if (listString.length < 21) {
- listString = listString.concat(`@${tags[i].user.username} `);
- } else {
- break;
- }
+ setMomentCategory(route.params.selectedCategory);
+ }, [route.params.selectedCategory]);
+
+ useEffect(() => {
+ let listString = '';
+ // Append non-truncated usernames together and no more than 21 characters total
+ // e.g. "@ivan.tagg"
+ // e.g. "@ivan.tagg @foobar . . ."
+ for (const tag of tags) {
+ const usernameStr = `@${tag.user.username} `;
+ if (listString.length + usernameStr.length > 21) {
+ listString = listString.concat('. . .');
+ break;
+ } else {
+ listString = listString.concat(usernameStr);
}
- setTaggedList(listString);
- };
- getTaggedUsersListString();
+ }
+ setTaggedUsersText(listString);
}, [tags]);
- const navigateToProfile = () => {
- //Since the logged In User is navigating to own profile, useXId is not required
- navigation.navigate('Profile', {
- screenType,
- userXId: undefined,
- });
- };
-
- const handleFailed = () => {
+ const handleFailed = (noCategory = false) => {
setLoading(false);
+ navigation.dangerouslyGetParent()?.setOptions({
+ tabBarVisible: true,
+ });
setTimeout(() => {
- Alert.alert(moment ? ERROR_SOMETHING_WENT_WRONG_REFRESH : ERROR_UPLOAD);
+ if (noCategory) {
+ Alert.alert(ERROR_NO_MOMENT_CATEGORY);
+ } else {
+ Alert.alert(moment ? ERROR_SOMETHING_WENT_WRONG_REFRESH : ERROR_UPLOAD);
+ }
}, 500);
};
const handleSuccess = () => {
setLoading(false);
- if (moment) {
- setLoading(false);
- navigation.goBack();
- } else {
- navigateToProfile();
+ navigation.dangerouslyGetParent()?.setOptions({
+ tabBarVisible: true,
+ });
+ if (!moment) {
+ // if posting, pop all screens until at camera screen (default upload screen)
+ // then switch to the profile tab
+ navigation.popToTop();
+ RootNavigation.navigate('ProfileTab');
setTimeout(() => {
if (isMediaAVideo) {
Alert.alert(
'Beautiful, the Moment was uploaded successfully! Check back in a bit and refresh to see it!',
);
} else {
- Alert.alert('');
+ Alert.alert(SUCCESS_PIC_UPLOAD);
}
}, 500);
+ } else {
+ // if editing, simply go back to profile screen
+ navigation.navigate('Profile', {
+ userXId: undefined,
+ screenType: route.params.screenType,
+ });
}
};
@@ -142,15 +165,15 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
const handleShare = async () => {
setLoading(true);
- if (moment || !title) {
- handleFailed();
+ if (moment || !momentCategory) {
+ handleFailed(true);
return;
}
let profileCompletionStage;
let momentId;
// separate upload logic for image/video
if (isMediaAVideo) {
- const presignedURLResponse = await handlePresignedURL(title);
+ const presignedURLResponse = await handlePresignedURL(momentCategory);
if (!presignedURLResponse) {
handleFailed();
return;
@@ -163,7 +186,12 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
handleFailed();
}
} else {
- const momentResponse = await postMoment(mediaUri, caption, title, userId);
+ const momentResponse = await postMoment(
+ mediaUri,
+ caption,
+ momentCategory,
+ userId,
+ );
if (!momentResponse) {
handleFailed();
return;
@@ -187,12 +215,13 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
handleSuccess();
};
- const handleDoneEditing = async () => {
+ const handleSubmitEditChanges = async () => {
setLoading(true);
- if (moment?.moment_id) {
+ if (moment?.moment_id && momentCategory) {
const success = await patchMoment(
moment.moment_id,
caption,
+ momentCategory,
formattedTags(),
);
if (success) {
@@ -204,12 +233,46 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
}
};
+ const SelectableItem: FC<{
+ text: 'Tag Friends' | 'Category';
+ imageUri: ImageSourcePropType;
+ onPress: () => void;
+ }> = ({text, imageUri, onPress}) => {
+ return (
+ <TouchableOpacity
+ onPress={onPress}
+ style={styles.selectableItemContainer}>
+ <View style={styles.row}>
+ {text === 'Category' && !momentCategory && (
+ <Text style={styles.asteriskText}>* </Text>
+ )}
+ <Image style={styles.tagIcon} source={imageUri} />
+ <Text style={styles.selectableItemTitle}>{text}</Text>
+ </View>
+ <View style={styles.row}>
+ {text === 'Tag Friends' && (
+ <Text style={styles.itemInfoText}>{taggedUsersText}</Text>
+ )}
+ {text === 'Category' && (
+ <Text style={styles.itemInfoText}>{momentCategory}</Text>
+ )}
+ <FrontArrow
+ width={normalize(13)}
+ height={normalize(13)}
+ color={'white'}
+ />
+ </View>
+ </TouchableOpacity>
+ );
+ };
+
return (
<SearchBackground>
- {loading ? <TaggLoadingIndicator fullscreen /> : <Fragment />}
+ {loading && <TaggLoadingIndicator fullscreen />}
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
+ keyboardVerticalOffset={isIPhoneX() ? 40 : 30}
style={styles.flex}>
<View style={styles.contentContainer}>
<View style={styles.buttonsContainer}>
@@ -218,60 +281,84 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
buttonStyle={styles.button}
onPress={() => navigation.goBack()}
/>
- <Button
- title={moment ? 'Done' : 'Share'}
- titleStyle={styles.shareButtonTitle}
- buttonStyle={styles.button}
- onPress={moment ? handleDoneEditing : handleShare}
+ </View>
+ <CaptionScreenHeader style={styles.header} title={'Moments'} />
+ <View style={styles.captionContainer}>
+ {isMediaAVideo ? (
+ <Video
+ style={styles.media}
+ source={{uri: mediaUri}}
+ repeat={true}
+ />
+ ) : (
+ <Image
+ style={styles.media}
+ source={{uri: mediaUri}}
+ resizeMode={'contain'}
+ />
+ )}
+ <MentionInputControlled
+ style={styles.text}
+ containerStyle={styles.flex}
+ placeholder="Write something....."
+ placeholderTextColor="white"
+ value={caption}
+ onChange={setCaption}
+ partTypes={mentionPartTypes('white', 'caption', true)}
/>
</View>
- <CaptionScreenHeader
- style={styles.header}
- {...{title: moment ? moment.moment_category : title ?? ''}}
- />
- {isMediaAVideo ? (
- <Video
- style={styles.media}
- source={{uri: mediaUri}}
- repeat={true}
+ {useMemo(
+ () => (
+ <SelectableItem
+ text={'Category'}
+ imageUri={require('../../assets/images/images.png')}
+ onPress={() =>
+ navigation.navigate('ChoosingCategoryScreen', {})
+ }
+ />
+ ),
+ [momentCategory],
+ )}
+ {useMemo(
+ () => (
+ <SelectableItem
+ text={'Tag Friends'}
+ imageUri={require('../../assets/icons/tagging/tag-icon.png')}
+ onPress={() =>
+ navigation.navigate('TagFriendsScreen', {
+ media: {
+ uri: mediaUri,
+ isVideo: isMediaAVideo,
+ },
+ selectedTags: tags,
+ })
+ }
+ />
+ ),
+ [taggedUsersText],
+ )}
+ {momentCategory ? (
+ <TaggSquareButton
+ onPress={moment ? handleSubmitEditChanges : handleShare}
+ title={moment ? 'Update' : 'Post'}
+ buttonStyle={'large'}
+ buttonColor={'blue'}
+ labelColor={'white'}
+ style={styles.postButton}
+ labelStyle={styles.postText}
/>
) : (
- <Image
- style={styles.media}
- source={{uri: mediaUri}}
- resizeMode={'contain'}
+ <TaggSquareButton
+ disabled={true}
+ onPress={moment ? handleSubmitEditChanges : handleShare}
+ title={moment ? 'Update' : 'Post'}
+ buttonStyle={'large'}
+ buttonColor={'blue'}
+ labelColor={'white'}
+ style={[styles.postButton, styles.greyBackground]}
+ labelStyle={styles.postText}
/>
)}
- <MentionInputControlled
- containerStyle={styles.text}
- placeholder="Write something....."
- placeholderTextColor="gray"
- value={caption}
- onChange={setCaption}
- partTypes={mentionPartTypes('blue', 'caption')}
- />
- <TouchableOpacity
- onPress={() =>
- navigation.navigate('TagFriendsScreen', {
- media: {
- uri: mediaUri,
- isVideo: isMediaAVideo,
- },
- selectedTags: tags,
- })
- }
- style={styles.tagFriendsContainer}>
- <Image
- source={require('../../assets/icons/tagging/tag-icon.png')}
- style={styles.tagIcon}
- />
- <Text style={styles.tagFriendsTitle}>Tag Friends</Text>
- <Text numberOfLines={1} style={styles.taggedListContainer}>
- {taggedList}
- {taggedList.length > 21 ? '. . .' : ''}
- </Text>
- <FrontArrow width={12} height={12} color={'white'} />
- </TouchableOpacity>
</View>
</KeyboardAvoidingView>
</TouchableWithoutFeedback>
@@ -297,48 +384,90 @@ const styles = StyleSheet.create({
color: TAGG_LIGHT_BLUE_2,
},
header: {
- marginVertical: 20,
+ marginTop: 20,
+ marginBottom: 30,
+ },
+ captionContainer: {
+ flexDirection: 'row',
+ padding: normalize(15),
+ marginBottom: normalize(35),
+ borderColor: 'white',
+ borderTopWidth: 1,
+ borderBottomWidth: 1,
+ zIndex: 1,
},
media: {
- position: 'relative',
- width: SCREEN_WIDTH,
- aspectRatio: 1,
- marginBottom: '3%',
+ height: normalize(150),
+ aspectRatio: 9 / 16,
},
text: {
- position: 'relative',
- backgroundColor: 'white',
- width: '100%',
- paddingHorizontal: '2%',
- paddingVertical: '1%',
- height: 60,
+ color: 'white',
+ fontSize: normalize(12),
+ lineHeight: 14,
+ fontWeight: '500',
+ height: normalize(150),
+ marginLeft: normalize(15),
},
flex: {
flex: 1,
},
- tagFriendsTitle: {
+ selectableItemTitle: {
color: 'white',
- fontSize: normalize(12),
+ fontSize: normalize(14),
lineHeight: normalize(16.71),
letterSpacing: normalize(0.3),
fontWeight: '600',
},
- tagFriendsContainer: {
+ selectableItemContainer: {
marginHorizontal: '5%',
- marginTop: '3%',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
+ marginBottom: normalize(42),
},
- taggedListContainer: {
+ asteriskText: {
+ color: TAGG_LIGHT_BLUE_2,
+ fontWeight: 'bold',
+ fontSize: normalize(15),
+ height: 15,
+ alignSelf: 'center',
+ },
+ itemInfoText: {
color: 'white',
width: 150,
fontSize: normalize(10),
lineHeight: normalize(11),
letterSpacing: normalize(0.3),
textAlign: 'right',
+
+ marginRight: 5,
+ },
+ tagIcon: {
+ width: normalize(20),
+ height: normalize(20),
+ marginRight: 15,
+ },
+ row: {
+ flexDirection: 'row',
+ },
+ greyBackground: {
+ backgroundColor: '#C4C4C4',
+ },
+ postButton: {
+ width: SCREEN_WIDTH * 0.8,
+ height: normalize(37),
+ justifyContent: 'center',
+ alignItems: 'center',
+ borderRadius: 6,
+ alignSelf: 'center',
+ },
+ postText: {
+ color: 'white',
+ fontWeight: 'bold',
+ fontSize: normalize(15),
+ lineHeight: 18,
+ letterSpacing: 2,
},
- tagIcon: {width: 20, height: 20},
});
export default CaptionScreen;
diff --git a/src/screens/profile/CategorySelection.tsx b/src/screens/profile/CategorySelection.tsx
index ea443fce..2f364e59 100644
--- a/src/screens/profile/CategorySelection.tsx
+++ b/src/screens/profile/CategorySelection.tsx
@@ -170,6 +170,7 @@ const CategorySelection: React.FC<CategorySelectionProps> = ({
onPress={() => {
navigation.push('CreateCustomCategory', {
existingCategories: momentCategories.concat(selectedCategories),
+ fromScreen: route.name,
});
}}>
<PlusIcon width={30} height={30} color="white" />
diff --git a/src/screens/profile/ChoosingCategoryScreen.tsx b/src/screens/profile/ChoosingCategoryScreen.tsx
new file mode 100644
index 00000000..8a7e3007
--- /dev/null
+++ b/src/screens/profile/ChoosingCategoryScreen.tsx
@@ -0,0 +1,192 @@
+import {useBottomTabBarHeight} from '@react-navigation/bottom-tabs';
+import {RouteProp, useNavigation} from '@react-navigation/native';
+import React, {FC, useEffect} from 'react';
+import {
+ Image,
+ ScrollView,
+ StyleSheet,
+ Text,
+ TouchableOpacity,
+ View,
+} from 'react-native';
+import LinearGradient from 'react-native-linear-gradient';
+import {useDispatch, useSelector} from 'react-redux';
+import FrontArrow from '../../assets/icons/front-arrow.svg';
+import PlusIcon from '../../assets/icons/plus-icon.svg';
+import {SearchBackground, TaggSquareButton} from '../../components';
+import {TAGGS_GRADIENT, TAGG_DARK_PURPLEISH_BLUE} from '../../constants';
+import {MainStackParams} from '../../routes';
+import {updateMomentCategories} from '../../store/actions';
+import {RootState} from '../../store/rootReducer';
+import {
+ getMomentCategoryIconInfo,
+ HeaderHeight,
+ normalize,
+ SCREEN_HEIGHT,
+ SCREEN_WIDTH,
+ StatusBarHeight,
+} from '../../utils';
+
+type ChoosingCategoryScreenRouteProps = RouteProp<
+ MainStackParams,
+ 'ChoosingCategoryScreen'
+>;
+
+interface ChoosingCategoryScreenProps {
+ route: ChoosingCategoryScreenRouteProps;
+}
+
+const ChoosingCategoryScreen: React.FC<ChoosingCategoryScreenProps> = ({
+ route,
+}) => {
+ const {momentCategories} = useSelector(
+ (state: RootState) => state.momentCategories,
+ );
+ const dispatch = useDispatch();
+ const navigation = useNavigation();
+ const tabBarHeight = useBottomTabBarHeight();
+
+ useEffect(() => {
+ if (route.params.newCustomCategory) {
+ dispatch(
+ updateMomentCategories(
+ momentCategories.concat([route.params.newCustomCategory]),
+ false,
+ ),
+ );
+ }
+ }, [route.params.newCustomCategory]);
+
+ const ListItem: FC<{
+ title: string;
+ onPress: () => void;
+ }> = ({title, onPress}) => {
+ const icon = getMomentCategoryIconInfo(title).icon;
+ return (
+ <TouchableOpacity onPress={onPress} style={styles.itemContainer}>
+ <View style={styles.row}>
+ <LinearGradient
+ style={styles.gradientIcon}
+ colors={[TAGGS_GRADIENT.start, TAGGS_GRADIENT.end]}
+ useAngle={true}
+ angle={-45}>
+ <View style={styles.iconBackground}>
+ <Image style={styles.icon} source={icon} />
+ </View>
+ </LinearGradient>
+ <Text style={styles.itemTitle}>{title}</Text>
+ </View>
+ <View style={styles.row}>
+ <FrontArrow
+ width={normalize(13)}
+ height={normalize(13)}
+ color={'white'}
+ />
+ </View>
+ </TouchableOpacity>
+ );
+ };
+
+ return (
+ <SearchBackground>
+ <View style={{marginTop: StatusBarHeight + HeaderHeight}}>
+ <ScrollView
+ style={{height: SCREEN_HEIGHT * 0.9}}
+ contentContainerStyle={{paddingBottom: tabBarHeight}}>
+ {momentCategories.map((title) => (
+ <ListItem
+ key={title}
+ title={title}
+ onPress={() =>
+ navigation.navigate('CaptionScreen', {
+ selectedCategory: title,
+ })
+ }
+ />
+ ))}
+ <TaggSquareButton
+ onPress={() =>
+ navigation.navigate('CreateCustomCategory', {
+ existingCategories: momentCategories,
+ fromScreen: route.name,
+ })
+ }
+ title={'Create a new category'}
+ buttonStyle={'large'}
+ buttonColor={'blue'}
+ labelColor={'white'}
+ style={styles.button}
+ labelStyle={styles.buttonText}
+ icon={<PlusIcon style={styles.plusIcon} />}
+ />
+ </ScrollView>
+ </View>
+ </SearchBackground>
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ marginTop: StatusBarHeight,
+ },
+ itemContainer: {
+ marginHorizontal: '5%',
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ alignItems: 'center',
+ marginVertical: normalize(20),
+ borderRadius: 4,
+ },
+ gradientIcon: {
+ width: normalize(40),
+ height: normalize(40),
+ justifyContent: 'center',
+ alignItems: 'center',
+ borderRadius: 4,
+ },
+ iconBackground: {
+ height: '85%',
+ width: '85%',
+ justifyContent: 'center',
+ alignItems: 'center',
+ backgroundColor: TAGG_DARK_PURPLEISH_BLUE,
+ },
+ icon: {
+ height: normalize(25),
+ width: normalize(25),
+ },
+ itemTitle: {
+ color: 'white',
+ fontSize: normalize(14),
+ lineHeight: normalize(16.71),
+ letterSpacing: normalize(0.3),
+ fontWeight: '600',
+ alignSelf: 'center',
+ marginLeft: normalize(25),
+ },
+ row: {
+ flexDirection: 'row',
+ },
+ button: {
+ width: SCREEN_WIDTH * 0.9,
+ height: normalize(67),
+ justifyContent: 'center',
+ alignItems: 'center',
+ borderRadius: 8,
+ alignSelf: 'center',
+ marginTop: 40,
+ },
+ buttonText: {
+ color: 'white',
+ fontSize: normalize(15),
+ lineHeight: 18,
+ },
+ plusIcon: {
+ color: 'white',
+ marginRight: normalize(25),
+ width: 30,
+ height: 30,
+ },
+});
+
+export default ChoosingCategoryScreen;
diff --git a/src/screens/profile/CreateCustomCategory.tsx b/src/screens/profile/CreateCustomCategory.tsx
index c4b17b1e..91083c7c 100644
--- a/src/screens/profile/CreateCustomCategory.tsx
+++ b/src/screens/profile/CreateCustomCategory.tsx
@@ -37,14 +37,14 @@ const CreateCustomCategory: React.FC<CreateCustomCategoryProps> = ({
/**
* Same component to be used for category selection while onboarding and while on profile
*/
- const {existingCategories} = route.params;
+ const {existingCategories, fromScreen} = route.params;
const [newCategory, setNewCategory] = useState('');
const handleButtonPress = () => {
if (existingCategories.includes(newCategory)) {
Alert.alert('Looks like you already have that one created!');
} else {
- navigation.navigate('CategorySelection', {
+ navigation.navigate(fromScreen, {
newCustomCategory: newCategory,
});
}
diff --git a/src/screens/profile/index.ts b/src/screens/profile/index.ts
index ea0505a2..101101b8 100644
--- a/src/screens/profile/index.ts
+++ b/src/screens/profile/index.ts
@@ -13,3 +13,4 @@ export {default as AccountType} from './AccountType';
export {default as CategorySelection} from './CategorySelection';
export {default as CreateCustomCategory} from './CreateCustomCategory';
export {default as CommentReactionScreen} from './CommentReactionScreen';
+export {default as ChoosingCategoryScreen} from './ChoosingCategoryScreen';