import React, { useCallback, useEffect, useRef, useState } from 'react'
import axios from 'axios'
import CommentForm from '../comments/CommentForm'
import ReactionBar from '../comments/ReactionBar'
import { isFlood } from '../../utils/emojiFlood'
// ── Helpers ───────────────────────────────────────────────────────────────────
function timeAgo(dateStr) {
if (!dateStr) return ''
const date = new Date(dateStr)
const seconds = Math.floor((Date.now() - date.getTime()) / 1000)
if (seconds < 60) return 'just now'
const minutes = Math.floor(seconds / 60)
if (minutes < 60) return `${minutes}m ago`
const hours = Math.floor(minutes / 60)
if (hours < 24) return `${hours}h ago`
const days = Math.floor(hours / 24)
if (days < 365) return `${days}d ago`
return date.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })
}
function Avatar({ user, size = 36 }) {
if (user?.avatar_url) {
return (
{
e.currentTarget.onerror = null
e.currentTarget.src = 'https://files.skinbase.org/avatars/default.webp'
}}
/>
)
}
const initials = (user?.name || user?.username || '?').slice(0, 1).toUpperCase()
return (
{initials}
)
}
// ── Single comment ────────────────────────────────────────────────────────────
function CommentItem({ comment, isLoggedIn }) {
const user = comment.user
const html = comment.rendered_content ?? null
const plain = comment.content ?? ''
// Emoji-flood collapse: long runs of repeated emoji get a show-more toggle.
const flood = isFlood(plain)
const [expanded, setExpanded] = useState(!flood)
// Build initial reaction totals (empty if not provided by server)
const [reactionTotals, setReactionTotals] = useState(comment.reactions ?? {})
// Load reactions lazily if not provided
useEffect(() => {
if (comment.reactions || !comment.id) return
axios
.get(`/api/comments/${comment.id}/reactions`)
.then(({ data }) => setReactionTotals(data.totals ?? {}))
.catch(() => {})
}, [comment.id, comment.reactions])
return (
{plain}
)} {/* Gradient fade at the bottom while collapsed */} {flood && !expanded && ( )}No comments yet. Be the first!
) : ( <>