From f662d1cd85447de0f6be945a350d1f2d1be5033e Mon Sep 17 00:00:00 2001
From: ankit-thanekar007 <ankit.thanekar007@gmail.com>
Date: Wed, 17 Mar 2021 11:07:45 -0700
Subject: Separated Private and Public Profiles

---
 src/components/profile/PublicProfile.tsx | 284 +++++++++++++++++++++++++++++++
 1 file changed, 284 insertions(+)
 create mode 100644 src/components/profile/PublicProfile.tsx

(limited to 'src/components/profile/PublicProfile.tsx')

diff --git a/src/components/profile/PublicProfile.tsx b/src/components/profile/PublicProfile.tsx
new file mode 100644
index 00000000..f453d05b
--- /dev/null
+++ b/src/components/profile/PublicProfile.tsx
@@ -0,0 +1,284 @@
+import {useFocusEffect, useNavigation} from '@react-navigation/native';
+import React, {useCallback, useEffect, useState} from 'react';
+import {Alert, StyleSheet, Text, View} from 'react-native';
+import {TouchableOpacity} from 'react-native-gesture-handler';
+import {useDispatch, useSelector, useStore} from 'react-redux';
+import GreyPlusLogo from '../../assets/icons/grey-plus-logo.svg';
+import {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 {
+  deleteUserMomentsForCategory,
+  updateMomentCategories,
+} 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,
+  ContentProps,
+  MomentType,
+} from '../../types';
+import {moveCategory, normalize, SCREEN_HEIGHT} from '../../utils';
+import {TaggPrompt} from '../common';
+import {Moment} from '../moments';
+
+const PublicProfile: React.FC<ContentProps> = ({y, userXId, screenType}) => {
+  const dispatch = useDispatch();
+
+  const {profile = NO_PROFILE} = userXId
+    ? useSelector((state: RootState) => state.userX[screenType][userXId])
+    : useSelector((state: RootState) => state.user);
+
+  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);
+
+  const {user: loggedInUser = NO_USER} = useSelector(
+    (state: RootState) => state.user,
+  );
+
+  const navigation = useNavigation();
+
+  /**
+   * States
+   */
+  const [imagesMap, setImagesMap] = useState<Map<string, MomentType[]>>(
+    new Map(),
+  );
+
+  const [isStageTwoPromptClosed, setIsStageTwoPromptClosed] = useState<boolean>(
+    false,
+  );
+  const [isStageOnePromptClosed, setIsStageOnePromptClosed] = useState<boolean>(
+    false,
+  );
+  const [
+    isStageThreePromptClosed,
+    setIsStageThreePromptClosed,
+  ] = useState<boolean>(false);
+
+  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(() => {
+      const navigateToMomentUploadPrompt = () => {
+        switch (profile.profile_completion_stage) {
+          case 1:
+            if (
+              momentCategories &&
+              momentCategories[0] &&
+              !isStageOnePromptClosed
+            ) {
+              navigation.navigate('MomentUploadPrompt', {
+                screenType,
+                momentCategory: momentCategories[0],
+              });
+              setIsStageOnePromptClosed(true);
+            }
+            break;
+          case 2:
+            setIsStageTwoPromptClosed(false);
+            break;
+          case 3:
+            setIsStageThreePromptClosed(false);
+            break;
+          default:
+            break;
+        }
+      };
+      if (!userXId) {
+        setTimeout(navigateToMomentUploadPrompt, 2000);
+      }
+    }, [
+      profile.profile_completion_stage,
+      momentCategories,
+      userXId,
+      isStageOnePromptClosed,
+    ]),
+  );
+
+  /**
+   * 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 createImagesMap = useCallback(() => {
+    let map = new Map();
+    moments.forEach(function (imageObject) {
+        let 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]);
+
+  return (
+    <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>
+  );
+};
+
+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%',
+  },
+});
+
+export default PublicProfile;
-- 
cgit v1.2.3-70-g09d2


From 82acd049763452decdab0c40e6cf7286dd2ed57d Mon Sep 17 00:00:00 2001
From: ankit-thanekar007 <ankit.thanekar007@gmail.com>
Date: Thu, 25 Mar 2021 17:09:45 -0700
Subject: Private account toggle changes

---
 src/components/profile/Content.tsx        | 29 ++++++++++++++++++++++-------
 src/components/profile/PrivateProfile.tsx |  4 ++--
 src/components/profile/ProfileBody.tsx    |  1 +
 src/components/profile/PublicProfile.tsx  |  2 +-
 4 files changed, 26 insertions(+), 10 deletions(-)

(limited to 'src/components/profile/PublicProfile.tsx')

diff --git a/src/components/profile/Content.tsx b/src/components/profile/Content.tsx
index 860e16c5..8d77d798 100644
--- a/src/components/profile/Content.tsx
+++ b/src/components/profile/Content.tsx
@@ -41,7 +41,6 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
   const {user = NO_USER, profile = NO_PROFILE} = userXId
     ? useSelector((state: RootState) => state.userX[screenType][userXId])
     : useSelector((state: RootState) => state.user);
-
   const {blockedUsers = EMPTY_PROFILE_PREVIEW_LIST} = useSelector(
     (state: RootState) => state.blocked,
   );
@@ -55,20 +54,19 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
    */
   const [isFriend, setIsFriend] = useState<boolean>(false);
   const [isBlocked, setIsBlocked] = useState<boolean>(false);
-  const [isPrivate, setIsPrivate] = useState<boolean>(true);
   const [profileBodyHeight, setProfileBodyHeight] = useState(0);
   const [shouldBounce, setShouldBounce] = useState<boolean>(true);
   const [refreshing, setRefreshing] = 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);
     });
@@ -88,6 +86,10 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
     }
   }, [blockedUsers, user]);
 
+  useEffect(() => {
+    setIsFriend(profile.friendship_status === 'friends');
+  }, [profile.friendship_status]);
+
   /**
    * Handles a click on the block / unblock button.
    * loadFriends updates friends list for the logged in user
@@ -108,6 +110,16 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
     }
   };
 
+  const canViewProfile = () => {
+    if (loggedInUser.userId === user.userId) {
+      return true;
+    } else if (profile.is_private && !isFriend) {
+      return false;
+    } else {
+      return true;
+    }
+  };
+
   const handleScroll = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
     /**
      * Set the new y position
@@ -153,13 +165,16 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
           isBlocked,
         }}
       />
-      {isPrivate ? (
-        <PrivateProfile />
-      ) : (
+      {canViewProfile() ? (
         <>
-          <TaggsBar {...{y, profileBodyHeight, userXId, screenType}} />
+          <TaggsBar
+            {...{y, profileBodyHeight, userXId, screenType}}
+            whiteRing={undefined}
+          />
           <PublicProfile {...{y, userXId, screenType}} />
         </>
+      ) : (
+        <PrivateProfile />
       )}
     </Animated.ScrollView>
   );
diff --git a/src/components/profile/PrivateProfile.tsx b/src/components/profile/PrivateProfile.tsx
index efa7ff39..07a0dccc 100644
--- a/src/components/profile/PrivateProfile.tsx
+++ b/src/components/profile/PrivateProfile.tsx
@@ -16,10 +16,10 @@ const PrivateProfile: React.FC = () => {
 
 const styles = StyleSheet.create({
   container: {
-    backgroundColor: '#F9F9F9',
     alignItems: 'center',
     justifyContent: 'center',
-    height: SCREEN_HEIGHT * 0.3,
+    backgroundColor: '#F9F9F9',
+    height: SCREEN_HEIGHT * 0.35,
   },
   privateAccountTextContainer: {marginTop: '8%'},
   privateAccountTextStyle: {
diff --git a/src/components/profile/ProfileBody.tsx b/src/components/profile/ProfileBody.tsx
index 646be3e0..3aef5990 100644
--- a/src/components/profile/ProfileBody.tsx
+++ b/src/components/profile/ProfileBody.tsx
@@ -119,6 +119,7 @@ const styles = StyleSheet.create({
     flex: 1,
     paddingTop: '3.5%',
     paddingBottom: '2%',
+    width: '50%',
   },
   container: {
     paddingVertical: '1%',
diff --git a/src/components/profile/PublicProfile.tsx b/src/components/profile/PublicProfile.tsx
index f453d05b..4b5166f0 100644
--- a/src/components/profile/PublicProfile.tsx
+++ b/src/components/profile/PublicProfile.tsx
@@ -227,7 +227,7 @@ const PublicProfile: React.FC<ContentProps> = ({y, userXId, screenType}) => {
       {!userXId && (
         <TouchableOpacity
           onPress={() =>
-            navigation.push('CategorySelection', {
+            navigation.navigate('CategorySelection', {
               screenType: CategorySelectionScreenType.Profile,
               user: loggedInUser,
             })
-- 
cgit v1.2.3-70-g09d2


From 64f8829ab55bfe6851f10ca933043877769c56bf Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Fri, 26 Mar 2021 17:28:23 -0400
Subject: show taggsbar, prevent taggsbar navigation on profile and SP

---
 src/components/profile/Content.tsx       | 28 +++++++++++++++-------------
 src/components/profile/PublicProfile.tsx |  5 ++---
 src/components/taggs/Tagg.tsx            | 30 +++++++++++++++++-------------
 src/components/taggs/TaggsBar.tsx        |  4 ++++
 src/screens/suggestedPeople/SPBody.tsx   | 14 +++++++++++++-
 src/types/types.ts                       |  1 +
 src/utils/users.ts                       |  8 ++++++++
 7 files changed, 60 insertions(+), 30 deletions(-)

(limited to 'src/components/profile/PublicProfile.tsx')

diff --git a/src/components/profile/Content.tsx b/src/components/profile/Content.tsx
index 8d77d798..9fb6f79b 100644
--- a/src/components/profile/Content.tsx
+++ b/src/components/profile/Content.tsx
@@ -22,6 +22,7 @@ import {
 import {RootState} from '../../store/rootreducer';
 import {ContentProps} from '../../types';
 import {
+  canViewProfile,
   fetchUserX,
   getUserAsProfilePreviewType,
   SCREEN_HEIGHT,
@@ -81,7 +82,7 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
     const isActuallyBlocked = blockedUsers.some(
       (cur_user) => user.username === cur_user.username,
     );
-    if (isBlocked != isActuallyBlocked) {
+    if (isBlocked !== isActuallyBlocked) {
       setIsBlocked(isActuallyBlocked);
     }
   }, [blockedUsers, user]);
@@ -110,16 +111,6 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
     }
   };
 
-  const canViewProfile = () => {
-    if (loggedInUser.userId === user.userId) {
-      return true;
-    } else if (profile.is_private && !isFriend) {
-      return false;
-    } else {
-      return true;
-    }
-  };
-
   const handleScroll = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
     /**
      * Set the new y position
@@ -165,7 +156,11 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
           isBlocked,
         }}
       />
-      {canViewProfile() ? (
+      {canViewProfile(
+        loggedInUser.userId === user.userId,
+        profile.is_private,
+        isFriend,
+      ) ? (
         <>
           <TaggsBar
             {...{y, profileBodyHeight, userXId, screenType}}
@@ -174,7 +169,14 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
           <PublicProfile {...{y, userXId, screenType}} />
         </>
       ) : (
-        <PrivateProfile />
+        <>
+          <TaggsBar
+            {...{y, profileBodyHeight, userXId, screenType}}
+            whiteRing={undefined}
+            allowNavigation={false}
+          />
+          <PrivateProfile />
+        </>
       )}
     </Animated.ScrollView>
   );
diff --git a/src/components/profile/PublicProfile.tsx b/src/components/profile/PublicProfile.tsx
index 4b5166f0..a70e8e50 100644
--- a/src/components/profile/PublicProfile.tsx
+++ b/src/components/profile/PublicProfile.tsx
@@ -2,7 +2,7 @@ import {useFocusEffect, useNavigation} from '@react-navigation/native';
 import React, {useCallback, useEffect, useState} from 'react';
 import {Alert, StyleSheet, Text, View} from 'react-native';
 import {TouchableOpacity} from 'react-native-gesture-handler';
-import {useDispatch, useSelector, useStore} from 'react-redux';
+import {useDispatch, useSelector} from 'react-redux';
 import GreyPlusLogo from '../../assets/icons/grey-plus-logo.svg';
 import {TAGG_LIGHT_BLUE} from '../../constants';
 import {
@@ -17,7 +17,6 @@ import {
 } from '../../store/actions';
 import {
   EMPTY_MOMENTS_LIST,
-  EMPTY_PROFILE_PREVIEW_LIST,
   NO_PROFILE,
   NO_USER,
 } from '../../store/initialStates';
@@ -159,7 +158,7 @@ const PublicProfile: React.FC<ContentProps> = ({y, userXId, screenType}) => {
   const createImagesMap = useCallback(() => {
     let map = new Map();
     moments.forEach(function (imageObject) {
-        let moment_category = imageObject.moment_category;
+      let moment_category = imageObject.moment_category;
       if (map.has(moment_category)) {
         map.get(moment_category).push(imageObject);
       } else {
diff --git a/src/components/taggs/Tagg.tsx b/src/components/taggs/Tagg.tsx
index 547a77cb..ae9ab091 100644
--- a/src/components/taggs/Tagg.tsx
+++ b/src/components/taggs/Tagg.tsx
@@ -34,6 +34,7 @@ interface TaggProps {
   userXId: string | undefined;
   user: UserType;
   whiteRing: boolean | undefined;
+  allowNavigation?: boolean;
 }
 
 const Tagg: React.FC<TaggProps> = ({
@@ -45,6 +46,7 @@ const Tagg: React.FC<TaggProps> = ({
   userXId,
   user,
   whiteRing,
+  allowNavigation = true,
 }) => {
   const navigation = useNavigation();
   const [modalVisible, setModalVisible] = useState(false);
@@ -70,19 +72,21 @@ const Tagg: React.FC<TaggProps> = ({
 
   const modalOrAuthBrowserOrPass = async () => {
     if (youMayPass) {
-      if (INTEGRATED_SOCIAL_LIST.indexOf(social) !== -1) {
-        navigation.push('SocialMediaTaggs', {
-          socialMediaType: social,
-          userXId,
-        });
-      } else {
-        getNonIntegratedURL(social, user.userId).then((socialURL) => {
-          if (socialURL) {
-            Linking.openURL(socialURL);
-          } else {
-            Alert.alert(ERROR_UNABLE_TO_FIND_PROFILE);
-          }
-        });
+      if (allowNavigation) {
+        if (INTEGRATED_SOCIAL_LIST.indexOf(social) !== -1) {
+          navigation.push('SocialMediaTaggs', {
+            socialMediaType: social,
+            userXId,
+          });
+        } else {
+          getNonIntegratedURL(social, user.userId).then((socialURL) => {
+            if (socialURL) {
+              Linking.openURL(socialURL);
+            } else {
+              Alert.alert(ERROR_UNABLE_TO_FIND_PROFILE);
+            }
+          });
+        }
       }
     } else {
       if (isIntegrated) {
diff --git a/src/components/taggs/TaggsBar.tsx b/src/components/taggs/TaggsBar.tsx
index f952c53f..a9c428b2 100644
--- a/src/components/taggs/TaggsBar.tsx
+++ b/src/components/taggs/TaggsBar.tsx
@@ -22,6 +22,7 @@ interface TaggsBarProps {
   screenType: ScreenType;
   whiteRing: boolean | undefined;
   linkedSocials?: string[];
+  allowNavigation?: boolean;
 }
 const TaggsBar: React.FC<TaggsBarProps> = ({
   y,
@@ -30,6 +31,7 @@ const TaggsBar: React.FC<TaggsBarProps> = ({
   screenType,
   whiteRing,
   linkedSocials,
+  allowNavigation = true,
 }) => {
   let [taggs, setTaggs] = useState<Object[]>([]);
   let [taggsNeedUpdate, setTaggsNeedUpdate] = useState(true);
@@ -79,6 +81,7 @@ const TaggsBar: React.FC<TaggsBarProps> = ({
             setTaggsNeedUpdate={setTaggsNeedUpdate}
             setSocialDataNeedUpdate={handleSocialUpdate}
             whiteRing={whiteRing ? whiteRing : undefined}
+            allowNavigation={allowNavigation}
           />,
         );
         i++;
@@ -96,6 +99,7 @@ const TaggsBar: React.FC<TaggsBarProps> = ({
               userXId={userXId}
               user={user}
               whiteRing={whiteRing ? whiteRing : undefined}
+              allowNavigation={allowNavigation}
             />,
           );
           i++;
diff --git a/src/screens/suggestedPeople/SPBody.tsx b/src/screens/suggestedPeople/SPBody.tsx
index 8e0801c2..7bedb137 100644
--- a/src/screens/suggestedPeople/SPBody.tsx
+++ b/src/screens/suggestedPeople/SPBody.tsx
@@ -14,7 +14,13 @@ import {
   SuggestedPeopleDataType,
   UniversityBadge,
 } from '../../types';
-import {isIPhoneX, normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
+import {
+  canViewProfile,
+  isIPhoneX,
+  normalize,
+  SCREEN_HEIGHT,
+  SCREEN_WIDTH,
+} from '../../utils';
 
 interface SPBodyProps {
   item: SuggestedPeopleDataType;
@@ -32,6 +38,7 @@ const SPBody: React.FC<SPBodyProps> = ({
     suggested_people_url,
     friendship,
     badges,
+    is_private,
   },
   itemIndex,
   onAddFriend,
@@ -156,6 +163,11 @@ const SPBody: React.FC<SPBodyProps> = ({
             screenType={screenType}
             whiteRing={true}
             linkedSocials={social_links}
+            allowNavigation={canViewProfile(
+              loggedInUserId === user.id,
+              is_private,
+              friendship.status === 'friends',
+            )}
           />
           <View style={styles.marginManager}>
             <MutualFriends user={user} friends={mutual_friends} />
diff --git a/src/types/types.ts b/src/types/types.ts
index e96d35a9..b2d39cd9 100644
--- a/src/types/types.ts
+++ b/src/types/types.ts
@@ -251,6 +251,7 @@ export type SuggestedPeopleDataType = {
   social_links: string[];
   suggested_people_url: string;
   friendship: FriendshipType;
+  is_private: boolean;
 };
 
 export type FriendshipType = {
diff --git a/src/utils/users.ts b/src/utils/users.ts
index d5e44b36..6cb6d46c 100644
--- a/src/utils/users.ts
+++ b/src/utils/users.ts
@@ -174,3 +174,11 @@ export const defaultUserProfile = () => {
   const defaultImage = require('../assets/images/avatar-placeholder.png');
   return defaultImage;
 };
+
+export const canViewProfile = (
+  ownProfile: boolean,
+  isPrivate: boolean,
+  isFriend: boolean,
+) => {
+  return ownProfile || isFriend || !isPrivate;
+};
-- 
cgit v1.2.3-70-g09d2


From 59f64faa456b7f4852eef3d9281afde8d8f46e9a Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Mon, 29 Mar 2021 14:13:06 -0400
Subject: fix linter warnings

---
 src/components/profile/PublicProfile.tsx | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

(limited to 'src/components/profile/PublicProfile.tsx')

diff --git a/src/components/profile/PublicProfile.tsx b/src/components/profile/PublicProfile.tsx
index a70e8e50..8d597986 100644
--- a/src/components/profile/PublicProfile.tsx
+++ b/src/components/profile/PublicProfile.tsx
@@ -30,20 +30,20 @@ import {moveCategory, normalize, SCREEN_HEIGHT} from '../../utils';
 import {TaggPrompt} from '../common';
 import {Moment} from '../moments';
 
-const PublicProfile: React.FC<ContentProps> = ({y, userXId, screenType}) => {
+const PublicProfile: React.FC<ContentProps> = ({userXId, screenType}) => {
   const dispatch = useDispatch();
 
-  const {profile = NO_PROFILE} = userXId
-    ? useSelector((state: RootState) => state.userX[screenType][userXId])
-    : useSelector((state: RootState) => state.user);
+  const {profile = NO_PROFILE} = useSelector((state: RootState) =>
+    userXId ? state.userX[screenType][userXId] : state.user,
+  );
 
-  const {moments = EMPTY_MOMENTS_LIST} = userXId
-    ? useSelector((state: RootState) => state.userX[screenType][userXId])
-    : useSelector((state: RootState) => state.moments);
+  const {moments = EMPTY_MOMENTS_LIST} = useSelector((state: RootState) =>
+    userXId ? state.userX[screenType][userXId] : state.moments,
+  );
 
-  const {momentCategories = []} = userXId
-    ? useSelector((state: RootState) => state.userX[screenType][userXId])
-    : useSelector((state: RootState) => state.momentCategories);
+  const {momentCategories = []} = useSelector((state: RootState) =>
+    userXId ? state.userX[screenType][userXId] : state.momentCategories,
+  );
 
   const {user: loggedInUser = NO_USER} = useSelector(
     (state: RootState) => state.user,
@@ -117,10 +117,12 @@ const PublicProfile: React.FC<ContentProps> = ({y, userXId, screenType}) => {
         setTimeout(navigateToMomentUploadPrompt, 2000);
       }
     }, [
+      userXId,
       profile.profile_completion_stage,
       momentCategories,
-      userXId,
       isStageOnePromptClosed,
+      navigation,
+      screenType,
     ]),
   );
 
@@ -188,7 +190,7 @@ const PublicProfile: React.FC<ContentProps> = ({y, userXId, screenType}) => {
           <TaggPrompt
             messageHeader={UPLOAD_MOMENT_PROMPT_TWO_HEADER}
             messageBody={UPLOAD_MOMENT_PROMPT_TWO_MESSAGE}
-            logoType=""
+            logoType="tagg"
             onClose={() => {
               setIsStageTwoPromptClosed(true);
             }}
@@ -200,7 +202,7 @@ const PublicProfile: React.FC<ContentProps> = ({y, userXId, screenType}) => {
           <TaggPrompt
             messageHeader={UPLOAD_MOMENT_PROMPT_THREE_HEADER}
             messageBody={UPLOAD_MOMENT_PROMPT_THREE_MESSAGE}
-            logoType=""
+            logoType="tagg"
             onClose={() => {
               setIsStageThreePromptClosed(true);
             }}
-- 
cgit v1.2.3-70-g09d2


From 872a3e8dbb7182e532d7878f3b1f316b3ca69386 Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Mon, 29 Mar 2021 14:14:01 -0400
Subject: cleaned up code

---
 src/components/profile/PublicProfile.tsx | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

(limited to 'src/components/profile/PublicProfile.tsx')

diff --git a/src/components/profile/PublicProfile.tsx b/src/components/profile/PublicProfile.tsx
index 8d597986..3272bca1 100644
--- a/src/components/profile/PublicProfile.tsx
+++ b/src/components/profile/PublicProfile.tsx
@@ -58,16 +58,11 @@ const PublicProfile: React.FC<ContentProps> = ({userXId, screenType}) => {
     new Map(),
   );
 
-  const [isStageTwoPromptClosed, setIsStageTwoPromptClosed] = useState<boolean>(
+  const [isStageTwoPromptClosed, setIsStageTwoPromptClosed] = useState(false);
+  const [isStageOnePromptClosed, setIsStageOnePromptClosed] = useState(false);
+  const [isStageThreePromptClosed, setIsStageThreePromptClosed] = useState(
     false,
   );
-  const [isStageOnePromptClosed, setIsStageOnePromptClosed] = useState<boolean>(
-    false,
-  );
-  const [
-    isStageThreePromptClosed,
-    setIsStageThreePromptClosed,
-  ] = useState<boolean>(false);
 
   const move = (direction: 'up' | 'down', title: string) => {
     let categories = [...momentCategories];
-- 
cgit v1.2.3-70-g09d2


From ee80ddfb8a486fea31d845aba4e0b4847fe637e9 Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Mon, 29 Mar 2021 14:43:35 -0400
Subject: updated padding

---
 src/components/profile/Content.tsx        | 1 -
 src/components/profile/PrivateProfile.tsx | 3 ++-
 src/components/profile/PublicProfile.tsx  | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

(limited to 'src/components/profile/PublicProfile.tsx')

diff --git a/src/components/profile/Content.tsx b/src/components/profile/Content.tsx
index c9a87ad1..a22b9728 100644
--- a/src/components/profile/Content.tsx
+++ b/src/components/profile/Content.tsx
@@ -172,7 +172,6 @@ const styles = StyleSheet.create({
   },
   contentContainer: {
     flexGrow: 1,
-    paddingBottom: SCREEN_HEIGHT * 0.1,
   },
 });
 
diff --git a/src/components/profile/PrivateProfile.tsx b/src/components/profile/PrivateProfile.tsx
index 07a0dccc..bc75a18a 100644
--- a/src/components/profile/PrivateProfile.tsx
+++ b/src/components/profile/PrivateProfile.tsx
@@ -19,7 +19,8 @@ const styles = StyleSheet.create({
     alignItems: 'center',
     justifyContent: 'center',
     backgroundColor: '#F9F9F9',
-    height: SCREEN_HEIGHT * 0.35,
+    height: SCREEN_HEIGHT * 0.4,
+    paddingBottom: SCREEN_HEIGHT * 0.1,
   },
   privateAccountTextContainer: {marginTop: '8%'},
   privateAccountTextStyle: {
diff --git a/src/components/profile/PublicProfile.tsx b/src/components/profile/PublicProfile.tsx
index 3272bca1..9683d8f2 100644
--- a/src/components/profile/PublicProfile.tsx
+++ b/src/components/profile/PublicProfile.tsx
@@ -245,7 +245,7 @@ const styles = StyleSheet.create({
   },
   momentsContainer: {
     backgroundColor: '#f2f2f2',
-    paddingBottom: SCREEN_HEIGHT / 10,
+    paddingBottom: SCREEN_HEIGHT * 0.15,
     flex: 1,
     flexDirection: 'column',
   },
-- 
cgit v1.2.3-70-g09d2

