// 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 ( <> {locale.comments} {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} /> > ); }
{locale.loading}
{error}
{locale.noComments}
{comment.content}