import React, { useEffect, useMemo, useState } from 'react'; import { IUser } from '@growi/core'; import { UserPicture } from '@growi/ui'; import { format } from 'date-fns'; import { useTranslation } from 'next-i18next'; import dynamic from 'next/dynamic'; import { UncontrolledTooltip } from 'reactstrap'; import { RendererOptions } from '~/services/renderer/renderer'; import { ICommentHasId } from '../../interfaces/comment'; import FormattedDistanceDate from '../FormattedDistanceDate'; import HistoryIcon from '../Icons/HistoryIcon'; import RevisionRenderer from '../Page/RevisionRenderer'; import Username from '../User/Username'; import { CommentControl } from './CommentControl'; import { CommentEditorProps } from './CommentEditor'; import styles from './Comment.module.scss'; const CommentEditor = dynamic(() => import('./CommentEditor').then(mod => mod.CommentEditor), { ssr: false }); type CommentProps = { comment: ICommentHasId, rendererOptions: RendererOptions, revisionId: string, revisionCreatedAt: Date, currentUser: IUser, isReadOnly: boolean, deleteBtnClicked: (comment: ICommentHasId) => void, onComment: () => void, } export const Comment = (props: CommentProps): JSX.Element => { const { comment, rendererOptions, revisionId, revisionCreatedAt, currentUser, isReadOnly, deleteBtnClicked, onComment, } = props; const { t } = useTranslation(); const [markdown, setMarkdown] = useState(''); const [isReEdit, setIsReEdit] = useState(false); const commentId = comment._id; const creator = comment.creator; const isMarkdown = comment.isMarkdown; const createdAt = new Date(comment.createdAt); const updatedAt = new Date(comment.updatedAt); const isEdited = createdAt < updatedAt; useEffect(() => { if (revisionId == null) { return; } setMarkdown(comment.comment); const isCurrentRevision = () => { return comment.revision === revisionId; }; isCurrentRevision(); }, [comment, revisionId]); const isCurrentUserEqualsToAuthor = () => { const { creator }: any = comment; if (creator == null || currentUser == null) { return false; } return creator.username === currentUser.username; }; const getRootClassName = (comment: ICommentHasId) => { let className = 'page-comment flex-column'; // Conditional for called from SearchResultContext if (revisionId != null && revisionCreatedAt != null) { if (comment.revision === revisionId) { className += ' page-comment-current'; } else if (comment.createdAt.getTime() > revisionCreatedAt.getTime()) { className += ' page-comment-newer'; } else { className += ' page-comment-older'; } } if (isCurrentUserEqualsToAuthor()) { className += ' page-comment-me'; } return className; }; const deleteBtnClickedHandler = () => { deleteBtnClicked(comment); }; const renderText = (comment: string) => { return {comment}; }; const commentBody = useMemo(() => { if (rendererOptions == null) { return <>; } return isMarkdown ? ( ) : renderText(comment.comment); }, [comment, isMarkdown, markdown, rendererOptions]); const rootClassName = getRootClassName(comment); const revHref = `?revision=${comment.revision}`; const editedDateId = `editedDate-${comment._id}`; const editedDateFormatted = isEdited ? format(updatedAt, 'yyyy/MM/dd HH:mm') : null; return (
{ (isReEdit && !isReadOnly) ? ( setIsReEdit(false)} onCommentButtonClicked={() => { setIsReEdit(false); if (onComment != null) onComment(); }} /> ) : (
{commentBody}
{ isEdited && ( <>  (edited) {editedDateFormatted} ) } {t('page_comment.display_the_page_when_posting_this_comment')}
{ (isCurrentUserEqualsToAuthor() && !isReadOnly) && ( setIsReEdit(true)} /> ) }
) }
); };