import React, { useContext, useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import { useDispatch, useSelector } from 'react-redux'; import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; import { Button, useToggle } from '@edx/paragon'; import HTMLLoader from '../../../../components/HTMLLoader'; import { ContentActions, EndorsementStatus } from '../../../../data/constants'; import { AlertBanner, Confirmation, EndorsedAlertBanner } from '../../../common'; import { DiscussionContext } from '../../../common/context'; import HoverCard from '../../../common/HoverCard'; import { useUserCanAddThreadInBlackoutDate } from '../../../data/hooks'; import { fetchThread } from '../../../posts/data/thunks'; import LikeButton from '../../../posts/post/LikeButton'; import { useActions } from '../../../utils'; import { selectCommentCurrentPage, selectCommentHasMorePages, selectCommentResponses } from '../../data/selectors'; import { editComment, fetchCommentResponses, removeComment } from '../../data/thunks'; import messages from '../../messages'; import CommentEditor from './CommentEditor'; import CommentHeader from './CommentHeader'; import { commentShape } from './proptypes'; import Reply from './Reply'; function Comment({ postType, comment, showFullThread = true, isClosedPost, intl, marginBottom, }) { const dispatch = useDispatch(); const hasChildren = comment.childCount > 0; const isNested = Boolean(comment.parentId); const inlineReplies = useSelector(selectCommentResponses(comment.id)); const [isEditing, setEditing] = useState(false); const [isDeleting, showDeleteConfirmation, hideDeleteConfirmation] = useToggle(false); const [isReporting, showReportConfirmation, hideReportConfirmation] = useToggle(false); const [isReplying, setReplying] = useState(false); const hasMorePages = useSelector(selectCommentHasMorePages(comment.id)); const currentPage = useSelector(selectCommentCurrentPage(comment.id)); const userCanAddThreadInBlackoutDate = useUserCanAddThreadInBlackoutDate(); const { courseId, } = useContext(DiscussionContext); useEffect(() => { // If the comment has a parent comment, it won't have any children, so don't fetch them. if (hasChildren && !currentPage && showFullThread) { dispatch(fetchCommentResponses(comment.id, { page: 1 })); } }, [comment.id]); const actions = useActions({ ...comment, postType, }); const endorseIcons = actions.find(({ action }) => action === EndorsementStatus.ENDORSED); const handleAbusedFlag = () => { if (comment.abuseFlagged) { dispatch(editComment(comment.id, { flagged: !comment.abuseFlagged })); } else { showReportConfirmation(); } }; const handleDeleteConfirmation = () => { dispatch(removeComment(comment.id)); hideDeleteConfirmation(); }; const handleReportConfirmation = () => { dispatch(editComment(comment.id, { flagged: !comment.abuseFlagged })); hideReportConfirmation(); }; const actionHandlers = { [ContentActions.EDIT_CONTENT]: () => setEditing(true), [ContentActions.ENDORSE]: async () => { await dispatch(editComment(comment.id, { endorsed: !comment.endorsed }, ContentActions.ENDORSE)); await dispatch(fetchThread(comment.threadId, courseId)); }, [ContentActions.DELETE]: showDeleteConfirmation, [ContentActions.REPORT]: () => handleAbusedFlag(), }; const handleLoadMoreComments = () => ( dispatch(fetchCommentResponses(comment.id, { page: currentPage + 1 })) ); return (