import React, { useEffect, useState } from 'react'; import { createPortal } from 'react-dom'; import { ImageOff, Loader2, X } from 'lucide-react'; import { mediaObjectURL, parseMediaContent } from '../../lib/media'; interface ImageBlockProps { content: string; canEdit: boolean; onCaptionChange: (caption: string) => void; } // Image block: the picture (click = full screen) and an optional caption below it. export const ImageBlock: React.FC = ({ content, canEdit, onCaptionChange }) => { const ref = parseMediaContent(content); const [src, setSrc] = useState(null); const [failed, setFailed] = useState(false); const [zoomed, setZoomed] = useState(false); const [caption, setCaption] = useState(ref?.caption || ''); useEffect(() => { setCaption(ref?.caption || ''); }, [ref?.caption]); const mediaId = ref?.id; useEffect(() => { if (!mediaId) return; let alive = true; setFailed(false); mediaObjectURL(mediaId) .then((u) => alive && setSrc(u)) .catch(() => alive && setFailed(true)); return () => { alive = false; }; }, [mediaId]); useEffect(() => { if (!zoomed) return; const onKey = (e: KeyboardEvent) => e.key === 'Escape' && setZoomed(false); window.addEventListener('keydown', onKey); return () => window.removeEventListener('keydown', onKey); }, [zoomed]); if (!ref) { return
Bild-Verweis ist beschädigt: {content}
; } const commitCaption = () => { if (caption.trim() !== ref.caption) onCaptionChange(caption.trim()); }; return (
{failed ? (
Bild nicht verfügbar (offline oder gelöscht)
) : src ? ( ) : (
)} {canEdit ? ( setCaption(e.target.value)} onBlur={commitCaption} onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); (e.target as HTMLInputElement).blur(); } }} placeholder="Beschriftung hinzufügen…" className="w-full bg-transparent border-0 p-0 text-xs text-muted placeholder-faint focus:outline-none focus:ring-0" /> ) : ( ref.caption &&
{ref.caption}
)} {zoomed && src && createPortal(
setZoomed(false)} className="fixed inset-0 z-[100] bg-black/85 flex flex-col items-center justify-center p-4 cursor-zoom-out" > {ref.caption} {ref.caption &&

{ref.caption}

}
, document.body )}
); };