feat(frontend): show OcrProgress during OCR job + check status on load
- 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 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import DocumentViewer from '$lib/components/DocumentViewer.svelte';
|
|||||||
import TranscriptionEditView from '$lib/components/TranscriptionEditView.svelte';
|
import TranscriptionEditView from '$lib/components/TranscriptionEditView.svelte';
|
||||||
import TranscriptionReadView from '$lib/components/TranscriptionReadView.svelte';
|
import TranscriptionReadView from '$lib/components/TranscriptionReadView.svelte';
|
||||||
import TranscriptionPanelHeader from '$lib/components/TranscriptionPanelHeader.svelte';
|
import TranscriptionPanelHeader from '$lib/components/TranscriptionPanelHeader.svelte';
|
||||||
|
import OcrProgress from '$lib/components/OcrProgress.svelte';
|
||||||
import type { TranscriptionBlockData } from '$lib/types';
|
import type { TranscriptionBlockData } from '$lib/types';
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
@@ -57,6 +58,7 @@ let activeAnnotationId = $state<string | null>(null);
|
|||||||
let highlightBlockId = $state<string | null>(null);
|
let highlightBlockId = $state<string | null>(null);
|
||||||
let flashAnnotationId = $state<string | null>(null);
|
let flashAnnotationId = $state<string | null>(null);
|
||||||
let pdfStripExpanded = $state(false);
|
let pdfStripExpanded = $state(false);
|
||||||
|
let ocrJobId = $state<string | null>(null);
|
||||||
|
|
||||||
const prefersReducedMotion = $derived(
|
const prefersReducedMotion = $derived(
|
||||||
typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
||||||
@@ -135,14 +137,21 @@ async function triggerOcr(scriptType: string) {
|
|||||||
body: JSON.stringify({ scriptType })
|
body: JSON.stringify({ scriptType })
|
||||||
});
|
});
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
await loadTranscriptionBlocks();
|
const data = await res.json();
|
||||||
annotationReloadKey++;
|
ocrJobId = data.jobId;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to trigger OCR:', 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: {
|
async function createBlockFromDraw(rect: {
|
||||||
x: number;
|
x: number;
|
||||||
y: 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(() => {
|
$effect(() => {
|
||||||
if (transcribeMode) {
|
if (transcribeMode) {
|
||||||
loadTranscriptionBlocks().then(() => {
|
loadTranscriptionBlocks().then(() => {
|
||||||
panelMode = transcriptionBlocks.length > 0 ? 'read' : 'edit';
|
panelMode = transcriptionBlocks.length > 0 ? 'read' : 'edit';
|
||||||
});
|
});
|
||||||
|
checkOcrStatus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -328,7 +353,11 @@ onMount(() => {
|
|||||||
onClose={() => (transcribeMode = false)}
|
onClose={() => (transcribeMode = false)}
|
||||||
/>
|
/>
|
||||||
<div class="flex-1 overflow-y-auto">
|
<div class="flex-1 overflow-y-auto">
|
||||||
{#if panelMode === 'read'}
|
{#if ocrJobId}
|
||||||
|
<div class="p-4">
|
||||||
|
<OcrProgress jobId={ocrJobId} onDone={handleOcrDone} />
|
||||||
|
</div>
|
||||||
|
{:else if panelMode === 'read'}
|
||||||
<TranscriptionReadView
|
<TranscriptionReadView
|
||||||
blocks={transcriptionBlocks}
|
blocks={transcriptionBlocks}
|
||||||
highlightBlockId={highlightBlockId}
|
highlightBlockId={highlightBlockId}
|
||||||
|
|||||||
Reference in New Issue
Block a user