| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- import React, { useEffect, useState } from 'react';
- import { UserPicture } from '@growi/ui';
- import { format } from 'date-fns';
- import { useTranslation } from 'next-i18next';
- import { UncontrolledTooltip } from 'reactstrap';
- import { RendererOptions } from '~/services/renderer/renderer';
- import { useCurrentUser } from '~/stores/context';
- 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 { CommentEditor } from './CommentEditor';
- import styles from './Comment.module.scss';
- type CommentProps = {
- comment: ICommentHasId,
- isReadOnly: boolean,
- deleteBtnClicked: (comment: ICommentHasId) => void,
- onComment: () => void,
- rendererOptions: RendererOptions,
- currentPagePath: string,
- currentRevisionId: string,
- currentRevisionCreatedAt: Date,
- }
- export const Comment = (props: CommentProps): JSX.Element => {
- const {
- comment, isReadOnly, deleteBtnClicked, onComment, rendererOptions,
- currentPagePath, currentRevisionId, currentRevisionCreatedAt,
- } = props;
- const { t } = useTranslation();
- const { data: currentUser } = useCurrentUser();
- 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(() => {
- setMarkdown(comment.comment);
- const isCurrentRevision = () => {
- return comment.revision === currentRevisionId;
- };
- isCurrentRevision();
- }, [comment, currentRevisionId]);
- const isCurrentUserEqualsToAuthor = () => {
- const { creator }: any = comment;
- if (creator == null || currentUser == null) {
- return false;
- }
- return creator.username === currentUser.username;
- };
- const getRootClassName = (comment) => {
- let className = `${styles['page-comment']} page-comment flex-column`;
- if (comment.revision === currentRevisionId) {
- className += ' page-comment-current';
- }
- else if (comment.createdAt.getTime() > currentRevisionCreatedAt.getTime()) {
- className += ' page-comment-newer';
- }
- else {
- className += ' page-comment-older';
- }
- if (isCurrentUserEqualsToAuthor()) {
- className += ' page-comment-me';
- }
- return className;
- };
- const deleteBtnClickedHandler = (comment) => {
- deleteBtnClicked(comment);
- };
- const renderText = (comment) => {
- return <span style={{ whiteSpace: 'pre-wrap' }}>{comment}</span>;
- };
- const renderRevisionBody = () => {
- return (
- <RevisionRenderer
- rendererOptions={rendererOptions}
- markdown={markdown}
- additionalClassName="comment"
- pagePath={currentPagePath}
- />
- );
- };
- const rootClassName = getRootClassName(comment);
- const commentBody = isMarkdown ? renderRevisionBody() : renderText(comment.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) ? (
- <CommentEditor
- rendererOptions={rendererOptions}
- replyTo={undefined}
- currentCommentId={commentId}
- commentBody={comment.comment}
- onCancelButtonClicked={() => setIsReEdit(false)}
- onCommentButtonClicked={() => {
- setIsReEdit(false);
- if (onComment != null) onComment();
- }}
- />
- ) : (
- <div id={commentId} className={rootClassName}>
- <div className={`${styles['page-comment-writer']} page-comment-writer`}>
- <UserPicture user={creator} noLink noTooltip />
- </div>
- <div className={`${styles['page-comment-main']} page-comment-main`}>
- <div className="page-comment-creator">
- <Username user={creator} />
- </div>
- <div className="page-comment-body">{commentBody}</div>
- <div className="page-comment-meta">
- <a href={`#${commentId}`}>
- <FormattedDistanceDate id={commentId} date={comment.createdAt} />
- </a>
- { isEdited && (
- <>
- <span id={editedDateId}> (edited)</span>
- <UncontrolledTooltip placement="bottom" fade={false} target={editedDateId}>{editedDateFormatted}</UncontrolledTooltip>
- </>
- )}
- <span className="ml-2">
- <a id={`page-comment-revision-${commentId}`} className="page-comment-revision" href={revHref}>
- <HistoryIcon />
- </a>
- <UncontrolledTooltip placement="bottom" fade={false} target={`page-comment-revision-${commentId}`}>
- {t('page_comment.display_the_page_when_posting_this_comment')}
- </UncontrolledTooltip>
- </span>
- </div>
- {(isCurrentUserEqualsToAuthor() && !isReadOnly) && (
- <CommentControl
- onClickDeleteBtn={deleteBtnClickedHandler}
- onClickEditBtn={() => setIsReEdit(true)}
- />
- ) }
- </div>
- </div>
- )
- }
- </>
- );
- };
|