"use client"; import { useState, type FormEvent, type ReactNode } from "react"; import { DecryptedImage } from "@/components/common/decrypted-image"; import { COMMENT_MAX_LENGTH, COMMENT_SORTS, formatCommentTime, type CommentTarget } from "./data"; import { CommentReplyPreview } from "./comment-reply-preview"; import { HeartIcon } from "./heart-icon"; import { InlineReplyBox } from "./inline-reply-box"; import { useComments } from "./use-comments"; function SheetHead({ title, onClose, children }: { title: ReactNode; onClose: () => void; children?: ReactNode }) { return (

{title}

{children ?? }
); } /** H5 短剧播放页评论底部弹层 */ export function H5CommentSheet({ onClose, target }: { onClose: () => void; target: CommentTarget | null }) { const { sort, setSort, comments, total, hasMore, loading, loadingMore, error, loadMore, toggleLike, post, posting, postError, reload, } = useComments({ target }); const [text, setText] = useState(""); const [replyTo, setReplyTo] = useState<{ id: number; userName: string } | null>(null); const submit = async (event: FormEvent) => { event.preventDefault(); const content = text.trim(); if (!content || posting || replyTo) return; const ok = await post(content); if (ok) setText(""); }; const submitReply = async (content: string) => { if (!replyTo) return false; const ok = await post(content, { parentsId: replyTo.id }); if (ok) setReplyTo(null); return ok; }; return (
{COMMENT_SORTS.map((item) => ( ))}
{loading ? (

评论加载中…

) : error ? (

{error}

) : comments.length === 0 ? (

暂无评论

) : (
    {comments.map((comment) => { const liked = Boolean(comment.isLike); const commentId = Number(comment.id) || 0; const isReplying = replyTo?.id === commentId; return (
  • {comment.userName}

    {comment.text}

    {formatCommentTime(comment.createdAt)}
    {isReplying && replyTo ? ( setReplyTo(null)} /> ) : null}
  • ); })}
)} {!loading && !error && comments.length > 0 ? ( ) : null}
{!replyTo && postError ?

{postError}

: null}
setText(event.target.value)} placeholder="发表评论…" aria-label="评论内容" className="h-9 min-w-0 flex-1 rounded-full bg-white/5 px-4 text-sm text-white outline-none placeholder:text-white/35 disabled:opacity-60" />
); }