// this component will // render its children // render a like button // render a permalink button // render a reply button // render a flag button // translate things? import React, {PropTypes} from 'react'; import PermalinkButton from 'coral-plugin-permalinks/PermalinkButton'; import AuthorName from 'coral-plugin-author-name/AuthorName'; import TagLabel from 'coral-plugin-tag-label/TagLabel'; import Content from 'coral-plugin-commentcontent/CommentContent'; import PubDate from 'coral-plugin-pubdate/PubDate'; import {ReplyBox, ReplyButton} from 'coral-plugin-replies'; import FlagComment from 'coral-plugin-flags/FlagComment'; import LikeButton from 'coral-plugin-likes/LikeButton'; import {BestButton, IfUserCanModifyBest, BEST_TAG, commentIsBest, BestIndicator} from 'coral-plugin-best/BestButton'; import LoadMore from 'coral-embed-stream/src/LoadMore'; import {Slot} from 'coral-framework'; import IgnoredCommentTombstone from './IgnoredCommentTombstone'; import {TopRightMenu} from './TopRightMenu'; import styles from './Comment.css'; const getActionSummary = (type, comment) => comment.action_summaries .filter((a) => a.__typename === type)[0]; const isStaff = (tags) => !tags.every((t) => t.name !== 'STAFF') ; // hold actions links (e.g. Like, Reply) along the comment footer const ActionButton = ({children}) => { return { children }; }; class Comment extends React.Component { constructor(props) { super(props); this.state = {replyBoxVisible: false}; } static propTypes = { reactKey: PropTypes.string.isRequired, // id of currently opened ReplyBox. tracked in Stream.js activeReplyBox: PropTypes.string.isRequired, disableReply: PropTypes.bool, setActiveReplyBox: PropTypes.func.isRequired, showSignInDialog: PropTypes.func.isRequired, postFlag: PropTypes.func.isRequired, postLike: PropTypes.func.isRequired, deleteAction: PropTypes.func.isRequired, parentId: PropTypes.string, highlighted: PropTypes.string, addNotification: PropTypes.func.isRequired, postItem: PropTypes.func.isRequired, depth: PropTypes.number.isRequired, asset: PropTypes.shape({ id: PropTypes.string, title: PropTypes.string, url: PropTypes.string }).isRequired, currentUser: PropTypes.shape({ id: PropTypes.string.isRequired }), comment: PropTypes.shape({ depth: PropTypes.number, action_summaries: PropTypes.array.isRequired, body: PropTypes.string.isRequired, id: PropTypes.string.isRequired, tags: PropTypes.arrayOf( PropTypes.shape({ name: PropTypes.string }) ), replies: PropTypes.arrayOf( PropTypes.shape({ body: PropTypes.string.isRequired, id: PropTypes.string.isRequired })), user: PropTypes.shape({ id: PropTypes.string.isRequired, name: PropTypes.string.isRequired }).isRequired }).isRequired, // given a comment, return whether it should be rendered as ignored commentIsIgnored: React.PropTypes.func, // dispatch action to add a tag to a comment addCommentTag: React.PropTypes.func, // dispatch action to remove a tag from a comment removeCommentTag: React.PropTypes.func, // dispatch action to ignore another user ignoreUser: React.PropTypes.func, } render () { const { comment, parentId, currentUser, asset, depth, postItem, addNotification, showSignInDialog, postLike, highlighted, postFlag, postDontAgree, loadMore, setActiveReplyBox, activeReplyBox, deleteAction, addCommentTag, removeCommentTag, ignoreUser, disableReply, commentIsIgnored, } = this.props; const like = getActionSummary('LikeActionSummary', comment); const flag = getActionSummary('FlagActionSummary', comment); const dontagree = getActionSummary('DontAgreeActionSummary', comment); let commentClass = parentId ? `reply ${styles.Reply}` : `comment ${styles.Comment}`; commentClass += comment.id === 'pending' ? ` ${styles.pendingComment}` : ''; // call a function, and if it errors, call addNotification('error', ...) (e.g. to show user a snackbar) const notifyOnError = (fn, errorToMessage) => async function (...args) { if (typeof errorToMessage !== 'function') {errorToMessage = (error) => error.message;} try { return await fn(...args); } catch (error) { addNotification('error', errorToMessage(error)); throw error; } }; const addBestTag = notifyOnError(() => addCommentTag({ id: comment.id, tag: BEST_TAG, }), () => 'Failed to tag comment as best'); const removeBestTag = notifyOnError(() => removeCommentTag({ id: comment.id, tag: BEST_TAG, }), () => 'Failed to remove best comment tag'); return (

{ isStaff(comment.tags) ? Staff : null } { commentIsBest(comment) ? : null } { (currentUser && (comment.user.id !== currentUser.id)) ? : null }
{ !disableReply && setActiveReplyBox(comment.id)} parentCommentId={parentId || comment.id} currentUserId={currentUser && currentUser.id} banned={false} /> }
{ activeReplyBox === comment.id ? { setActiveReplyBox(''); }} setActiveReplyBox={setActiveReplyBox} parentId={parentId || comment.id} addNotification={addNotification} authorId={currentUser.id} postItem={postItem} assetId={asset.id} /> : null } { comment.replies && comment.replies.map(reply => { return commentIsIgnored(reply) ? : ; }) } { comment.replies &&
comment.replies.length} loadMore={loadMore}/>
}
); } } export default Comment;