diff options
Diffstat (limited to 'src/screens')
-rw-r--r-- | src/screens/onboarding/ProfileOnboarding.tsx | 150 | ||||
-rw-r--r-- | src/screens/profile/EditProfile.tsx | 591 | ||||
-rw-r--r-- | src/screens/profile/MomentCommentsScreen.tsx | 2 | ||||
-rw-r--r-- | src/screens/profile/ProfileScreen.tsx | 9 | ||||
-rw-r--r-- | src/screens/profile/index.ts | 1 | ||||
-rw-r--r-- | src/screens/search/SearchScreen.tsx | 4 |
6 files changed, 682 insertions, 75 deletions
diff --git a/src/screens/onboarding/ProfileOnboarding.tsx b/src/screens/onboarding/ProfileOnboarding.tsx index 3979de38..f21f3864 100644 --- a/src/screens/onboarding/ProfileOnboarding.tsx +++ b/src/screens/onboarding/ProfileOnboarding.tsx @@ -15,7 +15,6 @@ import { Background, TaggBigInput, TaggInput, - TaggDatePicker, TaggDropDown, BirthDatePicker, } from '../../components'; @@ -52,12 +51,13 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({ navigation, }) => { const {userId, username} = route.params; + let emptyDate: string | undefined; const [form, setForm] = React.useState({ largePic: '', smallPic: '', website: '', bio: '', - birthdate: '', + birthdate: emptyDate, gender: '', isValidWebsite: true, isValidBio: true, @@ -65,7 +65,7 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({ attemptedSubmit: false, token: '', }); - const [customGender, setCustomGender] = React.useState(); + const [customGender, setCustomGender] = React.useState(Boolean); // refs for changing focus const bioRef = React.useRef(); @@ -232,7 +232,7 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({ const handleBirthdateUpdate = (birthdate: Date) => { setForm({ ...form, - birthdate: moment(birthdate).format('YYYY-MM-DD'), + birthdate: birthdate && moment(birthdate).format('YYYY-MM-DD'), }); }; @@ -357,81 +357,85 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({ <LargeProfilePic /> <SmallProfilePic /> </View> - <TaggInput - accessibilityHint="Enter a website." - accessibilityLabel="Website input field." - placeholder="Website" - autoCompleteType="off" - textContentType="URL" - autoCapitalize="none" - returnKeyType="next" - onChangeText={handleWebsiteUpdate} - onSubmitEditing={() => handleFocusChange('bio')} - blurOnSubmit={false} - valid={form.isValidWebsite} - attemptedSubmit={form.attemptedSubmit} - invalidWarning={'Website must be a valid link to your website'} - width={280} - /> - <TaggBigInput - accessibilityHint="Enter a bio." - accessibilityLabel="Bio input field." - placeholder="Bio" - autoCompleteType="off" - textContentType="none" - autoCapitalize="none" - returnKeyType="next" - onChangeText={handleBioUpdate} - onSubmitEditing={() => handleFocusChange('bio')} - blurOnSubmit={false} - ref={bioRef} - valid={form.isValidBio} - attemptedSubmit={form.attemptedSubmit} - invalidWarning={ - 'Bio must be less than 150 characters and must contain valid characters' - } - width={280} - /> - <BirthDatePicker - ref={birthdateRef} - handleBDUpdate={handleBirthdateUpdate} - width={280} - /> - <TaggDropDown - onValueChange={(value) => handleGenderUpdate(value)} - items={[ - {label: 'Male', value: 'male'}, - {label: 'Female', value: 'female'}, - {label: 'Custom', value: 'custom'}, - ]} - placeholder={{ - label: 'Gender', - value: null, - color: '#ddd', - }} - /> - {customGender && ( + <View style={styles.contentContainer}> <TaggInput - accessibilityHint="Custom" - accessibilityLabel="Gender input field." - placeholder="Enter your gender" + accessibilityHint="Enter a website." + accessibilityLabel="Website input field." + placeholder="Website" + autoCompleteType="off" + textContentType="URL" + autoCapitalize="none" + returnKeyType="next" + onChangeText={handleWebsiteUpdate} + onSubmitEditing={() => handleFocusChange('bio')} + blurOnSubmit={false} + valid={form.isValidWebsite} + attemptedSubmit={form.attemptedSubmit} + invalidWarning={'Website must be a valid link to your website'} + width={280} + /> + <TaggBigInput + accessibilityHint="Enter a bio." + accessibilityLabel="Bio input field." + placeholder="Bio" autoCompleteType="off" textContentType="none" autoCapitalize="none" returnKeyType="next" + onChangeText={handleBioUpdate} + onSubmitEditing={() => handleFocusChange('bio')} blurOnSubmit={false} - ref={customGenderRef} - onChangeText={handleCustomGenderUpdate} - onSubmitEditing={() => handleSubmit()} - valid={form.isValidGender} + ref={bioRef} + valid={form.isValidBio} attemptedSubmit={form.attemptedSubmit} - invalidWarning={'Custom field can only contain letters and hyphens'} + invalidWarning={ + 'Bio must be less than 150 characters and must contain valid characters' + } width={280} /> - )} - <TouchableOpacity onPress={handleSubmit} style={styles.submitBtn}> - <Text style={styles.submitBtnLabel}>Let's start!</Text> - </TouchableOpacity> + <BirthDatePicker + ref={birthdateRef} + handleBDUpdate={handleBirthdateUpdate} + width={280} + date={form.birthdate} + showPresetdate={false} + /> + <TaggDropDown + onValueChange={(value: string) => handleGenderUpdate(value)} + items={[ + {label: 'Male', value: 'male'}, + {label: 'Female', value: 'female'}, + {label: 'Custom', value: 'custom'}, + ]} + placeholder={{ + label: 'Gender', + value: null, + color: '#ddd', + }} + /> + {customGender && ( + <TaggInput + accessibilityHint="Custom" + accessibilityLabel="Gender input field." + placeholder="Enter your gender" + autoCompleteType="off" + textContentType="none" + autoCapitalize="none" + returnKeyType="next" + blurOnSubmit={false} + ref={customGenderRef} + onChangeText={handleCustomGenderUpdate} + onSubmitEditing={() => handleSubmit()} + valid={form.isValidGender} + attemptedSubmit={form.attemptedSubmit} + invalidWarning={'Custom field can only contain letters and hyphens'} + width={280} + /> + )} + <TouchableOpacity onPress={handleSubmit} style={styles.submitBtn}> + <Text style={styles.submitBtnLabel}>Let's start!</Text> + </TouchableOpacity> + </View> </Background> ); }; @@ -441,6 +445,11 @@ const styles = StyleSheet.create({ flexDirection: 'row', marginBottom: '5%', }, + contentContainer: { + position: 'relative', + width: 280, + alignSelf: 'center', + }, largeProfileUploader: { justifyContent: 'center', alignItems: 'center', @@ -493,6 +502,7 @@ const styles = StyleSheet.create({ height: 40, borderRadius: 5, marginTop: '5%', + alignSelf: 'center', }, submitBtnLabel: { fontSize: 16, diff --git a/src/screens/profile/EditProfile.tsx b/src/screens/profile/EditProfile.tsx new file mode 100644 index 00000000..01b67155 --- /dev/null +++ b/src/screens/profile/EditProfile.tsx @@ -0,0 +1,591 @@ +import React, {useCallback, useEffect, useState} from 'react'; +import {RouteProp} from '@react-navigation/native'; +import moment from 'moment'; +import {StackNavigationProp} from '@react-navigation/stack'; +import { + Text, + StatusBar, + StyleSheet, + Image, + TouchableOpacity, + Alert, + View, + SafeAreaView, +} from 'react-native'; +import {Button} from 'react-native-elements'; +import { + Background, + TaggBigInput, + TaggInput, + TaggDropDown, + BirthDatePicker, + TabsGradient, +} from '../../components'; +import {OnboardingStackParams} from '../../routes/onboarding'; +import ImagePicker from 'react-native-image-crop-picker'; +import { + EDIT_PROFILE_ENDPOINT, + websiteRegex, + bioRegex, + genderRegex, +} from '../../constants'; +import AsyncStorage from '@react-native-community/async-storage'; +import {AuthContext} from '../../routes'; +import Animated from 'react-native-reanimated'; +import {SCREEN_HEIGHT} from '../../utils'; + +type ProfileOnboardingScreenRouteProp = RouteProp< + OnboardingStackParams, + 'ProfileOnboarding' +>; +type ProfileOnboardingScreenNavigationProp = StackNavigationProp< + OnboardingStackParams, + 'ProfileOnboarding' +>; +interface ProfileOnboardingProps { + route: ProfileOnboardingScreenRouteProp; + navigation: ProfileOnboardingScreenNavigationProp; +} + +/** + * Create profile screen for onboarding. + * @param navigation react-navigation navigation object + */ + +const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({ + route, + navigation, +}) => { + const y: Animated.Value<number> = Animated.useValue(0); + const {userId, username} = route.params; + const { + profile: {website, biography, birthday, gender}, + avatar, + cover, + updateIsEditedProfile, + } = React.useContext(AuthContext); + const [needsUpdate, setNeedsUpdate] = useState(false); + + useEffect(() => { + updateIsEditedProfile(needsUpdate); + }, [needsUpdate, updateIsEditedProfile]); + + const [isCustomGender, setIsCustomGender] = React.useState<boolean>( + gender !== '' && gender !== 'female' && gender !== 'male', + ); + + const [form, setForm] = React.useState({ + largePic: cover ? cover : '', + smallPic: avatar ? avatar : '', + website: website ? website : '', + bio: biography ? biography : '', + birthdate: birthday && moment(birthday).format('YYYY-MM-DD'), + gender: isCustomGender ? 'custom' : gender, + customGenderText: isCustomGender ? gender : '', + isValidWebsite: true, + isValidBio: true, + isValidGender: true, + attemptedSubmit: false, + }); + // refs for changing focus + const bioRef = React.useRef(); + const birthdateRef = React.useRef(); + const genderRef = React.useRef(); + const customGenderRef = React.useRef(); + /** + * Handles focus change to the next input field. + * @param field key for field to move focus onto + */ + const handleFocusChange = (field: string): void => { + switch (field) { + case 'bio': + const bioField: any = bioRef.current; + bioField.focus(); + break; + case 'birthdate': + const birthdateField: any = birthdateRef.current; + birthdateField.focus(); + break; + case 'gender': + const genderField: any = genderRef.current; + genderField.focus(); + break; + case 'customGender': + const customGenderField: any = customGenderRef.current; + customGenderField.focus(); + break; + default: + return; + } + }; + + /** + * Profile screen "Add Large Profile Pic Here" button + */ + const LargeProfilePic = () => ( + <TouchableOpacity + accessible={true} + accessibilityLabel="ADD LARGE PROFILE PIC HERE" + onPress={goToGalleryLargePic} + style={styles.largeProfileUploader}> + {form.largePic ? ( + <Image source={{uri: form.largePic}} style={styles.largeProfilePic} /> + ) : ( + <Text style={styles.largeProfileText}>ADD LARGE PROFILE PIC HERE</Text> + )} + </TouchableOpacity> + ); + + /** + * Profile screen "Add Smaller Profile Pic Here" button + */ + const SmallProfilePic = () => ( + <TouchableOpacity + accessible={true} + accessibilityLabel="ADD SMALLER PIC" + onPress={goToGallerySmallPic} + style={styles.smallProfileUploader}> + {form.smallPic ? ( + <Image source={{uri: form.smallPic}} style={styles.smallProfilePic} /> + ) : ( + <Text style={styles.smallProfileText}>ADD SMALLER PIC</Text> + )} + </TouchableOpacity> + ); + + /* + * Handles tap on add profile picture buttons by navigating to camera access + * and selecting a picture from gallery for large profile picture + */ + const goToGalleryLargePic = () => { + ImagePicker.openPicker({ + width: 580, + height: 580, + cropping: true, + cropperToolbarTitle: 'Large profile picture', + mediaType: 'photo', + }) + .then((picture) => { + if ('path' in picture) { + setForm({ + ...form, + largePic: picture.path, + }); + } + }) + .catch(() => {}); + }; + + /* + * Handles tap on add profile picture buttons by navigating to camera access + * and selecting a picture from gallery for small profile picture + */ + const goToGallerySmallPic = () => { + ImagePicker.openPicker({ + width: 580, + height: 580, + cropping: true, + cropperToolbarTitle: 'Small profile picture', + mediaType: 'photo', + cropperCircleOverlay: true, + }) + .then((picture) => { + if ('path' in picture) { + setForm({ + ...form, + smallPic: picture.path, + }); + } + }) + .catch(() => {}); + }; + + /* + * Handles changes to the website field value and verifies the input by updating state and running a validation function. + */ + const handleWebsiteUpdate = (website: string) => { + website = website.trim(); + let isValidWebsite: boolean = websiteRegex.test(website); + setForm({ + ...form, + website, + isValidWebsite, + }); + }; + + /* + * Handles changes to the bio field value and verifies the input by updating state and running a validation function. + */ + const handleBioUpdate = (bio: string) => { + let isValidBio: boolean = bioRegex.test(bio); + setForm({ + ...form, + bio, + isValidBio, + }); + }; + + const handleGenderUpdate = (gender: string) => { + if (gender === 'custom') { + setForm({...form, gender}); + setIsCustomGender(true); + } else if (gender === null) { + // not doing anything will make the picker "bounce back" + } else { + setIsCustomGender(false); + let isValidGender: boolean = true; + setForm({ + ...form, + gender, + isValidGender, + }); + } + }; + + const handleCustomGenderUpdate = (customGenderText: string) => { + let isValidGender: boolean = genderRegex.test(customGenderText); + customGenderText = customGenderText.replace(' ', '-'); + setForm({ + ...form, + customGenderText, + isValidGender, + }); + }; + + const handleBirthdateUpdate = (birthdate: Date) => { + setForm({ + ...form, + birthdate: birthdate && moment(birthdate).format('YYYY-MM-DD'), + }); + }; + + const handleSubmit = useCallback(async () => { + if (!form.largePic) { + Alert.alert('Please upload a large profile picture!'); + return; + } + if (!form.smallPic) { + Alert.alert('Please upload a small profile picture!'); + return; + } + if (!form.attemptedSubmit) { + setForm({ + ...form, + attemptedSubmit: true, + }); + } + let invalidFields: boolean = false; + const request = new FormData(); + if (form.largePic) { + request.append('largeProfilePicture', { + uri: form.largePic, + name: 'large_profile_pic.jpg', + type: 'image/jpg', + }); + } + if (form.smallPic) { + request.append('smallProfilePicture', { + uri: form.smallPic, + name: 'small_profile_pic.jpg', + type: 'image/jpg', + }); + } + if (form.website) { + if (form.isValidWebsite) { + request.append('website', form.website); + } else { + setForm({...form, attemptedSubmit: false}); + setTimeout(() => setForm({...form, attemptedSubmit: true})); + invalidFields = true; + } + } + + if (form.bio) { + if (form.isValidBio) { + request.append('biography', form.bio); + } else { + setForm({...form, attemptedSubmit: false}); + setTimeout(() => setForm({...form, attemptedSubmit: true})); + invalidFields = true; + } + } + + if (form.birthdate) { + request.append('birthday', form.birthdate); + } + + if (isCustomGender) { + if (form.isValidGender) { + request.append('gender', form.customGenderText); + } else { + setForm({...form, attemptedSubmit: false}); + setTimeout(() => setForm({...form, attemptedSubmit: true})); + invalidFields = true; + } + } else { + if (form.isValidGender) { + request.append('gender', form.gender); + } + } + + if (invalidFields) { + return; + } + + const endpoint = EDIT_PROFILE_ENDPOINT + `${userId}/`; + try { + const token = await AsyncStorage.getItem('token'); + let response = await fetch(endpoint, { + method: 'PATCH', + headers: { + 'Content-Type': 'multipart/form-data', + Authorization: 'Token ' + token, + }, + body: request, + }); + let statusCode = response.status; + let data = await response.json(); + if (statusCode === 200) { + setNeedsUpdate(true); + navigation.pop(); + } else if (statusCode === 400) { + Alert.alert( + 'Profile update failed. 😔', + data.error || 'Something went wrong! ðŸ˜', + ); + } else { + Alert.alert( + 'Something went wrong! ðŸ˜', + "Would you believe me if I told you that I don't know what happened?", + ); + } + } catch (error) { + Alert.alert( + 'Profile creation failed 😓', + 'Please double-check your network connection and retry.', + ); + return { + name: 'Profile creation error', + description: error, + }; + } + }, [isCustomGender, form, navigation, userId]); + + React.useLayoutEffect(() => { + navigation.setOptions({ + headerRight: () => ( + <Button + title={'Save'} + buttonStyle={{backgroundColor: 'transparent'}} + titleStyle={{fontWeight: 'bold'}} + onPress={handleSubmit} + /> + ), + }); + }, [navigation, handleSubmit]); + + return ( + <Background centered> + <SafeAreaView> + <Animated.ScrollView + style={styles.container} + onScroll={(e) => y.setValue(e.nativeEvent.contentOffset.y)} + showsHorizontalScrollIndicator={false} + showsVerticalScrollIndicator={true} + scrollEventThrottle={1} + alwaysBounceVertical + contentContainerStyle={{paddingBottom: SCREEN_HEIGHT / 15}}> + <StatusBar barStyle="light-content" translucent={false} /> + <View + style={{ + position: 'relative', + alignSelf: 'center', + }}> + <View> + <View style={styles.profile}> + <LargeProfilePic /> + <SmallProfilePic /> + </View> + <View + style={{ + position: 'relative', + width: 280, + alignSelf: 'center', + }}> + <TaggInput + accessibilityHint="Enter a website." + accessibilityLabel="Website input field." + placeholder="Website" + autoCompleteType="off" + textContentType="URL" + autoCapitalize="none" + returnKeyType="next" + onChangeText={handleWebsiteUpdate} + onSubmitEditing={() => handleFocusChange('bio')} + blurOnSubmit={false} + valid={form.isValidWebsite} + attemptedSubmit={form.attemptedSubmit} + invalidWarning={ + 'Website must be a valid link to your website' + } + width={280} + value={form.website} + /> + <TaggBigInput + accessibilityHint="Enter a bio." + accessibilityLabel="Bio input field." + placeholder="Bio" + autoCompleteType="off" + textContentType="none" + autoCapitalize="none" + returnKeyType="next" + onChangeText={handleBioUpdate} + onSubmitEditing={() => handleFocusChange('bio')} + blurOnSubmit={false} + ref={bioRef} + valid={form.isValidBio} + attemptedSubmit={form.attemptedSubmit} + invalidWarning={ + 'Bio must be less than 150 characters and must contain valid characters' + } + width={280} + value={form.bio} + /> + <BirthDatePicker + ref={birthdateRef} + handleBDUpdate={handleBirthdateUpdate} + width={280} + date={form.birthdate} + showPresetdate={true} + /> + + <TaggDropDown + value={form.gender} + onValueChange={(value: string) => handleGenderUpdate(value)} + items={[ + {label: 'Male', value: 'male'}, + {label: 'Female', value: 'female'}, + {label: 'Custom', value: 'custom'}, + ]} + placeholder={{ + label: 'Gender', + value: null, + color: '#fff', + }} + /> + {isCustomGender && ( + <TaggInput + style={styles.customGenderInput} + value={form.customGenderText} + accessibilityHint="Custom" + accessibilityLabel="Gender input field." + placeholder="Enter your gender" + autoCompleteType="off" + textContentType="none" + autoCapitalize="none" + returnKeyType="next" + blurOnSubmit={false} + ref={customGenderRef} + onChangeText={handleCustomGenderUpdate} + onSubmitEditing={() => handleSubmit()} + valid={form.isValidGender} + attemptedSubmit={form.attemptedSubmit} + invalidWarning={ + 'Custom field can only contain letters and hyphens' + } + /> + )} + </View> + </View> + </View> + </Animated.ScrollView> + </SafeAreaView> + <TabsGradient /> + </Background> + ); +}; + +const styles = StyleSheet.create({ + container: { + marginTop: '10%', + flex: 1, + flexDirection: 'column', + width: '100%', + }, + profile: { + flexDirection: 'row', + marginBottom: '5%', + justifyContent: 'flex-end', + }, + largeProfileUploader: { + justifyContent: 'center', + alignItems: 'center', + padding: 15, + backgroundColor: '#fff', + marginLeft: '13%', + marginTop: '5%', + height: 230, + width: 230, + borderRadius: 23, + }, + largeProfileText: { + textAlign: 'center', + fontSize: 14, + fontWeight: 'bold', + color: '#863FF9', + }, + largeProfilePic: { + height: 230, + width: 230, + borderRadius: 23, + }, + smallProfileUploader: { + justifyContent: 'center', + alignItems: 'center', + padding: 20, + backgroundColor: '#E1F0FF', + right: '18%', + marginTop: '38%', + height: 110, + width: 110, + borderRadius: 55, + }, + smallProfileText: { + textAlign: 'center', + fontSize: 14, + fontWeight: 'bold', + color: '#806DF4', + }, + smallProfilePic: { + height: 110, + width: 110, + borderRadius: 55, + }, + submitBtn: { + backgroundColor: '#8F01FF', + justifyContent: 'center', + alignItems: 'center', + width: 150, + height: 40, + borderRadius: 5, + marginTop: '5%', + }, + submitBtnLabel: { + fontSize: 16, + fontWeight: '500', + color: '#fff', + }, + customGenderInput: { + width: '100%', + height: 40, + fontSize: 16, + fontWeight: '600', + color: '#fff', + borderColor: '#fffdfd', + borderWidth: 2, + borderRadius: 20, + paddingLeft: 13, + }, +}); + +export default ProfileOnboarding; diff --git a/src/screens/profile/MomentCommentsScreen.tsx b/src/screens/profile/MomentCommentsScreen.tsx index 0d685ad1..7a0bfa66 100644 --- a/src/screens/profile/MomentCommentsScreen.tsx +++ b/src/screens/profile/MomentCommentsScreen.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import {RouteProp, useNavigation} from '@react-navigation/native'; import {ProfileStackParams} from '../../routes/profile'; -import {CenteredView, CommentTile, OverlayView} from '../../components'; +import {CenteredView, CommentTile} from '../../components'; import {CommentType} from '../../types'; import {ScrollView, StyleSheet, Text, View} from 'react-native'; import {SCREEN_WIDTH} from '../../utils/screenDimensions'; diff --git a/src/screens/profile/ProfileScreen.tsx b/src/screens/profile/ProfileScreen.tsx index 9579a696..d32eca98 100644 --- a/src/screens/profile/ProfileScreen.tsx +++ b/src/screens/profile/ProfileScreen.tsx @@ -1,9 +1,9 @@ -import React from 'react'; +import React, {useContext, useEffect} from 'react'; import {StatusBar} from 'react-native'; import Animated from 'react-native-reanimated'; import {Content, Cover, TabsGradient} from '../../components'; import {RouteProp} from '@react-navigation/native'; -import {ProfileStackParams, ProfileProvider} from '../../routes/'; +import {ProfileStackParams, ProfileProvider, AuthContext} from '../../routes/'; /** * Profile Screen for a user's profile @@ -19,6 +19,11 @@ interface ProfileOnboardingProps { const ProfileScreen: React.FC<ProfileOnboardingProps> = ({route}) => { const {isProfileView, username, userId} = route.params; const y = Animated.useValue(0); + const {updateIsEditedProfile} = useContext(AuthContext); + + useEffect(() => { + updateIsEditedProfile(false); + }); const profileView = () => { return ( diff --git a/src/screens/profile/index.ts b/src/screens/profile/index.ts index c2bd4c4b..3bfe5d30 100644 --- a/src/screens/profile/index.ts +++ b/src/screens/profile/index.ts @@ -4,3 +4,4 @@ export {default as CaptionScreen} from './CaptionScreen'; export {default as IndividualMoment} from './IndividualMoment'; export {default as MomentCommentsScreen} from './MomentCommentsScreen'; export {default as FollowersListScreen} from './FollowersListScreen'; +export {default as EditProfile} from './EditProfile'; diff --git a/src/screens/search/SearchScreen.tsx b/src/screens/search/SearchScreen.tsx index f528358a..aef3d0a8 100644 --- a/src/screens/search/SearchScreen.tsx +++ b/src/screens/search/SearchScreen.tsx @@ -19,7 +19,7 @@ import { SearchResultsBackground, TabsGradient, } from '../../components'; -import {SEARCH_ENDPOINT} from '../../constants'; +import {SEARCH_ENDPOINT, TAGG_TEXT_LIGHT_BLUE} from '../../constants'; import {AuthContext} from '../../routes/authentication'; import {ProfilePreviewType, UserType} from '../../types'; import {SCREEN_HEIGHT, SCREEN_WIDTH, StatusBarHeight} from '../../utils'; @@ -191,7 +191,7 @@ const styles = StyleSheet.create({ clear: { fontSize: 17, fontWeight: 'bold', - color: '#698DD3', + color: TAGG_TEXT_LIGHT_BLUE, }, image: { width: SCREEN_WIDTH, |