// astroparse — upload (folio drop) + animated pipeline screens
function UploadScreen({ onFile, onSample, onImportSession }) {
const [dragging, setDragging] = React.useState(false);
const fileRef = React.useRef(null);
const sessionRef = React.useRef(null);
const handleDrop = (e) => {
e.preventDefault();
setDragging(false);
const f = e.dataTransfer.files && e.dataTransfer.files[0];
if (f) onFile(f.name);
};
return (
astroparse
{ e.preventDefault(); setDragging(true); }}
onDragLeave={() => setDragging(false)}
onDrop={handleDrop}
onClick={() => fileRef.current && fileRef.current.click()}
>
¶
Place a manuscript here
drop an astronomy PDF, or click to browse
parsed with pymupdf4llm · annotated against the literature via Pathfinder
{ const f = e.target.files[0]; if (f) onFile(f.name); }}
/>
·
{
const f = e.target.files[0];
if (!f) return;
const r = new FileReader();
r.onload = () => onImportSession(r.result);
r.readAsText(f);
}}
/>
prototype — parsing is simulated; any dropped PDF opens the bundled manuscript (Mowla & Iyer 2024)
);
}
function PipelineScreen({ fileName, onDone }) {
const stages = window.ASTROPARSE_DATA.pipelineStages;
// progress: index of current stage; logIdx: how many log lines shown in current stage
const [stageIdx, setStageIdx] = React.useState(0);
const [logIdx, setLogIdx] = React.useState(0);
const [finished, setFinished] = React.useState(false);
const doneRef = React.useRef(false);
React.useEffect(() => {
if (finished) {
const t = setTimeout(() => { if (!doneRef.current) { doneRef.current = true; onDone(); } }, 1100);
return () => clearTimeout(t);
}
const stage = stages[stageIdx];
if (!stage) { setFinished(true); return; }
if (logIdx < stage.logs.length) {
const t = setTimeout(() => setLogIdx(logIdx + 1), 420);
return () => clearTimeout(t);
}
const t = setTimeout(() => { setStageIdx(stageIdx + 1); setLogIdx(0); }, 380);
return () => clearTimeout(t);
}, [stageIdx, logIdx, finished]);
return (