/* eslint-disable radix */ import React, {Fragment, useEffect, useRef, useState} from 'react'; import {Text, View} from 'react-native-animatable'; import {ProfilePreview} from '../profile'; import {CommentType, ScreenType, TypeOfComment} from '../../types'; import {Alert, Animated, StyleSheet} from 'react-native'; import ClockIcon from '../../assets/icons/clock-icon-01.svg'; import {TAGG_LIGHT_BLUE} from '../../constants'; import {RectButton, TouchableOpacity} from 'react-native-gesture-handler'; import {getTimePosted, normalize, SCREEN_WIDTH} from '../../utils'; import Arrow from '../../assets/icons/back-arrow-colored.svg'; import Trash from '../../assets/ionicons/trash-outline.svg'; import CommentsContainer from './CommentsContainer'; import Swipeable from 'react-native-gesture-handler/Swipeable'; import {deleteComment, getCommentsCount} from '../../services'; import {ERROR_FAILED_TO_DELETE_COMMENT} from '../../constants/strings'; import {useSelector} from 'react-redux'; import {RootState} from '../../store/rootReducer'; /** * Displays users's profile picture, comment posted by them and the time difference between now and when a comment was posted. */ interface CommentTileProps { comment_object: CommentType; screenType: ScreenType; typeOfComment: TypeOfComment; setCommentObjectInFocus?: (comment: CommentType | undefined) => void; newCommentsAvailable: boolean; setNewCommentsAvailable: (available: boolean) => void; canDelete: boolean; } const CommentTile: React.FC = ({ comment_object, screenType, typeOfComment, setCommentObjectInFocus, newCommentsAvailable, setNewCommentsAvailable, canDelete, }) => { const timePosted = getTimePosted(comment_object.date_created); const [showReplies, setShowReplies] = useState(false); const [showKeyboard, setShowKeyboard] = useState(false); const [newThreadAvailable, setNewThreadAvailable] = useState(true); const swipeRef = useRef(null); const isThread = typeOfComment === 'Thread'; const {replyPosted} = useSelector((state: RootState) => state.user); /** * Bubbling up, for handling a new comment in a thread. */ useEffect(() => { if (newCommentsAvailable) { setNewThreadAvailable(true); } }, [newCommentsAvailable]); useEffect(() => { if (replyPosted && typeOfComment === 'Comment') { if (replyPosted.parent_comment.comment_id === comment_object.comment_id) { setShowReplies(true); } } // eslint-disable-next-line react-hooks/exhaustive-deps }, [replyPosted]); /** * Case : A COMMENT IS IN FOCUS && REPLY SECTION IS HIDDEN * Bring the current comment to focus * Case : No COMMENT IS IN FOCUS && REPLY SECTION IS SHOWN * Unfocus comment in focus */ const toggleAddComment = () => { //Do not allow user to reply to a thread if (!isThread) { if (setCommentObjectInFocus) { if (!showKeyboard) { setCommentObjectInFocus(comment_object); } else { setCommentObjectInFocus(undefined); } } setShowKeyboard(!showKeyboard); } }; const toggleReplies = async () => { if (showReplies) { //To update count of replies in case we deleted a reply comment_object.replies_count = parseInt( await getCommentsCount(comment_object.comment_id, true), ); } setNewThreadAvailable(true); setShowReplies(!showReplies); }; /** * Method to compute text to be shown for replies button */ const getRepliesText = () => showReplies ? 'Hide' : comment_object.replies_count > 0 ? `Replies (${comment_object.replies_count})` : 'Replies'; const renderRightAction = (text: string, color: string, progress) => { const pressHandler = async () => { swipeRef.current?.close(); const success = await deleteComment(comment_object.comment_id, isThread); if (success) { setNewCommentsAvailable(true); } else { Alert.alert(ERROR_FAILED_TO_DELETE_COMMENT); } }; return ( {text} ); }; const renderRightActions = (progress: Animated.AnimatedInterpolation) => canDelete ? ( {renderRightAction('Delete', '#c42634', progress)} ) : ( ); return ( {comment_object.comment} {' ' + timePosted} {/*** Show replies text only if there are some replies present */} {typeOfComment === 'Comment' && comment_object.replies_count > 0 && ( {getRepliesText()} )} {/*** Show replies if toggle state is true */} {showReplies && ( )} ); }; const styles = StyleSheet.create({ container: { borderBottomWidth: 1, borderColor: 'lightgray', backgroundColor: 'white', flexDirection: 'column', flex: 1, paddingTop: '3%', paddingBottom: '5%', marginLeft: '7%', }, swipeActions: { flexDirection: 'row', }, moreMarginWithThread: { marginLeft: '14%', }, body: { marginLeft: 56, }, comment: { marginBottom: '2%', marginRight: '2%', }, date_time: { color: 'gray', fontSize: normalize(12), }, clockIcon: { width: 12, height: 12, alignSelf: 'center', }, clockIconAndTime: { flexDirection: 'row', marginTop: '3%', }, flexer: { flex: 1, }, repliesTextAndIconContainer: { flexDirection: 'row', alignItems: 'center', marginTop: '5%', marginLeft: 56, }, repliesText: { color: TAGG_LIGHT_BLUE, fontWeight: '500', fontSize: normalize(12), marginRight: '1%', }, repliesBody: { width: SCREEN_WIDTH, }, repliesDownArrow: { transform: [{rotate: '270deg'}], marginTop: '1%', }, repliesUpArrow: { transform: [{rotate: '90deg'}], marginTop: '1%', }, actionText: { color: 'white', fontSize: normalize(12), fontWeight: '500', backgroundColor: 'transparent', paddingHorizontal: '5%', marginTop: '5%', }, rightAction: { alignItems: 'center', flex: 1, justifyContent: 'center', flexDirection: 'column', }, swipableContainer: { backgroundColor: 'white', }, }); export default CommentTile;