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
3 changed files with 29 additions and 1 deletions
Showing only changes of commit 6475ebcc60 - Show all commits

View File

@@ -14,6 +14,7 @@ type Props = {
saveState: SaveState;
canComment: boolean;
currentUserId: string | null;
commentCount: number;
onTextChange: (text: string) => void;
onFocus: () => void;
onDeleteClick: () => void;
@@ -30,6 +31,7 @@ let {
saveState,
canComment,
currentUserId,
commentCount,
onTextChange,
onFocus,
onDeleteClick,
@@ -37,7 +39,7 @@ let {
}: Props = $props();
let localText = $state(text);
let commentOpen = $state(false);
let commentOpen = $state(commentCount > 0);
let selectedQuote = $state<string | null>(null);
let textareaEl = $state<HTMLTextAreaElement | null>(null);

View File

@@ -16,6 +16,7 @@ function renderBlock(overrides: Record<string, unknown> = {}) {
saveState: 'idle' as const,
canComment: true,
currentUserId: 'user-1',
commentCount: 0,
onTextChange: vi.fn(),
onFocus: vi.fn(),
onDeleteClick: vi.fn(),

View File

@@ -30,10 +30,34 @@ let activeBlockId: string | null = $state(null);
let saveStates = new SvelteMap<string, SaveState>();
let debounceTimers = new SvelteMap<string, ReturnType<typeof setTimeout>>();
let pendingTexts = new SvelteMap<string, string>();
let commentCounts = new SvelteMap<string, number>();
let sortedBlocks = $derived([...blocks].sort((a, b) => a.sortOrder - b.sortOrder));
let hasBlocks = $derived(blocks.length > 0);
async function loadCommentCounts() {
for (const block of blocks) {
try {
const res = await fetch(
`/api/documents/${documentId}/transcription-blocks/${block.id}/comments`
);
if (res.ok) {
const comments = (await res.json()) as Array<{ replies: unknown[] }>;
const total = comments.reduce((s, c) => s + 1 + (c.replies?.length ?? 0), 0);
commentCounts.set(block.id, total);
}
} catch {
// ignore
}
}
}
$effect(() => {
if (blocks.length > 0) {
loadCommentCounts();
}
});
function getSaveState(blockId: string): SaveState {
return saveStates.get(blockId) ?? 'idle';
}
@@ -167,6 +191,7 @@ $effect(() => {
saveState={getSaveState(block.id)}
canComment={canComment}
currentUserId={currentUserId}
commentCount={commentCounts.get(block.id) ?? 0}
onTextChange={(text) => handleTextChange(block.id, text)}
onFocus={() => handleFocus(block.id)}
onDeleteClick={() => handleDelete(block.id)}