import { useState } from "react"; import { observer } from "mobx-react-lite"; import { Col, Collapse, ListGroupItem, Row, Spinner } from "reactstrap"; import { sprintf } from "sprintf-js"; import { useTranslation } from "react-i18next"; import { Item, Menu, useContextMenu } from "react-contexify"; import Swal from "sweetalert2"; import w0 from "src/assets/w0.png"; import w1 from "src/assets/w1.png"; import w2 from "src/assets/w2.png"; import w4 from "src/assets/w4.png"; import w5 from "src/assets/w5.png"; import w6 from "src/assets/w6.png"; import w7 from "src/assets/w7.png"; import CommentItems from "src/note/CommentItems"; import { NoteAPINote } from "src/wwwAPI"; import { wwwAXIOS } from "src/Www"; import { formatText, getGenreText } from "src/Utility"; import useGetComment from "./useGetComment"; const ws = [w0, w1, w2, "", w4, w5, w6, w7]; export default observer( ({ noteID, artist, title, genre, levelText, level, highestCount, totalCount, fittedText, wantAvatarID, wantAvatarName, handled, }: NoteAPINote & { handled?: number }) => { const [isCommentOpened, setCommentOpened] = useState(false); const { t } = useTranslation(); const { show: viewToilInput } = useContextMenu({ id: `toil-${noteID}`, }); const { data: { comments, commentPlace, totalComments }, isFetched: isCommentLoaded, } = useGetComment(noteID, isCommentOpened); return ( <ListGroupItem> <Row className="g-0 route" onClick={async () => { setCommentOpened((prevState) => !prevState); }} onContextMenu={(event) => { event.preventDefault(); viewToilInput({ event, props: { noteID } }); }} > {typeof handled === "number" && ( <Col className="m-1" xs="auto"> <img src={ws[handled]} width={8} height={48} alt="" /> </Col> )} <Col className="m-1" xs="auto"> <span className={`level${level}`}>{levelText}</span>{" "} <span className="title">{title}</span>{" "} {isCommentOpened && !isCommentLoaded && ( <Spinner size="sm" color="primary" /> )} <br /> {fittedText && ( <span className="fittedText">{fittedText}</span> )}{" "} <span className="artist">{artist}</span>{" "} <span className="genre">{getGenreText(genre)}</span> <br /> {typeof highestCount === "number" && typeof totalCount === "number" && ( <> <span className="fittedText"> {sprintf(t("highestCountText"), formatText(highestCount))} </span> <br /> <span className="fittedText"> {sprintf(t("totalCountText"), formatText(totalCount))} </span> </> )} </Col> </Row> {noteID && ( <Menu id={`toil-${noteID}`}> <Item onClick={async ({ props: { noteID } }) => { const { isConfirmed, value } = await Swal.fire({ title: t("toilNoteFileText"), input: "text", }); if (isConfirmed) { await wwwAXIOS.post("/toil", { noteID, commentary: value, }); } }} > <span>{t("toilNoteFile")}</span> </Item> </Menu> )} <Collapse isOpen={isCommentOpened}> <CommentItems comments={comments} commentPlace={commentPlace} totalCount={totalComments} wantAvatarID={wantAvatarID} wantAvatarName={wantAvatarName} /> </Collapse> </ListGroupItem> ); }, );