From 0b338e0c243c63fc836c7a9829ef3787045bc034 Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Mon, 10 May 2021 16:28:37 -0400
Subject: added navigation to "Likes" screen

---
 src/screens/profile/CommentReactionScreen.tsx | 66 +++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)
 create mode 100644 src/screens/profile/CommentReactionScreen.tsx

(limited to 'src/screens/profile/CommentReactionScreen.tsx')

diff --git a/src/screens/profile/CommentReactionScreen.tsx b/src/screens/profile/CommentReactionScreen.tsx
new file mode 100644
index 00000000..1bda2a65
--- /dev/null
+++ b/src/screens/profile/CommentReactionScreen.tsx
@@ -0,0 +1,66 @@
+import {RouteProp} from '@react-navigation/native';
+import React, {useEffect, useState} from 'react';
+import {ScrollView, StatusBar, StyleSheet, View} from 'react-native';
+import {SafeAreaView} from 'react-native-safe-area-context';
+import {useSelector, useStore} from 'react-redux';
+import {Friends} from '../../components';
+import {MainStackParams} from '../../routes/main';
+import {RootState} from '../../store/rootReducer';
+import {ProfilePreviewType, ScreenType} from '../../types';
+import {HeaderHeight, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
+
+/**
+ * Comments Screen for an image uploaded
+ * Displays all comments for a particular moment uploaded by the user followed by a text area to add the comment.
+ * Comment is posted when return is pressed on the keypad.
+ */
+
+type CommentReactionScreenRouteProps = RouteProp<
+  MainStackParams,
+  'CommentReactionScreen'
+>;
+
+interface CommentReactionScreenProps {
+  route: CommentReactionScreenRouteProps;
+}
+
+const CommentReactionScreen: React.FC<CommentReactionScreenProps> = ({
+  route,
+}) => {
+  const {comment, screenType} = route.params;
+  // const [users, setUsers] = useState<ProfilePreviewType[]>([]);
+  const {friends: users} = useSelector((state: RootState) => state.friends);
+
+  useEffect(() => {}, []);
+
+  console.log(screenType);
+
+  return (
+    <View style={styles.background}>
+      <SafeAreaView>
+        <ScrollView style={styles.container}>
+          <Friends
+            result={users}
+            screenType={screenType}
+            userId={undefined}
+            hideSubheader
+          />
+        </ScrollView>
+      </SafeAreaView>
+    </View>
+  );
+};
+
+const styles = StyleSheet.create({
+  background: {
+    backgroundColor: 'white',
+    width: SCREEN_WIDTH,
+    height: SCREEN_HEIGHT,
+  },
+  container: {
+    marginTop: HeaderHeight,
+    height: SCREEN_HEIGHT - HeaderHeight,
+  },
+});
+
+export default CommentReactionScreen;
-- 
cgit v1.2.3-70-g09d2


From c3f7b66e4941d3bc0a0406e46f3b8fce5e01329e Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Mon, 10 May 2021 16:37:11 -0400
Subject: finished likes screen

---
 src/components/comments/CommentTile.tsx       |  1 +
 src/constants/api.ts                          |  2 +-
 src/screens/profile/CommentReactionScreen.tsx | 36 +++++++++++++++------------
 3 files changed, 22 insertions(+), 17 deletions(-)

(limited to 'src/screens/profile/CommentReactionScreen.tsx')

diff --git a/src/components/comments/CommentTile.tsx b/src/components/comments/CommentTile.tsx
index 688a16e6..e3364007 100644
--- a/src/components/comments/CommentTile.tsx
+++ b/src/components/comments/CommentTile.tsx
@@ -171,6 +171,7 @@ const CommentTile: React.FC<CommentTileProps> = ({
             <View style={styles.row}>
               <TouchableOpacity
                 style={styles.row}
+                disabled={commentObject.reaction_count === 0}
                 onPress={() => {
                   navigation.navigate('CommentReactionScreen', {
                     comment: commentObject,
diff --git a/src/constants/api.ts b/src/constants/api.ts
index 1a31e815..2d9a60db 100644
--- a/src/constants/api.ts
+++ b/src/constants/api.ts
@@ -32,7 +32,7 @@ export const MOMENTS_ENDPOINT: string = API_URL + 'moments/';
 export const MOMENT_THUMBNAIL_ENDPOINT: string = API_URL + 'moment-thumbnail/';
 export const VERIFY_INVITATION_CODE_ENDPOUNT: string = API_URL + 'verify-code/';
 export const COMMENTS_ENDPOINT: string = API_URL + 'comments/';
-export const COMMENT_REACTIONS_ENDPOINT: string = API_URL + 'react-comment/';
+export const COMMENT_REACTIONS_ENDPOINT: string = API_URL + 'reaction-comment/';
 export const FRIENDS_ENDPOINT: string = API_URL + 'friends/';
 export const ALL_USERS_ENDPOINT: string = API_URL + 'users/';
 export const REPORT_ISSUE_ENDPOINT: string = API_URL + 'report/';
diff --git a/src/screens/profile/CommentReactionScreen.tsx b/src/screens/profile/CommentReactionScreen.tsx
index 1bda2a65..23a1f768 100644
--- a/src/screens/profile/CommentReactionScreen.tsx
+++ b/src/screens/profile/CommentReactionScreen.tsx
@@ -1,20 +1,14 @@
-import {RouteProp} from '@react-navigation/native';
+import {RouteProp, useNavigation} from '@react-navigation/native';
 import React, {useEffect, useState} from 'react';
-import {ScrollView, StatusBar, StyleSheet, View} from 'react-native';
+import {Alert, ScrollView, StyleSheet, View} from 'react-native';
 import {SafeAreaView} from 'react-native-safe-area-context';
-import {useSelector, useStore} from 'react-redux';
 import {Friends} from '../../components';
+import {ERROR_SOMETHING_WENT_WRONG} from '../../constants/strings';
 import {MainStackParams} from '../../routes/main';
-import {RootState} from '../../store/rootReducer';
-import {ProfilePreviewType, ScreenType} from '../../types';
+import {getUsersReactedToAComment} from '../../services';
+import {ProfilePreviewType} from '../../types';
 import {HeaderHeight, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
 
-/**
- * Comments Screen for an image uploaded
- * Displays all comments for a particular moment uploaded by the user followed by a text area to add the comment.
- * Comment is posted when return is pressed on the keypad.
- */
-
 type CommentReactionScreenRouteProps = RouteProp<
   MainStackParams,
   'CommentReactionScreen'
@@ -27,13 +21,23 @@ interface CommentReactionScreenProps {
 const CommentReactionScreen: React.FC<CommentReactionScreenProps> = ({
   route,
 }) => {
+  const navigation = useNavigation();
   const {comment, screenType} = route.params;
-  // const [users, setUsers] = useState<ProfilePreviewType[]>([]);
-  const {friends: users} = useSelector((state: RootState) => state.friends);
-
-  useEffect(() => {}, []);
+  const [users, setUsers] = useState<ProfilePreviewType[]>([]);
 
-  console.log(screenType);
+  useEffect(() => {
+    const loadUsers = async () => {
+      const response = await getUsersReactedToAComment(comment);
+      if (response.length !== 0) {
+        console.log(response);
+        setUsers(users);
+      } else {
+        Alert.alert(ERROR_SOMETHING_WENT_WRONG);
+        navigation.goBack();
+      }
+    };
+    loadUsers();
+  }, []);
 
   return (
     <View style={styles.background}>
-- 
cgit v1.2.3-70-g09d2


From 69c07634befdad4be416df843ecb803e760c5883 Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Tue, 11 May 2021 15:10:02 -0400
Subject: cleaned up dead code

---
 src/components/comments/CommentTile.tsx       |  3 +-
 src/components/profile/Friends.tsx            | 79 ++-------------------------
 src/screens/profile/CommentReactionScreen.tsx |  3 +-
 3 files changed, 8 insertions(+), 77 deletions(-)

(limited to 'src/screens/profile/CommentReactionScreen.tsx')

diff --git a/src/components/comments/CommentTile.tsx b/src/components/comments/CommentTile.tsx
index d028ceea..e38946af 100644
--- a/src/components/comments/CommentTile.tsx
+++ b/src/components/comments/CommentTile.tsx
@@ -1,4 +1,4 @@
-import {CommonActions, useNavigation} from '@react-navigation/native';
+import {useNavigation} from '@react-navigation/native';
 import React, {Fragment, useContext, useEffect, useRef, useState} from 'react';
 import {Alert, Animated, StyleSheet} from 'react-native';
 import {Text, View} from 'react-native-animatable';
@@ -55,7 +55,6 @@ const CommentTile: React.FC<CommentTileProps> = ({
   const [showReplies, setShowReplies] = useState<boolean>(false);
   const [showKeyboard, setShowKeyboard] = useState<boolean>(false);
   const [shouldUpdateChild, setShouldUpdateChild] = useState(true);
-  const [forceRerender, setForceRerender] = useState(0);
   const swipeRef = useRef<Swipeable>(null);
   const {replyPosted} = useSelector((state: RootState) => state.user);
   const state: RootState = useStore().getState();
diff --git a/src/components/profile/Friends.tsx b/src/components/profile/Friends.tsx
index c9d8e6ae..f800597b 100644
--- a/src/components/profile/Friends.tsx
+++ b/src/components/profile/Friends.tsx
@@ -1,102 +1,35 @@
-import React, {useEffect, useState} from 'react';
+import React from 'react';
 import {ScrollView, StyleSheet, Text, View} from 'react-native';
-import {checkPermission} from 'react-native-contacts';
 import {TouchableOpacity} from 'react-native-gesture-handler';
 import {useDispatch, useStore} from 'react-redux';
 import {TAGG_LIGHT_BLUE} from '../../constants';
-import {usersFromContactsService} from '../../services';
 import {NO_USER} from '../../store/initialStates';
 import {RootState} from '../../store/rootReducer';
 import {ProfilePreviewType, ScreenType} from '../../types';
-import {
-  extractContacts,
-  normalize,
-  SCREEN_HEIGHT,
-  SCREEN_WIDTH,
-} from '../../utils';
-import {handleAddFriend, handleUnfriend} from '../../utils/friends';
+import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
+import {handleUnfriend} from '../../utils/friends';
 import {ProfilePreview} from '../profile';
 
 interface FriendsProps {
   result: Array<ProfilePreviewType>;
   screenType: ScreenType;
   userId: string | undefined;
-  hideSubheader?: boolean;
+  hideFriendsFeature?: boolean;
 }
 
 const Friends: React.FC<FriendsProps> = ({
   result,
   screenType,
   userId,
-  hideSubheader,
+  hideFriendsFeature,
 }) => {
   const state: RootState = useStore().getState();
   const dispatch = useDispatch();
   const {user: loggedInUser = NO_USER} = state.user;
-  const [usersFromContacts, setUsersFromContacts] = useState<
-    ProfilePreviewType[]
-  >([]);
-
-  useEffect(() => {
-    const handleFindFriends = () => {
-      extractContacts().then(async (contacts) => {
-        const permission = await checkPermission();
-        if (permission === 'authorized') {
-          let response = await usersFromContactsService(contacts);
-          setUsersFromContacts(response.existing_tagg_users);
-        } else {
-          console.log('Authorize access to contacts');
-        }
-      });
-    };
-    handleFindFriends();
-  }, []);
-
-  const UsersFromContacts = () => (
-    <>
-      {usersFromContacts?.splice(0, 2).map((profilePreview) => (
-        <View key={profilePreview.id} style={styles.container}>
-          <View style={styles.friend}>
-            <ProfilePreview
-              {...{profilePreview}}
-              previewType={'Friend'}
-              screenType={screenType}
-            />
-          </View>
-          <TouchableOpacity
-            style={styles.addFriendButton}
-            onPress={() => {
-              handleAddFriend(screenType, profilePreview, dispatch, state).then(
-                (success) => {
-                  if (success) {
-                    let users = usersFromContacts;
-                    setUsersFromContacts(
-                      users.filter(
-                        (user) => user.username !== profilePreview.username,
-                      ),
-                    );
-                  }
-                },
-              );
-            }}>
-            <Text style={styles.addFriendButtonTitle}>Add Friend</Text>
-          </TouchableOpacity>
-        </View>
-      ))}
-    </>
-  );
 
   return (
     <>
-      {loggedInUser.userId === userId && usersFromContacts.length !== 0 && (
-        <View style={styles.subheader}>
-          <View style={styles.addFriendHeaderContainer}>
-            <Text style={styles.subheaderText}>Contacts on Tagg</Text>
-          </View>
-          <UsersFromContacts />
-        </View>
-      )}
-      {!hideSubheader && (
+      {!hideFriendsFeature && (
         <Text style={[styles.subheaderText, styles.friendsSubheaderText]}>
           Friends
         </Text>
diff --git a/src/screens/profile/CommentReactionScreen.tsx b/src/screens/profile/CommentReactionScreen.tsx
index 23a1f768..488497ee 100644
--- a/src/screens/profile/CommentReactionScreen.tsx
+++ b/src/screens/profile/CommentReactionScreen.tsx
@@ -29,7 +29,6 @@ const CommentReactionScreen: React.FC<CommentReactionScreenProps> = ({
     const loadUsers = async () => {
       const response = await getUsersReactedToAComment(comment);
       if (response.length !== 0) {
-        console.log(response);
         setUsers(users);
       } else {
         Alert.alert(ERROR_SOMETHING_WENT_WRONG);
@@ -47,7 +46,7 @@ const CommentReactionScreen: React.FC<CommentReactionScreenProps> = ({
             result={users}
             screenType={screenType}
             userId={undefined}
-            hideSubheader
+            hideFriendsFeature
           />
         </ScrollView>
       </SafeAreaView>
-- 
cgit v1.2.3-70-g09d2


From 58ab56d0b03491dd062d09e2ee96fe8f88e74bc9 Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Tue, 11 May 2021 17:55:43 -0400
Subject: fixed issue, basic functionality working

---
 src/components/comments/CommentTile.tsx       |  7 ++++---
 src/components/common/LikeButton.tsx          | 12 +++++++-----
 src/constants/api.ts                          |  1 +
 src/screens/profile/CommentReactionScreen.tsx |  2 +-
 src/services/CommentService.ts                | 24 ++++++++++++++++++------
 5 files changed, 31 insertions(+), 15 deletions(-)

(limited to 'src/screens/profile/CommentReactionScreen.tsx')

diff --git a/src/components/comments/CommentTile.tsx b/src/components/comments/CommentTile.tsx
index e38946af..1f1fafda 100644
--- a/src/components/comments/CommentTile.tsx
+++ b/src/components/comments/CommentTile.tsx
@@ -150,10 +150,11 @@ const CommentTile: React.FC<CommentTileProps> = ({
             screenType={screenType}
           />
           <LikeButton
-            filled={commentObject.user_reaction !== null}
+            initialLikeState={commentObject.user_reaction !== null}
             onPress={() => {
-              handleLikeUnlikeComment(commentObject);
-              setShouldUpdateParent(true);
+              handleLikeUnlikeComment(commentObject).then(() => {
+                setShouldUpdateParent(true);
+              });
             }}
             style={styles.likeButton}
           />
diff --git a/src/components/common/LikeButton.tsx b/src/components/common/LikeButton.tsx
index f817bd98..43b3ac37 100644
--- a/src/components/common/LikeButton.tsx
+++ b/src/components/common/LikeButton.tsx
@@ -4,23 +4,25 @@ import {normalize} from '../../utils';
 
 interface LikeButtonProps {
   onPress: () => void;
-  filled: boolean;
   style: ImageStyle;
+  initialLikeState: boolean;
 }
 const LikeButton: React.FC<LikeButtonProps> = ({
   onPress,
-  filled: initialFillState,
   style,
+  initialLikeState,
 }) => {
-  const [filled, setFilled] = useState(initialFillState);
+  const [filled, setFilled] = useState(initialLikeState);
   const uri = filled
     ? require('../../assets/images/heart-filled.png')
     : require('../../assets/images/heart-outlined.png');
   return (
     <TouchableOpacity
       onPress={() => {
-        setFilled(!filled);
-        onPress();
+        if (filled === initialLikeState) {
+          setFilled(!filled);
+          onPress();
+        }
       }}>
       <Image style={[styles.image, style]} source={uri} />
     </TouchableOpacity>
diff --git a/src/constants/api.ts b/src/constants/api.ts
index 2d9a60db..6a924f1d 100644
--- a/src/constants/api.ts
+++ b/src/constants/api.ts
@@ -33,6 +33,7 @@ export const MOMENT_THUMBNAIL_ENDPOINT: string = API_URL + 'moment-thumbnail/';
 export const VERIFY_INVITATION_CODE_ENDPOUNT: string = API_URL + 'verify-code/';
 export const COMMENTS_ENDPOINT: string = API_URL + 'comments/';
 export const COMMENT_REACTIONS_ENDPOINT: string = API_URL + 'reaction-comment/';
+export const COMMENT_REACTIONS_REPLY_ENDPOINT: string = API_URL + 'reaction-reply/';
 export const FRIENDS_ENDPOINT: string = API_URL + 'friends/';
 export const ALL_USERS_ENDPOINT: string = API_URL + 'users/';
 export const REPORT_ISSUE_ENDPOINT: string = API_URL + 'report/';
diff --git a/src/screens/profile/CommentReactionScreen.tsx b/src/screens/profile/CommentReactionScreen.tsx
index 488497ee..0596a184 100644
--- a/src/screens/profile/CommentReactionScreen.tsx
+++ b/src/screens/profile/CommentReactionScreen.tsx
@@ -29,7 +29,7 @@ const CommentReactionScreen: React.FC<CommentReactionScreenProps> = ({
     const loadUsers = async () => {
       const response = await getUsersReactedToAComment(comment);
       if (response.length !== 0) {
-        setUsers(users);
+        setUsers(response);
       } else {
         Alert.alert(ERROR_SOMETHING_WENT_WRONG);
         navigation.goBack();
diff --git a/src/services/CommentService.ts b/src/services/CommentService.ts
index e85b1991..b21c6dfd 100644
--- a/src/services/CommentService.ts
+++ b/src/services/CommentService.ts
@@ -3,11 +3,13 @@ import {Alert} from 'react-native';
 import {
   COMMENTS_ENDPOINT,
   COMMENT_REACTIONS_ENDPOINT,
+  COMMENT_REACTIONS_REPLY_ENDPOINT,
   COMMENT_THREAD_ENDPOINT,
 } from '../constants';
 import {ERROR_FAILED_TO_COMMENT} from '../constants/strings';
 import {
   CommentBaseType,
+  CommentThreadType,
   CommentType,
   ProfilePreviewType,
   ReactionOptionsType,
@@ -133,12 +135,18 @@ export const deleteComment = async (id: string, isThread: boolean) => {
  * @param comment the comment object that contains `user_reaction` (or not)
  * @returns
  */
-export const handleLikeUnlikeComment = async (comment: CommentBaseType) => {
+export const handleLikeUnlikeComment = async (
+  comment: CommentType | CommentThreadType,
+) => {
   try {
+    const isReply = 'parent_comment' in comment;
     const token = await AsyncStorage.getItem('token');
+    let url = isReply
+      ? COMMENT_REACTIONS_REPLY_ENDPOINT
+      : COMMENT_REACTIONS_ENDPOINT;
     if (comment.user_reaction !== null) {
       // unlike a comment
-      const url = COMMENT_REACTIONS_ENDPOINT + `${comment.user_reaction.id}/`;
+      url += `${comment.user_reaction.id}/`;
       const response = await fetch(url, {
         method: 'DELETE',
         headers: {
@@ -148,7 +156,6 @@ export const handleLikeUnlikeComment = async (comment: CommentBaseType) => {
       return response.status === 200;
     } else {
       // like a comment
-      const url = COMMENT_REACTIONS_ENDPOINT;
       const form = new FormData();
       form.append('comment_id', comment.comment_id);
       form.append('reaction_type', ReactionOptionsType.Like);
@@ -168,11 +175,16 @@ export const handleLikeUnlikeComment = async (comment: CommentBaseType) => {
   }
 };
 
-export const getUsersReactedToAComment = async (comment: CommentBaseType) => {
+export const getUsersReactedToAComment = async (
+  comment: CommentType | CommentThreadType,
+) => {
   try {
+    const isReply = 'parent_comment' in comment;
     const token = await AsyncStorage.getItem('token');
-    const url =
-      COMMENT_REACTIONS_ENDPOINT + `?comment_id=${comment.comment_id}`;
+    let url = isReply
+      ? COMMENT_REACTIONS_REPLY_ENDPOINT
+      : COMMENT_REACTIONS_ENDPOINT;
+    url += `?comment_id=${comment.comment_id}`;
     const response = await fetch(url, {
       method: 'GET',
       headers: {
-- 
cgit v1.2.3-70-g09d2

