From 43e1c33edf6fca78e366403f167cc01ea075a226 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Fri, 7 May 2021 15:12:13 -0400 Subject: added like button --- src/assets/images/heart-filled.png | Bin 0 -> 1208 bytes src/assets/images/heart-outlined.png | Bin 0 -> 1055 bytes src/components/comments/CommentTile.tsx | 22 +++++++++++++++++----- src/components/common/LikeButton.tsx | 32 ++++++++++++++++++++++++++++++++ src/components/common/index.ts | 1 + 5 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 src/assets/images/heart-filled.png create mode 100644 src/assets/images/heart-outlined.png create mode 100644 src/components/common/LikeButton.tsx (limited to 'src') diff --git a/src/assets/images/heart-filled.png b/src/assets/images/heart-filled.png new file mode 100644 index 00000000..59bf0ab1 Binary files /dev/null and b/src/assets/images/heart-filled.png differ diff --git a/src/assets/images/heart-outlined.png b/src/assets/images/heart-outlined.png new file mode 100644 index 00000000..aeb87a99 Binary files /dev/null and b/src/assets/images/heart-outlined.png differ diff --git a/src/components/comments/CommentTile.tsx b/src/components/comments/CommentTile.tsx index ecdb4c30..cf79b68c 100644 --- a/src/components/comments/CommentTile.tsx +++ b/src/components/comments/CommentTile.tsx @@ -26,6 +26,7 @@ import { SCREEN_WIDTH, } from '../../utils'; import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments'; +import {LikeButton} from '../common'; import {ProfilePreview} from '../profile'; import CommentsContainer from './CommentsContainer'; @@ -143,11 +144,14 @@ const CommentTile: React.FC = ({ containerStyle={styles.swipableContainer}> - + + + {}} style={styles.likeButton} /> + {renderTextWithMentions({ value: commentObject.comment, @@ -215,6 +219,14 @@ const styles = StyleSheet.create({ moreMarginWithThread: { marginLeft: '14%', }, + commentHeaderContainer: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + }, + likeButton: { + marginRight: 10, + }, body: { marginLeft: 56, }, diff --git a/src/components/common/LikeButton.tsx b/src/components/common/LikeButton.tsx new file mode 100644 index 00000000..28eff768 --- /dev/null +++ b/src/components/common/LikeButton.tsx @@ -0,0 +1,32 @@ +import React, {useState} from 'react'; +import {Image, ImageStyle, StyleSheet, TouchableOpacity} from 'react-native'; +import {normalize} from '../../utils'; + +interface LikeButtonProps { + onPress: () => void; + style: ImageStyle; +} +const LikeButton: React.FC = ({onPress, style}) => { + const [filled, setFilled] = useState(false); + const uri = filled + ? require('../../assets/images/heart-filled.png') + : require('../../assets/images/heart-outlined.png'); + return ( + { + setFilled(!filled); + onPress(); + }}> + + + ); +}; + +const styles = StyleSheet.create({ + image: { + width: normalize(18), + height: normalize(15), + }, +}); + +export default LikeButton; diff --git a/src/components/common/index.ts b/src/components/common/index.ts index b38056c6..48abb8b8 100644 --- a/src/components/common/index.ts +++ b/src/components/common/index.ts @@ -26,3 +26,4 @@ export {default as BasicButton} from './BasicButton'; export {default as Avatar} from './Avatar'; export {default as TaggTypeahead} from './TaggTypeahead'; export {default as TaggUserRowCell} from './TaggUserRowCell'; +export {default as LikeButton} from './LikeButton'; -- cgit v1.2.3-70-g09d2 From a19514a3916a2dc2eab28a085866b34f2e9f2bc6 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Fri, 7 May 2021 15:24:21 -0400 Subject: styled comment --- src/components/comments/CommentTile.tsx | 76 +++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/components/comments/CommentTile.tsx b/src/components/comments/CommentTile.tsx index cf79b68c..f793cdbe 100644 --- a/src/components/comments/CommentTile.tsx +++ b/src/components/comments/CommentTile.tsx @@ -160,33 +160,42 @@ const CommentTile: React.FC = ({ onPress: (user: UserType) => navigateToProfile(state, dispatch, navigation, screenType, user), })} - - - {' ' + timePosted} - + + + + {' ' + timePosted} + + + 5 + Likes + + {/* Show replies text only if there are some replies present */} + {!isThread && (commentObject as CommentType).replies_count > 0 ? ( + + + {getRepliesText(commentObject as CommentType)} + + + + ) : ( + // empty view for justify content's space-between + + )} - {/*** Show replies text only if there are some replies present */} - {!isThread && (commentObject as CommentType).replies_count > 0 && ( - - - {getRepliesText(commentObject as CommentType)} - - - - )} - - {/*** Show replies if toggle state is true */} + {/* Show replies if toggle state is true */} {showReplies && ( Date: Fri, 7 May 2021 15:56:07 -0400 Subject: updated minor styling --- src/components/comments/CommentTile.tsx | 63 ++++++++++++--------------- src/components/comments/CommentsContainer.tsx | 1 - src/screens/profile/MomentCommentsScreen.tsx | 2 +- 3 files changed, 30 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/components/comments/CommentTile.tsx b/src/components/comments/CommentTile.tsx index f793cdbe..cc847885 100644 --- a/src/components/comments/CommentTile.tsx +++ b/src/components/comments/CommentTile.tsx @@ -19,12 +19,7 @@ import { ScreenType, UserType, } from '../../types'; -import { - getTimePosted, - navigateToProfile, - normalize, - SCREEN_WIDTH, -} from '../../utils'; +import {getTimePosted, navigateToProfile, normalize} from '../../utils'; import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments'; import {LikeButton} from '../common'; import {ProfilePreview} from '../profile'; @@ -101,7 +96,7 @@ const CommentTile: React.FC = ({ showReplies ? 'Hide' : comment.replies_count > 0 - ? `Replies (${comment.replies_count})` + ? `Replies (${comment.replies_count}) ` : 'Replies'; const renderRightAction = (text: string, color: string) => { @@ -166,32 +161,31 @@ const CommentTile: React.FC = ({ {' ' + timePosted} - 5 - Likes - - {/* Show replies text only if there are some replies present */} - {!isThread && (commentObject as CommentType).replies_count > 0 ? ( - - - {getRepliesText(commentObject as CommentType)} - - + {}}> + 999 + Likes - ) : ( - // empty view for justify content's space-between - - )} + {/* Show replies text only if there are some replies present */} + {!isThread && (commentObject as CommentType).replies_count > 0 && ( + + + {getRepliesText(commentObject as CommentType)} + + + + )} + @@ -219,8 +213,8 @@ const styles = StyleSheet.create({ flexDirection: 'column', flex: 1, paddingTop: '3%', - marginLeft: '7%', - paddingBottom: 5, + marginLeft: '5%', + paddingBottom: '2%', }, swipeActions: { flexDirection: 'row', @@ -268,6 +262,7 @@ const styles = StyleSheet.create({ repliesTextAndIconContainer: { flexDirection: 'row', alignItems: 'center', + paddingLeft: 10, }, repliesText: { color: TAGG_LIGHT_BLUE, diff --git a/src/components/comments/CommentsContainer.tsx b/src/components/comments/CommentsContainer.tsx index cd9ecb02..bd8d5c49 100644 --- a/src/components/comments/CommentsContainer.tsx +++ b/src/components/comments/CommentsContainer.tsx @@ -125,7 +125,6 @@ const CommentsContainer: React.FC = ({ }; const styles = StyleSheet.create({ - scrollView: {}, scrollViewContent: { justifyContent: 'center', }, diff --git a/src/screens/profile/MomentCommentsScreen.tsx b/src/screens/profile/MomentCommentsScreen.tsx index 1a913e58..ffe21f4c 100644 --- a/src/screens/profile/MomentCommentsScreen.tsx +++ b/src/screens/profile/MomentCommentsScreen.tsx @@ -105,7 +105,7 @@ const styles = StyleSheet.create({ }, body: { marginTop: HeaderHeight, - width: SCREEN_WIDTH * 0.9, + width: SCREEN_WIDTH * 0.95, height: SCREEN_HEIGHT * 0.8, paddingTop: '3%', }, -- cgit v1.2.3-70-g09d2 From 4f37038df45ee1aea6d42933ffa79f70a0a426d2 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Mon, 10 May 2021 15:17:45 -0400 Subject: added basic type, added like/unlike handler --- src/components/comments/CommentTile.tsx | 16 +++++++++++++--- src/components/common/LikeButton.tsx | 9 +++++++-- src/services/CommentService.ts | 18 +++++++++++++++++- src/types/types.ts | 11 +++++++++++ 4 files changed, 48 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/components/comments/CommentTile.tsx b/src/components/comments/CommentTile.tsx index cc847885..8074a015 100644 --- a/src/components/comments/CommentTile.tsx +++ b/src/components/comments/CommentTile.tsx @@ -11,7 +11,11 @@ import Trash from '../../assets/ionicons/trash-outline.svg'; import {TAGG_LIGHT_BLUE} from '../../constants'; import {ERROR_FAILED_TO_DELETE_COMMENT} from '../../constants/strings'; import {CommentContext} from '../../screens/profile/MomentCommentsScreen'; -import {deleteComment, getCommentsCount} from '../../services'; +import { + deleteComment, + getCommentsCount, + handleLikeUnlikeComment, +} from '../../services'; import {RootState} from '../../store/rootReducer'; import { CommentThreadType, @@ -145,7 +149,11 @@ const CommentTile: React.FC = ({ previewType={'Comment'} screenType={screenType} /> - {}} style={styles.likeButton} /> + handleLikeUnlikeComment(commentObject)} + style={styles.likeButton} + /> {renderTextWithMentions({ @@ -162,7 +170,9 @@ const CommentTile: React.FC = ({ {}}> - 999 + + {commentObject.reaction_count} + Likes {/* Show replies text only if there are some replies present */} diff --git a/src/components/common/LikeButton.tsx b/src/components/common/LikeButton.tsx index 28eff768..f817bd98 100644 --- a/src/components/common/LikeButton.tsx +++ b/src/components/common/LikeButton.tsx @@ -4,10 +4,15 @@ import {normalize} from '../../utils'; interface LikeButtonProps { onPress: () => void; + filled: boolean; style: ImageStyle; } -const LikeButton: React.FC = ({onPress, style}) => { - const [filled, setFilled] = useState(false); +const LikeButton: React.FC = ({ + onPress, + filled: initialFillState, + style, +}) => { + const [filled, setFilled] = useState(initialFillState); const uri = filled ? require('../../assets/images/heart-filled.png') : require('../../assets/images/heart-outlined.png'); diff --git a/src/services/CommentService.ts b/src/services/CommentService.ts index 2faaa8db..6f054c72 100644 --- a/src/services/CommentService.ts +++ b/src/services/CommentService.ts @@ -2,7 +2,7 @@ import AsyncStorage from '@react-native-community/async-storage'; import {Alert} from 'react-native'; import {COMMENTS_ENDPOINT, COMMENT_THREAD_ENDPOINT} from '../constants'; import {ERROR_FAILED_TO_COMMENT} from '../constants/strings'; -import {CommentType} from '../types'; +import {CommentBaseType, CommentType} from '../types'; export const getComments = async ( objectId: string, @@ -116,3 +116,19 @@ export const deleteComment = async (id: string, isThread: boolean) => { return false; } }; + +/** + * If `user_reaction` is undefined, we like the comment, if `user_reaction` + * is defined, we unlike the comment. + * + * @param comment the comment object + * @returns + */ +export const handleLikeUnlikeComment = async (comment: CommentBaseType) => { + try { + return undefined; + } catch (error) { + console.log('Unable to like/unlike a comment'); + console.error(error); + } +}; diff --git a/src/types/types.ts b/src/types/types.ts index 00501d49..e922d307 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -122,6 +122,8 @@ export interface CommentBaseType { comment: string; date_created: string; commenter: ProfilePreviewType; + user_reaction: ReactionType | undefined; + reaction_count: number; } export interface CommentType extends CommentBaseType { @@ -316,3 +318,12 @@ export type ChatContextType = { >; chatClient: StreamChat; }; + +export enum ReactionOptionsType { + Like = 'LIKE', +} + +export type ReactionType = { + id: string; + type: ReactionOptionsType; +}; -- cgit v1.2.3-70-g09d2 From c67025c0137074842b2cfeacefe1ea48d5748630 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Mon, 10 May 2021 15:43:33 -0400 Subject: added getUsersReactedToAComment implementation --- src/constants/api.ts | 1 + src/services/CommentService.ts | 49 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/constants/api.ts b/src/constants/api.ts index d45616a1..1a31e815 100644 --- a/src/constants/api.ts +++ b/src/constants/api.ts @@ -32,6 +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 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/services/CommentService.ts b/src/services/CommentService.ts index 6f054c72..69c5f3bc 100644 --- a/src/services/CommentService.ts +++ b/src/services/CommentService.ts @@ -1,8 +1,17 @@ import AsyncStorage from '@react-native-community/async-storage'; import {Alert} from 'react-native'; -import {COMMENTS_ENDPOINT, COMMENT_THREAD_ENDPOINT} from '../constants'; +import { + COMMENTS_ENDPOINT, + COMMENT_REACTIONS_ENDPOINT, + COMMENT_THREAD_ENDPOINT, +} from '../constants'; import {ERROR_FAILED_TO_COMMENT} from '../constants/strings'; -import {CommentBaseType, CommentType} from '../types'; +import { + CommentBaseType, + CommentType, + ProfilePreviewType, + ReactionOptionsType, +} from '../types'; export const getComments = async ( objectId: string, @@ -121,14 +130,48 @@ export const deleteComment = async (id: string, isThread: boolean) => { * If `user_reaction` is undefined, we like the comment, if `user_reaction` * is defined, we unlike the comment. * - * @param comment the comment object + * @param comment the comment object that contains `user_reaction` (or not) * @returns */ export const handleLikeUnlikeComment = async (comment: CommentBaseType) => { try { + const token = await AsyncStorage.getItem('token'); + if (comment.user_reaction !== undefined) { + // unlike a comment + } else { + // like a comment + } return undefined; } catch (error) { console.log('Unable to like/unlike a comment'); console.error(error); } }; + +export const getUsersReactedToAComment = async (comment: CommentBaseType) => { + try { + const token = await AsyncStorage.getItem('token'); + const url = + COMMENT_REACTIONS_ENDPOINT + `?comment_id=${comment.comment_id}`; + const response = await fetch(url, { + method: 'GET', + headers: { + Authorization: 'Token ' + token, + }, + }); + const typedResponse: { + reaction: ReactionOptionsType; + users: ProfilePreviewType[]; + }[] = await response.json(); + for (const obj of typedResponse) { + if (obj.reaction === ReactionOptionsType.Like) { + return obj.users; + } + } + return []; + } catch (error) { + console.log('Unable to fetch list of users whom reacted to a comment'); + console.error(error); + } + return []; +}; -- cgit v1.2.3-70-g09d2 From 6674e928c3621c742b56842db9e01d665a244ad3 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Mon, 10 May 2021 15:51:34 -0400 Subject: added implementation for handling like or unlike a comment --- src/services/CommentService.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src') diff --git a/src/services/CommentService.ts b/src/services/CommentService.ts index 69c5f3bc..7ede11cc 100644 --- a/src/services/CommentService.ts +++ b/src/services/CommentService.ts @@ -138,8 +138,29 @@ export const handleLikeUnlikeComment = async (comment: CommentBaseType) => { const token = await AsyncStorage.getItem('token'); if (comment.user_reaction !== undefined) { // unlike a comment + const url = COMMENT_REACTIONS_ENDPOINT + `${comment.user_reaction.id}/`; + const response = await fetch(url, { + method: 'DELETE', + headers: { + Authorization: 'Token ' + token, + }, + }); + 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); + const response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'multipart/form-data', + Authorization: 'Token ' + token, + }, + body: form, + }); + return response.status === 200; } return undefined; } catch (error) { -- cgit v1.2.3-70-g09d2 From 3dd918e6a981645cd7bed7d32425ac64cb9af601 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Mon, 10 May 2021 15:52:06 -0400 Subject: cleaned up code --- src/services/CommentService.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/services/CommentService.ts b/src/services/CommentService.ts index 7ede11cc..910f4fa6 100644 --- a/src/services/CommentService.ts +++ b/src/services/CommentService.ts @@ -162,7 +162,6 @@ export const handleLikeUnlikeComment = async (comment: CommentBaseType) => { }); return response.status === 200; } - return undefined; } catch (error) { console.log('Unable to like/unlike a comment'); console.error(error); -- cgit v1.2.3-70-g09d2 From 0b338e0c243c63fc836c7a9829ef3787045bc034 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Mon, 10 May 2021 16:28:37 -0400 Subject: added navigation to "Likes" screen --- src/components/comments/CommentTile.tsx | 9 +++- src/components/profile/Friends.tsx | 28 ++++++------ src/routes/main/MainStackNavigator.tsx | 11 ++++- src/routes/main/MainStackScreen.tsx | 8 ++++ src/screens/profile/CommentReactionScreen.tsx | 66 +++++++++++++++++++++++++++ src/screens/profile/FriendsListScreen.tsx | 4 -- src/screens/profile/index.ts | 1 + 7 files changed, 106 insertions(+), 21 deletions(-) create mode 100644 src/screens/profile/CommentReactionScreen.tsx (limited to 'src') diff --git a/src/components/comments/CommentTile.tsx b/src/components/comments/CommentTile.tsx index 8074a015..688a16e6 100644 --- a/src/components/comments/CommentTile.tsx +++ b/src/components/comments/CommentTile.tsx @@ -169,7 +169,14 @@ const CommentTile: React.FC = ({ {' ' + timePosted} - {}}> + { + navigation.navigate('CommentReactionScreen', { + comment: commentObject, + screenType: screenType, + }); + }}> {commentObject.reaction_count} diff --git a/src/components/profile/Friends.tsx b/src/components/profile/Friends.tsx index a7a06567..c9d8e6ae 100644 --- a/src/components/profile/Friends.tsx +++ b/src/components/profile/Friends.tsx @@ -21,9 +21,15 @@ interface FriendsProps { result: Array; screenType: ScreenType; userId: string | undefined; + hideSubheader?: boolean; } -const Friends: React.FC = ({result, screenType, userId}) => { +const Friends: React.FC = ({ + result, + screenType, + userId, + hideSubheader, +}) => { const state: RootState = useStore().getState(); const dispatch = useDispatch(); const {user: loggedInUser = NO_USER} = state.user; @@ -85,14 +91,16 @@ const Friends: React.FC = ({result, screenType, userId}) => { {loggedInUser.userId === userId && usersFromContacts.length !== 0 && ( - Contacts on Tagg + Contacts on Tagg )} - - Friends - + {!hideSubheader && ( + + Friends + + )} = ({route}) => { ...headerBarOptions('black', 'Comments'), }} /> + ; + +interface CommentReactionScreenProps { + route: CommentReactionScreenRouteProps; +} + +const CommentReactionScreen: React.FC = ({ + route, +}) => { + const {comment, screenType} = route.params; + // const [users, setUsers] = useState([]); + const {friends: users} = useSelector((state: RootState) => state.friends); + + useEffect(() => {}, []); + + console.log(screenType); + + return ( + + + + + + + + ); +}; + +const styles = StyleSheet.create({ + background: { + backgroundColor: 'white', + width: SCREEN_WIDTH, + height: SCREEN_HEIGHT, + }, + container: { + marginTop: HeaderHeight, + height: SCREEN_HEIGHT - HeaderHeight, + }, +}); + +export default CommentReactionScreen; diff --git a/src/screens/profile/FriendsListScreen.tsx b/src/screens/profile/FriendsListScreen.tsx index 1d10bc86..73364f3b 100644 --- a/src/screens/profile/FriendsListScreen.tsx +++ b/src/screens/profile/FriendsListScreen.tsx @@ -36,10 +36,6 @@ const FriendsListScreen: React.FC = ({route}) => { }; const styles = StyleSheet.create({ - background: { - backgroundColor: 'white', - height: '100%', - }, backButton: { marginLeft: 10, }, diff --git a/src/screens/profile/index.ts b/src/screens/profile/index.ts index d5377494..ea0505a2 100644 --- a/src/screens/profile/index.ts +++ b/src/screens/profile/index.ts @@ -12,3 +12,4 @@ export {default as PrivacyScreen} from './PrivacyScreen'; export {default as AccountType} from './AccountType'; export {default as CategorySelection} from './CategorySelection'; export {default as CreateCustomCategory} from './CreateCustomCategory'; +export {default as CommentReactionScreen} from './CommentReactionScreen'; -- cgit v1.2.3-70-g09d2 From c3f7b66e4941d3bc0a0406e46f3b8fce5e01329e Mon Sep 17 00:00:00 2001 From: Ivan Chen 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') 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 = ({ { 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 = ({ route, }) => { + const navigation = useNavigation(); const {comment, screenType} = route.params; - // const [users, setUsers] = useState([]); - const {friends: users} = useSelector((state: RootState) => state.friends); - - useEffect(() => {}, []); + const [users, setUsers] = useState([]); - 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 ( -- cgit v1.2.3-70-g09d2 From 0e9ec9b6403c1556fc53e895eb16ca477106e48e Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Mon, 10 May 2021 16:42:09 -0400 Subject: fixed undefined -> null --- src/components/comments/CommentTile.tsx | 2 +- src/services/CommentService.ts | 2 +- src/types/types.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/components/comments/CommentTile.tsx b/src/components/comments/CommentTile.tsx index e3364007..a31c5b51 100644 --- a/src/components/comments/CommentTile.tsx +++ b/src/components/comments/CommentTile.tsx @@ -150,7 +150,7 @@ const CommentTile: React.FC = ({ screenType={screenType} /> handleLikeUnlikeComment(commentObject)} style={styles.likeButton} /> diff --git a/src/services/CommentService.ts b/src/services/CommentService.ts index 910f4fa6..f5583ac0 100644 --- a/src/services/CommentService.ts +++ b/src/services/CommentService.ts @@ -136,7 +136,7 @@ export const deleteComment = async (id: string, isThread: boolean) => { export const handleLikeUnlikeComment = async (comment: CommentBaseType) => { try { const token = await AsyncStorage.getItem('token'); - if (comment.user_reaction !== undefined) { + if (comment.user_reaction !== null) { // unlike a comment const url = COMMENT_REACTIONS_ENDPOINT + `${comment.user_reaction.id}/`; const response = await fetch(url, { diff --git a/src/types/types.ts b/src/types/types.ts index e922d307..e9975529 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -122,7 +122,7 @@ export interface CommentBaseType { comment: string; date_created: string; commenter: ProfilePreviewType; - user_reaction: ReactionType | undefined; + user_reaction: ReactionType | null; reaction_count: number; } -- cgit v1.2.3-70-g09d2 From 46cc8a33fe206c2c3bbd781374e727c1a42b9094 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Mon, 10 May 2021 20:00:21 -0400 Subject: fixed minor issues --- src/components/comments/CommentTile.tsx | 8 ++++++-- src/services/CommentService.ts | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/components/comments/CommentTile.tsx b/src/components/comments/CommentTile.tsx index a31c5b51..d028ceea 100644 --- a/src/components/comments/CommentTile.tsx +++ b/src/components/comments/CommentTile.tsx @@ -1,4 +1,4 @@ -import {useNavigation} from '@react-navigation/native'; +import {CommonActions, 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,6 +55,7 @@ const CommentTile: React.FC = ({ const [showReplies, setShowReplies] = useState(false); const [showKeyboard, setShowKeyboard] = useState(false); const [shouldUpdateChild, setShouldUpdateChild] = useState(true); + const [forceRerender, setForceRerender] = useState(0); const swipeRef = useRef(null); const {replyPosted} = useSelector((state: RootState) => state.user); const state: RootState = useStore().getState(); @@ -151,7 +152,10 @@ const CommentTile: React.FC = ({ /> handleLikeUnlikeComment(commentObject)} + onPress={() => { + handleLikeUnlikeComment(commentObject); + setShouldUpdateParent(true); + }} style={styles.likeButton} /> diff --git a/src/services/CommentService.ts b/src/services/CommentService.ts index f5583ac0..e85b1991 100644 --- a/src/services/CommentService.ts +++ b/src/services/CommentService.ts @@ -181,11 +181,11 @@ export const getUsersReactedToAComment = async (comment: CommentBaseType) => { }); const typedResponse: { reaction: ReactionOptionsType; - users: ProfilePreviewType[]; + user_list: ProfilePreviewType[]; }[] = await response.json(); for (const obj of typedResponse) { if (obj.reaction === ReactionOptionsType.Like) { - return obj.users; + return obj.user_list; } } return []; -- cgit v1.2.3-70-g09d2 From 69c07634befdad4be416df843ecb803e760c5883 Mon Sep 17 00:00:00 2001 From: Ivan Chen 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') 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 = ({ const [showReplies, setShowReplies] = useState(false); const [showKeyboard, setShowKeyboard] = useState(false); const [shouldUpdateChild, setShouldUpdateChild] = useState(true); - const [forceRerender, setForceRerender] = useState(0); const swipeRef = useRef(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; screenType: ScreenType; userId: string | undefined; - hideSubheader?: boolean; + hideFriendsFeature?: boolean; } const Friends: React.FC = ({ 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) => ( - - - - - { - handleAddFriend(screenType, profilePreview, dispatch, state).then( - (success) => { - if (success) { - let users = usersFromContacts; - setUsersFromContacts( - users.filter( - (user) => user.username !== profilePreview.username, - ), - ); - } - }, - ); - }}> - Add Friend - - - ))} - - ); return ( <> - {loggedInUser.userId === userId && usersFromContacts.length !== 0 && ( - - - Contacts on Tagg - - - - )} - {!hideSubheader && ( + {!hideFriendsFeature && ( Friends 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 = ({ 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 = ({ result={users} screenType={screenType} userId={undefined} - hideSubheader + hideFriendsFeature /> -- cgit v1.2.3-70-g09d2 From 58ab56d0b03491dd062d09e2ee96fe8f88e74bc9 Mon Sep 17 00:00:00 2001 From: Ivan Chen 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') 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 = ({ screenType={screenType} /> { - 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 = ({ 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 ( { - setFilled(!filled); - onPress(); + if (filled === initialLikeState) { + setFilled(!filled); + onPress(); + } }}> 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 = ({ 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 From 17b8a3712ac34cb382c30864b4404f49118220a9 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Tue, 11 May 2021 17:56:01 -0400 Subject: fixed linter --- src/services/CommentService.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/services/CommentService.ts b/src/services/CommentService.ts index b21c6dfd..75bef2e4 100644 --- a/src/services/CommentService.ts +++ b/src/services/CommentService.ts @@ -8,7 +8,6 @@ import { } from '../constants'; import {ERROR_FAILED_TO_COMMENT} from '../constants/strings'; import { - CommentBaseType, CommentThreadType, CommentType, ProfilePreviewType, -- cgit v1.2.3-70-g09d2 From fab3b1f7d046895dbaaff1ceddbc75f9ffc7fda0 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Tue, 11 May 2021 18:35:29 -0400 Subject: updated with new endpoints --- src/services/CommentService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/services/CommentService.ts b/src/services/CommentService.ts index 75bef2e4..ad8f14ac 100644 --- a/src/services/CommentService.ts +++ b/src/services/CommentService.ts @@ -145,7 +145,7 @@ export const handleLikeUnlikeComment = async ( : COMMENT_REACTIONS_ENDPOINT; if (comment.user_reaction !== null) { // unlike a comment - url += `${comment.user_reaction.id}/`; + url += `${comment.comment_id}/?reaction_type=LIKE`; const response = await fetch(url, { method: 'DELETE', headers: { -- cgit v1.2.3-70-g09d2 From 51f397132d227edf5e07d48d673ee167d2aa5937 Mon Sep 17 00:00:00 2001 From: Ivan Chen Date: Tue, 11 May 2021 18:42:53 -0400 Subject: made things faster --- src/components/comments/CommentTile.tsx | 14 +++++++------- src/components/common/LikeButton.tsx | 17 ++++++++--------- src/services/CommentService.ts | 3 ++- 3 files changed, 17 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/components/comments/CommentTile.tsx b/src/components/comments/CommentTile.tsx index 1f1fafda..ee32f889 100644 --- a/src/components/comments/CommentTile.tsx +++ b/src/components/comments/CommentTile.tsx @@ -55,6 +55,7 @@ const CommentTile: React.FC = ({ const [showReplies, setShowReplies] = useState(false); const [showKeyboard, setShowKeyboard] = useState(false); const [shouldUpdateChild, setShouldUpdateChild] = useState(true); + const [liked, setLiked] = useState(commentObject.user_reaction !== null); const swipeRef = useRef(null); const {replyPosted} = useSelector((state: RootState) => state.user); const state: RootState = useStore().getState(); @@ -150,12 +151,9 @@ const CommentTile: React.FC = ({ screenType={screenType} /> { - handleLikeUnlikeComment(commentObject).then(() => { - setShouldUpdateParent(true); - }); - }} + liked={liked} + setLiked={setLiked} + onPress={() => handleLikeUnlikeComment(commentObject, liked)} style={styles.likeButton} /> @@ -183,7 +181,9 @@ const CommentTile: React.FC = ({ }); }}> - {commentObject.reaction_count} + {commentObject.user_reaction !== null + ? commentObject.reaction_count + (liked ? 0 : -1) + : commentObject.reaction_count + (liked ? 1 : 0)} Likes diff --git a/src/components/common/LikeButton.tsx b/src/components/common/LikeButton.tsx index 43b3ac37..81383eca 100644 --- a/src/components/common/LikeButton.tsx +++ b/src/components/common/LikeButton.tsx @@ -1,28 +1,27 @@ -import React, {useState} from 'react'; +import React from 'react'; import {Image, ImageStyle, StyleSheet, TouchableOpacity} from 'react-native'; import {normalize} from '../../utils'; interface LikeButtonProps { onPress: () => void; style: ImageStyle; - initialLikeState: boolean; + liked: boolean; + setLiked: (liked: boolean) => void; } const LikeButton: React.FC = ({ onPress, style, - initialLikeState, + liked, + setLiked, }) => { - const [filled, setFilled] = useState(initialLikeState); - const uri = filled + const uri = liked ? require('../../assets/images/heart-filled.png') : require('../../assets/images/heart-outlined.png'); return ( { - if (filled === initialLikeState) { - setFilled(!filled); - onPress(); - } + setLiked(!liked); + onPress(); }}> diff --git a/src/services/CommentService.ts b/src/services/CommentService.ts index ad8f14ac..6d71ce9c 100644 --- a/src/services/CommentService.ts +++ b/src/services/CommentService.ts @@ -136,6 +136,7 @@ export const deleteComment = async (id: string, isThread: boolean) => { */ export const handleLikeUnlikeComment = async ( comment: CommentType | CommentThreadType, + liked: boolean, ) => { try { const isReply = 'parent_comment' in comment; @@ -143,7 +144,7 @@ export const handleLikeUnlikeComment = async ( let url = isReply ? COMMENT_REACTIONS_REPLY_ENDPOINT : COMMENT_REACTIONS_ENDPOINT; - if (comment.user_reaction !== null) { + if (liked) { // unlike a comment url += `${comment.comment_id}/?reaction_type=LIKE`; const response = await fetch(url, { -- cgit v1.2.3-70-g09d2