From f6667e0e1529069ee4b1f595889f0b4e8b600935 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 12 Apr 2026 22:09:24 +0200 Subject: [PATCH] feat(frontend): show OcrProgress during OCR job + check status on load MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - triggerOcr captures jobId from POST response and shows OcrProgress - OcrProgress rendered in the transcription panel when ocrJobId is set - handleOcrDone reloads blocks and annotations when OCR completes - checkOcrStatus called when entering transcription mode — resumes progress display if a job is already running for this document Refs #226 Co-Authored-By: Claude Sonnet 4.6 --- .../src/routes/documents/[id]/+page.svelte | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/frontend/src/routes/documents/[id]/+page.svelte b/frontend/src/routes/documents/[id]/+page.svelte index 498e8601..dbcddf78 100644 --- a/frontend/src/routes/documents/[id]/+page.svelte +++ b/frontend/src/routes/documents/[id]/+page.svelte @@ -6,6 +6,7 @@ import DocumentViewer from '$lib/components/DocumentViewer.svelte'; import TranscriptionEditView from '$lib/components/TranscriptionEditView.svelte'; import TranscriptionReadView from '$lib/components/TranscriptionReadView.svelte'; import TranscriptionPanelHeader from '$lib/components/TranscriptionPanelHeader.svelte'; +import OcrProgress from '$lib/components/OcrProgress.svelte'; import type { TranscriptionBlockData } from '$lib/types'; let { data } = $props(); @@ -57,6 +58,7 @@ let activeAnnotationId = $state(null); let highlightBlockId = $state(null); let flashAnnotationId = $state(null); let pdfStripExpanded = $state(false); +let ocrJobId = $state(null); const prefersReducedMotion = $derived( typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches @@ -135,14 +137,21 @@ async function triggerOcr(scriptType: string) { body: JSON.stringify({ scriptType }) }); if (res.ok) { - await loadTranscriptionBlocks(); - annotationReloadKey++; + const data = await res.json(); + ocrJobId = data.jobId; } } catch (e) { console.error('Failed to trigger OCR:', e); } } +async function handleOcrDone() { + ocrJobId = null; + await loadTranscriptionBlocks(); + annotationReloadKey++; + panelMode = transcriptionBlocks.length > 0 ? 'read' : 'edit'; +} + async function createBlockFromDraw(rect: { x: number; y: number; @@ -223,12 +232,28 @@ function handleParagraphClick(annotationId: string) { ); } -// Load blocks when transcribe mode is entered and set default panel mode +async function checkOcrStatus() { + if (!doc?.id) return; + try { + const res = await fetch(`/api/documents/${doc.id}/ocr-status`); + if (res.ok) { + const status = await res.json(); + if (status.status === 'PENDING' || status.status === 'RUNNING') { + ocrJobId = status.jobId; + } + } + } catch { + // OCR status check is best-effort + } +} + +// Load blocks and check OCR status when transcribe mode is entered $effect(() => { if (transcribeMode) { loadTranscriptionBlocks().then(() => { panelMode = transcriptionBlocks.length > 0 ? 'read' : 'edit'; }); + checkOcrStatus(); } }); @@ -328,7 +353,11 @@ onMount(() => { onClose={() => (transcribeMode = false)} />
- {#if panelMode === 'read'} + {#if ocrJobId} +
+ +
+ {:else if panelMode === 'read'}