import React, { useContext } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import { useDispatch, useSelector } from 'react-redux'; import { useHistory, useLocation } from 'react-router-dom'; import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; import { Hyperlink, useToggle } from '@edx/paragon'; import HTMLLoader from '../../../components/HTMLLoader'; import { ContentActions } from '../../../data/constants'; import { selectorForUnitSubsection, selectTopicContext } from '../../../data/selectors'; import { AlertBanner, Confirmation } from '../../common'; import { DiscussionContext } from '../../common/context'; import HoverCard from '../../common/HoverCard'; import { selectModerationSettings } from '../../data/selectors'; import { selectTopic } from '../../topics/data/selectors'; import { removeThread, updateExistingThread } from '../data/thunks'; import ClosePostReasonModal from './ClosePostReasonModal'; import messages from './messages'; import PostFooter from './PostFooter'; import PostHeader from './PostHeader'; import { postShape } from './proptypes'; function Post({ post, preview, intl, handleAddResponseButton, }) { const location = useLocation(); const history = useHistory(); const dispatch = useDispatch(); const { enableInContextSidebar } = useContext(DiscussionContext); const courseId = useSelector((state) => state.config.id); const topic = useSelector(selectTopic(post.topicId)); const getTopicSubsection = useSelector(selectorForUnitSubsection); const topicContext = useSelector(selectTopicContext(post.topicId)); const { reasonCodesEnabled } = useSelector(selectModerationSettings); const [isDeleting, showDeleteConfirmation, hideDeleteConfirmation] = useToggle(false); const [isReporting, showReportConfirmation, hideReportConfirmation] = useToggle(false); const [isClosing, showClosePostModal, hideClosePostModal] = useToggle(false); const handleAbusedFlag = () => { if (post.abuseFlagged) { dispatch(updateExistingThread(post.id, { flagged: !post.abuseFlagged })); } else { showReportConfirmation(); } }; const handleDeleteConfirmation = async () => { await dispatch(removeThread(post.id)); history.push({ pathname: '.', search: enableInContextSidebar && '?inContextSidebar', }); hideDeleteConfirmation(); }; const handleReportConfirmation = () => { dispatch(updateExistingThread(post.id, { flagged: !post.abuseFlagged })); hideReportConfirmation(); }; const actionHandlers = { [ContentActions.EDIT_CONTENT]: () => history.push({ ...location, pathname: `${location.pathname}/edit`, }), [ContentActions.DELETE]: showDeleteConfirmation, [ContentActions.CLOSE]: () => { if (post.closed) { dispatch(updateExistingThread(post.id, { closed: false })); } else if (reasonCodesEnabled) { showClosePostModal(); } else { dispatch(updateExistingThread(post.id, { closed: true })); } }, [ContentActions.COPY_LINK]: () => { navigator.clipboard.writeText(`${window.location.origin}/${courseId}/posts/${post.id}`); }, [ContentActions.PIN]: () => dispatch(updateExistingThread(post.id, { pinned: !post.pinned })), [ContentActions.REPORT]: () => handleAbusedFlag(), }; const getTopicCategoryName = topicData => ( topicData.usageKey ? getTopicSubsection(topicData.usageKey)?.displayName : topicData.categoryId ); return (
{!post.abuseFlagged && ( )} dispatch(updateExistingThread(post.id, { voted: !post.voted }))} onFollow={() => dispatch(updateExistingThread(post.id, { following: !post.following }))} isClosedPost={post.closed} />
{topicContext && (
{intl.formatMessage(messages.relatedTo)}{' '} {(topicContext && !topic) ? ( <> {topicContext.chapterName} / {topicContext.verticalName} / {topicContext.unitName} ) : `${getTopicCategoryName(topic)} / ${topic.name}`}
)} { dispatch(updateExistingThread(post.id, { closed: true, closeReasonCode })); hideClosePostModal(); }} />
); } Post.propTypes = { intl: intlShape.isRequired, post: postShape.isRequired, preview: PropTypes.bool, handleAddResponseButton: PropTypes.func.isRequired, }; Post.defaultProps = { preview: false, }; export default injectIntl(Post);