aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/comments/AddComment.tsx13
-rw-r--r--src/components/comments/CommentTile.tsx9
-rw-r--r--src/components/comments/CommentsCount.tsx9
-rw-r--r--src/components/common/AvatarTitle.tsx5
-rw-r--r--src/components/common/TaggLoadingIndicator.tsx27
-rw-r--r--src/components/common/index.ts2
-rw-r--r--src/components/common/post/Post.tsx28
-rw-r--r--src/components/common/post/PostHeader.tsx78
-rw-r--r--src/components/common/post/index.ts1
-rw-r--r--src/components/moments/Moment.tsx20
-rw-r--r--src/components/moments/MomentTile.tsx23
-rw-r--r--src/components/profile/Avatar.tsx18
-rw-r--r--src/components/profile/Content.tsx167
-rw-r--r--src/components/profile/Cover.tsx19
-rw-r--r--src/components/profile/FollowCount.tsx34
-rw-r--r--src/components/profile/Followers.tsx10
-rw-r--r--src/components/profile/MoreInfoDrawer.tsx6
-rw-r--r--src/components/profile/ProfileBody.tsx23
-rw-r--r--src/components/profile/ProfileHeader.tsx48
-rw-r--r--src/components/profile/ProfilePreview.tsx30
-rw-r--r--src/components/search/DiscoverUsers.tsx19
-rw-r--r--src/components/search/RecentSearches.tsx13
-rw-r--r--src/components/search/SearchResults.tsx14
-rw-r--r--src/components/taggs/Tagg.tsx41
-rw-r--r--src/components/taggs/TaggsBar.tsx61
25 files changed, 369 insertions, 349 deletions
diff --git a/src/components/comments/AddComment.tsx b/src/components/comments/AddComment.tsx
index ac1628da..f8c0b6bc 100644
--- a/src/components/comments/AddComment.tsx
+++ b/src/components/comments/AddComment.tsx
@@ -7,9 +7,11 @@ import {
View,
} from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
-import {AuthContext} from '../../routes';
import {TaggBigInput} from '../onboarding';
import {postMomentComment} from '../../services';
+import {logout} from '../../store/actions';
+import {useSelector, useDispatch} from 'react-redux';
+import {RootState} from '../../store/rootreducer';
/**
* This file provides the add comment view for a user.
@@ -27,11 +29,12 @@ const AddComment: React.FC<AddCommentProps> = ({
moment_id,
}) => {
const [comment, setComment] = React.useState('');
+
+ const dispatch = useDispatch();
const {
avatar,
- user: {userId, username},
- logout,
- } = React.useContext(AuthContext);
+ user: {userId},
+ } = useSelector((state: RootState) => state.user);
const handleCommentUpdate = (comment: string) => {
setComment(comment);
@@ -41,7 +44,7 @@ const AddComment: React.FC<AddCommentProps> = ({
try {
const token = await AsyncStorage.getItem('token');
if (!token) {
- logout();
+ dispatch(logout());
return;
}
const postedComment = await postMomentComment(
diff --git a/src/components/comments/CommentTile.tsx b/src/components/comments/CommentTile.tsx
index bee590f5..da78a4dc 100644
--- a/src/components/comments/CommentTile.tsx
+++ b/src/components/comments/CommentTile.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import {Text, View} from 'react-native-animatable';
import {ProfilePreview} from '../profile';
-import {CommentType} from '../../types';
+import {CommentType, ScreenType} from '../../types';
import {StyleSheet} from 'react-native';
import {getTimePosted} from '../../utils';
import ClockIcon from '../../assets/icons/clock-icon-01.svg';
@@ -12,9 +12,13 @@ import ClockIcon from '../../assets/icons/clock-icon-01.svg';
interface CommentTileProps {
comment_object: CommentType;
+ screenType: ScreenType;
}
-const CommentTile: React.FC<CommentTileProps> = ({comment_object}) => {
+const CommentTile: React.FC<CommentTileProps> = ({
+ comment_object,
+ screenType,
+}) => {
const timePosted = getTimePosted(comment_object.date_time);
return (
<View style={styles.container}>
@@ -26,6 +30,7 @@ const CommentTile: React.FC<CommentTileProps> = ({comment_object}) => {
last_name: '',
}}
previewType={'Comment'}
+ screenType={screenType}
/>
<View style={styles.body}>
<Text style={styles.comment}>{comment_object.comment}</Text>
diff --git a/src/components/comments/CommentsCount.tsx b/src/components/comments/CommentsCount.tsx
index a9d5b6d6..d210c39a 100644
--- a/src/components/comments/CommentsCount.tsx
+++ b/src/components/comments/CommentsCount.tsx
@@ -3,6 +3,7 @@ import {Text} from 'react-native-animatable';
import {StyleSheet, TouchableOpacity} from 'react-native';
import CommentIcon from '../../assets/icons/moment-comment-icon.svg';
import {useNavigation} from '@react-navigation/native';
+import {ScreenType} from '../../types';
/**
* Provides a view for the comment icon and the comment count.
@@ -11,20 +12,20 @@ import {useNavigation} from '@react-navigation/native';
type CommentsCountProps = {
comments_count: string;
- isProfileView: boolean;
moment_id: string;
+ screenType: ScreenType;
};
const CommentsCount: React.FC<CommentsCountProps> = ({
comments_count,
- isProfileView,
moment_id,
+ screenType,
}) => {
const navigation = useNavigation();
const navigateToCommentsScreen = async () => {
navigation.push('MomentCommentsScreen', {
- isProfileView: isProfileView,
- moment_id: moment_id,
+ moment_id,
+ screenType,
});
};
return (
diff --git a/src/components/common/AvatarTitle.tsx b/src/components/common/AvatarTitle.tsx
index 65ae7486..a38f46fa 100644
--- a/src/components/common/AvatarTitle.tsx
+++ b/src/components/common/AvatarTitle.tsx
@@ -2,12 +2,9 @@ import React from 'react';
import {Image, StyleSheet, View} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {TAGGS_GRADIENT} from '../../constants';
-import {AuthContext, ProfileContext} from '../../routes/';
-import {loadAvatar} from '../../services';
-import AsyncStorage from '@react-native-community/async-storage';
type AvatarTitleProps = {
- avatar: string;
+ avatar: string | null;
};
const AvatarTitle: React.FC<AvatarTitleProps> = ({avatar}) => {
return (
diff --git a/src/components/common/TaggLoadingIndicator.tsx b/src/components/common/TaggLoadingIndicator.tsx
new file mode 100644
index 00000000..cfb99e80
--- /dev/null
+++ b/src/components/common/TaggLoadingIndicator.tsx
@@ -0,0 +1,27 @@
+import * as React from 'react';
+import {ActivityIndicator, StyleSheet, View} from 'react-native';
+
+type TaggLoadingIndicatorProps = {
+ color: string;
+};
+const TaggLoadingIndicator: React.FC<TaggLoadingIndicatorProps> = ({color}) => {
+ return (
+ <View style={[styles.container, styles.horizontal]}>
+ <ActivityIndicator size="large" color={color} />
+ </View>
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ justifyContent: 'center',
+ },
+ horizontal: {
+ flexDirection: 'row',
+ justifyContent: 'space-around',
+ padding: 10,
+ },
+});
+
+export default TaggLoadingIndicator;
diff --git a/src/components/common/index.ts b/src/components/common/index.ts
index 0feeaab8..f6521497 100644
--- a/src/components/common/index.ts
+++ b/src/components/common/index.ts
@@ -15,4 +15,4 @@ export {default as ComingSoon} from './ComingSoon';
export {default as PostCarousel} from './PostCarousel';
export {default as TaggDatePicker} from './TaggDatePicker';
export {default as BottomDrawer} from './BottomDrawer';
-export * from './post';
+export {default as TaggLoadingTndicator} from './TaggLoadingIndicator';
diff --git a/src/components/common/post/Post.tsx b/src/components/common/post/Post.tsx
deleted file mode 100644
index 9fa167f2..00000000
--- a/src/components/common/post/Post.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import React from 'react';
-import {StyleSheet, View, Image} from 'react-native';
-import {PostType} from '../../../types';
-import PostHeader from './PostHeader';
-import {SCREEN_WIDTH} from '../../../utils';
-
-interface PostProps {
- post: PostType;
-}
-const Post: React.FC<PostProps> = ({post: {owner, social, data}}) => {
- return (
- <>
- <PostHeader post={data} owner={owner} social={social} />
- <View style={styles.image}>
- {data && <Image style={styles.image} source={{uri: data.media_url}} />}
- </View>
- </>
- );
-};
-
-const styles = StyleSheet.create({
- image: {
- width: SCREEN_WIDTH,
- height: SCREEN_WIDTH,
- backgroundColor: '#eee',
- },
-});
-export default Post;
diff --git a/src/components/common/post/PostHeader.tsx b/src/components/common/post/PostHeader.tsx
deleted file mode 100644
index 0e9c708b..00000000
--- a/src/components/common/post/PostHeader.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import React from 'react';
-import {UserType, InstagramPostType} from '../../../types';
-import {View, StyleSheet, Image, Text} from 'react-native';
-import {AuthContext} from '../../../routes/authentication';
-import SocialIcon from '../SocialIcon';
-import moment from 'moment';
-
-const AVATAR_DIM = 35;
-interface PostHeaderProps {
- owner: UserType;
- post: InstagramPostType | undefined;
- social: string;
-}
-const PostHeader: React.FC<PostHeaderProps> = ({
- owner: {username},
- post,
- social,
-}) => {
- const {avatar} = React.useContext(AuthContext);
-
- return (
- <View style={styles.container}>
- <View style={styles.topRow}>
- <Image
- style={styles.avatar}
- source={
- avatar
- ? {uri: avatar}
- : require('../../../assets/images/avatar-placeholder.png')
- }
- />
- <Text style={styles.username}>{username}</Text>
- {post && <SocialIcon style={styles.icon} social={social} />}
- </View>
- {post && (
- <Text style={styles.timestamp}>
- {moment(post.timestamp).format('LL')} at{' '}
- {moment(post.timestamp).format('LT')}
- </Text>
- )}
- </View>
- );
-};
-
-const styles = StyleSheet.create({
- container: {
- flexDirection: 'column',
- justifyContent: 'space-between',
- padding: 10,
- backgroundColor: 'white',
- },
- topRow: {
- flexDirection: 'row',
- alignItems: 'center',
- },
- avatar: {
- width: AVATAR_DIM,
- height: AVATAR_DIM,
- borderRadius: AVATAR_DIM / 2,
- marginRight: 10,
- },
- icon: {
- width: AVATAR_DIM,
- height: AVATAR_DIM,
- borderRadius: AVATAR_DIM / 2,
- marginLeft: '55%',
- },
- username: {
- fontSize: 18,
- },
- timestamp: {
- color: '#6A757D',
- fontSize: 11,
- marginLeft: AVATAR_DIM + 10,
- },
-});
-
-export default PostHeader;
diff --git a/src/components/common/post/index.ts b/src/components/common/post/index.ts
deleted file mode 100644
index 358a59d5..00000000
--- a/src/components/common/post/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export {default as Post} from './Post';
diff --git a/src/components/moments/Moment.tsx b/src/components/moments/Moment.tsx
index 9e138ef3..0c8febcf 100644
--- a/src/components/moments/Moment.tsx
+++ b/src/components/moments/Moment.tsx
@@ -10,15 +10,21 @@ import {TAGG_TEXT_LIGHT_BLUE} from '../../constants';
import {SCREEN_WIDTH} from '../../utils';
import ImagePicker from 'react-native-image-crop-picker';
import MomentTile from './MomentTile';
-import {MomentType} from 'src/types';
+import {MomentType, ScreenType} from 'src/types';
interface MomentProps {
title: string;
images: MomentType[] | undefined;
- isProfileView: boolean;
+ userXId: string;
+ screenType: ScreenType;
}
-const Moment: React.FC<MomentProps> = ({title, images, isProfileView}) => {
+const Moment: React.FC<MomentProps> = ({
+ title,
+ images,
+ userXId,
+ screenType,
+}) => {
const navigation = useNavigation();
const navigateToImagePicker = () => {
@@ -32,6 +38,7 @@ const Moment: React.FC<MomentProps> = ({title, images, isProfileView}) => {
.then((picture) => {
if ('path' in picture) {
navigation.navigate('CaptionScreen', {
+ screenType,
title: title,
image: picture,
});
@@ -45,7 +52,7 @@ const Moment: React.FC<MomentProps> = ({title, images, isProfileView}) => {
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.titleText}>{title}</Text>
- {!isProfileView ? (
+ {!userXId ? (
<PlusIcon
width={21}
height={21}
@@ -64,10 +71,11 @@ const Moment: React.FC<MomentProps> = ({title, images, isProfileView}) => {
<MomentTile
key={imageObj.moment_id}
moment={imageObj}
- isProfileView={isProfileView}
+ userXId={userXId}
+ screenType={screenType}
/>
))}
- {(images === undefined || images.length === 0) && !isProfileView && (
+ {(images === undefined || images.length === 0) && !userXId && (
<TouchableOpacity onPress={() => navigateToImagePicker()}>
<LinearGradient
colors={['rgba(105, 141, 211, 1)', 'rgba(105, 141, 211, 0.3)']}>
diff --git a/src/components/moments/MomentTile.tsx b/src/components/moments/MomentTile.tsx
index 787957e0..cc24c531 100644
--- a/src/components/moments/MomentTile.tsx
+++ b/src/components/moments/MomentTile.tsx
@@ -1,26 +1,29 @@
import {useNavigation} from '@react-navigation/native';
import React from 'react';
import {StyleSheet, View, Image, TouchableOpacity} from 'react-native';
-import {MomentType} from 'src/types';
-import {ProfileContext} from '../../routes';
+import {MomentType, ScreenType} from 'src/types';
interface MomentTileProps {
moment: MomentType;
- isProfileView: boolean;
+ userXId: string;
+ screenType: ScreenType;
}
-const MomentTile: React.FC<MomentTileProps> = ({moment, isProfileView}) => {
+const MomentTile: React.FC<MomentTileProps> = ({
+ moment,
+ userXId,
+ screenType,
+}) => {
const navigation = useNavigation();
- //Username is needed by the IndividualMoment screen
- const {
- user: {username},
- } = React.useContext(ProfileContext);
-
const {path_hash} = moment;
return (
<TouchableOpacity
onPress={() => {
- navigation.push('IndividualMoment', {moment, isProfileView, username});
+ navigation.push('IndividualMoment', {
+ moment,
+ screenType,
+ userXId,
+ });
}}>
<View style={styles.image}>
<Image style={styles.image} source={{uri: path_hash}} />
diff --git a/src/components/profile/Avatar.tsx b/src/components/profile/Avatar.tsx
index aca3bf4d..903d0d18 100644
--- a/src/components/profile/Avatar.tsx
+++ b/src/components/profile/Avatar.tsx
@@ -1,16 +1,20 @@
-import React from 'react';
+import React, {useContext} from 'react';
import {Image, StyleSheet} from 'react-native';
-import {AuthContext, ProfileContext} from '../../routes/';
+import {useSelector} from 'react-redux';
+import {RootState} from '../../store/rootreducer';
+import {ScreenType} from '../../types';
const PROFILE_DIM = 100;
interface AvatarProps {
style: object;
- isProfileView: boolean;
+ userXId: string;
+ screenType: ScreenType;
}
-const Avatar: React.FC<AvatarProps> = ({style, isProfileView}) => {
- const {avatar} = isProfileView
- ? React.useContext(ProfileContext)
- : React.useContext(AuthContext);
+const Avatar: React.FC<AvatarProps> = ({style, screenType, userXId}) => {
+ const {avatar} = userXId
+ ? useSelector((state: RootState) => state.userX[screenType][userXId])
+ : useSelector((state: RootState) => state.user);
+
return (
<Image
style={[styles.image, style]}
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>
diff --git a/src/components/profile/Cover.tsx b/src/components/profile/Cover.tsx
index 36e41776..3c0f7045 100644
--- a/src/components/profile/Cover.tsx
+++ b/src/components/profile/Cover.tsx
@@ -1,18 +1,23 @@
-import React from 'react';
+import React, {useContext} from 'react';
import {Image, StyleSheet} from 'react-native';
import Animated from 'react-native-reanimated';
import {IMAGE_WIDTH, COVER_HEIGHT, IMAGE_HEIGHT} from '../../constants';
-import {AuthContext, ProfileContext} from '../../routes/';
+import {useSelector, useStore} from 'react-redux';
+import {RootState} from '../../store/rootreducer';
+import {ScreenType} from '../../types';
+import {DUMMY_USERID, NO_USER_DATA} from '../../store/initialStates';
const {interpolate, Extrapolate} = Animated;
interface CoverProps {
y: Animated.Value<number>;
- isProfileView: boolean;
+ userXId: string;
+ screenType: ScreenType;
}
-const Cover: React.FC<CoverProps> = ({y, isProfileView}) => {
- const {cover} = isProfileView
- ? React.useContext(ProfileContext)
- : React.useContext(AuthContext);
+const Cover: React.FC<CoverProps> = ({y, userXId, screenType}) => {
+ const {cover = ''} = userXId
+ ? useSelector((state: RootState) => state.userX[screenType][userXId])
+ : useSelector((state: RootState) => state.user);
+
const scale: Animated.Node<number> = interpolate(y, {
inputRange: [-COVER_HEIGHT, 0],
outputRange: [1.5, 1.25],
diff --git a/src/components/profile/FollowCount.tsx b/src/components/profile/FollowCount.tsx
index 3e270428..a23a3533 100644
--- a/src/components/profile/FollowCount.tsx
+++ b/src/components/profile/FollowCount.tsx
@@ -1,24 +1,33 @@
-import React from 'react';
+import React, {useContext} from 'react';
import {View, Text, StyleSheet, ViewProps} from 'react-native';
import {TouchableOpacity} from 'react-native-gesture-handler';
import {useNavigation} from '@react-navigation/native';
-import {AuthContext, ProfileContext} from '../../routes';
+import {RootState} from '../../store/rootReducer';
+import {useSelector} from 'react-redux';
+import {ScreenType} from '../../types';
+import {EMPTY_PROFILE_PREVIEW_LIST} from '../../store/initialStates';
interface FollowCountProps extends ViewProps {
mode: 'followers' | 'following';
- count: number;
- isProfileView: boolean;
+ userXId: string;
+ screenType: ScreenType;
}
const FollowCount: React.FC<FollowCountProps> = ({
style,
mode,
- count,
- isProfileView,
+ userXId,
+ screenType,
}) => {
- const {followers, following} = isProfileView
- ? React.useContext(ProfileContext)
- : React.useContext(AuthContext);
+ const {
+ followers = EMPTY_PROFILE_PREVIEW_LIST,
+ following = EMPTY_PROFILE_PREVIEW_LIST,
+ } = userXId
+ ? useSelector((state: RootState) => state.userX[screenType][userXId])
+ : useSelector((state: RootState) => state.follow);
+
+ const isFollowers = mode === 'followers';
+ const count = isFollowers ? followers.length : following.length;
const navigation = useNavigation();
const displayed: string =
@@ -33,14 +42,15 @@ const FollowCount: React.FC<FollowCountProps> = ({
<TouchableOpacity
onPress={() =>
navigation.push('FollowersListScreen', {
- isFollowers: mode === 'followers',
- list: mode === 'followers' ? followers : following,
+ isFollowers,
+ userXId,
+ screenType,
})
}>
<View style={[styles.container, style]}>
<Text style={styles.count}>{displayed}</Text>
<Text style={styles.label}>
- {mode === 'followers' ? 'Followers' : 'Following'}
+ {isFollowers ? 'Followers' : 'Following'}
</Text>
</View>
</TouchableOpacity>
diff --git a/src/components/profile/Followers.tsx b/src/components/profile/Followers.tsx
index e11041d0..c665603d 100644
--- a/src/components/profile/Followers.tsx
+++ b/src/components/profile/Followers.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import {View, StyleSheet, ViewProps, Text} from 'react-native';
-import {ProfilePreviewType} from '../../types';
+import {ProfilePreviewType, ScreenType} from '../../types';
import {ProfilePreview} from '..';
import {useNavigation} from '@react-navigation/native';
import {Button} from 'react-native-elements';
@@ -8,9 +8,14 @@ import {Button} from 'react-native-elements';
interface FollowersListProps {
result: Array<ProfilePreviewType>;
sectionTitle: string;
+ screenType: ScreenType;
}
-const Followers: React.FC<FollowersListProps> = ({result, sectionTitle}) => {
+const Followers: React.FC<FollowersListProps> = ({
+ result,
+ sectionTitle,
+ screenType,
+}) => {
const navigation = useNavigation();
return (
<>
@@ -31,6 +36,7 @@ const Followers: React.FC<FollowersListProps> = ({result, sectionTitle}) => {
key={profilePreview.id}
{...{profilePreview}}
previewType={'Comment'}
+ screenType={screenType}
/>
))}
</>
diff --git a/src/components/profile/MoreInfoDrawer.tsx b/src/components/profile/MoreInfoDrawer.tsx
index 719c1894..a8908b4d 100644
--- a/src/components/profile/MoreInfoDrawer.tsx
+++ b/src/components/profile/MoreInfoDrawer.tsx
@@ -4,14 +4,14 @@ import {StyleSheet, Text, TouchableOpacity, View} from 'react-native';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import {TAGG_TEXT_LIGHT_BLUE} from '../../constants';
import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
-import {AuthContext} from '../../routes';
import {BottomDrawer} from '../common';
import PersonOutline from '../../assets/ionicons/person-outline.svg';
+import {useSelector} from 'react-redux';
+import {RootState} from '../../store/rootreducer';
interface MoreInfoDrawerProps {
isOpen: boolean;
setIsOpen: (visible: boolean) => void;
- isProfileView: boolean;
}
const MoreInfoDrawer: React.FC<MoreInfoDrawerProps> = (props) => {
@@ -20,7 +20,7 @@ const MoreInfoDrawer: React.FC<MoreInfoDrawerProps> = (props) => {
const navigation = useNavigation();
const {
user: {userId, username},
- } = useContext(AuthContext);
+ } = useSelector((state: RootState) => state.user);
const goToEditProfile = () => {
navigation.push('EditProfile', {
diff --git a/src/components/profile/ProfileBody.tsx b/src/components/profile/ProfileBody.tsx
index c0253533..3c05fc26 100644
--- a/src/components/profile/ProfileBody.tsx
+++ b/src/components/profile/ProfileBody.tsx
@@ -1,33 +1,38 @@
-import React from 'react';
+import React, {useContext} from 'react';
import {StyleSheet, View, Text, LayoutChangeEvent} from 'react-native';
import {TAGG_DARK_BLUE, TOGGLE_BUTTON_TYPE} from '../../constants';
-import {AuthContext, ProfileContext} from '../../routes/';
import ToggleButton from './ToggleButton';
+import {RootState} from '../../store/rootReducer';
+import {useSelector} from 'react-redux';
+import {ScreenType} from '../../types';
+import {NO_PROFILE} from '../../store/initialStates';
interface ProfileBodyProps {
onLayout: (event: LayoutChangeEvent) => void;
- isProfileView: boolean;
isFollowed: boolean;
isBlocked: boolean;
isOwnProfile: boolean;
handleFollowUnfollow: Function;
handleBlockUnblock: Function;
+ userXId: string;
+ screenType: ScreenType;
}
const ProfileBody: React.FC<ProfileBodyProps> = ({
onLayout,
- isProfileView,
isFollowed,
isBlocked,
isOwnProfile,
handleFollowUnfollow,
handleBlockUnblock,
+ userXId,
+ screenType,
}) => {
const {
- profile,
+ profile = NO_PROFILE,
user: {username},
- } = isProfileView
- ? React.useContext(ProfileContext)
- : React.useContext(AuthContext);
+ } = userXId
+ ? useSelector((state: RootState) => state.userX[screenType][userXId])
+ : useSelector((state: RootState) => state.user);
const {biography, website} = profile;
@@ -36,7 +41,7 @@ const ProfileBody: React.FC<ProfileBodyProps> = ({
<Text style={styles.username}>{`@${username}`}</Text>
<Text style={styles.biography}>{`${biography}`}</Text>
<Text style={styles.website}>{`${website}`}</Text>
- {isProfileView && !isOwnProfile ? (
+ {userXId && !isOwnProfile ? (
<View style={styles.toggleButtonContainer}>
{!isBlocked && (
<ToggleButton
diff --git a/src/components/profile/ProfileHeader.tsx b/src/components/profile/ProfileHeader.tsx
index 62949746..621aae9a 100644
--- a/src/components/profile/ProfileHeader.tsx
+++ b/src/components/profile/ProfileHeader.tsx
@@ -1,34 +1,30 @@
-import React, {useState} from 'react';
+import React, {useState, useContext} from 'react';
import {StyleSheet, Text, TouchableOpacity, View} from 'react-native';
import MoreIcon from '../../assets/icons/more_horiz-24px.svg';
import {TAGG_DARK_BLUE} from '../../constants';
-import {AuthContext, ProfileContext} from '../../routes/';
import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
import Avatar from './Avatar';
import MoreInfoDrawer from './MoreInfoDrawer';
import FollowCount from './FollowCount';
+import {useSelector} from 'react-redux';
+import {RootState} from '../../store/rootreducer';
+import {ScreenType} from '../../types';
type ProfileHeaderProps = {
- isProfileView: boolean;
- numFollowing: number;
- numFollowers: number;
+ userXId: string;
+ screenType: ScreenType;
};
-const ProfileHeader: React.FC<ProfileHeaderProps> = ({
- isProfileView,
- numFollowing,
- numFollowers,
-}) => {
- const {
- profile: {name},
- } = isProfileView
- ? React.useContext(ProfileContext)
- : React.useContext(AuthContext);
+const ProfileHeader: React.FC<ProfileHeaderProps> = ({userXId, screenType}) => {
+ const {profile: {name = ''} = {}} = userXId
+ ? useSelector((state: RootState) => state.userX[screenType][userXId])
+ : useSelector((state: RootState) => state.user);
+
const [drawerVisible, setDrawerVisible] = useState(false);
return (
<View style={styles.container}>
- {!isProfileView && (
+ {!userXId && (
<>
<TouchableOpacity
style={styles.more}
@@ -37,29 +33,29 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({
}}>
<MoreIcon height={30} width={30} color={TAGG_DARK_BLUE} />
</TouchableOpacity>
- <MoreInfoDrawer
- isOpen={drawerVisible}
- setIsOpen={setDrawerVisible}
- isProfileView={isProfileView}
- />
+ <MoreInfoDrawer isOpen={drawerVisible} setIsOpen={setDrawerVisible} />
</>
)}
<View style={styles.row}>
- <Avatar style={styles.avatar} isProfileView={isProfileView} />
+ <Avatar
+ style={styles.avatar}
+ userXId={userXId}
+ screenType={screenType}
+ />
<View style={styles.header}>
<Text style={styles.name}>{name}</Text>
<View style={styles.row}>
<FollowCount
style={styles.follows}
mode="followers"
- count={numFollowers}
- isProfileView={isProfileView}
+ screenType={screenType}
+ userXId={userXId}
/>
<FollowCount
style={styles.follows}
mode="following"
- count={numFollowing}
- isProfileView={isProfileView}
+ screenType={screenType}
+ userXId={userXId}
/>
</View>
</View>
diff --git a/src/components/profile/ProfilePreview.tsx b/src/components/profile/ProfilePreview.tsx
index af116dd3..5567fa5a 100644
--- a/src/components/profile/ProfilePreview.tsx
+++ b/src/components/profile/ProfilePreview.tsx
@@ -1,5 +1,5 @@
import React, {useEffect, useState, useContext} from 'react';
-import {ProfilePreviewType} from '../../types';
+import {ProfilePreviewType, ScreenType} from '../../types';
import {
View,
Text,
@@ -14,8 +14,11 @@ import RNFetchBlob from 'rn-fetch-blob';
import AsyncStorage from '@react-native-community/async-storage';
import {AVATAR_PHOTO_ENDPOINT} from '../../constants';
import {UserType, PreviewType} from '../../types';
-import {AuthContext} from '../../routes/';
import {isUserBlocked} from '../../services';
+import {useSelector, useDispatch, useStore} from 'react-redux';
+import {RootState} from '../../store/rootreducer';
+import {loadUserX, logout} from '../../store/actions';
+import {userXInStore} from '../../utils';
const NO_USER: UserType = {
userId: '',
username: '',
@@ -27,22 +30,24 @@ const NO_USER: UserType = {
* If isComment is true then it means that we are not displaying this tile as a part of search results.
* And hence we do not cache the search results.
* On the other hand, if isComment is false, then we should update the search cache. (This cache needs to be revamped to clear outdated results.)
- * In either case, we update the userBeingVisited in our AuthContext (Which can be used to make api calls later on to fetch user specific data).
* Finally, We navigate to Profile.
*/
interface ProfilePreviewProps extends ViewProps {
profilePreview: ProfilePreviewType;
previewType: PreviewType;
+ screenType: ScreenType;
}
const ProfilePreview: React.FC<ProfilePreviewProps> = ({
profilePreview: {username, first_name, last_name, id},
previewType,
+ screenType,
}) => {
const navigation = useNavigation();
- const {user: loggedInUser, logout} = React.useContext(AuthContext);
+ const {user: loggedInUser} = useSelector((state: RootState) => state.user);
const [avatarURI, setAvatarURI] = useState<string | null>(null);
const [user, setUser] = useState<UserType>(NO_USER);
+ const dispatch = useDispatch();
useEffect(() => {
let mounted = true;
const loadAvatar = async () => {
@@ -87,12 +92,14 @@ const ProfilePreview: React.FC<ProfilePreviewProps> = ({
const checkIfUserIsBlocked = async (userId: string) => {
const token = await AsyncStorage.getItem('token');
if (!token) {
- logout();
+ dispatch(logout());
return false;
}
return await isUserBlocked(userId, loggedInUser.userId, token);
};
+ const state: RootState = useStore().getState();
+
const addToRecentlyStoredAndNavigateToProfile = async () => {
let user: ProfilePreviewType = {
id,
@@ -145,12 +152,19 @@ const ProfilePreview: React.FC<ProfilePreviewProps> = ({
}
/**
- * Navigate to profile of the user selected
+ * Dispatch an event to Fetch the user details
+ * If the user is already present in store, do not fetch again
+ * Finally, Navigate to profile of the user selected
*/
+ if (!userXInStore(state, screenType, user.id)) {
+ dispatch(
+ loadUserX({userId: user.id, username: user.username}, screenType),
+ );
+ }
navigation.push('Profile', {
- isProfileView: true,
username: user.username,
- userId: user.id,
+ userXId: user.id,
+ screenType: screenType,
});
} catch (e) {
console.log(e);
diff --git a/src/components/search/DiscoverUsers.tsx b/src/components/search/DiscoverUsers.tsx
index 885c712b..ec0a8daa 100644
--- a/src/components/search/DiscoverUsers.tsx
+++ b/src/components/search/DiscoverUsers.tsx
@@ -6,23 +6,32 @@ import {
StyleSheet,
TouchableOpacityProps,
} from 'react-native';
-import {ProfilePreviewType} from '../../types';
+import {PreviewType, ProfilePreviewType, ScreenType} from '../../types';
import SearchResults from './SearchResults';
interface DiscoverUsersProps extends TouchableOpacityProps {
- sectionTitle: string;
+ sectionTitle: PreviewType;
users: Array<ProfilePreviewType>;
+ screenType: ScreenType;
}
/**
* An image component that returns the <Image> of the icon for a specific social media platform.
*/
-const DiscoverUsers: React.FC<DiscoverUsersProps> = (props) => {
+const DiscoverUsers: React.FC<DiscoverUsersProps> = ({
+ sectionTitle,
+ screenType,
+ users,
+}) => {
return (
<View style={styles.container}>
<View style={styles.headerContainer}>
- <Text style={styles.title}>{props.sectionTitle}</Text>
+ <Text style={styles.title}>{sectionTitle}</Text>
</View>
- <SearchResults results={props.users} previewType={props.sectionTitle} />
+ <SearchResults
+ results={users}
+ previewType={sectionTitle}
+ screenType={screenType}
+ />
</View>
);
};
diff --git a/src/components/search/RecentSearches.tsx b/src/components/search/RecentSearches.tsx
index 6a98e49a..22a36a6b 100644
--- a/src/components/search/RecentSearches.tsx
+++ b/src/components/search/RecentSearches.tsx
@@ -6,14 +6,15 @@ import {
StyleSheet,
TouchableOpacityProps,
} from 'react-native';
-import {ProfilePreviewType} from 'src/types';
-import { TAGG_TEXT_LIGHT_BLUE } from '../../constants';
+import {PreviewType, ProfilePreviewType, ScreenType} from 'src/types';
+import {TAGG_TEXT_LIGHT_BLUE} from '../../constants';
import SearchResults from './SearchResults';
interface RecentSearchesProps extends TouchableOpacityProps {
- sectionTitle: string;
+ sectionTitle: PreviewType;
sectionButtonTitle: string;
recents: Array<ProfilePreviewType>;
+ screenType: ScreenType;
}
/**
* An image component that returns the <Image> of the icon for a specific social media platform.
@@ -29,7 +30,11 @@ const RecentSearches: React.FC<RecentSearchesProps> = (props) => {
</TouchableOpacity>
)}
</View>
- <SearchResults results={props.recents} previewType={props.sectionTitle} />
+ <SearchResults
+ results={props.recents}
+ previewType={props.sectionTitle}
+ screenType={props.screenType}
+ />
</>
);
};
diff --git a/src/components/search/SearchResults.tsx b/src/components/search/SearchResults.tsx
index 2d5c9db8..001c7968 100644
--- a/src/components/search/SearchResults.tsx
+++ b/src/components/search/SearchResults.tsx
@@ -1,20 +1,26 @@
import React from 'react';
-import {ProfilePreviewType, PreviewType} from '../../types';
+import {ProfilePreviewType, PreviewType, ScreenType} from '../../types';
import ProfilePreview from '../profile/ProfilePreview';
import {StyleSheet, View} from 'react-native';
interface SearchResultsProps {
results: Array<ProfilePreviewType>;
previewType: PreviewType;
+ screenType: ScreenType;
}
-const SearchResults: React.FC<SearchResultsProps> = (props) => {
+const SearchResults: React.FC<SearchResultsProps> = ({
+ results,
+ previewType,
+ screenType,
+}) => {
return (
<View style={styles.container}>
- {props.results.map((profilePreview) => (
+ {results.map((profilePreview) => (
<ProfilePreview
style={styles.result}
key={profilePreview.id}
{...{profilePreview}}
- previewType={props.previewType}
+ previewType={previewType}
+ screenType={screenType}
/>
))}
</View>
diff --git a/src/components/taggs/Tagg.tsx b/src/components/taggs/Tagg.tsx
index 9f8fafd1..086b3c87 100644
--- a/src/components/taggs/Tagg.tsx
+++ b/src/components/taggs/Tagg.tsx
@@ -1,5 +1,5 @@
import {useNavigation} from '@react-navigation/native';
-import React, {Fragment, useContext, useState} from 'react';
+import React, {Fragment, useContext, useEffect, useState} from 'react';
import {Alert, Linking, StyleSheet, TouchableOpacity, View} from 'react-native';
import PurpleRingPlus from '../../assets/icons/purple_ring+.svg';
import PurpleRing from '../../assets/icons/purple_ring.svg';
@@ -17,36 +17,35 @@ import {
registerNonIntegratedSocialLink,
} from '../../services';
import {SmallSocialIcon, SocialIcon, SocialLinkModal} from '../common';
-import {AuthContext, ProfileContext} from '../../routes';
+import {useSelector} from 'react-redux';
+import {RootState} from '../../store/rootreducer';
+import {ScreenType} from '../../types';
interface TaggProps {
social: string;
- isProfileView: boolean;
isLinked: boolean;
isIntegrated: boolean;
setTaggsNeedUpdate: (_: boolean) => void;
- setSocialDataNeedUpdate: (_: string[]) => void;
- userId: string;
+ setSocialDataNeedUpdate: (_: string) => void;
+ userXId: string;
+ screenType: ScreenType;
}
const Tagg: React.FC<TaggProps> = ({
social,
- isProfileView,
isLinked,
isIntegrated,
setTaggsNeedUpdate,
setSocialDataNeedUpdate,
- userId,
+ userXId,
+ screenType,
}) => {
const navigation = useNavigation();
const [modalVisible, setModalVisible] = useState(false);
- const youMayPass = isLinked || isProfileView;
- const {
- profile: {name},
- socialAccounts,
- avatar,
- } = isProfileView ? useContext(ProfileContext) : useContext(AuthContext);
-
+ const youMayPass = isLinked || userXId;
+ const {user} = userXId
+ ? useSelector((state: RootState) => state.userX[screenType][userXId])
+ : useSelector((state: RootState) => state.user);
/*
case isProfileView:
case linked:
@@ -62,7 +61,7 @@ const Tagg: React.FC<TaggProps> = ({
show auth browser
case !integrated_social:
show modal
- Tagg's "Tagg" will use the Ring instead of PurpleRing
+ Tagg's "Tagg" will use the Ring instead of PurpleRing
*/
const modalOrAuthBrowserOrPass = async () => {
@@ -70,14 +69,10 @@ const Tagg: React.FC<TaggProps> = ({
if (INTEGRATED_SOCIAL_LIST.indexOf(social) !== -1) {
navigation.push('SocialMediaTaggs', {
socialMediaType: social,
- isProfileView: isProfileView,
- userId: userId,
- name: name,
- accountData: socialAccounts[social],
- avatar: avatar,
+ userXId,
});
} else {
- getNonIntegratedURL(social, userId).then((socialURL) => {
+ getNonIntegratedURL(social, user.userId).then((socialURL) => {
if (socialURL) {
Linking.openURL(socialURL);
} else {
@@ -89,7 +84,7 @@ const Tagg: React.FC<TaggProps> = ({
if (isIntegrated) {
handlePressForAuthBrowser(social).then((success) => {
setTaggsNeedUpdate(success);
- setSocialDataNeedUpdate(success ? [social] : []);
+ if (success) setSocialDataNeedUpdate(social);
});
} else {
setModalVisible(true);
@@ -127,7 +122,7 @@ const Tagg: React.FC<TaggProps> = ({
return (
<>
- {isProfileView && !isLinked ? (
+ {userXId && !isLinked ? (
<Fragment />
) : (
<>
diff --git a/src/components/taggs/TaggsBar.tsx b/src/components/taggs/TaggsBar.tsx
index aac68e99..12e4b93a 100644
--- a/src/components/taggs/TaggsBar.tsx
+++ b/src/components/taggs/TaggsBar.tsx
@@ -1,35 +1,53 @@
-// @refresh react
-import React, {useEffect, useState} from 'react';
+import React, {useEffect, useState, useContext} from 'react';
import {StyleSheet} from 'react-native';
import Animated from 'react-native-reanimated';
+import {useDispatch, useSelector} from 'react-redux';
import {
INTEGRATED_SOCIAL_LIST,
PROFILE_CUTOUT_BOTTOM_Y,
SOCIAL_LIST,
} from '../../constants';
-import {AuthContext, ProfileContext} from '../../routes';
import {getLinkedSocials} from '../../services';
import {StatusBarHeight} from '../../utils';
import Tagg from './Tagg';
+import {RootState} from '../../store/rootReducer';
+import {ScreenType} from '../../types';
+import {loadIndividualSocial} from '../../store/actions';
const {View, ScrollView, interpolate, Extrapolate} = Animated;
interface TaggsBarProps {
y: Animated.Value<number>;
profileBodyHeight: number;
- isProfileView: boolean;
+ userXId: string;
+ screenType: ScreenType;
}
const TaggsBar: React.FC<TaggsBarProps> = ({
y,
profileBodyHeight,
- isProfileView,
+ userXId,
+ screenType,
}) => {
let [taggs, setTaggs] = useState<Object[]>([]);
let [taggsNeedUpdate, setTaggsNeedUpdate] = useState(true);
- const context = isProfileView
- ? React.useContext(ProfileContext)
- : React.useContext(AuthContext);
- const {user, socialsNeedUpdate} = context;
+ const {user} = userXId
+ ? useSelector((state: RootState) => state.userX[screenType][userXId])
+ : useSelector((state: RootState) => state.user);
+
+ const dispatch = useDispatch();
+
+ /**
+ * Updates the individual social that needs update
+ * @param socialType Type of the social that needs update
+ */
+ const handleSocialUpdate = (socialType: string) => {
+ dispatch(loadIndividualSocial(user.userId, socialType));
+ };
+
+ /**
+ * This useEffect should be called evey time the user being viewed is changed OR
+ * And update is triggered manually
+ */
useEffect(() => {
const loadData = async () => {
getLinkedSocials(user.userId).then((linkedSocials) => {
@@ -43,12 +61,12 @@ const TaggsBar: React.FC<TaggsBarProps> = ({
<Tagg
key={i}
social={social}
- isProfileView={isProfileView}
+ userXId={userXId}
+ screenType={screenType}
isLinked={true}
isIntegrated={INTEGRATED_SOCIAL_LIST.indexOf(social) !== -1}
setTaggsNeedUpdate={setTaggsNeedUpdate}
- setSocialDataNeedUpdate={socialsNeedUpdate}
- userId={user.userId}
+ setSocialDataNeedUpdate={handleSocialUpdate}
/>,
);
i++;
@@ -58,12 +76,12 @@ const TaggsBar: React.FC<TaggsBarProps> = ({
<Tagg
key={i}
social={social}
- isProfileView={isProfileView}
+ userXId={userXId}
+ screenType={screenType}
isLinked={false}
isIntegrated={INTEGRATED_SOCIAL_LIST.indexOf(social) !== -1}
setTaggsNeedUpdate={setTaggsNeedUpdate}
- setSocialDataNeedUpdate={socialsNeedUpdate}
- userId={user.userId}
+ setSocialDataNeedUpdate={handleSocialUpdate}
/>,
);
i++;
@@ -73,17 +91,8 @@ const TaggsBar: React.FC<TaggsBarProps> = ({
});
};
- if (taggsNeedUpdate) {
- /**
- * Triggering redundant call to the backend for now to make the app work.
- * TODO : Figure out a better way to get the updates social posts for the profile being visited.
- * Have an event triggered from ProfileProvider based on which we could make a call to backedn to get updated posts.
- */
- //We may need the line below in future ?
- // socialsNeedUpdate(INTEGRATED_SOCIAL_LIST);
- loadData();
- }
- }, [isProfileView, taggsNeedUpdate, user.userId]);
+ loadData();
+ }, [taggsNeedUpdate, user]);
const shadowOpacity: Animated.Node<number> = interpolate(y, {
inputRange: [