diff --git a/frontend/src/lib/components/TranscriptionEditView.svelte b/frontend/src/lib/components/TranscriptionEditView.svelte index f4f57c51..e30d10f5 100644 --- a/frontend/src/lib/components/TranscriptionEditView.svelte +++ b/frontend/src/lib/components/TranscriptionEditView.svelte @@ -7,13 +7,14 @@ import type { TranscriptionBlockData } from '$lib/types'; type SaveState = 'idle' | 'saving' | 'saved' | 'fading' | 'error'; type Props = { + documentId: string; blocks: TranscriptionBlockData[]; onBlockFocus: (blockId: string) => void; onSaveBlock: (blockId: string, text: string) => Promise; onDeleteBlock: (blockId: string) => Promise; }; -let { blocks, onBlockFocus, onSaveBlock, onDeleteBlock }: Props = $props(); +let { documentId, blocks, onBlockFocus, onSaveBlock, onDeleteBlock }: Props = $props(); let activeBlockId: string | null = $state(null); let saveStates = new SvelteMap(); @@ -115,9 +116,19 @@ function handleDelete(blockId: string) { onDeleteBlock(blockId); } +function flushViaBeacon() { + for (const [blockId, text] of pendingTexts) { + clearDebounce(blockId); + const url = `/api/documents/${documentId}/transcription-blocks/${blockId}`; + const body = JSON.stringify({ text }); + navigator.sendBeacon(url, new Blob([body], { type: 'application/json' })); + pendingTexts.delete(blockId); + } +} + $effect(() => { function onBeforeUnload() { - flushAllPending(); + flushViaBeacon(); } window.addEventListener('beforeunload', onBeforeUnload); diff --git a/frontend/src/routes/documents/[id]/+page.svelte b/frontend/src/routes/documents/[id]/+page.svelte index e71593e0..fac7d987 100644 --- a/frontend/src/routes/documents/[id]/+page.svelte +++ b/frontend/src/routes/documents/[id]/+page.svelte @@ -199,6 +199,7 @@ onMount(() => { {#if transcribeMode}