diff options
author | Ivan Chen <ivan@tagg.id> | 2021-03-29 18:17:46 -0400 |
---|---|---|
committer | Ivan Chen <ivan@tagg.id> | 2021-03-29 18:17:46 -0400 |
commit | d5669f3d08bee68b37f51727e499e84610685422 (patch) | |
tree | 8de9664c49e63833504aafd69ca8f965249d412d /src/components/profile/Content.tsx | |
parent | d1e5d18c36af46b450ec7d019550c05b1a78f2db (diff) | |
parent | b0e4fe55be8983079f499b923e953855afeb2c64 (diff) |
Merge branch 'master' into tma739-bugfix-profile-onboarding-tutorial
# Conflicts:
# src/components/profile/Content.tsx
Diffstat (limited to 'src/components/profile/Content.tsx')
-rw-r--r-- | src/components/profile/Content.tsx | 310 |
1 files changed, 32 insertions, 278 deletions
diff --git a/src/components/profile/Content.tsx b/src/components/profile/Content.tsx index c0cae4b8..9c33eabc 100644 --- a/src/components/profile/Content.tsx +++ b/src/components/profile/Content.tsx @@ -1,95 +1,56 @@ -import {useFocusEffect, useNavigation} from '@react-navigation/native'; -import React, {useCallback, useEffect, useState, useRef} from 'react'; +import React, {useCallback, useEffect, useRef, useState} from 'react'; import { - Alert, LayoutChangeEvent, NativeScrollEvent, NativeSyntheticEvent, RefreshControl, StyleSheet, - 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 './Cover'; -import GreyPlusLogo from '../../assets/icons/grey-plus-logo.svg'; -import {COVER_HEIGHT, TAGG_LIGHT_BLUE} from '../../constants'; -import { - UPLOAD_MOMENT_PROMPT_THREE_HEADER, - UPLOAD_MOMENT_PROMPT_THREE_MESSAGE, - UPLOAD_MOMENT_PROMPT_TWO_HEADER, - UPLOAD_MOMENT_PROMPT_TWO_MESSAGE, -} from '../../constants/strings'; +import {COVER_HEIGHT} from '../../constants'; import { blockUnblockUser, - deleteUserMomentsForCategory, loadFriendsData, - updateMomentCategories, updateUserXFriends, } 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 {ContentProps} from '../../types'; import { + canViewProfile, fetchUserX, getUserAsProfilePreviewType, - moveCategory, - normalize, SCREEN_HEIGHT, userLogin, } from '../../utils'; -import {TaggPrompt} from '../common'; -import {Moment} from '../moments'; import TaggsBar from '../taggs/TaggsBar'; +import Cover from './Cover'; +import PrivateProfile from './PrivateProfile'; import ProfileBody from './ProfileBody'; import ProfileCutout from './ProfileCutout'; import ProfileHeader from './ProfileHeader'; - -interface ContentProps { - y: Animated.Value<number>; - userXId: string | undefined; - screenType: ScreenType; -} +import PublicProfile from './PublicProfile'; const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => { const dispatch = useDispatch(); - - const {user = NO_USER, profile = NO_PROFILE} = userXId - ? useSelector((state: RootState) => state.userX[screenType][userXId]) - : useSelector((state: RootState) => state.user); - - const {friends = EMPTY_PROFILE_PREVIEW_LIST} = userXId - ? useSelector((state: RootState) => state.userX[screenType][userXId]) - : useSelector((state: RootState) => state.friends); - const { - friends: friendsLoggedInUser = EMPTY_PROFILE_PREVIEW_LIST, - } = useSelector((state: RootState) => state.friends); - - const {moments = EMPTY_MOMENTS_LIST} = userXId - ? useSelector((state: RootState) => state.userX[screenType][userXId]) - : useSelector((state: RootState) => state.moments); - - const {momentCategories = []} = userXId - ? useSelector((state: RootState) => state.userX[screenType][userXId]) - : useSelector((state: RootState) => state.momentCategories); - + user = NO_USER, + profile = NO_PROFILE, + } = useSelector((state: RootState) => + userXId ? state.userX[screenType][userXId] : state.user, + ); const {blockedUsers = EMPTY_PROFILE_PREVIEW_LIST} = useSelector( (state: RootState) => state.blocked, ); const {user: loggedInUser = NO_USER} = useSelector( (state: RootState) => state.user, ); - const state = useStore().getState(); - - const navigation = useNavigation(); + const state: RootState = useStore().getState(); /* * Used to imperatively scroll to the top when presenting the moment tutorial. @@ -103,35 +64,20 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => { /** * States */ - const [imagesMap, setImagesMap] = useState<Map<string, MomentType[]>>( - new Map(), - ); - const [isFriend, setIsFriend] = useState<boolean>(false); const [isBlocked, setIsBlocked] = useState<boolean>(false); const [profileBodyHeight, setProfileBodyHeight] = useState(0); const [shouldBounce, setShouldBounce] = useState<boolean>(true); const [refreshing, setRefreshing] = useState<boolean>(false); - const [isStageTwoPromptClosed, setIsStageTwoPromptClosed] = useState<boolean>( - false, - ); - const [isStageOnePromptClosed, setIsStageOnePromptClosed] = useState<boolean>( - false, - ); - const [ - isStageThreePromptClosed, - setIsStageThreePromptClosed, - ] = useState<boolean>(false); - const onRefresh = useCallback(() => { const refrestState = async () => { + setRefreshing(true); if (!userXId) { await userLogin(dispatch, loggedInUser); } else { await fetchUserX(dispatch, user, screenType); } }; - setRefreshing(true); refrestState().then(() => { setRefreshing(false); }); @@ -142,92 +88,11 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => { setProfileBodyHeight(height); }; - const createImagesMap = useCallback(() => { - var map = new Map(); - moments.forEach(function (imageObject) { - var moment_category = imageObject.moment_category; - if (map.has(moment_category)) { - map.get(moment_category).push(imageObject); - } else { - map.set(moment_category, [imageObject]); - } - }); - setImagesMap(map); - }, [moments]); - - useEffect(() => { - createImagesMap(); - }, [createImagesMap]); - - const move = (direction: 'up' | 'down', title: string) => { - let categories = [...momentCategories]; - categories = moveCategory(categories, title, direction === 'up'); - dispatch(updateMomentCategories(categories, false)); - }; - - /** - * Prompt user to perform an activity based on their profile completion stage - * To fire 2 seconds after the screen comes in focus - * 1 means STAGE_1: - * The user must upload a moment, so take them to a screen guiding them to post a moment - * 2 means STAGE_2: - * The user must create another category so show a prompt on top of the screen - * 3 means STAGE_3: - * The user must upload a moment to the second category, so show a prompt on top of the screen - * Else, profile is complete and no prompt needs to be shown - */ - useFocusEffect( - useCallback(() => { - setScrollEnabled(false); - const navigateToMomentUploadPrompt = () => { - switch (profile.profile_completion_stage) { - case 1: - if ( - momentCategories && - momentCategories[0] && - !isStageOnePromptClosed - ) { - navigation.navigate('MomentUploadPrompt', { - screenType, - momentCategory: momentCategories[0], - profileBodyHeight, - }); - setIsStageOnePromptClosed(true); - } - break; - case 2: - setIsStageTwoPromptClosed(false); - break; - case 3: - setIsStageThreePromptClosed(false); - break; - default: - break; - } - }; - if (!userXId) { - setTimeout(() => { - if (scrollViewRef.current) { - scrollViewRef.current.getNode().scrollTo({y: 0}); - } - navigateToMomentUploadPrompt(); - setScrollEnabled(true); - }, 2000); - } - }, [ - profile.profile_completion_stage, - momentCategories, - userXId, - isStageOnePromptClosed, - profileBodyHeight, - ]), - ); - useEffect(() => { const isActuallyBlocked = blockedUsers.some( (cur_user) => user.username === cur_user.username, ); - if (isBlocked != isActuallyBlocked) { + if (isBlocked !== isActuallyBlocked) { setIsBlocked(isActuallyBlocked); } }, [blockedUsers, user]); @@ -252,37 +117,6 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => { } }; - /** - * Handle deletion of a category - * Confirm with user before deleting the category - * @param category category to be deleted - */ - const handleCategoryDeletion = (category: string) => { - Alert.alert( - 'Category Deletion', - `Are you sure that you want to delete the category ${category} ?`, - [ - { - text: 'Cancel', - style: 'cancel', - }, - { - text: 'Yes', - onPress: () => { - dispatch( - updateMomentCategories( - momentCategories.filter((mc) => mc !== category), - false, - ), - ); - dispatch(deleteUserMomentsForCategory(category)); - }, - }, - ], - {cancelable: true}, - ); - }; - const handleScroll = (e: NativeSyntheticEvent<NativeScrollEvent>) => { /** * Set the new y position @@ -304,6 +138,7 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => { return ( <Animated.ScrollView ref={scrollViewRef} + contentContainerStyle={styles.contentContainer} style={styles.container} onScroll={(e) => handleScroll(e)} bounces={shouldBounce} @@ -324,7 +159,6 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => { onLayout, userXId, screenType, - isFriend, handleBlockUnblock, isBlocked, }} @@ -333,111 +167,31 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => { {...{y, profileBodyHeight, userXId, screenType}} whiteRing={undefined} /> - <View style={styles.momentsContainer}> - {userXId && moments.length === 0 && ( - <View style={styles.plusIconContainer}> - <GreyPlusLogo width={90} height={90} /> - <Text style={styles.noMomentsText}>{`Looks like ${ - profile.name.split(' ')[0] - } has not posted any moments yet`}</Text> - </View> - )} - {!userXId && - profile.profile_completion_stage === 2 && - !isStageTwoPromptClosed && ( - <TaggPrompt - messageHeader={UPLOAD_MOMENT_PROMPT_TWO_HEADER} - messageBody={UPLOAD_MOMENT_PROMPT_TWO_MESSAGE} - logoType="" - onClose={() => { - setIsStageTwoPromptClosed(true); - }} - /> - )} - {!userXId && - profile.profile_completion_stage === 3 && - !isStageThreePromptClosed && ( - <TaggPrompt - messageHeader={UPLOAD_MOMENT_PROMPT_THREE_HEADER} - messageBody={UPLOAD_MOMENT_PROMPT_THREE_MESSAGE} - logoType="" - onClose={() => { - setIsStageThreePromptClosed(true); - }} - /> - )} - {momentCategories.map( - (title, index) => - (!userXId || imagesMap.get(title)) && ( - <Moment - key={index} - title={title} - images={imagesMap.get(title)} - userXId={userXId} - screenType={screenType} - handleMomentCategoryDelete={handleCategoryDeletion} - shouldAllowDeletion={momentCategories.length > 1} - showUpButton={index !== 0} - showDownButton={index !== momentCategories.length - 1} - move={move} - /> - ), - )} - {!userXId && ( - <TouchableOpacity - onPress={() => - navigation.push('CategorySelection', { - screenType: CategorySelectionScreenType.Profile, - user: loggedInUser, - }) - } - style={styles.createCategoryButton}> - <Text style={styles.createCategoryButtonLabel}> - Create a new category - </Text> - </TouchableOpacity> - )} - </View> + {canViewProfile(state, userXId, screenType) ? ( + <PublicProfile + {...{ + y, + userXId, + screenType, + setScrollEnabled, + profileBodyHeight, + scrollViewRef, + }} + /> + ) : ( + <PrivateProfile /> + )} </Animated.ScrollView> ); }; const styles = StyleSheet.create({ container: { - flex: 1, backgroundColor: '#fff', - }, - momentsContainer: { - backgroundColor: '#f2f2f2', - paddingBottom: SCREEN_HEIGHT / 10, flex: 1, - flexDirection: 'column', - }, - createCategoryButton: { - backgroundColor: TAGG_LIGHT_BLUE, - justifyContent: 'center', - alignItems: 'center', - width: '70%', - height: 30, - marginTop: '15%', - alignSelf: 'center', - }, - createCategoryButtonLabel: { - fontSize: normalize(16), - fontWeight: '500', - color: 'white', - }, - plusIconContainer: { - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center', - marginVertical: '10%', }, - noMomentsText: { - fontSize: normalize(14), - fontWeight: 'bold', - color: 'gray', - marginVertical: '8%', + contentContainer: { + flexGrow: 1, }, }); |