From 61256942e1e77915799162da01a0811d8bfc7290 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 4 Jun 2026 16:56:36 +0200 Subject: [PATCH] feat(transcribe): wire keyboard shortcuts into the document panel (#327) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Attaches the transcribeShortcuts action to the document page and wires every command to existing context setters: j/k walk the sortOrder-sorted regions and set activeAnnotationId, e toggles read/edit, n arms a draw cue (edit only), Delete routes to the existing confirm path, ? opens the cheatsheet, and Esc is now owned solely by the action — the inline onMount Esc listener is removed (decision B1). Renders ShortcutCheatsheet and a draw-armed hint. "t" toggles the document-level KURRENT_RECOGNITION training enrollment (the only training surface that exists; there is no per-region flag yet — see #321) and no-ops unless a region is active. Also reconciles annotation Delete: the shape no longer self-handles the key, with onfocus syncing the active region so the action deletes exactly once. Co-Authored-By: Claude Sonnet 4.6 --- .../src/lib/document/DocumentViewer.svelte | 6 +- .../annotation/AnnotationLayer.svelte | 6 +- .../annotation/AnnotationShape.svelte | 15 +++- .../annotation/AnnotationShape.svelte.spec.ts | 60 +++++++++---- .../src/lib/document/viewer/PdfViewer.svelte | 6 +- .../src/routes/documents/[id]/+page.svelte | 84 +++++++++++++++++-- 6 files changed, 142 insertions(+), 35 deletions(-) diff --git a/frontend/src/lib/document/DocumentViewer.svelte b/frontend/src/lib/document/DocumentViewer.svelte index aa8a575f..6b189961 100644 --- a/frontend/src/lib/document/DocumentViewer.svelte +++ b/frontend/src/lib/document/DocumentViewer.svelte @@ -25,7 +25,7 @@ type Props = { flashAnnotationId?: string | null; onAnnotationClick: (id: string) => void; onTranscriptionDraw?: (rect: DrawRect) => void; - onDeleteAnnotationRequest?: (annotationId: string) => void; + onAnnotationFocus?: (id: string) => void; }; let { @@ -42,7 +42,7 @@ let { flashAnnotationId = null, onAnnotationClick, onTranscriptionDraw, - onDeleteAnnotationRequest + onAnnotationFocus }: Props = $props(); @@ -104,7 +104,7 @@ let { flashAnnotationId={flashAnnotationId} onAnnotationClick={onAnnotationClick} onTranscriptionDraw={onTranscriptionDraw} - onDeleteAnnotationRequest={onDeleteAnnotationRequest} + onAnnotationFocus={onAnnotationFocus} documentFileHash={doc.fileHash ?? null} /> {:else if fileUrl} diff --git a/frontend/src/lib/document/annotation/AnnotationLayer.svelte b/frontend/src/lib/document/annotation/AnnotationLayer.svelte index d392628c..35b321de 100644 --- a/frontend/src/lib/document/annotation/AnnotationLayer.svelte +++ b/frontend/src/lib/document/annotation/AnnotationLayer.svelte @@ -19,7 +19,7 @@ let { flashAnnotationId = null, onDraw, onAnnotationClick, - onDeleteRequest + onAnnotationFocus }: { annotations: Annotation[]; canDraw: boolean; @@ -30,7 +30,7 @@ let { flashAnnotationId?: string | null; onDraw: (rect: DrawRect) => void; onAnnotationClick?: (id: string) => void; - onDeleteRequest?: (annotationId: string) => void; + onAnnotationFocus?: (id: string) => void; } = $props(); let drawStart = $state<{ x: number; y: number } | null>(null); @@ -115,8 +115,8 @@ const containerStyle = $derived( blockNumber={blockNumbers[annotation.id]} isFlashing={flashAnnotationId === annotation.id} showDelete={canDraw} - onDeleteRequest={() => onDeleteRequest?.(annotation.id)} onclick={() => onAnnotationClick?.(annotation.id)} + onfocus={() => onAnnotationFocus?.(annotation.id)} onpointerenter={() => (hoveredId = annotation.id)} onpointerleave={() => (hoveredId = null)} /> diff --git a/frontend/src/lib/document/annotation/AnnotationShape.svelte b/frontend/src/lib/document/annotation/AnnotationShape.svelte index c0cb985f..7b301d76 100644 --- a/frontend/src/lib/document/annotation/AnnotationShape.svelte +++ b/frontend/src/lib/document/annotation/AnnotationShape.svelte @@ -1,5 +1,6 @@