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/components/common/LikeButton.tsx | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/components/common/LikeButton.tsx (limited to 'src/components/common/LikeButton.tsx') 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; -- 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/components/common/LikeButton.tsx') 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 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/components/common/LikeButton.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 = ({ 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 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/components/common/LikeButton.tsx') 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