import React, {Fragment, memo, useContext, useState} from 'react'; import {SiteConfigContext} from '@common/core/settings/site-config-context'; import {Link} from 'react-router-dom'; import {Comment} from '@common/comments/comment'; import {useAuth} from '@common/auth/use-auth'; import {UserAvatar} from '@common/ui/images/user-avatar'; import {Button} from '@common/ui/buttons/button'; import {Trans} from '@common/i18n/trans'; import {NewCommentForm} from '@common/comments/new-comment-form'; import {User} from '@common/auth/user'; import {Commentable} from '@common/comments/commentable'; import {useDeleteComments} from '@common/comments/requests/use-delete-comments'; import {DialogTrigger} from '@common/ui/overlays/dialog/dialog-trigger'; import {queryClient} from '@common/http/query-client'; import {ConfirmationDialog} from '@common/ui/overlays/dialog/confirmation-dialog'; import {FormattedDuration} from '@common/i18n/formatted-duration'; import {useIsMobileMediaQuery} from '@common/utils/hooks/is-mobile-media-query'; import {ThumbButtons} from '@common/votes/thumb-buttons'; import {ReplyIcon} from '@common/icons/material/Reply'; import {MoreVertIcon} from '@common/icons/material/MoreVert'; import { Menu, MenuItem, MenuTrigger, } from '@common/ui/navigation/menu/menu-trigger'; import {FormattedRelativeTime} from '@common/i18n/formatted-relative-time'; import {useSubmitReport} from '@common/reports/requests/use-submit-report'; interface CommentListItemProps { comment: Comment; commentable: Commentable; canDelete?: boolean; } export function CommentListItem({ comment, commentable, // user can delete comment if they have created it, or they have relevant permissions on commentable canDelete, }: CommentListItemProps) { const isMobile = useIsMobileMediaQuery(); const {user, hasPermission} = useAuth(); const [replyFormVisible, setReplyFormVisible] = useState(false); const showReplyButton = user != null && !comment.deleted && !isMobile && comment.depth < 5 && hasPermission('comments.create'); return (
{ if (isMobile) { setReplyFormVisible(!replyFormVisible); } }} >
{comment.user && } {comment.position ? ( ) : null}
{comment.deleted ? ( ) : ( comment.content )}
{!comment.deleted && (
{showReplyButton && ( )}
)}
{replyFormVisible ? ( { setReplyFormVisible(false); }} /> ) : null}
); } interface PositionProps { commentable: Commentable; position: number; } const Position = memo(({commentable, position}: PositionProps) => { if (!commentable.duration) return null; const seconds = (position / 100) * (commentable.duration / 1000); return ( , }} /> ); }); interface DeleteCommentsButtonProps { comment: Comment; canDelete?: boolean; user: User | null; } export function CommentOptionsTrigger({ comment, canDelete, user, }: DeleteCommentsButtonProps) { const deleteComments = useDeleteComments(); const reportComment = useSubmitReport(comment); const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); const showDeleteButton = (comment.user_id === user?.id || canDelete) && !comment.deleted; const handleReport = () => { reportComment.mutate({}); }; const handleDelete = (isConfirmed: boolean) => { setIsDeleteDialogOpen(false); if (isConfirmed) { deleteComments.mutate( {commentIds: [comment.id]}, { onSuccess: () => { queryClient.invalidateQueries({queryKey: ['comment']}); }, }, ); } }; return ( handleReport()}> {showDeleteButton && ( setIsDeleteDialogOpen(true)} > )} handleDelete(isConfirmed)} > } body={ } confirm={} /> ); } interface UserDisplayNameProps { user: User; } function UserDisplayName({user}: UserDisplayNameProps) { const {auth} = useContext(SiteConfigContext); if (auth.getUserProfileLink) { return ( {user.display_name} ); } return
{user.display_name}
; }