import React from 'react';
import { MODES, modeById } from '../lib/modes.js';
// NoteBody — shared note-body state renderer (loading / streaming / error / done).
// Extracted so FigurePopover can reuse the exact same state logic without copy-paste.
// Props match the shape MarginNote already uses internally.
// entry — commentary entry or undefined
// generating — boolean
// onRegenerate — () => void
export function NoteBody({ entry, generating, onRegenerate }) {
if (generating && !entry?.text) {
return
consulting the literature
;
}
if (entry && entry.streaming && entry.text) {
return {entry.text}
;
}
if (entry && entry.error) {
return (
{entry.message ? entry.message + ' — ' : 'the annotator did not answer. '}
);
}
if (entry) {
return {entry.text}
;
}
return awaiting annotation…
;
}
// MarginNote — a single margin annotation card.
// Differences from prototype:
// 1. lit lookup comes through props (litByPara, litPapers) instead of window.ASTROPARSE_DATA.
// 2. modeById imported from lib/modes.js instead of global.
// Everything else (classNames, DOM structure, hover/mode/regen handlers) is identical.
export default function MarginNote({ para, mode, entry, generating, hovered, onHover, onSetMode, onRegenerate, onCite, top, noteRef, litByPara, litPapers, litCount, userNote, onSaveNote }) {
const m = modeById[mode];
const lit = (litByPara[para.id] || []).slice(0, litCount ?? 3).map((id) => litPapers[id]).filter(Boolean);
const [noteOpen, setNoteOpen] = React.useState(false);
const [draftText, setDraftText] = React.useState(userNote?.text || '');
const timerRef = React.useRef(null);
React.useEffect(() => { setDraftText(userNote?.text || ''); }, [userNote?.text]);
React.useEffect(() => { return () => { if (timerRef.current) clearTimeout(timerRef.current); }; }, []);
const handleNoteChange = (e) => {
const val = e.target.value;
setDraftText(val);
if (timerRef.current) clearTimeout(timerRef.current);
timerRef.current = setTimeout(() => {
onSaveNote && onSaveNote(para.id, val);
}, 400);
};
const handleNoteBlur = () => {
if (timerRef.current) clearTimeout(timerRef.current);
onSaveNote && onSaveNote(para.id, draftText);
if (!draftText.trim()) setNoteOpen(false);
};
return (
);
}