import "../../css/components/conversation/comment.css"; import React, { useEffect, useMemo, useRef, useState } from "react"; import { Box, Button, Typography, SxProps, Theme, CircularProgress } from "@mui/material"; import { useNotification } from "../ContextProvider"; import VoteButtons from "./comment/votebuttons"; import { useThreadId, useVotes } from "./ConversationContext"; import CommentTop from "./comment/commentTop"; import CommentBody from "./comment/commentBody"; import { api } from "../../lib/api"; import { EscalatorOutlined, Forum, KeyboardArrowDown, KeyboardArrowUp, } from "@mui/icons-material"; import CommentPopup from "../../lib/commentPopup"; import { parseError } from "../../lib/parseError"; import { Comment as CommentType } from "@metahkg/api"; /** * Comment component renders a comment * which includes a title (Tag) * the comment body * and upvote and downvote buttons */ export default function Comment(props: { comment: CommentType; noId?: boolean; inPopUp?: boolean; showReplies?: boolean; fetchComment?: boolean; noQuote?: boolean; setIsExpanded?: React.Dispatch>; fold?: boolean; openComment?: boolean; blocked?: boolean; noStory?: boolean; scrollIntoView?: boolean; className?: string; sx?: SxProps; maxHeight?: string | number; noFullWidth?: boolean; }) { const { noId, scrollIntoView, fetchComment, inPopUp, noQuote, setIsExpanded, noStory, openComment, sx, className, maxHeight, noFullWidth, } = props; const threadId = useThreadId(); const [comment, setComment] = useState(props.comment); const [votes] = useVotes(); const [, setNotification] = useNotification(); const [ready, setReady] = useState(!fetchComment); const [reFetch, setReFetch] = useState(false); const [showReplies, setShowReplies] = useState(props.showReplies); const [replies, setReplies] = useState([]); const [loading, setLoading] = useState(false); const [popupOpen, setPopupOpen] = useState(false); const [fold, setFold] = useState(props.fold); const commentRef = useRef(null); const prevVote = useRef(votes?.find((vote) => vote.cid === comment.id)?.vote); useEffect(() => { const currentVote = votes?.find((vote) => vote.cid === comment.id)?.vote; if (prevVote.current !== currentVote && currentVote) { prevVote.current = currentVote; setReFetch(true); } }, [votes?.[comment.id], prevVote, votes, comment.id]); useEffect(() => { commentRef.current && scrollIntoView && commentRef.current.scrollIntoView(); if (!ready || reFetch) { setReFetch(false); api.comment(threadId, comment.id) .then((data) => { setComment(data); setReady(true); }) .catch((err) => { setNotification({ open: true, text: parseError(err), }); }); } if (inPopUp) { setLoading(true); api.commentReplies(threadId, comment.id) .then((data) => { setReplies(data); setLoading(false); }) .catch(() => { setLoading(false); }); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [ready, reFetch]); return useMemo( () => ( {comment.replies?.length && ( )} ({ "& *::selection": { background: theme.palette.secondary.main, color: "black", }, bgcolor: "primary.main", maxHeight: inPopUp && !showReplies ? "90vh" : "", })} >
{!fold && (
)}
{ready && !fold && (
{!inPopUp && comment.replies?.length && ( )}
{openComment && ( Open Comment )}
)}
{loading && ( )} {!!replies.length && ( { setShowReplies(!showReplies); setIsExpanded && setIsExpanded(!showReplies); }} > {showReplies ? "Hide" : "Show"} Replies {showReplies ? ( ) : ( )} {showReplies && ( {replies.map((comment) => ( ))}
End
)}
)} ), [ className, comment, fold, inPopUp, loading, maxHeight, noFullWidth, noId, noQuote, noStory, openComment, popupOpen, ready, replies, setIsExpanded, showReplies, sx, threadId, ] ); }