diff options
author | Ashm Walia <40498934+ashmgarv@users.noreply.github.com> | 2020-12-04 08:50:24 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-04 11:50:24 -0500 |
commit | 0fd892ad288f2e1eaaa4fdf5e1fd6f15dbd45860 (patch) | |
tree | d7d53d94c6c4026ac9b325508ebce4706d412ac4 /src/components/profile/Content.tsx | |
parent | f620102190629e0b6f180d3ce056d850b1db5aaa (diff) |
[TMA - 398 AND TMA-430] Replace Providers with Redux Store (#125)
* First
* WIP
* Thunk
* Some more comments
* sc
* recent searches and follounfollow
* Edit profile dummy
* Block / unblock and some cleanup
* Replace auth provider
* Sc
* Delete AP after rebase
* Discover users
* Cleanup
* More cleanup
* Replace profile provider
* Fixed build failure
* Fixed a bug reported
* Prevent app crash when backend server is down
Diffstat (limited to 'src/components/profile/Content.tsx')
-rw-r--r-- | src/components/profile/Content.tsx | 167 |
1 files changed, 93 insertions, 74 deletions
diff --git a/src/components/profile/Content.tsx b/src/components/profile/Content.tsx index 13db60a5..73f6fad3 100644 --- a/src/components/profile/Content.tsx +++ b/src/components/profile/Content.tsx @@ -1,9 +1,13 @@ -import AsyncStorage from '@react-native-community/async-storage'; -import React, {useCallback, useEffect, useState} from 'react'; +import React, {useCallback, useEffect, useState, useContext} from 'react'; import {LayoutChangeEvent, StyleSheet, View} from 'react-native'; import Animated from 'react-native-reanimated'; -import {AuthContext, ProfileContext} from '../../routes/'; -import {MomentType} from 'src/types'; +import { + MomentType, + ProfilePreviewType, + ProfileType, + ScreenType, + UserType, +} from '../../types'; import {defaultMoments} from '../../constants'; import {SCREEN_HEIGHT} from '../../utils'; import TaggsBar from '../taggs/TaggsBar'; @@ -11,26 +15,49 @@ import {Moment} from '../moments'; import ProfileBody from './ProfileBody'; import ProfileCutout from './ProfileCutout'; import ProfileHeader from './ProfileHeader'; -import {followOrUnfollowUser, blockOrUnblockUser} from '../../services'; +import {useDispatch, useSelector, useStore} from 'react-redux'; +import {RootState} from '../../store/rootreducer'; +import { + followUnfollowUser, + blockUnblockUser, + loadFollowData, + updateUserXFollowersAndFollowing, +} from '../../store/actions'; +import { + NO_USER, + NO_PROFILE, + EMPTY_PROFILE_PREVIEW_LIST, + EMPTY_MOMENTS_LIST, +} from '../../store/initialStates'; interface ContentProps { y: Animated.Value<number>; - isProfileView: boolean; + userXId: string; + screenType: ScreenType; } -const Content: React.FC<ContentProps> = ({y, isProfileView}) => { - const [profileBodyHeight, setProfileBodyHeight] = useState(0); - const {user, moments, followers, following, updateFollowers} = isProfileView - ? React.useContext(ProfileContext) - : React.useContext(AuthContext); - - const { - logout, - user: loggedInUser, - updateFollowers: updateLoggedInUserFollowers, - blockedUsers, - updateBlockedUsers, - } = React.useContext(AuthContext); +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 {followers = EMPTY_PROFILE_PREVIEW_LIST} = userXId + ? useSelector((state: RootState) => state.userX[screenType][userXId]) + : useSelector((state: RootState) => state.follow); + + const {moments = EMPTY_MOMENTS_LIST} = userXId + ? useSelector((state: RootState) => state.userX[screenType][userXId]) + : useSelector((state: RootState) => state.moments); + + 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(); /** * States @@ -38,8 +65,9 @@ const Content: React.FC<ContentProps> = ({y, isProfileView}) => { const [imagesMap, setImagesMap] = useState<Map<string, MomentType[]>>( new Map(), ); - const [isFollowed, setIsFollowed] = React.useState<boolean>(false); - const [isBlocked, setIsBlocked] = React.useState<boolean>(false); + const [isFollowed, setIsFollowed] = useState<boolean>(false); + const [isBlocked, setIsBlocked] = useState<boolean>(false); + const [profileBodyHeight, setProfileBodyHeight] = useState(0); /** * If own profile is being viewed then do not show the follow button. @@ -51,8 +79,6 @@ const Content: React.FC<ContentProps> = ({y, isProfileView}) => { setProfileBodyHeight(height); }; - const {userId} = user; - const createImagesMap = useCallback(() => { var map = new Map(); moments.forEach(function (imageObject) { @@ -68,9 +94,6 @@ const Content: React.FC<ContentProps> = ({y, isProfileView}) => { }, [moments]); useEffect(() => { - if (!userId) { - return; - } createImagesMap(); }, [createImagesMap]); @@ -78,9 +101,6 @@ const Content: React.FC<ContentProps> = ({y, isProfileView}) => { * This hook is called on load of profile and when you update the followers list. */ useEffect(() => { - if (!userId) { - return; - } const isActuallyFollowed = followers.some( (follower) => follower.username === loggedInUser.username, ); @@ -90,62 +110,63 @@ const Content: React.FC<ContentProps> = ({y, isProfileView}) => { }, [followers]); useEffect(() => { - if (!userId) { - return; - } - const isActuallyBlocked = blockedUsers.some( (cur_user) => user.username === cur_user.username, ); if (isBlocked != isActuallyBlocked) { setIsBlocked(isActuallyBlocked); } - }, [blockedUsers]); + }, [blockedUsers, user]); + + /** + * The object returned by this method is added to the list of blocked / followed users by the reducer. + * Which helps us prevent an extra api call to the backend just to fetch a user. + */ + const getUserAsProfilePreviewType = ( + passedInUser: UserType, + passedInProfile: ProfileType, + ): ProfilePreviewType => { + const fullName = passedInProfile.name.split(' '); + return { + id: passedInUser.userId, + username: passedInUser.username, + first_name: fullName[0], + last_name: fullName[1], + }; + }; /** * Handles a click on the follow / unfollow button. - * updateFollowers and updateLoggedInUerFollowers to make sure that we update followers list / count for both the users in context. + * followUnfollowUser takes care of updating the following list for loggedInUser + * updateUserXFollowersAndFollowing updates followers and following list for the followed user. */ + const handleFollowUnfollow = async () => { - const token = await AsyncStorage.getItem('token'); - if (!token) { - logout(); - return; - } - const isUpdatedSuccessful = await followOrUnfollowUser( - loggedInUser.userId, - userId, - token, - isFollowed, + await dispatch( + followUnfollowUser( + loggedInUser, + getUserAsProfilePreviewType(user, profile), + isFollowed, + ), ); - if (isUpdatedSuccessful) { - setIsFollowed(!isFollowed); - updateFollowers(true); - updateLoggedInUserFollowers(true); - } + await dispatch(updateUserXFollowersAndFollowing(user.userId, state)); }; /** * Handles a click on the block / unblock button. + * loadFollowData updates followers / following list for the logged in user + * updateUserXFollowersAndFollowing updates followers and following list for the followed user. */ const handleBlockUnblock = async () => { - const token = await AsyncStorage.getItem('token'); - if (!token) { - logout(); - return; - } - const isUpdatedSuccessful = await blockOrUnblockUser( - loggedInUser.userId, - userId, - token, - isBlocked, + await dispatch( + blockUnblockUser( + loggedInUser, + getUserAsProfilePreviewType(user, profile), + isBlocked, + ), ); - if (isUpdatedSuccessful) { - setIsBlocked(!isBlocked); - updateBlockedUsers(true); - updateFollowers(true); - updateLoggedInUserFollowers(true); - } + await dispatch(loadFollowData(loggedInUser.userId)); + await dispatch(updateUserXFollowersAndFollowing(user.userId, state)); }; return ( @@ -155,15 +176,12 @@ const Content: React.FC<ContentProps> = ({y, isProfileView}) => { showsVerticalScrollIndicator={false} scrollEventThrottle={1}> <ProfileCutout /> - <ProfileHeader - isProfileView={isProfileView} - numFollowing={following.length} - numFollowers={followers.length} - /> + <ProfileHeader {...{userXId, screenType}} /> <ProfileBody {...{ onLayout, - isProfileView, + userXId, + screenType, isOwnProfile, isFollowed, handleFollowUnfollow, @@ -171,14 +189,15 @@ const Content: React.FC<ContentProps> = ({y, isProfileView}) => { handleBlockUnblock, }} /> - <TaggsBar {...{y, profileBodyHeight, isProfileView}} /> + <TaggsBar {...{y, profileBodyHeight, userXId, screenType}} /> <View style={styles.momentsContainer}> {defaultMoments.map((title, index) => ( <Moment key={index} title={title} images={imagesMap.get(title)} - isProfileView={isProfileView} + userXId={userXId} + screenType={screenType} /> ))} </View> |