refactor(transcribe): extract region navigation into a tested pure helper (#327)

Review follow-up (Sara): j/k wrap-around and fresh-entry had no direct
coverage — the logic lived inline in the page where the action spec only
mocks the callbacks. Extracted to a pure stepRegion() with 9 unit tests
(empty list, forward/back, both wraps, fresh-entry null + unknown id,
length-1). Also replaces the inline nested ternary Felix flagged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-06-04 17:14:39 +02:00
committed by marcel
parent f07527158c
commit ab469b744c
3 changed files with 85 additions and 9 deletions

View File

@@ -12,6 +12,7 @@ import ShortcutCheatsheet from '$lib/document/transcription/ShortcutCheatsheet.s
import { transcribeShortcuts } from '$lib/shared/actions/transcribeShortcuts';
import { createOcrJob } from '$lib/ocr/useOcrJob.svelte';
import { createTranscriptionBlocks } from '$lib/document/transcription/useTranscriptionBlocks.svelte';
import { stepRegion } from '$lib/document/transcription/regionNavigation';
import { createFileLoader } from '$lib/document/viewer/useFileLoader.svelte';
import { scrollToCommentFromQuery } from '$lib/shared/utils/deepLinkScroll';
import { getConfirmService } from '$lib/shared/services/confirm.svelte';
@@ -102,15 +103,9 @@ async function createBlockFromDraw(rect: {
const sortedBlocks = $derived([...transcription.blocks].sort((a, b) => a.sortOrder - b.sortOrder));
function goToRegion(delta: 1 | -1) {
if (sortedBlocks.length === 0) return;
const current = sortedBlocks.findIndex((b) => b.annotationId === activeAnnotationId);
const next =
current === -1
? delta > 0
? 0
: sortedBlocks.length - 1
: (current + delta + sortedBlocks.length) % sortedBlocks.length;
activeAnnotationId = sortedBlocks[next].annotationId;
const ids = sortedBlocks.map((b) => b.annotationId);
const next = stepRegion(ids, activeAnnotationId, delta);
if (next) activeAnnotationId = next;
}
function toggleMode() {