'use client'; import React, { useState, useEffect, useCallback, useRef } from 'react'; import { createPortal } from 'react-dom'; import { X, Download, Reply, Star, ZoomIn, ZoomOut, ChevronLeft, ChevronRight, Video, } from 'lucide-react'; import { Message } from '../types/inboxTypes'; import { getMediaUrl } from '../utils/inboxUtils'; import { format } from 'date-fns'; import { parseSafeDate } from '../utils/inboxUtils'; interface MediaViewerProps { msgs: Message[] currentMsgId: string onClose: () => void onReply?: (msg: Message) => void onStar?: (msg: Message) => void } const MediaViewer: React.FC = ({ msgs, currentMsgId, onClose, onReply, onStar }) => { const [currentIdx, setCurrentIdx] = useState(() => { const idx = msgs.findIndex(m => m.message_id === currentMsgId) return idx >= 0 ? idx : 0 }) const [zoom, setZoom] = useState(1) const filmstripRef = useRef(null) const currentMsg = msgs[currentIdx] const currentUrl = getMediaUrl(currentMsg?.media_url) const goNext = useCallback(() => { setCurrentIdx(i => Math.min(i + 1, msgs.length - 1)) setZoom(1) }, [msgs.length]) const goPrev = useCallback(() => { setCurrentIdx(i => Math.max(i - 1, 0)) setZoom(1) }, []) // Keyboard: ← → Esc useEffect(() => { const handler = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose() if (e.key === 'ArrowRight') goNext() if (e.key === 'ArrowLeft') goPrev() } window.addEventListener('keydown', handler) return () => window.removeEventListener('keydown', handler) }, [onClose, goNext, goPrev]) // Scroll filmstrip to keep current thumbnail visible useEffect(() => { const el = filmstripRef.current if (!el) return const thumb = el.children[currentIdx] as HTMLElement if (thumb) thumb.scrollIntoView({ inline: 'center', block: 'nearest', behavior: 'smooth' }) }, [currentIdx]) if (!currentMsg) return null const isVideo = currentMsg.type === 'video' const isImage = currentMsg.type === 'image' const caption = currentMsg.text?.trim() || null const timeStr = currentMsg.timestamp ? format(parseSafeDate(currentMsg.timestamp), 'dd/MM/yyyy HH:mm') : '' const senderLabel = currentMsg.direction === 'out' ? 'Você' : 'Contato' const viewer = (
{/* ── Top bar ─────────────────────────────────────────── */}
{/* Left: back + sender info */}
{senderLabel}
{timeStr}
{/* Right: actions */}
{isImage && ( <> )} {currentUrl && ( )}
{/* ── Main content ─────────────────────────────────────── */}
{/* Left arrow */} {currentIdx > 0 && ( )} {/* Media */}
e.stopPropagation()}> {!currentUrl ? (
Mídia não disponível
) : isVideo ? (
{/* Right arrow */} {currentIdx < msgs.length - 1 && ( )} {/* Caption */} {caption && (
{caption}
)}
{/* ── Bottom filmstrip ─────────────────────────────────── */} {msgs.length > 1 && (
{msgs.map((m, i) => { const url = getMediaUrl(m.media_url) const isVid = m.type === 'video' const isActive = i === currentIdx return ( ) })}
)}
) return typeof document !== 'undefined' ? createPortal(viewer, document.body) : null } export default MediaViewer