diff options
| author | Ivan Chen <ivan@tagg.id> | 2021-02-01 16:01:03 -0500 |
|---|---|---|
| committer | Ivan Chen <ivan@tagg.id> | 2021-02-01 16:01:03 -0500 |
| commit | 8d1013e86cf2d66671c337d49a80da157802ad86 (patch) | |
| tree | 656b1656068bb6636919359d4faaf7051994ff74 /src/screens | |
| parent | 951d85348acef13ec7830629205c30ad5f766bee (diff) | |
| parent | 7a09cc96bf1fe468a612bb44362bbef24fccc773 (diff) | |
Merge branch 'master' into TMA-546-Onboarding-Page
Diffstat (limited to 'src/screens')
| -rw-r--r-- | src/screens/main/NotificationsScreen.tsx | 2 | ||||
| -rw-r--r-- | src/screens/onboarding/RegistrationOne.tsx | 4 | ||||
| -rw-r--r-- | src/screens/profile/EditProfile.tsx | 48 | ||||
| -rw-r--r-- | src/screens/profile/IndividualMoment.tsx | 13 | ||||
| -rw-r--r-- | src/screens/profile/MomentCommentsScreen.tsx | 167 | ||||
| -rw-r--r-- | src/screens/profile/MomentUploadPromptScreen.tsx | 8 | ||||
| -rw-r--r-- | src/screens/search/SearchScreen.tsx | 13 |
7 files changed, 134 insertions, 121 deletions
diff --git a/src/screens/main/NotificationsScreen.tsx b/src/screens/main/NotificationsScreen.tsx index 4bdee942..d9952aa8 100644 --- a/src/screens/main/NotificationsScreen.tsx +++ b/src/screens/main/NotificationsScreen.tsx @@ -70,7 +70,7 @@ const NotificationsScreen: React.FC = () => { //Called when user leaves the screen return () => resetNewNotificationFlag(); - }, [newNotificationReceived]), + }, [newNotificationReceived, dispatch, refreshNotifications]), ); // handles storing and fetching the "previously viewed" information diff --git a/src/screens/onboarding/RegistrationOne.tsx b/src/screens/onboarding/RegistrationOne.tsx index 2a1d884d..c9822f76 100644 --- a/src/screens/onboarding/RegistrationOne.tsx +++ b/src/screens/onboarding/RegistrationOne.tsx @@ -146,7 +146,7 @@ const RegistrationOne: React.FC<RegistrationOneProps> = ({navigation}) => { <Text style={styles.formHeader}>ENTER PHONE NUMBER</Text> </View> <TaggInput - maxLength={12} // currently only support US phone numbers + maxLength={10} // currently only support US phone numbers accessibilityHint="Enter your phone number." accessibilityLabel="Phone number input field." placeholder="Phone Number" @@ -154,7 +154,7 @@ const RegistrationOne: React.FC<RegistrationOneProps> = ({navigation}) => { textContentType="telephoneNumber" autoCapitalize="none" returnKeyType="next" - keyboardType="phone-pad" + keyboardType="number-pad" onChangeText={handlePhoneUpdate} blurOnSubmit={false} ref={phoneRef} 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/IndividualMoment.tsx b/src/screens/profile/IndividualMoment.tsx index f13e1295..8c1dc327 100644 --- a/src/screens/profile/IndividualMoment.tsx +++ b/src/screens/profile/IndividualMoment.tsx @@ -4,12 +4,12 @@ import {StackNavigationProp} from '@react-navigation/stack'; import React from 'react'; import {FlatList, StyleSheet, View} from 'react-native'; import {useSelector} from 'react-redux'; -import {ProfileStackParams} from 'src/routes/main/ProfileStack'; import { IndividualMomentTitleBar, MomentPostContent, MomentPostHeader, } from '../../components'; +import {MainStackParams} from '../../routes'; import {RootState} from '../../store/rootreducer'; import {MomentType} from '../../types'; import {SCREEN_HEIGHT, SCREEN_WIDTH, StatusBarHeight} from '../../utils'; @@ -17,12 +17,9 @@ import {SCREEN_HEIGHT, SCREEN_WIDTH, StatusBarHeight} from '../../utils'; /** * Individual moment view opened when user clicks on a moment tile */ -type IndividualMomentRouteProp = RouteProp< - ProfileStackParams, - 'IndividualMoment' ->; +type IndividualMomentRouteProp = RouteProp<MainStackParams, 'IndividualMoment'>; type IndividualMomentNavigationProp = StackNavigationProp< - ProfileStackParams, + MainStackParams, 'IndividualMoment' >; interface IndividualMomentProps { @@ -70,7 +67,7 @@ const IndividualMoment: React.FC<IndividualMomentProps> = ({ style={styles.postContent} momentId={item.moment_id} caption={item.caption} - pathHash={item.path_hash} + pathHash={item.moment_url} dateTime={item.date_created} screenType={screenType} /> @@ -80,7 +77,7 @@ const IndividualMoment: React.FC<IndividualMomentProps> = ({ return ( <BlurView blurType="light" - blurAmount={10} + blurAmount={30} reducedTransparencyFallbackColor="white" style={styles.contentContainer}> <IndividualMomentTitleBar diff --git a/src/screens/profile/MomentCommentsScreen.tsx b/src/screens/profile/MomentCommentsScreen.tsx index ebe4da28..5c3b8579 100644 --- a/src/screens/profile/MomentCommentsScreen.tsx +++ b/src/screens/profile/MomentCommentsScreen.tsx @@ -1,17 +1,15 @@ -import * as React from 'react'; import {RouteProp, useNavigation} from '@react-navigation/native'; -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 React, {useState} from 'react'; +import {StyleSheet, Text, TouchableOpacity, View} from 'react-native'; +import {SafeAreaView} from 'react-native-safe-area-context'; +import BackIcon from '../../assets/icons/back-arrow.svg'; +import {TabsGradient} from '../../components'; 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 CommentsContainer from '../../components/comments/CommentsContainer'; +import {ADD_COMMENT_TEXT} from '../../constants/strings'; +import {MainStackParams} from '../../routes/main'; +import {CommentType} from '../../types'; +import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; /** * Comments Screen for an image uploaded @@ -20,7 +18,7 @@ import {logout} from '../../store/actions'; */ type MomentCommentsScreenRouteProps = RouteProp< - ProfileStackParams, + MainStackParams, 'MomentCommentsScreen' >; @@ -30,109 +28,96 @@ interface MomentCommentsScreenProps { const MomentCommentsScreen: React.FC<MomentCommentsScreenProps> = ({route}) => { const navigation = useNavigation(); - const {moment_id, screenType} = route.params; - const [commentsList, setCommentsList] = React.useState([]); + const {moment_id, screenType, comment_id} = route.params; + + //Receives comment length from child CommentsContainer + const [commentsLength, setCommentsLength] = useState<number>(0); const [newCommentsAvailable, setNewCommentsAvailable] = React.useState(true); - const dispatch = useDispatch(); - useEffect(() => { - const loadComments = async () => { - const token = await AsyncStorage.getItem('token'); - if (!token) { - dispatch(logout()); - return; - } - getMomentComments(moment_id, setCommentsList, token); - setNewCommentsAvailable(false); - }; - if (newCommentsAvailable) { - loadComments(); - } - }, [dispatch, moment_id, newCommentsAvailable]); + //Keeps track of the current comments object in focus so that the application knows which comment to post a reply to + const [commentObjectInFocus, setCommentObjectInFocus] = useState< + CommentType | undefined + >(undefined); 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}>{commentsLength + ' Comments'}</Text> + </View> + <View style={styles.body}> + <CommentsContainer + objectId={moment_id} + commentId={comment_id} + screenType={screenType} + setCommentsLength={setCommentsLength} + newCommentsAvailable={newCommentsAvailable} + setNewCommentsAvailable={setNewCommentsAvailable} + setCommentObjectInFocus={setCommentObjectInFocus} + commentObjectInFocus={commentObjectInFocus} + typeOfComment={'Comment'} + /> + <AddComment + placeholderText={ + commentObjectInFocus + ? ADD_COMMENT_TEXT(commentObjectInFocus.commenter.username) + : ADD_COMMENT_TEXT() + } + setNewCommentsAvailable={setNewCommentsAvailable} + objectId={ + commentObjectInFocus ? commentObjectInFocus.comment_id : moment_id + } + isCommentInFocus={commentObjectInFocus ? true : false} /> - <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> + </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', - }, - container: { - position: 'relative', - top: '5%', - left: '5%', - backgroundColor: 'white', - borderRadius: 5, - width: SCREEN_WIDTH / 1.1, - height: '55%', + fontSize: 20.5, + fontWeight: '600', }, - 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 * 0.9, + 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..f0be7c9e 100644 --- a/src/screens/search/SearchScreen.tsx +++ b/src/screens/search/SearchScreen.tsx @@ -20,7 +20,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'; @@ -36,9 +36,7 @@ const NO_USER: UserType = { */ const SearchScreen: React.FC = () => { - const {recentSearches, explores} = useSelector( - (state: RootState) => state.taggUsers, - ); + const {recentSearches} = useSelector((state: RootState) => state.taggUsers); const [query, setQuery] = useState<string>(''); const [results, setResults] = useState<Array<ProfilePreviewType>>([]); const [recents, setRecents] = useState<Array<ProfilePreviewType>>( @@ -46,7 +44,6 @@ const SearchScreen: React.FC = () => { ); const [searching, setSearching] = useState(false); const top = Animated.useValue(-SCREEN_HEIGHT); - const [user, setUser] = useState<UserType>(NO_USER); const [refreshing, setRefreshing] = useState<boolean>(false); const dispatch = useDispatch(); @@ -69,10 +66,6 @@ const SearchScreen: React.FC = () => { const loadResults = async (q: string) => { try { const token = await AsyncStorage.getItem('token'); - if (!token) { - setUser(NO_USER); - return; - } const response = await fetch(`${SEARCH_ENDPOINT}?query=${q}`, { method: 'GET', headers: { @@ -213,7 +206,7 @@ const styles = StyleSheet.create({ clear: { fontSize: 17, fontWeight: 'bold', - color: TAGG_TEXT_LIGHT_BLUE, + color: TAGG_LIGHT_BLUE, }, image: { width: SCREEN_WIDTH, |
