- transcription/: TranscriptionBlock, Column, EditView, PanelHeader, ReadView, Section + transcriptionMarkers, blockConflictMerge, saveBlockWithConflictRetry + useBlockAutoSave, useBlockDragDrop hooks - annotation/: AnnotationLayer, AnnotationShape, AnnotationEditOverlay - viewer/: PdfViewer, PdfControls + useFileLoader, usePdfRenderer hooks Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
116 lines
3.2 KiB
Svelte
116 lines
3.2 KiB
Svelte
<script lang="ts">
|
|
import { m } from '$lib/paraglide/messages.js';
|
|
import PdfViewer from '$lib/document/viewer/PdfViewer.svelte';
|
|
|
|
type Doc = {
|
|
id: string;
|
|
filePath?: string | null;
|
|
contentType?: string | null;
|
|
fileHash?: string | null;
|
|
};
|
|
|
|
type DrawRect = { x: number; y: number; width: number; height: number; pageNumber: number };
|
|
|
|
type Props = {
|
|
doc: Doc;
|
|
fileUrl: string;
|
|
isLoading: boolean;
|
|
error: string;
|
|
transcribeMode?: boolean;
|
|
blockNumbers?: Record<string, number>;
|
|
annotationReloadKey?: number;
|
|
activeAnnotationId: string | null;
|
|
annotationsDimmed?: boolean;
|
|
flashAnnotationId?: string | null;
|
|
onAnnotationClick: (id: string) => void;
|
|
onTranscriptionDraw?: (rect: DrawRect) => void;
|
|
onDeleteAnnotationRequest?: (annotationId: string) => void;
|
|
};
|
|
|
|
let {
|
|
doc,
|
|
fileUrl,
|
|
isLoading,
|
|
error,
|
|
transcribeMode = false,
|
|
blockNumbers = {},
|
|
annotationReloadKey = 0,
|
|
activeAnnotationId = $bindable(),
|
|
annotationsDimmed = false,
|
|
flashAnnotationId = null,
|
|
onAnnotationClick,
|
|
onTranscriptionDraw,
|
|
onDeleteAnnotationRequest
|
|
}: Props = $props();
|
|
</script>
|
|
|
|
<div class="absolute inset-0 bg-pdf-bg">
|
|
{#if isLoading}
|
|
<div class="flex h-full flex-col items-center justify-center text-accent">
|
|
<svg
|
|
class="mb-4 h-8 w-8 animate-spin"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"
|
|
></circle>
|
|
<path
|
|
class="opacity-75"
|
|
fill="currentColor"
|
|
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
></path>
|
|
</svg>
|
|
<span class="font-sans text-sm tracking-wide">{m.doc_loading()}</span>
|
|
</div>
|
|
{:else if error}
|
|
<div class="flex h-full flex-col items-center justify-center px-4 text-center text-ink-3">
|
|
<p class="mb-2 font-serif">{error}</p>
|
|
{#if doc.filePath}
|
|
<a
|
|
href="/api/documents/{doc.id}/file"
|
|
target="_blank"
|
|
class="text-sm underline hover:text-white"
|
|
>
|
|
{m.doc_download_link()}
|
|
</a>
|
|
{/if}
|
|
</div>
|
|
{:else if !doc.filePath}
|
|
<div class="flex h-full flex-col items-center justify-center text-ink-3">
|
|
<div class="mb-6 rounded-full bg-surface/5 p-8">
|
|
<img
|
|
src="/degruyter-icons/Simple/Medium-24px/SVG/Action/PDF-Document-MD.svg"
|
|
alt=""
|
|
aria-hidden="true"
|
|
class="h-12 w-12 opacity-50 invert"
|
|
/>
|
|
</div>
|
|
<p class="font-sans text-sm tracking-wide uppercase">{m.doc_no_scan()}</p>
|
|
</div>
|
|
{:else if fileUrl && doc.contentType?.startsWith('application/pdf')}
|
|
<PdfViewer
|
|
url={fileUrl}
|
|
documentId={doc.id}
|
|
transcribeMode={transcribeMode}
|
|
blockNumbers={blockNumbers}
|
|
annotationReloadKey={annotationReloadKey}
|
|
bind:activeAnnotationId={activeAnnotationId}
|
|
annotationsDimmed={annotationsDimmed}
|
|
flashAnnotationId={flashAnnotationId}
|
|
onAnnotationClick={onAnnotationClick}
|
|
onTranscriptionDraw={onTranscriptionDraw}
|
|
onDeleteAnnotationRequest={onDeleteAnnotationRequest}
|
|
documentFileHash={doc.fileHash ?? null}
|
|
/>
|
|
{:else if fileUrl}
|
|
<div class="flex h-full w-full items-center justify-center overflow-auto p-8">
|
|
<img
|
|
src={fileUrl}
|
|
alt={m.doc_image_alt()}
|
|
class="max-h-full max-w-full object-contain shadow-2xl"
|
|
/>
|
|
</div>
|
|
{/if}
|
|
</div>
|