feat(transcription): enable drawing turquoise rectangles on PDF to create blocks
Some checks failed
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Failing after 1m29s
CI / Backend Unit Tests (pull_request) Failing after 2m40s
CI / E2E Tests (pull_request) Failing after 1h22m53s

- AnnotationLayer: add dimColor prop — annotations matching dim color
  render at 30% opacity with pointer-events disabled (300ms transition)
- PdfViewer: add transcribeMode prop, derived drawingEnabled/drawColor;
  in transcribe mode draws with turquoise (#00C7B1), routes draw events
  to onTranscriptionDraw callback instead of annotation endpoint
- DocumentViewer: pass through transcribeMode + onTranscriptionDraw
- Document detail page: createBlockFromDraw() POSTs to transcription
  blocks API on draw completion, adds created block to list
- Mode-based dimming: yellow annotations dim in transcribe mode,
  turquoise annotations dim in annotate mode

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-05 20:44:45 +02:00
parent aaffee2804
commit 99e2e6e5c1
4 changed files with 73 additions and 7 deletions

View File

@@ -12,6 +12,7 @@ let {
annotations = [],
canAnnotate,
color,
dimColor,
onDraw,
onDelete,
commentCounts,
@@ -20,12 +21,18 @@ let {
annotations: Annotation[];
canAnnotate: boolean;
color: string;
dimColor?: string;
onDraw: (rect: { x: number; y: number; width: number; height: number }) => void;
onDelete: (id: string) => void;
commentCounts?: Record<string, number>;
onAnnotationClick?: (id: string) => void;
} = $props();
function isDimmed(annotation: Annotation): boolean {
if (!dimColor) return false;
return annotation.color.toLowerCase() === dimColor.toLowerCase();
}
let drawStart = $state<{ x: number; y: number } | null>(null);
let drawRect = $state<DrawRect | null>(null);
@@ -123,8 +130,9 @@ const containerStyle = $derived(
height: {annotation.height * 100}%;
background-color: {hexToRgba(annotation.color, hoveredId === annotation.id ? 0.5 : 0.3)};
box-shadow: {hoveredId === annotation.id ? `inset 0 0 0 2px ${hexToRgba(annotation.color, 0.8)}` : 'none'};
pointer-events: auto;
transition: background-color 0.15s ease, box-shadow 0.15s ease;
opacity: {isDimmed(annotation) ? 0.3 : 1};
pointer-events: {isDimmed(annotation) ? 'none' : 'auto'};
transition: background-color 0.15s ease, box-shadow 0.15s ease, opacity 0.3s ease;
{onAnnotationClick && !canAnnotate ? 'cursor: pointer;' : ''}
"
>