diff options
Diffstat (limited to 'src/components/profile')
| -rw-r--r-- | src/components/profile/Content.tsx | 91 | ||||
| -rw-r--r-- | src/components/profile/FriendsCount.tsx | 11 | ||||
| -rw-r--r-- | src/components/profile/ProfileBody.tsx | 35 | ||||
| -rw-r--r-- | src/components/profile/ProfileHeader.tsx | 44 | ||||
| -rw-r--r-- | src/components/profile/ProfileMoreInfoDrawer.tsx | 5 | ||||
| -rw-r--r-- | src/components/profile/ProfilePreview.tsx | 61 | ||||
| -rw-r--r-- | src/components/profile/ToggleButton.tsx | 8 | ||||
| -rw-r--r-- | src/components/profile/UniversityIcon.tsx | 12 |
8 files changed, 118 insertions, 149 deletions
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..851dbc3b 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; @@ -16,10 +17,10 @@ const FriendsCount: React.FC<FriendsCountProps> = ({ userXId, screenType, }) => { - const count = (userXId + const {friends} = userXId ? useSelector((state: RootState) => state.userX[screenType][userXId]) - : useSelector((state: RootState) => state.friends) - )?.friends.length; + : useSelector((state: RootState) => state.friends); + const count = friends ? friends.length : 0; const displayedCount: string = count < 5e3 @@ -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..1ee3ae2b 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'; @@ -105,8 +105,8 @@ const ProfileBody: React.FC<ProfileBodyProps> = ({ {friendship_status === 'friends' && ( <Button title={'Unfriend'} - buttonStyle={styles.button} - titleStyle={styles.buttonTitle} + buttonStyle={styles.requestedButton} + titleStyle={styles.requestedButtonTitle} onPress={handleFriendUnfriend} // unfriend, no record status /> )} @@ -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%', }, @@ -177,16 +176,17 @@ const styles = StyleSheet.create({ justifyContent: 'center', alignItems: 'center', width: SCREEN_WIDTH * 0.4, - height: SCREEN_WIDTH * 0.09, - borderColor: TAGG_TEXT_LIGHT_BLUE, - borderWidth: 3, - borderRadius: 5, + height: SCREEN_WIDTH * 0.075, + borderColor: TAGG_LIGHT_BLUE, + borderWidth: 2, + borderRadius: 0, marginRight: '2%', + marginLeft: '1%', padding: 0, backgroundColor: 'transparent', }, requestedButtonTitle: { - color: TAGG_TEXT_LIGHT_BLUE, + color: TAGG_LIGHT_BLUE, padding: 0, fontSize: 14, fontWeight: '700', @@ -201,11 +201,14 @@ const styles = StyleSheet.create({ justifyContent: 'center', alignItems: 'center', width: SCREEN_WIDTH * 0.4, - height: SCREEN_WIDTH * 0.09, + height: SCREEN_WIDTH * 0.075, padding: 0, - borderRadius: 5, + borderWidth: 2, + borderColor: TAGG_LIGHT_BLUE, + borderRadius: 0, marginRight: '2%', - backgroundColor: TAGG_TEXT_LIGHT_BLUE, + marginLeft: '1%', + 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..38defb8d 100644 --- a/src/components/profile/ProfilePreview.tsx +++ b/src/components/profile/ProfilePreview.tsx @@ -1,32 +1,21 @@ -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 {loadImageFromURL} from '../../services'; import {RootState} from '../../store/rootreducer'; -import {logout} from '../../store/actions'; +import {PreviewType, ProfilePreviewType, ScreenType} 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: '', - username: '', -}; /** * This component returns user's profile picture friended by username as a touchable component. @@ -44,28 +33,23 @@ interface ProfilePreviewProps extends ViewProps { } const ProfilePreview: React.FC<ProfilePreviewProps> = ({ - profilePreview: {username, first_name, last_name, id}, + profilePreview: {username, first_name, last_name, id, thumbnail_url}, previewType, screenType, }) => { const navigation = useNavigation(); const {user: loggedInUser} = useSelector((state: RootState) => state.user); - const [avatarURI, setAvatarURI] = useState<string | null>(null); - const [user, setUser] = useState<UserType>(NO_USER); + const [avatar, setAvatar] = useState<string | null>(null); const dispatch = useDispatch(); + useEffect(() => { - let mounted = true; - const loadAvatarImage = async () => { - const response = await loadAvatar(id, true); - if (mounted) { - setAvatarURI(response); + (async () => { + const response = await loadImageFromURL(thumbnail_url); + if (response) { + setAvatar(response); } - }; - loadAvatarImage(); - return () => { - mounted = false; - }; - }, [id]); + })(); + }, []); /** * Adds a searched user to the recently searched cache if they're tapped on. @@ -81,6 +65,7 @@ const ProfilePreview: React.FC<ProfilePreviewProps> = ({ username, first_name, last_name, + thumbnail_url, }; try { @@ -212,8 +197,8 @@ const ProfilePreview: React.FC<ProfilePreviewProps> = ({ <Image style={avatarStyle} source={ - avatarURI - ? {uri: avatarURI} + avatar + ? {uri: avatar} : require('../../assets/images/avatar-placeholder.png') } /> 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), }, }); |
