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:
@@ -1,9 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from 'svelte';
|
import { onMount, setContext } from 'svelte';
|
||||||
import type { PDFDocumentProxy, PDFPageProxy, RenderTask } from 'pdfjs-dist';
|
import type { PDFDocumentProxy, PDFPageProxy, RenderTask } from 'pdfjs-dist';
|
||||||
import AnnotationLayer from './AnnotationLayer.svelte';
|
import AnnotationLayer from './AnnotationLayer.svelte';
|
||||||
import type { Annotation } from '$lib/types';
|
import type { Annotation } from '$lib/types';
|
||||||
import { m } from '$lib/paraglide/messages.js';
|
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 };
|
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 annotations = $state<Annotation[]>([]);
|
||||||
let showAnnotations = $state(true);
|
let showAnnotations = $state(true);
|
||||||
|
let annotationUpdateError = $state<string | null>(null);
|
||||||
|
|
||||||
const TRANSCRIPTION_COLOR = '#00C7B1';
|
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 }) {
|
async function handleDraw(rect: { x: number; y: number; width: number; height: number }) {
|
||||||
if (!documentId || !transcribeMode) return;
|
if (!documentId || !transcribeMode) return;
|
||||||
await onTranscriptionDraw?.({ ...rect, pageNumber: currentPage });
|
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>
|
<span class="font-sans text-xs text-amber-300">{m.annotation_outdated_notice()}</span>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/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 -->
|
<!-- Controls -->
|
||||||
<div
|
<div
|
||||||
class="flex shrink-0 items-center justify-between gap-2 border-b border-pdf-ctrl px-4 py-2"
|
class="flex shrink-0 items-center justify-between gap-2 border-b border-pdf-ctrl px-4 py-2"
|
||||||
|
|||||||
Reference in New Issue
Block a user