import React, {
useEffect, useMemo, useState, type JSX,
} from 'react';
import { isPopulated, type IUser } from '@growi/core';
import * as pathUtils from '@growi/core/dist/utils/path-utils';
import { UserPicture } from '@growi/ui/dist/components';
import { format, parseISO } from 'date-fns';
import { useTranslation } from 'next-i18next';
import Link from 'next/link';
import { UncontrolledTooltip } from 'reactstrap';
import urljoin from 'url-join';
import type { RendererOptions } from '~/interfaces/renderer-options';
import RevisionRenderer from '../../../components/PageView/RevisionRenderer';
import { Username } from '../../../components/User/Username';
import type { ICommentHasId } from '../../../interfaces/comment';
import FormattedDistanceDate from '../FormattedDistanceDate';
import { CommentControl } from './CommentControl';
import { CommentEditor } from './CommentEditor';
import styles from './Comment.module.scss';
type CommentProps = {
comment: ICommentHasId,
rendererOptions: RendererOptions,
revisionId: string,
revisionCreatedAt: Date,
currentUser: IUser,
isReadOnly: boolean,
pageId: string,
pagePath: string,
deleteBtnClicked: (comment: ICommentHasId) => void,
onComment: () => void,
}
export const Comment = (props: CommentProps): JSX.Element => {
const {
comment, rendererOptions, revisionId, revisionCreatedAt, currentUser, isReadOnly,
pageId, pagePath, deleteBtnClicked, onComment,
} = props;
const { returnPathForURL } = pathUtils;
const { t } = useTranslation();
const [markdown, setMarkdown] = useState('');
const [isReEdit, setIsReEdit] = useState(false);
const commentId = comment._id;
const creator = isPopulated(comment.creator) ? comment.creator : undefined;
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';
// TODO: fix so that `comment.createdAt` to be type Date https://redmine.weseek.co.jp/issues/113876
const commentCreatedAtFixed = typeof comment.createdAt === 'string'
? parseISO(comment.createdAt)
: comment.createdAt;
const revisionCreatedAtFixed = typeof revisionCreatedAt === 'string'
? parseISO(revisionCreatedAt)
: revisionCreatedAt;
// Conditional for called from SearchResultContext
if (revisionId != null && revisionCreatedAt != null) {
if (comment.revision === revisionId) {
className += ' page-comment-current';
}
else if (commentCreatedAtFixed.getTime() > revisionCreatedAtFixed.getTime()) {
className += ' page-comment-newer';
}
else {
className += ' page-comment-older';
}
}
if (isCurrentUserEqualsToAuthor()) {
className += ' page-comment-me';
}
return className;
};
const deleteBtnClickedHandler = () => {
deleteBtnClicked(comment);
};
const commentBody = useMemo(() => {
if (rendererOptions == null) {
return <>>;
}
return (