// Author: fruit.com.cn import { useEffect, useState } from 'react'; import { Send, X } from 'lucide-react'; import { engagementApi } from '../api/engagement'; function formatTime(value, htmlLang) { if (!value) return ''; const date = new Date(value); if (Number.isNaN(date.getTime())) return ''; return date.toLocaleString(htmlLang, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }); } export function CommentsSheet({ video, locale, onClose, onPosted }) { const [comments, setComments] = useState(null); const [error, setError] = useState(''); const [text, setText] = useState(''); const [sending, setSending] = useState(false); const loadComments = () => engagementApi.comments({ dramaId: video.id, episodeId: video.preview?.id }) .then((payload) => setComments(payload?.list || [])) .catch((loadError) => { setError(loadError.message || 'Request failed'); setComments([]); }); useEffect(() => { let active = true; setComments(null); setError(''); engagementApi.comments({ dramaId: video.id, episodeId: video.preview?.id }) .then((payload) => active && setComments(payload?.list || [])) .catch((loadError) => active && setError(loadError.message || 'Request failed')); return () => { active = false; }; }, [video.id, video.preview?.id]); const submit = async (event) => { event.preventDefault(); const content = text.trim(); if (!content || sending) return; setSending(true); setError(''); try { await engagementApi.publishComment({ dramaId: video.id, episodeId: video.preview?.id, content }); setText(''); await loadComments(); onPosted?.(); } catch (postError) { setError(postError.message || 'Request failed'); } finally { setSending(false); } }; return ( <>
{comments === null &&

{locale.loading}

} {error &&

{error}

} {comments && !comments.length && !error &&

{locale.noComments}

} {comments?.map((comment) => (
{comment.nickname?.[0] || 'Y'}
{comment.nickname || 'Guest'}

{comment.content}

{formatTime(comment.createdAt, locale.htmlLang)}
))}
setText(event.target.value)} placeholder={locale.commentPlaceholder} aria-label={locale.commentPlaceholder} />
); }