Spaces:
Running
Running
| <script lang="ts"> | |
| import {tick, onMount} from "svelte"; | |
| import PdfUploadText from "./PdfUploadText.svelte"; | |
| import type { Gradio } from "@gradio/utils"; | |
| import { Block, BlockLabel } from "@gradio/atoms"; | |
| import { BaseButton } from "@gradio/button"; | |
| import { File } from "@gradio/icons"; | |
| import { StatusTracker } from "@gradio/statustracker"; | |
| import type { LoadingStatus } from "@gradio/statustracker"; | |
| import type { FileData } from "@gradio/client"; | |
| import { normalise_file } from "@gradio/client"; | |
| import { Upload, ModifyUpload } from "@gradio/upload"; | |
| import pdfjsLib from "pdfjs-dist"; | |
| export let elem_id = ""; | |
| export let elem_classes: string[] = []; | |
| export let visible = true; | |
| export let value: FileData | null = null; | |
| export let container = true; | |
| export let scale: number | null = null; | |
| export let root: string; | |
| export let height: number | null = 500; | |
| export let label: string; | |
| export let proxy_url: string; | |
| export let min_width: number | undefined = undefined; | |
| export let loading_status: LoadingStatus; | |
| export let gradio: Gradio<{ | |
| change: never; | |
| upload: never; | |
| }>; | |
| pdfjsLib.GlobalWorkerOptions.workerSrc = "https://cdn.bootcss.com/pdf.js/3.11.174/pdf.worker.js"; | |
| let _value = value; | |
| let old_value = _value; | |
| let pdfDoc; | |
| let numPages = 1; | |
| let currentPage = 1; | |
| let canvasRef; | |
| async function handle_clear() { | |
| _value = null; | |
| await tick(); | |
| gradio.dispatch("change"); | |
| } | |
| async function handle_upload({detail}: CustomEvent<FileData>): Promise<void> { | |
| value = detail; | |
| await tick(); | |
| gradio.dispatch("change"); | |
| gradio.dispatch("upload"); | |
| } | |
| async function get_doc(value: FileData) { | |
| const loadingTask = pdfjsLib.getDocument(value.url); | |
| pdfDoc = await loadingTask.promise; | |
| numPages = pdfDoc.numPages; | |
| render_page(); | |
| } | |
| function render_page() { | |
| // Render a specific page of the PDF onto the canvas | |
| pdfDoc.getPage(currentPage).then(page => { | |
| const ctx = canvasRef.getContext('2d') | |
| ctx.clearRect(0, 0, canvasRef.width, canvasRef.height); | |
| let viewport = page.getViewport({ scale: 1 }); | |
| let scale = height / viewport.height; | |
| viewport = page.getViewport({ scale: scale }); | |
| const renderContext = { | |
| canvasContext: ctx, | |
| viewport, | |
| }; | |
| canvasRef.width = viewport.width; | |
| canvasRef.height = viewport.height; | |
| page.render(renderContext); | |
| }); | |
| } | |
| function next_page() { | |
| if (currentPage >= numPages) { | |
| return; | |
| } | |
| currentPage++; | |
| render_page(); | |
| } | |
| function prev_page() { | |
| if (currentPage == 1) { | |
| return; | |
| } | |
| currentPage--; | |
| render_page(); | |
| } | |
| $: height = height || 500; | |
| $: _value = normalise_file(value, root, proxy_url); | |
| $: if(JSON.stringify(old_value) != JSON.stringify(_value)) { | |
| if (_value){ | |
| get_doc(_value); | |
| } | |
| old_value = _value; | |
| gradio.dispatch("change"); | |
| } | |
| </script> | |
| <Block {visible} {elem_id} {elem_classes} {container} {scale} {min_width}> | |
| {#if loading_status} | |
| <StatusTracker | |
| autoscroll={gradio.autoscroll} | |
| i18n={gradio.i18n} | |
| {...loading_status} | |
| /> | |
| {/if} | |
| <BlockLabel | |
| show_label={label !== null} | |
| Icon={File} | |
| float={value === null} | |
| label={label || "File"} | |
| /> | |
| {#if _value} | |
| <ModifyUpload i18n={gradio.i18n} on:clear={handle_clear} absolute /> | |
| <div class="pdf-canvas" style="height: {height}px"> | |
| <canvas bind:this={canvasRef}></canvas> | |
| </div> | |
| <div class="button-row"> | |
| <BaseButton on:click={prev_page}> | |
| ⬅️ | |
| </BaseButton> | |
| <span class="page-count"> {currentPage} / {numPages} </span> | |
| <BaseButton on:click={next_page}> | |
| ➡️ | |
| </BaseButton> | |
| </div> | |
| {:else} | |
| <Upload | |
| on:load={handle_upload} | |
| filetype={"application/pdf"} | |
| file_count="single" | |
| {root} | |
| > | |
| <PdfUploadText/> | |
| </Upload> | |
| {/if} | |
| </Block> | |
| <style> | |
| .pdf-canvas { | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| overflow-y: auto; | |
| } | |
| .button-row { | |
| display: flex; | |
| flex-direction: row; | |
| width: 100%; | |
| justify-content: center; | |
| align-items: center; | |
| } | |
| .page-count { | |
| margin: 0 10px; | |
| font-family: var(--font-mono); | |
| } | |
| </style> |