feat: Expandable metadata drawer + transcription system (#175, #176) #178

Merged
marcel merged 47 commits from feat/issue-175-176-metadata-drawer-transcription into main 2026-04-06 11:31:11 +02:00
2 changed files with 14 additions and 2 deletions
Showing only changes of commit 052f70e871 - Show all commits

View File

@@ -7,13 +7,14 @@ import type { TranscriptionBlockData } from '$lib/types';
type SaveState = 'idle' | 'saving' | 'saved' | 'fading' | 'error'; type SaveState = 'idle' | 'saving' | 'saved' | 'fading' | 'error';
type Props = { type Props = {
documentId: string;
blocks: TranscriptionBlockData[]; blocks: TranscriptionBlockData[];
onBlockFocus: (blockId: string) => void; onBlockFocus: (blockId: string) => void;
onSaveBlock: (blockId: string, text: string) => Promise<void>; onSaveBlock: (blockId: string, text: string) => Promise<void>;
onDeleteBlock: (blockId: string) => Promise<void>; onDeleteBlock: (blockId: string) => Promise<void>;
}; };
let { blocks, onBlockFocus, onSaveBlock, onDeleteBlock }: Props = $props(); let { documentId, blocks, onBlockFocus, onSaveBlock, onDeleteBlock }: Props = $props();
let activeBlockId: string | null = $state(null); let activeBlockId: string | null = $state(null);
let saveStates = new SvelteMap<string, SaveState>(); let saveStates = new SvelteMap<string, SaveState>();
@@ -115,9 +116,19 @@ function handleDelete(blockId: string) {
onDeleteBlock(blockId); 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(() => { $effect(() => {
function onBeforeUnload() { function onBeforeUnload() {
flushAllPending(); flushViaBeacon();
} }
window.addEventListener('beforeunload', onBeforeUnload); window.addEventListener('beforeunload', onBeforeUnload);

View File

@@ -199,6 +199,7 @@ onMount(() => {
{#if transcribeMode} {#if transcribeMode}
<div class="w-[400px] shrink-0 border-l border-line lg:w-[480px]"> <div class="w-[400px] shrink-0 border-l border-line lg:w-[480px]">
<TranscriptionEditView <TranscriptionEditView
documentId={doc.id}
blocks={transcriptionBlocks} blocks={transcriptionBlocks}
onBlockFocus={handleBlockFocus} onBlockFocus={handleBlockFocus}
onSaveBlock={saveBlock} onSaveBlock={saveBlock}