feat(annotations): wire updateAnnotation context and error display into PdfViewer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-14 11:00:50 +02:00
parent 3fb32ea285
commit c610a3cc37

View File

@@ -1,9 +1,10 @@
<script lang="ts">
import { onMount } from 'svelte';
import { onMount, setContext } from 'svelte';
import type { PDFDocumentProxy, PDFPageProxy, RenderTask } from 'pdfjs-dist';
import AnnotationLayer from './AnnotationLayer.svelte';
import type { Annotation } from '$lib/types';
import { m } from '$lib/paraglide/messages.js';
import { parseBackendError, getErrorMessage } from '$lib/errors';
type DrawRect = { x: number; y: number; width: number; height: number; pageNumber: number };
@@ -55,6 +56,7 @@ let pdfjsReady = $state(false);
let annotations = $state<Annotation[]>([]);
let showAnnotations = $state(true);
let annotationUpdateError = $state<string | null>(null);
const TRANSCRIPTION_COLOR = '#00C7B1';
@@ -186,6 +188,29 @@ async function loadAnnotations(docId: string) {
}
}
async function updateAnnotation(
annotationId: string,
coords: { x: number; y: number; width: number; height: number }
) {
if (!documentId) return;
const res = await fetch(`/api/documents/${documentId}/annotations/${annotationId}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(coords)
});
if (!res.ok) {
const err = await parseBackendError(res);
const msg = getErrorMessage(err?.code ?? 'ANNOTATION_UPDATE_FAILED');
annotationUpdateError = msg;
setTimeout(() => (annotationUpdateError = null), 4000);
throw new Error(msg);
}
const updated = await res.json();
annotations = annotations.map((a) => (a.id === annotationId ? updated : a));
}
setContext('annotationUpdate', updateAnnotation);
async function handleDraw(rect: { x: number; y: number; width: number; height: number }) {
if (!documentId || !transcribeMode) return;
await onTranscriptionDraw?.({ ...rect, pageNumber: currentPage });
@@ -306,6 +331,26 @@ function zoomOut() {
<span class="font-sans text-xs text-amber-300">{m.annotation_outdated_notice()}</span>
</div>
{/if}
{#if annotationUpdateError}
<div
class="flex shrink-0 items-center gap-2 border-b border-red-500/30 bg-red-500/10 px-4 py-2"
aria-live="assertive"
role="alert"
>
<svg
class="h-4 w-4 shrink-0 text-red-400"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<circle cx="12" cy="12" r="10" />
<line x1="15" y1="9" x2="9" y2="15" />
<line x1="9" y1="9" x2="15" y2="15" />
</svg>
<span class="font-sans text-xs text-red-300">{annotationUpdateError}</span>
</div>
{/if}
<!-- Controls -->
<div
class="flex shrink-0 items-center justify-between gap-2 border-b border-pdf-ctrl px-4 py-2"