First PDF attempt
This commit is contained in:
@ -47,4 +47,16 @@ export class FileApi {
|
||||
`/file/${file.id}/download${forceDownload ? "?download=true" : ""}`
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Download uploaded file
|
||||
*/
|
||||
static async DownloadUploadedFile(file: UploadedFile): Promise<Blob> {
|
||||
return (
|
||||
await APIClient.exec({
|
||||
method: "GET",
|
||||
uri: `/file/${file.id}/download`,
|
||||
})
|
||||
).data;
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import CloudDownloadIcon from "@mui/icons-material/CloudDownload";
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
@ -6,9 +7,17 @@ import {
|
||||
Paper,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { FileApi, UploadedFile } from "../api/FileApi";
|
||||
import { filesize } from "filesize";
|
||||
import CloudDownloadIcon from "@mui/icons-material/CloudDownload";
|
||||
import { pdfjs } from "react-pdf";
|
||||
import { FileApi, UploadedFile } from "../api/FileApi";
|
||||
import React from "react";
|
||||
import { Document, Page } from "react-pdf";
|
||||
import { AsyncWidget } from "../widgets/AsyncWidget";
|
||||
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
|
||||
"pdfjs-dist/build/pdf.worker.min.mjs",
|
||||
import.meta.url
|
||||
).toString();
|
||||
|
||||
export function FileViewerDialog(p: {
|
||||
open: boolean;
|
||||
@ -22,11 +31,9 @@ export function FileViewerDialog(p: {
|
||||
{p.file.file_name} ({filesize(p.file.file_size)})
|
||||
</DialogTitle>
|
||||
<FileViewer
|
||||
fileName={p.file.file_name}
|
||||
fileSize={p.file.file_size}
|
||||
url={FileApi.DownloadURL(p.file)}
|
||||
downloadUrl={FileApi.DownloadURL(p.file, true)}
|
||||
mimetype={p.file.mime_type}
|
||||
{...p.file}
|
||||
/>
|
||||
<DialogActions>
|
||||
<Button onClick={p.onClose}>Close</Button>
|
||||
@ -35,18 +42,17 @@ export function FileViewerDialog(p: {
|
||||
);
|
||||
}
|
||||
|
||||
interface ViewerProps {
|
||||
fileName: string;
|
||||
fileSize: number;
|
||||
type ViewerProps = {
|
||||
url: string;
|
||||
downloadUrl: string;
|
||||
mimetype: string;
|
||||
}
|
||||
} & UploadedFile;
|
||||
|
||||
function FileViewer(p: ViewerProps): React.ReactElement {
|
||||
// Image
|
||||
if (p.mimetype.startsWith("image/"))
|
||||
return <ImageViewer {...p} />; // Default viewer
|
||||
if (p.mime_type.startsWith("image/")) return <ImageViewer {...p} />;
|
||||
// PDF
|
||||
else if (p.mime_type === "application/pdf") return <PDFViewer {...p} />;
|
||||
// Default viewer
|
||||
else return <DefaultViewer {...p} />;
|
||||
}
|
||||
|
||||
@ -54,6 +60,39 @@ function ImageViewer(p: ViewerProps): React.ReactElement {
|
||||
return <img src={p.url} />;
|
||||
}
|
||||
|
||||
function PDFViewer(p: ViewerProps): React.ReactElement {
|
||||
const [pdfUrl, setPdfUrl] = React.useState<string | undefined>();
|
||||
const [numPages, setNumPages] = React.useState<number>();
|
||||
const [pageNumber, setPageNumber] = React.useState<number>(1);
|
||||
|
||||
const load = async () => {
|
||||
const blob = await FileApi.DownloadUploadedFile(p);
|
||||
setPdfUrl(URL.createObjectURL(blob));
|
||||
};
|
||||
|
||||
function onDocumentLoadSuccess({ numPages }: { numPages: number }): void {
|
||||
setNumPages(numPages);
|
||||
}
|
||||
|
||||
return (
|
||||
<AsyncWidget
|
||||
loadKey={p.id}
|
||||
load={load}
|
||||
errMsg="Failed to load PDF!"
|
||||
build={() => (
|
||||
<div>
|
||||
<Document file={pdfUrl} onLoadSuccess={onDocumentLoadSuccess}>
|
||||
<Page pageNumber={pageNumber} />
|
||||
</Document>
|
||||
<p>
|
||||
Page {pageNumber} of {numPages}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function DefaultViewer(p: ViewerProps): React.ReactElement {
|
||||
return (
|
||||
<Paper
|
||||
@ -71,7 +110,7 @@ function DefaultViewer(p: ViewerProps): React.ReactElement {
|
||||
<CloudDownloadIcon fontSize="large" />
|
||||
</Typography>
|
||||
<Typography variant="caption" gutterBottom>
|
||||
{filesize(p.fileSize)}
|
||||
{filesize(p.file_size)}
|
||||
</Typography>
|
||||
<a href={p.downloadUrl} target="_blank" referrerPolicy="no-referrer">
|
||||
<Button variant="outlined">Download</Button>
|
||||
|
Reference in New Issue
Block a user