aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/common/TaggPopup.tsx19
-rw-r--r--src/components/common/TaggPrompt.tsx79
-rw-r--r--src/components/common/index.ts1
-rw-r--r--src/components/moments/Moment.tsx28
-rw-r--r--src/components/profile/Content.tsx84
5 files changed, 188 insertions, 23 deletions
diff --git a/src/components/common/TaggPopup.tsx b/src/components/common/TaggPopup.tsx
index db24adb8..86a472b1 100644
--- a/src/components/common/TaggPopup.tsx
+++ b/src/components/common/TaggPopup.tsx
@@ -31,7 +31,11 @@ const TaggPopup: React.FC<TaggPopupProps> = ({route, navigation}) => {
const {messageHeader, messageBody, next} = route.params.popupProps;
return (
- <View style={styles.container}>
+ <TouchableOpacity
+ style={styles.container}
+ onPressOut={() => {
+ navigation.goBack();
+ }}>
<View style={styles.popup}>
<Image
style={styles.icon}
@@ -61,7 +65,7 @@ const TaggPopup: React.FC<TaggPopupProps> = ({route, navigation}) => {
/>
</View>
)}
- </View>
+ </TouchableOpacity>
);
};
@@ -92,23 +96,23 @@ const styles = StyleSheet.create({
},
header: {
color: '#fff',
- fontSize: 16,
+ fontSize: SCREEN_WIDTH / 25,
fontWeight: '600',
textAlign: 'justify',
marginBottom: '2%',
- marginHorizontal: '2%',
+ marginLeft: '4%',
},
subtext: {
color: '#fff',
- fontSize: 12,
+ fontSize: SCREEN_WIDTH / 30,
fontWeight: '600',
textAlign: 'justify',
marginBottom: '15%',
- marginHorizontal: '2%',
+ marginLeft: '3%',
},
popup: {
width: SCREEN_WIDTH * 0.8,
- height: SCREEN_WIDTH * 0.2,
+ height: SCREEN_WIDTH * 0.24,
backgroundColor: 'black',
borderRadius: 8,
flexDirection: 'row',
@@ -116,6 +120,7 @@ const styles = StyleSheet.create({
flexWrap: 'wrap',
position: 'absolute',
bottom: SCREEN_HEIGHT * 0.7,
+ padding: SCREEN_WIDTH / 40,
},
footer: {
marginLeft: '50%',
diff --git a/src/components/common/TaggPrompt.tsx b/src/components/common/TaggPrompt.tsx
new file mode 100644
index 00000000..5cd3ac3f
--- /dev/null
+++ b/src/components/common/TaggPrompt.tsx
@@ -0,0 +1,79 @@
+import * as React from 'react';
+import {Platform, Text, StyleSheet, TouchableOpacity} from 'react-native';
+import {Image, View} from 'react-native-animatable';
+import {SCREEN_HEIGHT} from '../../utils';
+import CloseIcon from '../../assets/ionicons/close-outline.svg';
+
+type TaggPromptProps = {
+ messageHeader: string;
+ messageBody: string;
+ logoType: string;
+ onClose: () => void;
+};
+
+const TaggPrompt: React.FC<TaggPromptProps> = ({
+ messageHeader,
+ messageBody,
+ logoType,
+ onClose,
+}) => {
+ /**
+ * Generic prompt for Tagg
+ */
+
+ return (
+ <View style={styles.container}>
+ <Image
+ style={styles.icon}
+ source={require('../../assets/icons/plus-logo.png')}
+ />
+ <Text style={styles.header}>{messageHeader}</Text>
+ <Text style={styles.subtext}>{messageBody}</Text>
+ <TouchableOpacity
+ style={styles.closeButton}
+ onPress={() => {
+ onClose();
+ }}>
+ <CloseIcon height={'50%'} width={'50%'} color="gray" />
+ </TouchableOpacity>
+ </View>
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flexDirection: 'column',
+ justifyContent: 'center',
+ alignItems: 'center',
+ backgroundColor: 'white',
+ height: SCREEN_HEIGHT / 4.5,
+ paddingTop: SCREEN_HEIGHT / 10,
+ paddingBottom: SCREEN_HEIGHT / 50,
+ },
+ closeButton: {
+ position: 'relative',
+ height: '40%',
+ bottom: SCREEN_HEIGHT / 6,
+ aspectRatio: 1,
+ alignSelf: 'flex-end',
+ },
+ icon: {
+ width: 40,
+ height: 40,
+ },
+ header: {
+ color: 'black',
+ fontSize: 16,
+ fontWeight: '600',
+ textAlign: 'center',
+ marginTop: '2%',
+ },
+ subtext: {
+ color: 'gray',
+ fontSize: 12,
+ fontWeight: '500',
+ textAlign: 'center',
+ marginTop: '2%',
+ },
+});
+export default TaggPrompt;
diff --git a/src/components/common/index.ts b/src/components/common/index.ts
index d5d36297..9162ec70 100644
--- a/src/components/common/index.ts
+++ b/src/components/common/index.ts
@@ -18,3 +18,4 @@ export {default as BottomDrawer} from './BottomDrawer';
export {default as TaggLoadingTndicator} from './TaggLoadingIndicator';
export {default as GenericMoreInfoDrawer} from './GenericMoreInfoDrawer';
export {default as TaggPopUp} from './TaggPopup';
+export {default as TaggPrompt} from './TaggPrompt';
diff --git a/src/components/moments/Moment.tsx b/src/components/moments/Moment.tsx
index be6f78a8..446bc07b 100644
--- a/src/components/moments/Moment.tsx
+++ b/src/components/moments/Moment.tsx
@@ -1,6 +1,13 @@
import {useNavigation} from '@react-navigation/native';
import React from 'react';
-import {Alert, StyleSheet, View} from 'react-native';
+import {
+ Alert,
+ StyleProp,
+ StyleSheet,
+ View,
+ ViewProps,
+ ViewStyle,
+} from 'react-native';
import {Text} from 'react-native-animatable';
import {ScrollView, TouchableOpacity} from 'react-native-gesture-handler';
import LinearGradient from 'react-native-linear-gradient';
@@ -20,6 +27,7 @@ interface MomentProps {
screenType: ScreenType;
handleMomentCategoryDelete: (_: string) => void;
shouldAllowDeletion: boolean;
+ externalStyles?: Record<string, StyleProp<ViewStyle>>;
}
const Moment: React.FC<MomentProps> = ({
@@ -29,6 +37,7 @@ const Moment: React.FC<MomentProps> = ({
screenType,
handleMomentCategoryDelete,
shouldAllowDeletion,
+ externalStyles,
}) => {
const navigation = useNavigation();
@@ -63,9 +72,11 @@ const Moment: React.FC<MomentProps> = ({
});
};
return (
- <View style={styles.container}>
- <View style={styles.header}>
- <Text style={styles.titleText}>{title}</Text>
+ <View style={[styles.container, externalStyles?.container]}>
+ <View style={[styles.header, externalStyles?.header]}>
+ <Text style={[styles.titleText, externalStyles?.titleText]}>
+ {title}
+ </Text>
{!userXId ? (
<>
<PlusIcon
@@ -90,7 +101,7 @@ const Moment: React.FC<MomentProps> = ({
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
- style={styles.scrollContainer}>
+ style={[styles.scrollContainer, externalStyles?.scrollContainer]}>
{images &&
images.map((imageObj: MomentType) => (
<MomentTile
@@ -107,7 +118,7 @@ const Moment: React.FC<MomentProps> = ({
<View style={styles.defaultImage}>
<BigPlusIcon width={24} height={24} />
<Text style={styles.defaultImageText}>
- Add a moment of your {title.toLowerCase()}!
+ Add a moment of your {title?.toLowerCase()}!
</Text>
</View>
</LinearGradient>
@@ -126,12 +137,9 @@ const styles = StyleSheet.create({
},
header: {
flex: 1,
- paddingLeft: '3%',
- padding: 5,
- paddingTop: 20,
+ padding: '3%',
backgroundColor: 'white',
flexDirection: 'row',
- justifyContent: 'space-between',
alignItems: 'center',
},
titleText: {
diff --git a/src/components/profile/Content.tsx b/src/components/profile/Content.tsx
index 5fa05588..227e6783 100644
--- a/src/components/profile/Content.tsx
+++ b/src/components/profile/Content.tsx
@@ -43,8 +43,9 @@ import {
} from '../../store/initialStates';
import {Cover} from '.';
import {TouchableOpacity} from 'react-native-gesture-handler';
-import {useNavigation} from '@react-navigation/native';
+import {useFocusEffect, useNavigation} from '@react-navigation/native';
import GreyPlusLogo from '../../assets/icons/grey-plus-logo.svg';
+import {TaggPrompt} from '../common';
interface ContentProps {
y: Animated.Value<number>;
@@ -97,6 +98,14 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
const [shouldBounce, setShouldBounce] = useState<boolean>(true);
const [refreshing, setRefreshing] = useState<boolean>(false);
+ //These two booleans are used to see if user closed the pormpt displayed to them
+ const [isStageTwoPromptClosed, setIsStageTwoPromptClosed] = useState<boolean>(
+ false,
+ );
+ const [isStageThreePromptClosed, setIsStageThreePromptClosed] = useState<
+ boolean
+ >(false);
+
const onRefresh = useCallback(() => {
const refrestState = async () => {
if (!userXId) {
@@ -134,6 +143,43 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
}, [createImagesMap]);
/**
+ * Prompt user to perform an activity based on their profile completion stage
+ * To fire 2 seconds after the screen comes in focus
+ * 1 means STAGE_1:
+ * The user must upload a moment, so take them to a screen guiding them to post a moment
+ * 2 means STAGE_2:
+ * The user must create another category so show a prompt on top of the screen
+ * 3 means STAGE_3:
+ * The user must upload a moment to the second category, so show a prompt on top of the screen
+ * Else, profile is complete and no prompt needs to be shown
+ */
+ useFocusEffect(
+ useCallback(() => {
+ const navigateToMomentUploadPrompt = () => {
+ switch (profile.profile_completion_stage) {
+ case 1:
+ if (momentCategories && momentCategories[0]) {
+ navigation.navigate('MomentUploadPrompt', {
+ screenType,
+ momentCategory: momentCategories[0],
+ });
+ }
+ break;
+ case 2:
+ setIsStageTwoPromptClosed(false);
+ break;
+ case 3:
+ setIsStageThreePromptClosed(false);
+ break;
+ default:
+ break;
+ }
+ };
+ setTimeout(navigateToMomentUploadPrompt, 2000);
+ }, [profile.profile_completion_stage, momentCategories]),
+ );
+
+ /**
* This hook is called on load of profile and when you update the friends list.
*/
useEffect(() => {
@@ -227,10 +273,8 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
onPress: () => {
dispatch(
updateMomentCategories(
- momentCategories.filter(
- (mc) => mc !== category,
- loggedInUser.userId,
- ),
+ momentCategories.filter((mc) => mc !== category),
+ false,
),
);
dispatch(deleteUserMomentsForCategory(category));
@@ -296,6 +340,34 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
} has not posted any moments yet`}</Text>
</View>
)}
+ {!userXId &&
+ profile.profile_completion_stage === 2 &&
+ !isStageTwoPromptClosed && (
+ <TaggPrompt
+ messageHeader="Create a new category"
+ messageBody={
+ 'Post your first moment to continue building your digital identity!'
+ }
+ logoType=""
+ onClose={() => {
+ setIsStageTwoPromptClosed(true);
+ }}
+ />
+ )}
+ {!userXId &&
+ profile.profile_completion_stage === 3 &&
+ !isStageThreePromptClosed && (
+ <TaggPrompt
+ messageHeader="Continue to build your profile"
+ messageBody={
+ 'Continue to personalize your own digital space in\nthis community by filling your profile with\ncategories and moments!'
+ }
+ logoType=""
+ onClose={() => {
+ setIsStageThreePromptClosed(true);
+ }}
+ />
+ )}
{momentCategories.map(
(title, index) =>
(!userXId || imagesMap.get(title)) && (
@@ -310,7 +382,7 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
/>
),
)}
- {!userXId && (
+ {!userXId && profile.profile_completion_stage !== 1 && (
<TouchableOpacity
onPress={() =>
navigation.push('CategorySelection', {