aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/assets/icons/back-arrow.svg1
-rw-r--r--src/assets/icons/up_arrow.svg1
-rw-r--r--src/components/comments/AddComment.tsx155
-rw-r--r--src/components/common/AcceptDeclineButtons.tsx8
-rw-r--r--src/components/common/GenericMoreInfoDrawer.tsx4
-rw-r--r--src/components/common/SocialLinkModal.tsx4
-rw-r--r--src/components/moments/Moment.tsx19
-rw-r--r--src/components/moments/MomentPostContent.tsx1
-rw-r--r--src/components/onboarding/TaggBigInput.tsx12
-rw-r--r--src/components/profile/Content.tsx91
-rw-r--r--src/components/profile/FriendsCount.tsx5
-rw-r--r--src/components/profile/ProfileBody.tsx17
-rw-r--r--src/components/profile/ProfileHeader.tsx44
-rw-r--r--src/components/profile/ProfileMoreInfoDrawer.tsx5
-rw-r--r--src/components/profile/ProfilePreview.tsx33
-rw-r--r--src/components/profile/ToggleButton.tsx8
-rw-r--r--src/components/profile/UniversityIcon.tsx12
-rw-r--r--src/components/search/Explore.tsx4
-rw-r--r--src/components/search/ExploreSection.tsx3
-rw-r--r--src/components/search/ExploreSectionUser.tsx6
-rw-r--r--src/components/search/RecentSearches.tsx4
-rw-r--r--src/components/taggs/Tagg.tsx3
-rw-r--r--src/components/taggs/TwitterTaggPost.tsx4
-rw-r--r--src/constants/constants.ts16
-rw-r--r--src/constants/strings.ts15
-rw-r--r--src/routes/main/MainStackScreen.tsx13
-rw-r--r--src/screens/profile/EditProfile.tsx48
-rw-r--r--src/screens/profile/MomentCommentsScreen.tsx149
-rw-r--r--src/screens/profile/MomentUploadPromptScreen.tsx8
-rw-r--r--src/screens/search/SearchScreen.tsx5
-rw-r--r--src/services/MomentServices.ts7
-rw-r--r--src/utils/index.ts3
-rw-r--r--src/utils/layouts.ts48
-rw-r--r--src/utils/screenDimensions.ts6
-rw-r--r--src/utils/statusBarHeight.ts28
35 files changed, 425 insertions, 365 deletions
diff --git a/src/assets/icons/back-arrow.svg b/src/assets/icons/back-arrow.svg
new file mode 100644
index 00000000..aa203dea
--- /dev/null
+++ b/src/assets/icons/back-arrow.svg
@@ -0,0 +1 @@
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 385.86 696.76"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:77.17px;}</style></defs><polyline class="cls-1" points="347.28 38.58 38.58 351.69 347.28 658.17"/></svg> \ No newline at end of file
diff --git a/src/assets/icons/up_arrow.svg b/src/assets/icons/up_arrow.svg
new file mode 100644
index 00000000..fc92b551
--- /dev/null
+++ b/src/assets/icons/up_arrow.svg
@@ -0,0 +1 @@
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 792 792"><defs></defs><path class="cls-1" d="M522.58,375.86l-18.19,16.86a13.06,13.06,0,0,1-18.46-.68l-62.6-67.45v219a22,22,0,0,1-22,22H393.1a22,22,0,0,1-22-22V322l-65,70.05a13.11,13.11,0,0,1-18.5.68l-18.19-16.86a13.12,13.12,0,0,1-.68-18.51l96.52-104,20.39-22,1.52-1.4a13.6,13.6,0,0,1,2.52-1.85,14.44,14.44,0,0,1,2.85-1.16,2.18,2.18,0,0,1,.88-.2,6.27,6.27,0,0,1,1.2-.2,11.3,11.3,0,0,1,1.16-.08h.44a11.3,11.3,0,0,1,1.16.08,6.58,6.58,0,0,1,1.28.2,4.48,4.48,0,0,1,.92.24c.48.12.93.32,1.41.48l1,.48a13.24,13.24,0,0,1,2.84,2l1.52,1.4,20.43,22,96.48,104A13.12,13.12,0,0,1,522.58,375.86Z" fill="currentColor"/></svg> \ No newline at end of file
diff --git a/src/components/comments/AddComment.tsx b/src/components/comments/AddComment.tsx
index f8c0b6bc..24b3473c 100644
--- a/src/components/comments/AddComment.tsx
+++ b/src/components/comments/AddComment.tsx
@@ -1,17 +1,19 @@
-import * as React from 'react';
+import React, {useEffect} from 'react';
import {
Image,
+ Keyboard,
KeyboardAvoidingView,
Platform,
StyleSheet,
View,
} from 'react-native';
-import AsyncStorage from '@react-native-community/async-storage';
-import {TaggBigInput} from '../onboarding';
+import {TextInput, TouchableOpacity} from 'react-native-gesture-handler';
+import {useSelector} from 'react-redux';
+import UpArrowIcon from '../../assets/icons/up_arrow.svg';
+import {TAGG_LIGHT_BLUE} from '../../constants';
import {postMomentComment} from '../../services';
-import {logout} from '../../store/actions';
-import {useSelector, useDispatch} from 'react-redux';
import {RootState} from '../../store/rootreducer';
+import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
/**
* This file provides the add comment view for a user.
@@ -29,87 +31,114 @@ const AddComment: React.FC<AddCommentProps> = ({
moment_id,
}) => {
const [comment, setComment] = React.useState('');
+ const [keyboardVisible, setKeyboardVisible] = React.useState(false);
- const dispatch = useDispatch();
const {
avatar,
user: {userId},
} = useSelector((state: RootState) => state.user);
- const handleCommentUpdate = (comment: string) => {
- setComment(comment);
- };
-
const postComment = async () => {
- try {
- const token = await AsyncStorage.getItem('token');
- if (!token) {
- dispatch(logout());
- return;
- }
- const postedComment = await postMomentComment(
- userId,
- comment,
- moment_id,
- token,
- );
+ const postedComment = await postMomentComment(
+ userId,
+ comment.trim(),
+ moment_id,
+ );
- if (postedComment) {
- //Set the current comment to en empty string if the comment was posted successfully.
- handleCommentUpdate('');
-
- //Indicate the MomentCommentsScreen that it needs to download the new comments again
- setNewCommentsAvailable(true);
- }
- } catch (err) {
- console.log('Error while posting comment!');
+ if (postedComment) {
+ setComment('');
+ setNewCommentsAvailable(true);
}
};
+ useEffect(() => {
+ const showKeyboard = () => setKeyboardVisible(true);
+ Keyboard.addListener('keyboardWillShow', showKeyboard);
+ return () => Keyboard.removeListener('keyboardWillShow', showKeyboard);
+ }, []);
+
+ useEffect(() => {
+ const hideKeyboard = () => setKeyboardVisible(false);
+ Keyboard.addListener('keyboardWillHide', hideKeyboard);
+ return () => Keyboard.removeListener('keyboardWillHide', hideKeyboard);
+ }, []);
+
return (
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
- keyboardVerticalOffset={130}>
- <View style={styles.container}>
- <Image
- style={styles.avatar}
- source={
- avatar
- ? {uri: avatar}
- : require('../../assets/images/avatar-placeholder.png')
- }
- />
- <TaggBigInput
- style={styles.text}
- multiline
- placeholder="Add a comment....."
- placeholderTextColor="gray"
- onChangeText={handleCommentUpdate}
- onSubmitEditing={postComment}
- value={comment}
- />
+ keyboardVerticalOffset={SCREEN_HEIGHT * 0.1}>
+ <View
+ style={[
+ styles.container,
+ keyboardVisible ? {backgroundColor: '#fff'} : {},
+ ]}>
+ <View style={styles.textContainer}>
+ <Image
+ style={styles.avatar}
+ source={
+ avatar
+ ? {uri: avatar}
+ : require('../../assets/images/avatar-placeholder.png')
+ }
+ />
+ <TextInput
+ style={styles.text}
+ placeholder="Add a comment..."
+ placeholderTextColor="grey"
+ onChangeText={setComment}
+ value={comment}
+ autoCorrect={false}
+ multiline={true}
+ />
+ <View style={styles.submitButton}>
+ <TouchableOpacity style={styles.submitButton} onPress={postComment}>
+ <UpArrowIcon width={35} height={35} color={'white'} />
+ </TouchableOpacity>
+ </View>
+ </View>
</View>
</KeyboardAvoidingView>
);
};
const styles = StyleSheet.create({
- container: {flexDirection: 'row'},
+ container: {
+ backgroundColor: '#f7f7f7',
+ alignItems: 'center',
+ width: SCREEN_WIDTH,
+ },
+ textContainer: {
+ width: '95%',
+ flexDirection: 'row',
+ backgroundColor: '#e8e8e8',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ margin: '3%',
+ borderRadius: 25,
+ },
text: {
- position: 'relative',
- right: '18%',
- backgroundColor: 'white',
- width: '70%',
- paddingLeft: '2%',
- paddingRight: '2%',
- paddingBottom: '1%',
- paddingTop: '1%',
- height: 60,
+ flex: 1,
+ padding: '1%',
+ marginHorizontal: '1%',
},
avatar: {
- height: 40,
- width: 40,
+ height: 35,
+ width: 35,
borderRadius: 30,
- marginRight: 15,
+ marginRight: 10,
+ marginLeft: '3%',
+ marginVertical: '2%',
+ alignSelf: 'flex-end',
+ },
+ submitButton: {
+ height: 35,
+ width: 35,
+ backgroundColor: TAGG_LIGHT_BLUE,
+ borderRadius: 999,
+ justifyContent: 'center',
+ alignItems: 'center',
+ marginRight: '3%',
+ marginVertical: '2%',
+ alignSelf: 'flex-end',
},
});
diff --git a/src/components/common/AcceptDeclineButtons.tsx b/src/components/common/AcceptDeclineButtons.tsx
index 221056c0..9caaffca 100644
--- a/src/components/common/AcceptDeclineButtons.tsx
+++ b/src/components/common/AcceptDeclineButtons.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import {StyleProp, StyleSheet, Text, View, ViewStyle} from 'react-native';
-import {TAGG_TEXT_LIGHT_BLUE} from '../../constants';
+import {TAGG_LIGHT_BLUE} from '../../constants';
import {ProfilePreviewType} from '../../types';
import {SCREEN_WIDTH} from '../../utils';
import {TouchableOpacity} from 'react-native-gesture-handler';
@@ -55,18 +55,18 @@ const styles = StyleSheet.create({
},
acceptButton: {
padding: 0,
- backgroundColor: TAGG_TEXT_LIGHT_BLUE,
+ backgroundColor: TAGG_LIGHT_BLUE,
},
rejectButton: {
borderWidth: 1,
backgroundColor: 'white',
- borderColor: TAGG_TEXT_LIGHT_BLUE,
+ borderColor: TAGG_LIGHT_BLUE,
},
acceptButtonTitleColor: {
color: 'white',
},
rejectButtonTitleColor: {
- color: TAGG_TEXT_LIGHT_BLUE,
+ color: TAGG_LIGHT_BLUE,
},
buttonTitle: {
padding: 0,
diff --git a/src/components/common/GenericMoreInfoDrawer.tsx b/src/components/common/GenericMoreInfoDrawer.tsx
index 098482ae..a23d7736 100644
--- a/src/components/common/GenericMoreInfoDrawer.tsx
+++ b/src/components/common/GenericMoreInfoDrawer.tsx
@@ -10,7 +10,7 @@ import {
} from 'react-native';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import {BottomDrawer} from '.';
-import {TAGG_TEXT_LIGHT_BLUE} from '../../constants';
+import {TAGG_LIGHT_BLUE} from '../../constants';
import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
// conforms the JSX onPress attribute type
@@ -87,7 +87,7 @@ const styles = StyleSheet.create({
panelButtonTitleCancel: {
fontSize: 18,
fontWeight: 'bold',
- color: TAGG_TEXT_LIGHT_BLUE,
+ color: TAGG_LIGHT_BLUE,
},
divider: {height: 1, borderWidth: 1, borderColor: '#e7e7e7'},
});
diff --git a/src/components/common/SocialLinkModal.tsx b/src/components/common/SocialLinkModal.tsx
index b307a62c..41b044fe 100644
--- a/src/components/common/SocialLinkModal.tsx
+++ b/src/components/common/SocialLinkModal.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import {Modal, StyleSheet, Text, TouchableHighlight, View} from 'react-native';
import {TextInput} from 'react-native-gesture-handler';
-import { TAGG_TEXT_LIGHT_BLUE } from '../../constants';
+import { TAGG_LIGHT_BLUE } from '../../constants';
import {SCREEN_WIDTH} from '../../utils';
interface SocialLinkModalProps {
@@ -105,7 +105,7 @@ const styles = StyleSheet.create({
fontSize: 14,
/* identical to box height */
textAlign: 'center',
- color: TAGG_TEXT_LIGHT_BLUE,
+ color: TAGG_LIGHT_BLUE,
},
textInput: {
height: 20,
diff --git a/src/components/moments/Moment.tsx b/src/components/moments/Moment.tsx
index 7905e8a9..a6b553b1 100644
--- a/src/components/moments/Moment.tsx
+++ b/src/components/moments/Moment.tsx
@@ -11,9 +11,9 @@ import DownIcon from '../../assets/icons/down_icon.svg';
import PlusIcon from '../../assets/icons/plus_icon-01.svg';
import BigPlusIcon from '../../assets/icons/plus_icon-02.svg';
import UpIcon from '../../assets/icons/up_icon.svg';
-import {TAGG_TEXT_LIGHT_BLUE} from '../../constants';
+import {TAGG_LIGHT_BLUE} from '../../constants';
import {ERROR_UPLOAD_MOMENT_SHORT} from '../../constants/strings';
-import {SCREEN_WIDTH} from '../../utils';
+import {normalize, SCREEN_WIDTH} from '../../utils';
import MomentTile from './MomentTile';
interface MomentProps {
@@ -87,7 +87,7 @@ const Moment: React.FC<MomentProps> = ({
width={19}
height={19}
onPress={() => move('up', title)}
- color={TAGG_TEXT_LIGHT_BLUE}
+ color={TAGG_LIGHT_BLUE}
style={{marginLeft: 5}}
/>
)}
@@ -96,7 +96,7 @@ const Moment: React.FC<MomentProps> = ({
width={19}
height={19}
onPress={() => move('down', title)}
- color={TAGG_TEXT_LIGHT_BLUE}
+ color={TAGG_LIGHT_BLUE}
style={{marginLeft: 5}}
/>
)}
@@ -111,7 +111,7 @@ const Moment: React.FC<MomentProps> = ({
width={21}
height={21}
onPress={() => navigateToImagePicker()}
- color={TAGG_TEXT_LIGHT_BLUE}
+ color={TAGG_LIGHT_BLUE}
style={{marginRight: 10}}
/>
{shouldAllowDeletion && (
@@ -171,15 +171,10 @@ const styles = StyleSheet.create({
alignItems: 'center',
},
titleText: {
- fontSize: 16,
+ fontSize: normalize(16),
fontWeight: 'bold',
- color: TAGG_TEXT_LIGHT_BLUE,
+ color: TAGG_LIGHT_BLUE,
},
- // titleContainer: {
- // flex: 1,
- // flexDirection: 'row',
- // justifyContent: 'flex-end',
- // },
flexer: {
flex: 1,
},
diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx
index 93271fa1..508b6d9f 100644
--- a/src/components/moments/MomentPostContent.tsx
+++ b/src/components/moments/MomentPostContent.tsx
@@ -27,6 +27,7 @@ const MomentPostContent: React.FC<MomentPostContentProps> = ({
setElapsedTime(getTimePosted(dateTime));
getMomentCommentsCount(momentId, setCommentsCount);
}, [dateTime, momentId]);
+
return (
<View style={[styles.container, style]}>
<Image
diff --git a/src/components/onboarding/TaggBigInput.tsx b/src/components/onboarding/TaggBigInput.tsx
index 4e8e1ef7..0e42bd13 100644
--- a/src/components/onboarding/TaggBigInput.tsx
+++ b/src/components/onboarding/TaggBigInput.tsx
@@ -1,5 +1,11 @@
import React from 'react';
-import {View, TextInput, StyleSheet, TextInputProps} from 'react-native';
+import {
+ View,
+ TextInput,
+ StyleSheet,
+ TextInputProps,
+ ViewStyle,
+} from 'react-native';
import * as Animatable from 'react-native-animatable';
import {TAGG_LIGHT_PURPLE} from '../../constants';
@@ -8,13 +14,15 @@ interface TaggBigInputProps extends TextInputProps {
invalidWarning?: string;
attemptedSubmit?: boolean;
width?: number | string;
+ containerStyle?: ViewStyle;
}
/**
* An input component that receives all props a normal TextInput component does. TaggInput components grow to 60% of their parent's width by default, but this can be set using the `width` prop.
*/
const TaggBigInput = React.forwardRef((props: TaggBigInputProps, ref: any) => {
return (
- <View style={styles.container}>
+ <View
+ style={props.containerStyle ? props.containerStyle : styles.container}>
<TextInput
style={[{width: props.width}, styles.input]}
placeholderTextColor="#ddd"
diff --git a/src/components/profile/Content.tsx b/src/components/profile/Content.tsx
index e7fb566b..a35a5820 100644
--- a/src/components/profile/Content.tsx
+++ b/src/components/profile/Content.tsx
@@ -1,3 +1,4 @@
+import {useFocusEffect, useNavigation} from '@react-navigation/native';
import React, {useCallback, useEffect, useState} from 'react';
import {
Alert,
@@ -9,52 +10,49 @@ import {
Text,
View,
} from 'react-native';
+import {TouchableOpacity} from 'react-native-gesture-handler';
import Animated from 'react-native-reanimated';
+import {useDispatch, useSelector, useStore} from 'react-redux';
+import {Cover} from '.';
+import GreyPlusLogo from '../../assets/icons/grey-plus-logo.svg';
+import {COVER_HEIGHT, TAGG_LIGHT_BLUE} from '../../constants';
import {
- CategorySelectionScreenType,
- FriendshipStatusType,
- MomentCategoryType,
- MomentType,
- ProfilePreviewType,
- ProfileType,
- ScreenType,
- UserType,
-} from '../../types';
-import {COVER_HEIGHT, TAGG_TEXT_LIGHT_BLUE} from '../../constants';
+ UPLOAD_MOMENT_PROMPT_THREE_HEADER,
+ UPLOAD_MOMENT_PROMPT_THREE_MESSAGE,
+ UPLOAD_MOMENT_PROMPT_TWO_HEADER,
+ UPLOAD_MOMENT_PROMPT_TWO_MESSAGE,
+} from '../../constants/strings';
+import {
+ blockUnblockUser,
+ deleteUserMomentsForCategory,
+ friendUnfriendUser,
+ loadFriendsData,
+ updateMomentCategories,
+ updateUserXFriends,
+ updateUserXProfileAllScreens,
+} from '../../store/actions';
+import {
+ EMPTY_MOMENTS_LIST,
+ EMPTY_PROFILE_PREVIEW_LIST,
+ NO_PROFILE,
+ NO_USER,
+} from '../../store/initialStates';
+import {RootState} from '../../store/rootreducer';
+import {CategorySelectionScreenType, MomentType, ScreenType} from '../../types';
import {
fetchUserX,
getUserAsProfilePreviewType,
moveCategory,
+ normalize,
SCREEN_HEIGHT,
userLogin,
} from '../../utils';
-import TaggsBar from '../taggs/TaggsBar';
+import {TaggPrompt} from '../common';
import {Moment} from '../moments';
+import TaggsBar from '../taggs/TaggsBar';
import ProfileBody from './ProfileBody';
import ProfileCutout from './ProfileCutout';
import ProfileHeader from './ProfileHeader';
-import {useDispatch, useSelector, useStore} from 'react-redux';
-import {RootState} from '../../store/rootreducer';
-import {
- friendUnfriendUser,
- blockUnblockUser,
- loadFriendsData,
- updateUserXFriends,
- updateMomentCategories,
- deleteUserMomentsForCategory,
- updateUserXProfileAllScreens,
-} from '../../store/actions';
-import {
- NO_USER,
- NO_PROFILE,
- EMPTY_PROFILE_PREVIEW_LIST,
- EMPTY_MOMENTS_LIST,
-} from '../../store/initialStates';
-import {Cover} from '.';
-import {TouchableOpacity} from 'react-native-gesture-handler';
-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>;
@@ -113,9 +111,10 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
const [isStageOnePromptClosed, setIsStageOnePromptClosed] = useState<boolean>(
false,
);
- const [isStageThreePromptClosed, setIsStageThreePromptClosed] = useState<
- boolean
- >(false);
+ const [
+ isStageThreePromptClosed,
+ setIsStageThreePromptClosed,
+ ] = useState<boolean>(false);
const onRefresh = useCallback(() => {
const refrestState = async () => {
@@ -284,7 +283,7 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
momentCategories.filter((mc) => mc !== category),
false,
),
- )
+ );
dispatch(deleteUserMomentsForCategory(category));
},
},
@@ -352,10 +351,8 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
profile.profile_completion_stage === 2 &&
!isStageTwoPromptClosed && (
<TaggPrompt
- messageHeader="Create a new category"
- messageBody={
- 'Post your first moment to continue building your digital identity!'
- }
+ messageHeader={UPLOAD_MOMENT_PROMPT_TWO_HEADER}
+ messageBody={UPLOAD_MOMENT_PROMPT_TWO_MESSAGE}
logoType=""
onClose={() => {
setIsStageTwoPromptClosed(true);
@@ -366,10 +363,8 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
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!'
- }
+ messageHeader={UPLOAD_MOMENT_PROMPT_THREE_HEADER}
+ messageBody={UPLOAD_MOMENT_PROMPT_THREE_MESSAGE}
logoType=""
onClose={() => {
setIsStageThreePromptClosed(true);
@@ -423,7 +418,7 @@ const styles = StyleSheet.create({
flexDirection: 'column',
},
createCategoryButton: {
- backgroundColor: TAGG_TEXT_LIGHT_BLUE,
+ backgroundColor: TAGG_LIGHT_BLUE,
justifyContent: 'center',
alignItems: 'center',
width: '70%',
@@ -432,7 +427,7 @@ const styles = StyleSheet.create({
alignSelf: 'center',
},
createCategoryButtonLabel: {
- fontSize: 16,
+ fontSize: normalize(16),
fontWeight: '500',
color: 'white',
},
@@ -443,7 +438,7 @@ const styles = StyleSheet.create({
marginVertical: '10%',
},
noMomentsText: {
- fontSize: 14,
+ fontSize: normalize(14),
fontWeight: 'bold',
color: 'gray',
marginVertical: '8%',
diff --git a/src/components/profile/FriendsCount.tsx b/src/components/profile/FriendsCount.tsx
index 23a24787..9647710e 100644
--- a/src/components/profile/FriendsCount.tsx
+++ b/src/components/profile/FriendsCount.tsx
@@ -5,6 +5,7 @@ import {useNavigation} from '@react-navigation/native';
import {RootState} from '../../store/rootReducer';
import {useSelector} from 'react-redux';
import {ScreenType} from '../../types';
+import {normalize} from '../../utils';
interface FriendsCountProps extends ViewProps {
userXId: string | undefined;
@@ -55,11 +56,11 @@ const styles = StyleSheet.create({
},
count: {
fontWeight: '700',
- fontSize: 13,
+ fontSize: normalize(14),
},
label: {
fontWeight: '500',
- fontSize: 13,
+ fontSize: normalize(14),
},
});
diff --git a/src/components/profile/ProfileBody.tsx b/src/components/profile/ProfileBody.tsx
index 6284ff59..d10e2e15 100644
--- a/src/components/profile/ProfileBody.tsx
+++ b/src/components/profile/ProfileBody.tsx
@@ -1,9 +1,9 @@
import React from 'react';
import {StyleSheet, View, Text, LayoutChangeEvent, Linking} from 'react-native';
-import {Button} from 'react-native-elements';
+import {Button, normalize} from 'react-native-elements';
import {
TAGG_DARK_BLUE,
- TAGG_TEXT_LIGHT_BLUE,
+ TAGG_LIGHT_BLUE,
TOGGLE_BUTTON_TYPE,
} from '../../constants';
import ToggleButton from './ToggleButton';
@@ -160,16 +160,15 @@ const styles = StyleSheet.create({
},
username: {
fontWeight: '600',
- fontSize: 16.5,
+ fontSize: normalize(12),
marginBottom: '1%',
- marginTop: '-3%',
},
biography: {
- fontSize: 16,
+ fontSize: normalize(12),
marginBottom: '1.5%',
},
website: {
- fontSize: 16,
+ fontSize: normalize(12),
color: TAGG_DARK_BLUE,
marginBottom: '1%',
},
@@ -178,7 +177,7 @@ const styles = StyleSheet.create({
alignItems: 'center',
width: SCREEN_WIDTH * 0.4,
height: SCREEN_WIDTH * 0.09,
- borderColor: TAGG_TEXT_LIGHT_BLUE,
+ borderColor: TAGG_LIGHT_BLUE,
borderWidth: 3,
borderRadius: 5,
marginRight: '2%',
@@ -186,7 +185,7 @@ const styles = StyleSheet.create({
backgroundColor: 'transparent',
},
requestedButtonTitle: {
- color: TAGG_TEXT_LIGHT_BLUE,
+ color: TAGG_LIGHT_BLUE,
padding: 0,
fontSize: 14,
fontWeight: '700',
@@ -205,7 +204,7 @@ const styles = StyleSheet.create({
padding: 0,
borderRadius: 5,
marginRight: '2%',
- backgroundColor: TAGG_TEXT_LIGHT_BLUE,
+ backgroundColor: TAGG_LIGHT_BLUE,
},
});
diff --git a/src/components/profile/ProfileHeader.tsx b/src/components/profile/ProfileHeader.tsx
index 8d502d97..7dad2a68 100644
--- a/src/components/profile/ProfileHeader.tsx
+++ b/src/components/profile/ProfileHeader.tsx
@@ -2,10 +2,10 @@ import React, {useState} from 'react';
import {StyleSheet, Text, View} from 'react-native';
import {useSelector} from 'react-redux';
import {UniversityIcon} from '.';
-import {NO_MOMENTS} from '../../store/initialStates';
+import {PROFILE_CUTOUT_TOP_Y} from '../../constants';
import {RootState} from '../../store/rootreducer';
import {ScreenType} from '../../types';
-import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
+import {normalize} from '../../utils';
import Avatar from './Avatar';
import FriendsCount from './FriendsCount';
import ProfileMoreInfoDrawer from './ProfileMoreInfoDrawer';
@@ -31,7 +31,6 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({
: useSelector((state: RootState) => state.user);
const [drawerVisible, setDrawerVisible] = useState(false);
const [firstName, lastName] = [...name.split(' ')];
-
return (
<View style={styles.container}>
<ProfileMoreInfoDrawer
@@ -59,13 +58,8 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({
</View>
)}
<View style={styles.friendsAndUniversity}>
- <FriendsCount
- style={styles.friends}
- screenType={screenType}
- userXId={userXId}
- />
+ <FriendsCount screenType={screenType} userXId={userXId} />
<UniversityIcon
- style={styles.university}
university="brown"
university_class={university_class}
/>
@@ -78,7 +72,7 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({
const styles = StyleSheet.create({
container: {
- top: SCREEN_HEIGHT / 2.4,
+ top: PROFILE_CUTOUT_TOP_Y * 1.02,
width: '100%',
position: 'absolute',
},
@@ -87,35 +81,27 @@ const styles = StyleSheet.create({
},
header: {
flexDirection: 'column',
- justifyContent: 'center',
+ justifyContent: 'space-evenly',
alignItems: 'center',
- marginTop: SCREEN_WIDTH / 18.2,
- marginLeft: SCREEN_WIDTH / 8,
- marginBottom: SCREEN_WIDTH / 50,
+ marginRight: '15%',
+ marginLeft: '5%',
+ flex: 1,
},
avatar: {
- bottom: SCREEN_WIDTH / 80,
- left: '10%',
+ marginLeft: '3%',
+ top: '-8%',
},
name: {
- marginLeft: SCREEN_WIDTH / 8,
- fontSize: 17,
+ fontSize: normalize(17),
fontWeight: '500',
alignSelf: 'center',
},
- friends: {
- alignSelf: 'flex-start',
- marginRight: SCREEN_WIDTH / 20,
- },
- university: {
- alignSelf: 'flex-end',
- bottom: 3,
- },
friendsAndUniversity: {
flexDirection: 'row',
- flex: 1,
- marginLeft: SCREEN_WIDTH / 10,
- marginTop: SCREEN_WIDTH / 40,
+ alignItems: 'center',
+ justifyContent: 'space-evenly',
+ width: '100%',
+ height: 50,
},
});
diff --git a/src/components/profile/ProfileMoreInfoDrawer.tsx b/src/components/profile/ProfileMoreInfoDrawer.tsx
index 76f0f27f..daa83eb3 100644
--- a/src/components/profile/ProfileMoreInfoDrawer.tsx
+++ b/src/components/profile/ProfileMoreInfoDrawer.tsx
@@ -4,7 +4,7 @@ import {StyleSheet, TouchableOpacity} from 'react-native';
import {useSelector} from 'react-redux';
import MoreIcon from '../../assets/icons/more_horiz-24px.svg';
import PersonOutline from '../../assets/ionicons/person-outline.svg';
-import {TAGG_DARK_BLUE, TAGG_TEXT_LIGHT_BLUE} from '../../constants';
+import {TAGG_DARK_BLUE, TAGG_LIGHT_BLUE} from '../../constants';
import {RootState} from '../../store/rootreducer';
import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
import {GenericMoreInfoDrawer} from '../common';
@@ -101,13 +101,12 @@ const styles = StyleSheet.create({
panelButtonTitleCancel: {
fontSize: 18,
fontWeight: 'bold',
- color: TAGG_TEXT_LIGHT_BLUE,
+ color: TAGG_LIGHT_BLUE,
},
divider: {height: 1, borderWidth: 1, borderColor: '#e7e7e7'},
more: {
position: 'absolute',
right: '5%',
- marginTop: '4%',
zIndex: 1,
},
});
diff --git a/src/components/profile/ProfilePreview.tsx b/src/components/profile/ProfilePreview.tsx
index b2c0a24d..389ca367 100644
--- a/src/components/profile/ProfilePreview.tsx
+++ b/src/components/profile/ProfilePreview.tsx
@@ -1,27 +1,26 @@
-import React, {useEffect, useState, useContext} from 'react';
-import {ProfilePreviewType, ScreenType} from '../../types';
+import AsyncStorage from '@react-native-community/async-storage';
+import {useNavigation} from '@react-navigation/native';
+import React, {useEffect, useState} from 'react';
import {
- View,
- Text,
+ Alert,
Image,
StyleSheet,
- ViewProps,
+ Text,
TouchableOpacity,
- Alert,
+ View,
+ ViewProps,
} from 'react-native';
-import {useNavigation} from '@react-navigation/native';
-import RNFetchBlob from 'rn-fetch-blob';
-import AsyncStorage from '@react-native-community/async-storage';
-import {PROFILE_PHOTO_THUMBNAIL_ENDPOINT} from '../../constants';
-import {UserType, PreviewType} from '../../types';
-import {isUserBlocked, loadAvatar} from '../../services';
-import {useSelector, useDispatch, useStore} from 'react-redux';
+import {useDispatch, useSelector, useStore} from 'react-redux';
+import {ERROR_UNABLE_TO_VIEW_PROFILE} from '../../constants/strings';
+import {loadAvatar} from '../../services';
import {RootState} from '../../store/rootreducer';
-import {logout} from '../../store/actions';
+import {
+ PreviewType,
+ ProfilePreviewType,
+ ScreenType,
+ UserType,
+} from '../../types';
import {checkIfUserIsBlocked, fetchUserX, userXInStore} from '../../utils';
-import {SearchResultsBackground} from '../search';
-import NavigationBar from 'src/routes/tabs';
-import {ERROR_UNABLE_TO_VIEW_PROFILE} from '../../constants/strings';
const NO_USER: UserType = {
userId: '',
diff --git a/src/components/profile/ToggleButton.tsx b/src/components/profile/ToggleButton.tsx
index 5d8f7874..236d811c 100644
--- a/src/components/profile/ToggleButton.tsx
+++ b/src/components/profile/ToggleButton.tsx
@@ -1,7 +1,7 @@
import * as React from 'react';
import {StyleSheet, Text} from 'react-native';
import {TouchableOpacity} from 'react-native-gesture-handler';
-import {TAGG_TEXT_LIGHT_BLUE} from '../../constants';
+import {TAGG_LIGHT_BLUE} from '../../constants';
import {getToggleButtonText, SCREEN_WIDTH} from '../../utils';
type ToggleButtonProps = {
@@ -36,7 +36,7 @@ const styles = StyleSheet.create({
alignItems: 'center',
width: SCREEN_WIDTH * 0.4,
height: SCREEN_WIDTH * 0.08,
- borderColor: TAGG_TEXT_LIGHT_BLUE,
+ borderColor: TAGG_LIGHT_BLUE,
borderWidth: 3,
borderRadius: 5,
marginRight: '2%',
@@ -45,10 +45,10 @@ const styles = StyleSheet.create({
fontWeight: 'bold',
},
buttonColor: {
- backgroundColor: TAGG_TEXT_LIGHT_BLUE,
+ backgroundColor: TAGG_LIGHT_BLUE,
},
textColor: {color: 'white'},
buttonColorToggled: {backgroundColor: 'white'},
- textColorToggled: {color: TAGG_TEXT_LIGHT_BLUE},
+ textColorToggled: {color: TAGG_LIGHT_BLUE},
});
export default ToggleButton;
diff --git a/src/components/profile/UniversityIcon.tsx b/src/components/profile/UniversityIcon.tsx
index 13586359..95aef8b9 100644
--- a/src/components/profile/UniversityIcon.tsx
+++ b/src/components/profile/UniversityIcon.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import {StyleSheet, ViewProps} from 'react-native';
import {Image, Text, View} from 'react-native-animatable';
-import {getUniversityClass} from '../../utils';
+import {getUniversityClass, normalize} from '../../utils';
export interface UniversityIconProps extends ViewProps {
university: string;
@@ -38,19 +38,19 @@ const UniversityIcon: React.FC<UniversityIconProps> = ({
const styles = StyleSheet.create({
container: {
- flex: 1,
flexDirection: 'column',
flexWrap: 'wrap',
justifyContent: 'center',
+ alignItems: 'center',
+ height: '100%',
},
univClass: {
- fontSize: 13,
+ fontSize: normalize(14),
fontWeight: '500',
},
icon: {
- alignSelf: 'center',
- width: 17,
- height: 19,
+ width: normalize(17),
+ height: normalize(19),
},
});
diff --git a/src/components/search/Explore.tsx b/src/components/search/Explore.tsx
index c07c66b8..4a71249b 100644
--- a/src/components/search/Explore.tsx
+++ b/src/components/search/Explore.tsx
@@ -4,6 +4,7 @@ import {useSelector} from 'react-redux';
import {EXPLORE_SECTION_TITLES} from '../../constants';
import {RootState} from '../../store/rootReducer';
import {ExploreSectionType} from '../../types';
+import {normalize} from '../../utils';
import ExploreSection from './ExploreSection';
const Explore: React.FC = () => {
@@ -21,11 +22,10 @@ const Explore: React.FC = () => {
const styles = StyleSheet.create({
container: {
zIndex: 0,
- // margin: '5%',
},
header: {
fontWeight: '700',
- fontSize: 22,
+ fontSize: normalize(22),
color: '#fff',
marginBottom: '2%',
margin: '5%',
diff --git a/src/components/search/ExploreSection.tsx b/src/components/search/ExploreSection.tsx
index 8e8b4988..17079e77 100644
--- a/src/components/search/ExploreSection.tsx
+++ b/src/components/search/ExploreSection.tsx
@@ -1,6 +1,7 @@
import React, {Fragment} from 'react';
import {ScrollView, StyleSheet, Text, View} from 'react-native';
import {ProfilePreviewType} from '../../types';
+import {normalize} from '../../utils';
import ExploreSectionUser from './ExploreSectionUser';
/**
@@ -34,7 +35,7 @@ const styles = StyleSheet.create({
},
header: {
fontWeight: '600',
- fontSize: 20,
+ fontSize: normalize(18),
color: '#fff',
marginLeft: '5%',
marginBottom: '5%',
diff --git a/src/components/search/ExploreSectionUser.tsx b/src/components/search/ExploreSectionUser.tsx
index 0bf68a20..68e077e3 100644
--- a/src/components/search/ExploreSectionUser.tsx
+++ b/src/components/search/ExploreSectionUser.tsx
@@ -12,7 +12,7 @@ import {useDispatch, useSelector, useStore} from 'react-redux';
import {loadAvatar} from '../../services';
import {RootState} from '../../store/rootReducer';
import {ProfilePreviewType, ScreenType} from '../../types';
-import {fetchUserX, userXInStore} from '../../utils';
+import {fetchUserX, normalize, userXInStore} from '../../utils';
/**
* Search Screen for user recommendations and a search
@@ -110,13 +110,13 @@ const styles = StyleSheet.create({
name: {
fontWeight: '600',
flexWrap: 'wrap',
- fontSize: 16,
+ fontSize: normalize(16),
color: '#fff',
textAlign: 'center',
},
username: {
fontWeight: '400',
- fontSize: 14,
+ fontSize: normalize(14),
color: '#fff',
},
});
diff --git a/src/components/search/RecentSearches.tsx b/src/components/search/RecentSearches.tsx
index 8a06017c..bdbd5773 100644
--- a/src/components/search/RecentSearches.tsx
+++ b/src/components/search/RecentSearches.tsx
@@ -7,7 +7,7 @@ import {
TouchableOpacityProps,
} from 'react-native';
import {PreviewType, ProfilePreviewType, ScreenType} from 'src/types';
-import {TAGG_TEXT_LIGHT_BLUE} from '../../constants';
+import {TAGG_LIGHT_BLUE} from '../../constants';
import SearchResults from './SearchResults';
interface RecentSearchesProps extends TouchableOpacityProps {
@@ -55,7 +55,7 @@ const styles = StyleSheet.create({
clear: {
fontSize: 18,
fontWeight: 'bold',
- color: TAGG_TEXT_LIGHT_BLUE,
+ color: TAGG_LIGHT_BLUE,
},
});
diff --git a/src/components/taggs/Tagg.tsx b/src/components/taggs/Tagg.tsx
index 82ac07df..5fa8b395 100644
--- a/src/components/taggs/Tagg.tsx
+++ b/src/components/taggs/Tagg.tsx
@@ -22,6 +22,7 @@ import {
ERROR_UNABLE_TO_FIND_PROFILE,
SUCCESS_LINK,
} from '../../constants/strings';
+import {normalize} from '../../utils';
interface TaggProps {
social: string;
@@ -165,7 +166,7 @@ const styles = StyleSheet.create({
justifyContent: 'space-between',
alignItems: 'center',
marginHorizontal: 15,
- height: 90,
+ height: normalize(90),
},
iconTap: {
justifyContent: 'center',
diff --git a/src/components/taggs/TwitterTaggPost.tsx b/src/components/taggs/TwitterTaggPost.tsx
index c971a82c..0cfde857 100644
--- a/src/components/taggs/TwitterTaggPost.tsx
+++ b/src/components/taggs/TwitterTaggPost.tsx
@@ -6,7 +6,7 @@ import LinearGradient from 'react-native-linear-gradient';
import {
AVATAR_DIM,
TAGGS_GRADIENT,
- TAGG_TEXT_LIGHT_BLUE,
+ TAGG_LIGHT_BLUE,
} from '../../constants';
import {TwitterPostType} from '../../types';
import {handleOpenSocialUrlOnBrowser, SCREEN_WIDTH} from '../../utils';
@@ -237,7 +237,7 @@ const styles = StyleSheet.create({
},
replyShowThisThread: {
fontSize: 15,
- color: TAGG_TEXT_LIGHT_BLUE,
+ color: TAGG_LIGHT_BLUE,
},
});
diff --git a/src/constants/constants.ts b/src/constants/constants.ts
index b96d9438..ad43c337 100644
--- a/src/constants/constants.ts
+++ b/src/constants/constants.ts
@@ -1,13 +1,15 @@
import {ReactText} from 'react';
import {BackgroundGradientType, ExploreSectionType} from './../types/';
-import {SCREEN_WIDTH, SCREEN_HEIGHT} from '../utils';
+import {SCREEN_WIDTH, SCREEN_HEIGHT, isIPhoneX, normalize} from '../utils';
export const CHIN_HEIGHT = 34;
-export const PROFILE_CUTOUT_TOP_Y = SCREEN_HEIGHT / 2.3;
-export const PROFILE_CUTOUT_BOTTOM_Y = SCREEN_HEIGHT / 1.76;
-export const PROFILE_CUTOUT_CORNER_X = SCREEN_WIDTH / 2.9;
-export const PROFILE_CUTOUT_CORNER_Y = SCREEN_HEIGHT / 1.95;
+export const PROFILE_CUTOUT_TOP_Y = SCREEN_HEIGHT * 0.435;
+export const PROFILE_CUTOUT_BOTTOM_Y = isIPhoneX()
+ ? SCREEN_HEIGHT * 0.55
+ : SCREEN_HEIGHT * 0.58;
+export const PROFILE_CUTOUT_CORNER_X = SCREEN_WIDTH * 0.344;
+export const PROFILE_CUTOUT_CORNER_Y = SCREEN_HEIGHT * 0.513;
export const IMAGE_WIDTH = SCREEN_WIDTH;
export const IMAGE_HEIGHT = SCREEN_WIDTH;
@@ -17,7 +19,7 @@ export const AVATAR_DIM = 44;
export const AVATAR_GRADIENT_DIM = 50;
export const TAGG_ICON_DIM = 58;
-export const TAGG_RING_DIM = 65;
+export const TAGG_RING_DIM = normalize(60);
export const INTEGRATED_SOCIAL_LIST: string[] = [
'Instagram',
@@ -59,7 +61,7 @@ export const SNAPCHAT_FONT_COLOR: string = '#FFFC00';
export const YOUTUBE_FONT_COLOR: string = '#FCA4A4';
export const TAGG_DARK_BLUE = '#4E699C';
-export const TAGG_TEXT_LIGHT_BLUE: string = '#698DD3';
+export const TAGG_LIGHT_BLUE: string = '#698DD3';
export const TAGG_LIGHT_PURPLE = '#F4DDFF';
export const TAGGS_GRADIENT = {
diff --git a/src/constants/strings.ts b/src/constants/strings.ts
index b5344afd..a1793658 100644
--- a/src/constants/strings.ts
+++ b/src/constants/strings.ts
@@ -12,23 +12,23 @@ export const ERROR_DOUBLE_CHECK_CONNECTION = 'Please double-check your network c
export const ERROR_DUP_OLD_PWD = 'You may not use a previously used password';
export const ERROR_EMAIL_IN_USE = 'Email already in use, please try another one';
export const ERROR_FAILED_LOGIN_INFO = 'Login failed, please try re-entering your login information';
-export const ERROR_FAILED_TO_COMMENT = 'Unable to post comment, refresh and try again!';
+export const ERROR_FAILED_TO_COMMENT = 'Unable to post comment, refresh and try again!';
export const ERROR_INVALID_INVITATION_CODE = 'Invitation code invalid, try again or talk to the friend that sent it 😬';
export const ERROR_INVALID_LOGIN = 'Invalid login, Please login again';
export const ERROR_INVALID_PWD_CODE = 'Looks like you have entered the wrong code, please try again';
export const ERROR_INVALID_VERIFICATION_CODE = 'Invalid verification code, try re-entering or tap the resend code button for a new code';
export const ERROR_INVALID_VERIFICATION_CODE_FORMAT = 'Please enter the 6 digit code sent to your phone';
export const ERROR_INVLAID_CODE = 'The code entered is not valid!';
-export const ERROR_LINK = (str: string) => `Unable to link with ${str}, Please check your login and try again`;
-export const ERROR_LOGIN = 'There was a problem logging you in, please refresh and try again';
+export const ERROR_LINK = (str: string) => `Unable to link with ${str}, Please check your login and try again`;
+export const ERROR_LOGIN = 'There was a problem logging you in, please refresh and try again';
export const ERROR_LOGIN_FAILED = 'Login failed. Check your username and passoword, and try again';
export const ERROR_NEXT_PAGE = 'There was a problem while loading the next page πŸ˜“, try again in a couple minutes';
export const ERROR_PROFILE_CREATION_SHORT = 'Profile creation failed πŸ˜“';
export const ERROR_PWD_ACCOUNT = (str: string) => `Please make sure that the email / username entered is registered with us. You may contact our customer support at ${str}`;
-export const ERROR_REGISTRATION = (str: string) => `Registration failed πŸ˜”, ${str}`;
+export const ERROR_REGISTRATION = (str: string) => `Registration failed πŸ˜”, ${str}`;
export const ERROR_SELECT_CLASS_YEAR = 'Please select your Class Year';
export const ERROR_SERVER_DOWN = 'mhm, looks like our servers are down, please refresh and try again in a few mins';
-export const ERROR_SOMETHING_WENT_WRONG = "Oh dear, don’t worry someone will be held responsible for this error, In the meantime refresh the app";
+export const ERROR_SOMETHING_WENT_WRONG = 'Oh dear, don’t worry someone will be held responsible for this error, In the meantime refresh the app';
export const ERROR_SOMETHING_WENT_WRONG_REFRESH = "Ha, looks like this one's on us, please refresh and try again";
export const ERROR_SOMETHING_WENT_WRONG_RELOAD = "You broke it, Just kidding! we don't know what happened... Please reload the app and try again";
export const ERROR_UNABLE_TO_FIND_PROFILE = 'We were unable to find this profile. Please check username and try again';
@@ -45,3 +45,8 @@ export const SUCCESS_LINK = (str: string) => `Successfully linked ${str} πŸŽ‰`;
export const SUCCESS_PIC_UPLOAD = 'Beautiful, the picture was uploaded successfully!';
export const SUCCESS_PWD_RESET = 'Your password was reset successfully!';
export const SUCCESS_VERIFICATION_CODE_SENT = 'New verification code sent! Check your phone messages for your code';
+export const UPLOAD_MOMENT_PROMPT_ONE_MESSAGE = 'Post your first moment to\n continue building your digital\nidentity!';
+export const UPLOAD_MOMENT_PROMPT_THREE_HEADER = 'Continue to build your profile';
+export const UPLOAD_MOMENT_PROMPT_THREE_MESSAGE = 'Continue to personalize your own digital space in\nthis community by filling your profile with\ncategories and moments!';
+export const UPLOAD_MOMENT_PROMPT_TWO_HEADER = 'Create a new category';
+export const UPLOAD_MOMENT_PROMPT_TWO_MESSAGE = 'You can now create new categories \nand continue to fill your profile with moments!';
diff --git a/src/routes/main/MainStackScreen.tsx b/src/routes/main/MainStackScreen.tsx
index 9250d0d1..3e425101 100644
--- a/src/routes/main/MainStackScreen.tsx
+++ b/src/routes/main/MainStackScreen.tsx
@@ -54,7 +54,7 @@ const MainStackScreen: React.FC<MainStackProps> = ({route}) => {
})();
const modalStyle: StackNavigationOptions = {
- cardStyle: {backgroundColor: 'transparent'},
+ cardStyle: {backgroundColor: 'rgba(80,80,80,0.9)'},
gestureDirection: 'vertical',
cardOverlayEnabled: true,
cardStyleInterpolator: ({current: {progress}}) => ({
@@ -64,14 +64,6 @@ const MainStackScreen: React.FC<MainStackProps> = ({route}) => {
outputRange: [0, 0.25, 0.7, 1],
}),
},
- overlayStyle: {
- backgroundColor: '#505050',
- opacity: progress.interpolate({
- inputRange: [0, 1],
- outputRange: [0, 0.9],
- extrapolate: 'clamp',
- }),
- },
}),
};
@@ -175,9 +167,6 @@ const MainStackScreen: React.FC<MainStackProps> = ({route}) => {
<MainStack.Screen
name="MomentCommentsScreen"
component={MomentCommentsScreen}
- options={{
- ...modalStyle,
- }}
initialParams={{screenType}}
/>
<MainStack.Screen
diff --git a/src/screens/profile/EditProfile.tsx b/src/screens/profile/EditProfile.tsx
index 3b3fa36e..7d3ca581 100644
--- a/src/screens/profile/EditProfile.tsx
+++ b/src/screens/profile/EditProfile.tsx
@@ -29,9 +29,10 @@ import {
websiteRegex,
bioRegex,
genderRegex,
+ CLASS_YEAR_LIST,
} from '../../constants';
import AsyncStorage from '@react-native-community/async-storage';
-import {ProfileStackParams} from '../../routes';
+import {MainStackParams} from '../../routes';
import Animated from 'react-native-reanimated';
import {HeaderHeight, SCREEN_HEIGHT} from '../../utils';
import {RootState} from '../../store/rootReducer';
@@ -47,12 +48,12 @@ import {
import TaggLoadingIndicator from '../../components/common/TaggLoadingIndicator';
type EditProfileNavigationProp = StackNavigationProp<
- ProfileStackParams,
+ MainStackParams,
'EditProfile'
>;
interface EditProfileProps {
- route: RouteProp<ProfileStackParams, 'EditProfile'>;
+ route: RouteProp<MainStackParams, 'EditProfile'>;
navigation: EditProfileNavigationProp;
}
@@ -65,7 +66,7 @@ const EditProfile: React.FC<EditProfileProps> = ({route, navigation}) => {
const y: Animated.Value<number> = Animated.useValue(0);
const {userId, username} = route.params;
const {
- profile: {website, biography, gender, snapchat, tiktok},
+ profile: {website, biography, gender, snapchat, tiktok, university_class},
avatar,
cover,
} = useSelector((state: RootState) => state.user);
@@ -99,6 +100,13 @@ const EditProfile: React.FC<EditProfileProps> = ({route, navigation}) => {
isValidSnapchat: true,
isValidTiktok: true,
attemptedSubmit: false,
+ classYear: university_class,
+ });
+
+ var classYearList: Array<any> = [];
+
+ CLASS_YEAR_LIST.map((value) => {
+ classYearList.push({label: value, value: value});
});
/**
@@ -254,6 +262,14 @@ const EditProfile: React.FC<EditProfileProps> = ({route, navigation}) => {
});
};
+ const handleClassYearUpdate = (value: string) => {
+ const classYear = Number.parseInt(value);
+ setForm({
+ ...form,
+ classYear,
+ });
+ };
+
const handleSubmit = useCallback(async () => {
if (!form.largePic) {
Alert.alert(ERROR_UPLOAD_LARGE_PROFILE_PIC);
@@ -297,7 +313,7 @@ const EditProfile: React.FC<EditProfileProps> = ({route, navigation}) => {
if (form.bio) {
if (form.isValidBio) {
- request.append('biography', form.bio);
+ request.append('biography', form.bio.trim());
} else {
setForm({...form, attemptedSubmit: false});
setTimeout(() => setForm({...form, attemptedSubmit: true}));
@@ -335,6 +351,15 @@ const EditProfile: React.FC<EditProfileProps> = ({route, navigation}) => {
invalidFields = true;
}
+ if (form.classYear !== university_class) {
+ if (!form.classYear) {
+ invalidFields = true;
+ Alert.alert('Please select a valid class year');
+ } else {
+ request.append('university_class', form.classYear);
+ }
+ }
+
if (invalidFields) {
return;
}
@@ -487,6 +512,19 @@ const EditProfile: React.FC<EditProfileProps> = ({route, navigation}) => {
value={form.customGenderText}
/>
)}
+
+ <TaggDropDown
+ value={form.classYear.toString()}
+ onValueChange={(value: string) =>
+ handleClassYearUpdate(value)
+ }
+ items={classYearList}
+ placeholder={{
+ label: 'Class Year',
+ value: null,
+ color: '#ddd',
+ }}
+ />
{snapchat !== '' && (
<View style={styles.row}>
<SocialIcon social={'Snapchat'} style={styles.icon} />
diff --git a/src/screens/profile/MomentCommentsScreen.tsx b/src/screens/profile/MomentCommentsScreen.tsx
index ebe4da28..2bceafc9 100644
--- a/src/screens/profile/MomentCommentsScreen.tsx
+++ b/src/screens/profile/MomentCommentsScreen.tsx
@@ -1,17 +1,21 @@
-import * as React from 'react';
import {RouteProp, useNavigation} from '@react-navigation/native';
+import React, {useEffect, useRef} from 'react';
+import {
+ ScrollView,
+ StyleSheet,
+ Text,
+ TouchableOpacity,
+ View,
+} from 'react-native';
+import {SafeAreaView} from 'react-native-safe-area-context';
+import {useDispatch} from 'react-redux';
+import {getMomentComments} from '../..//services';
+import BackIcon from '../../assets/icons/back-arrow.svg';
+import {CommentTile, TabsGradient} from '../../components';
+import {AddComment} from '../../components/';
import {ProfileStackParams} from '../../routes/main';
-import {CenteredView, CommentTile} from '../../components';
import {CommentType} from '../../types';
-import {ScrollView, StyleSheet, Text, View} from 'react-native';
-import {SCREEN_WIDTH} from '../../utils/screenDimensions';
-import {Button} from 'react-native-elements';
-import {AddComment} from '../../components/';
-import {useEffect} from 'react';
-import AsyncStorage from '@react-native-community/async-storage';
-import {getMomentComments} from '../..//services';
-import {useDispatch} from 'react-redux';
-import {logout} from '../../store/actions';
+import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
/**
* Comments Screen for an image uploaded
@@ -34,105 +38,98 @@ const MomentCommentsScreen: React.FC<MomentCommentsScreenProps> = ({route}) => {
const [commentsList, setCommentsList] = React.useState([]);
const [newCommentsAvailable, setNewCommentsAvailable] = React.useState(true);
const dispatch = useDispatch();
+ const ref = useRef<ScrollView>(null);
useEffect(() => {
const loadComments = async () => {
- const token = await AsyncStorage.getItem('token');
- if (!token) {
- dispatch(logout());
- return;
- }
- getMomentComments(moment_id, setCommentsList, token);
+ getMomentComments(moment_id, setCommentsList);
setNewCommentsAvailable(false);
};
if (newCommentsAvailable) {
loadComments();
+ setTimeout(() => {
+ ref.current?.scrollToEnd({
+ animated: true,
+ });
+ }, 500);
}
}, [dispatch, moment_id, newCommentsAvailable]);
return (
- <CenteredView>
- <View style={styles.modalView}>
+ <View style={styles.background}>
+ <SafeAreaView>
<View style={styles.header}>
- <Button
- title="X"
- buttonStyle={styles.button}
- titleStyle={styles.buttonText}
+ <TouchableOpacity
+ style={styles.headerButton}
onPress={() => {
navigation.pop();
- }}
- />
+ }}>
+ <BackIcon height={'100%'} width={'100%'} color={'white'} />
+ </TouchableOpacity>
<Text style={styles.headerText}>
{commentsList.length + ' Comments'}
</Text>
</View>
- <ScrollView
- style={styles.modalScrollView}
- contentContainerStyle={styles.modalScrollViewContent}>
- {commentsList &&
- commentsList.map((comment: CommentType) => (
- <CommentTile
- key={comment.comment_id}
- comment_object={comment}
- screenType={screenType}
- />
- ))}
- </ScrollView>
- <AddComment
- setNewCommentsAvailable={setNewCommentsAvailable}
- moment_id={moment_id}
- />
- </View>
- </CenteredView>
+ <View style={styles.body}>
+ <ScrollView
+ ref={ref}
+ style={styles.scrollView}
+ contentContainerStyle={styles.scrollViewContent}>
+ {commentsList &&
+ commentsList.map((comment: CommentType) => (
+ <CommentTile
+ key={comment.comment_id}
+ comment_object={comment}
+ screenType={screenType}
+ />
+ ))}
+ </ScrollView>
+ <AddComment
+ setNewCommentsAvailable={setNewCommentsAvailable}
+ moment_id={moment_id}
+ />
+ </View>
+ </SafeAreaView>
+ <TabsGradient />
+ </View>
);
};
const styles = StyleSheet.create({
- header: {flexDirection: 'row'},
+ background: {
+ backgroundColor: 'white',
+ height: '100%',
+ },
+ header: {justifyContent: 'center', padding: '3%'},
headerText: {
- position: 'relative',
- left: '180%',
+ position: 'absolute',
alignSelf: 'center',
- fontSize: 18,
- fontWeight: '500',
+ fontSize: 20.5,
+ fontWeight: '600',
},
- container: {
- position: 'relative',
- top: '5%',
- left: '5%',
- backgroundColor: 'white',
- borderRadius: 5,
- width: SCREEN_WIDTH / 1.1,
- height: '55%',
- },
- button: {
- backgroundColor: 'transparent',
+ headerButton: {
+ width: '5%',
+ aspectRatio: 1,
+ padding: 0,
+ marginLeft: '5%',
+ alignSelf: 'flex-start',
},
- buttonText: {
+ headerButtonText: {
color: 'black',
fontSize: 18,
fontWeight: '400',
},
- modalView: {
- width: '85%',
- height: '70%',
- backgroundColor: '#fff',
- shadowColor: '#000',
- shadowOpacity: 30,
- shadowOffset: {width: 0, height: 2},
- shadowRadius: 5,
- borderRadius: 8,
- paddingBottom: 15,
+ body: {
+ width: SCREEN_WIDTH,
+ height: SCREEN_HEIGHT * 0.8,
+ paddingTop: '3%',
+ },
+ scrollView: {
paddingHorizontal: 20,
- paddingTop: 5,
- justifyContent: 'space-between',
},
- modalScrollViewContent: {
+ scrollViewContent: {
justifyContent: 'center',
},
- modalScrollView: {
- marginBottom: 10,
- },
});
export default MomentCommentsScreen;
diff --git a/src/screens/profile/MomentUploadPromptScreen.tsx b/src/screens/profile/MomentUploadPromptScreen.tsx
index 6111985d..9d46c1e9 100644
--- a/src/screens/profile/MomentUploadPromptScreen.tsx
+++ b/src/screens/profile/MomentUploadPromptScreen.tsx
@@ -6,6 +6,7 @@ import CloseIcon from '../../assets/ionicons/close-outline.svg';
import {StyleSheet, Text, View} from 'react-native';
import {Moment} from '../../components';
import {Image} from 'react-native-animatable';
+import {UPLOAD_MOMENT_PROMPT_ONE_MESSAGE} from '../../constants/strings';
type MomentUploadPromptScreenRouteProp = RouteProp<
MainStackParams,
@@ -38,10 +39,7 @@ const MomentUploadPromptScreen: React.FC<MomentUploadPromptScreenProps> = ({
}}
/>
- <Text style={styles.text}>
- Post your first moment to {'\n'} continue building your digital {'\n'}{' '}
- identity!
- </Text>
+ <Text style={styles.text}>{UPLOAD_MOMENT_PROMPT_ONE_MESSAGE}</Text>
<Image
source={require('../../assets/gifs/dotted-arrow-white.gif')}
style={styles.arrowGif}
@@ -54,6 +52,8 @@ const MomentUploadPromptScreen: React.FC<MomentUploadPromptScreenProps> = ({
screenType={screenType}
handleMomentCategoryDelete={() => {}}
shouldAllowDeletion={false}
+ showDownButton={false}
+ showUpButton={false}
externalStyles={{
container: styles.momentContainer,
titleText: styles.momentHeaderText,
diff --git a/src/screens/search/SearchScreen.tsx b/src/screens/search/SearchScreen.tsx
index 9f98b4d7..059bd968 100644
--- a/src/screens/search/SearchScreen.tsx
+++ b/src/screens/search/SearchScreen.tsx
@@ -2,6 +2,7 @@ import AsyncStorage from '@react-native-community/async-storage';
import {useFocusEffect} from '@react-navigation/native';
import React, {useCallback, useEffect, useState} from 'react';
import {
+ Dimensions,
Keyboard,
RefreshControl,
ScrollView,
@@ -20,7 +21,7 @@ import {
SearchResultsBackground,
TabsGradient,
} from '../../components';
-import {SEARCH_ENDPOINT, TAGG_TEXT_LIGHT_BLUE} from '../../constants';
+import {SEARCH_ENDPOINT, TAGG_LIGHT_BLUE} from '../../constants';
import {loadRecentlySearched, resetScreenType} from '../../store/actions';
import {RootState} from '../../store/rootReducer';
import {ProfilePreviewType, ScreenType, UserType} from '../../types';
@@ -213,7 +214,7 @@ const styles = StyleSheet.create({
clear: {
fontSize: 17,
fontWeight: 'bold',
- color: TAGG_TEXT_LIGHT_BLUE,
+ color: TAGG_LIGHT_BLUE,
},
image: {
width: SCREEN_WIDTH,
diff --git a/src/services/MomentServices.ts b/src/services/MomentServices.ts
index 735f2ed2..7bad6d4c 100644
--- a/src/services/MomentServices.ts
+++ b/src/services/MomentServices.ts
@@ -14,9 +14,9 @@ import {checkImageUploadStatus} from '../utils';
export const getMomentComments = async (
momentId: string,
callback: Function,
- token: string,
) => {
try {
+ const token = await AsyncStorage.getItem('token');
const response = await fetch(COMMENTS_ENDPOINT + '?moment_id=' + momentId, {
method: 'GET',
headers: {
@@ -35,14 +35,13 @@ export const getMomentComments = async (
}
};
-//Post a comment on a moment
export const postMomentComment = async (
commenter: string,
comment: string,
momentId: string,
- token: string,
) => {
try {
+ const token = await AsyncStorage.getItem('token');
const request = new FormData();
request.append('moment_id', momentId);
request.append('commenter', commenter);
@@ -60,7 +59,7 @@ export const postMomentComment = async (
return await response.json();
} catch (error) {
Alert.alert(ERROR_FAILED_TO_COMMENT);
- return {};
+ return undefined;
}
};
diff --git a/src/utils/index.ts b/src/utils/index.ts
index f5352af1..629a0091 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -1,5 +1,4 @@
-export * from './screenDimensions';
-export * from './statusBarHeight';
+export * from './layouts';
export * from './moments';
export * from './common';
export * from './users';
diff --git a/src/utils/layouts.ts b/src/utils/layouts.ts
new file mode 100644
index 00000000..e2f1f0b1
--- /dev/null
+++ b/src/utils/layouts.ts
@@ -0,0 +1,48 @@
+import {PixelRatio, Platform, StatusBar} from 'react-native';
+import {Dimensions} from 'react-native';
+
+export const {width: SCREEN_WIDTH, height: SCREEN_HEIGHT} = Dimensions.get(
+ 'window',
+);
+
+export const SCREEN_RATIO = SCREEN_HEIGHT / SCREEN_WIDTH;
+
+/**
+ * Working as of Q1 2021, latest iPhone is 12
+ * iPhone 8/SE has a logical screen ratio of about 1.77
+ * Rest has a logical screen ratio of about 2.16
+ */
+export const isIPhoneX = () =>
+ Platform.OS === 'ios' && !Platform.isPad && !Platform.isTVOS
+ ? SCREEN_RATIO > 2
+ : false;
+
+// Taken from: https://github.com/react-navigation/react-navigation/issues/283
+export const HeaderHeight = Platform.select({
+ ios: 44,
+ android: 56,
+ default: 64,
+});
+
+export const StatusBarHeight = Platform.select({
+ ios: isIPhoneX() ? 44 : 20,
+ android: StatusBar.currentHeight,
+ default: 0,
+});
+
+export const AvatarHeaderHeight = (HeaderHeight + StatusBarHeight) * 1.3;
+
+/**
+ * This is a function for normalizing the font size for different devices, based on iphone 8.
+ *
+ * E.g. font size 13 on an iphone 8 is 13, but on an iPhone 11 is
+ * 14.5
+ */
+export const normalize = (fontSize: number) => {
+ // based on iphone 8 logical screen width
+ const scale = SCREEN_WIDTH / 375;
+ let newSize = fontSize * scale;
+ // round to the nearest 0.5
+ newSize = Math.round(PixelRatio.roundToNearestPixel(newSize) * 2) / 2;
+ return newSize;
+};
diff --git a/src/utils/screenDimensions.ts b/src/utils/screenDimensions.ts
deleted file mode 100644
index 56277ddc..00000000
--- a/src/utils/screenDimensions.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import {Dimensions} from 'react-native';
-
-const {width, height} = Dimensions.get('window');
-
-export const SCREEN_WIDTH = width;
-export const SCREEN_HEIGHT = height;
diff --git a/src/utils/statusBarHeight.ts b/src/utils/statusBarHeight.ts
deleted file mode 100644
index b8eb7b33..00000000
--- a/src/utils/statusBarHeight.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import {Platform, StatusBar} from 'react-native';
-import {SCREEN_HEIGHT, SCREEN_WIDTH} from './screenDimensions';
-
-const X_WIDTH = 375;
-const X_HEIGHT = 812;
-const XSMAX_WIDTH = 414;
-const XSMAX_HEIGHT = 896;
-
-export const isIPhoneX = () =>
- Platform.OS === 'ios' && !Platform.isPad && !Platform.isTVOS
- ? (SCREEN_WIDTH === X_WIDTH && SCREEN_HEIGHT === X_HEIGHT) ||
- (SCREEN_WIDTH === XSMAX_WIDTH && SCREEN_HEIGHT === XSMAX_HEIGHT)
- : false;
-
-// Taken from: https://github.com/react-navigation/react-navigation/issues/283
-export const HeaderHeight = Platform.select({
- ios: 44,
- android: 56,
- default: 64,
-});
-
-export const StatusBarHeight = Platform.select({
- ios: isIPhoneX() ? 44 : 20,
- android: StatusBar.currentHeight,
- default: 0,
-});
-
-export const AvatarHeaderHeight = (HeaderHeight + StatusBarHeight) * 1.3;