From c9d7d0a6f58708db866b9099c49800ce48930c65 Mon Sep 17 00:00:00 2001 From: enes Date: Wed, 21 Aug 2024 17:07:29 +0200 Subject: [PATCH] feat(content): show other file types as gray box --- src/components/DrawPDFFields/index.tsx | 4 +- .../DrawPDFFields/style.module.scss | 12 --- src/components/PDFView/PdfItem.tsx | 34 ++++--- src/components/PDFView/index.tsx | 5 +- src/index.css | 12 +++ src/pages/sign/index.tsx | 31 ++++-- src/pages/sign/internal/displayMeta.tsx | 11 ++- src/pages/verify/index.tsx | 95 +++++++++++-------- src/types/file.ts | 2 +- src/utils/file.ts | 16 +++- src/utils/pdf.ts | 11 ++- src/utils/utils.ts | 2 +- 12 files changed, 145 insertions(+), 90 deletions(-) diff --git a/src/components/DrawPDFFields/index.tsx b/src/components/DrawPDFFields/index.tsx index a3d43ae..3da227d 100644 --- a/src/components/DrawPDFFields/index.tsx +++ b/src/components/DrawPDFFields/index.tsx @@ -488,9 +488,7 @@ export const DrawPDFFields = (props: Props) => { {pdfFile ? ( getPdfPages(pdfFile, i) ) : ( -
- This is a {extension} file -
+
This is a {extension} file
)} {i < selectedFiles.length - 1 && ( diff --git a/src/components/DrawPDFFields/style.module.scss b/src/components/DrawPDFFields/style.module.scss index 142f88a..8c888ec 100644 --- a/src/components/DrawPDFFields/style.module.scss +++ b/src/components/DrawPDFFields/style.module.scss @@ -104,15 +104,3 @@ flex-direction: column; gap: 25px; } - -.otherFile { - border-radius: 4px; - background: rgba(255, 255, 255, 0.5); - height: 100px; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - color: rgba(0, 0, 0, 0.25); - font-size: 14px; -} diff --git a/src/components/PDFView/PdfItem.tsx b/src/components/PDFView/PdfItem.tsx index c502bb4..c7f3b54 100644 --- a/src/components/PDFView/PdfItem.tsx +++ b/src/components/PDFView/PdfItem.tsx @@ -1,12 +1,13 @@ import { PdfFile } from '../../types/drawing.ts' import { CurrentUserMark, Mark } from '../../types/mark.ts' +import { extractFileExtension } from '../../utils/meta.ts' import PdfPageItem from './PdfPageItem.tsx' interface PdfItemProps { currentUserMarks: CurrentUserMark[] handleMarkClick: (id: number) => void otherUserMarks: Mark[] - pdfFile: PdfFile + pdfFile: PdfFile | File selectedMark: CurrentUserMark | null selectedMarkValue: string } @@ -31,19 +32,24 @@ const PdfItem = ({ const filterMarksByPage = (marks: Mark[], page: number): Mark[] => { return marks.filter((mark) => mark.location.page === page) } - return pdfFile.pages.map((page, i) => { - return ( - - ) - }) + if ('pages' in pdfFile) { + return pdfFile.pages.map((page, i) => { + return ( + + ) + }) + } else { + const extension = extractFileExtension(pdfFile.name) + return
This is a {extension} file
+ } } export default PdfItem diff --git a/src/components/PDFView/index.tsx b/src/components/PDFView/index.tsx index ef765f0..6af3d69 100644 --- a/src/components/PDFView/index.tsx +++ b/src/components/PDFView/index.tsx @@ -51,11 +51,12 @@ const PdfView = ({ return ( <> {files.map((currentUserFile, index, arr) => { - const { hash, pdfFile, id } = currentUserFile + const { hash, pdfFile, id, filename } = currentUserFile + if (!hash) return return (
(pdfRefs.current[id] = el)} key={index} > diff --git a/src/index.css b/src/index.css index 7ee0eea..b292cb2 100644 --- a/src/index.css +++ b/src/index.css @@ -165,3 +165,15 @@ button:disabled { font-style: normal; font-display: swap; } + +.otherFile { + border-radius: 4px; + background: rgba(255, 255, 255, 0.5); + height: 100px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + color: rgba(0, 0, 0, 0.25); + font-size: 14px; +} diff --git a/src/pages/sign/index.tsx b/src/pages/sign/index.tsx index f8f6163..2bc7d49 100644 --- a/src/pages/sign/index.tsx +++ b/src/pages/sign/index.tsx @@ -33,13 +33,14 @@ import { sendNotification, signEventForMetaFile, updateUsersAppData, - findOtherUserMarks + findOtherUserMarks, + extractFileExtension } from '../../utils' import { Container } from '../../components/Container' import { DisplayMeta } from './internal/displayMeta' import styles from './style.module.scss' import { PdfFile } from '../../types/drawing.ts' -import { convertToPdfFile } from '../../utils/pdf.ts' +import { convertToPdfFile, toFile } from '../../utils/pdf.ts' import { CurrentUserMark, Mark } from '../../types/mark.ts' import { getLastSignersSig } from '../../utils/sign.ts' import { @@ -76,7 +77,7 @@ export const SignPage = () => { const [selectedFile, setSelectedFile] = useState(null) - const [files, setFiles] = useState<{ [filename: string]: PdfFile }>({}) + const [files, setFiles] = useState<{ [filename: string]: PdfFile | File }>({}) const [isLoading, setIsLoading] = useState(true) const [loadingSpinnerDesc, setLoadingSpinnerDesc] = useState('') @@ -402,7 +403,7 @@ export const SignPage = () => { return } - const files: { [filename: string]: PdfFile } = {} + const files: { [filename: string]: PdfFile | File } = {} const fileHashes: { [key: string]: string | null } = {} const fileNames = Object.values(zip.files).map((entry) => entry.name) @@ -419,7 +420,11 @@ export const SignPage = () => { try { files[fileName] = await convertToPdfFile(arrayBuffer, fileName) } catch (error) { - console.error('Not a .pdf file:', error) + files[fileName] = toFile( + arrayBuffer, + fileName, + 'application/' + extractFileExtension(fileName) + ) } const hash = await getHash(arrayBuffer) if (hash) { @@ -767,8 +772,12 @@ export const SignPage = () => { zip.file('meta.json', stringifiedMeta) - for (const [fileName, pdf] of Object.entries(files)) { - zip.file(`files/${fileName}`, await pdf.file.arrayBuffer()) + for (const [fileName, file] of Object.entries(files)) { + if ('pages' in file) { + zip.file(`files/${fileName}`, await file.file.arrayBuffer()) + } else { + zip.file(`files/${fileName}`, await file.arrayBuffer()) + } } const arrayBuffer = await zip @@ -805,8 +814,12 @@ export const SignPage = () => { zip.file('meta.json', stringifiedMeta) - for (const [fileName, pdf] of Object.entries(files)) { - zip.file(`files/${fileName}`, await pdf.file.arrayBuffer()) + for (const [fileName, file] of Object.entries(files)) { + if ('pages' in file) { + zip.file(`files/${fileName}`, await file.file.arrayBuffer()) + } else { + zip.file(`files/${fileName}`, await file.arrayBuffer()) + } } const arrayBuffer = await zip diff --git a/src/pages/sign/internal/displayMeta.tsx b/src/pages/sign/internal/displayMeta.tsx index 03ba364..8e09612 100644 --- a/src/pages/sign/internal/displayMeta.tsx +++ b/src/pages/sign/internal/displayMeta.tsx @@ -38,7 +38,7 @@ import { PdfFile } from '../../../types/drawing.ts' type DisplayMetaProps = { meta: Meta - files: { [filename: string]: PdfFile } + files: { [filename: string]: PdfFile | File } submittedBy: string signers: `npub1${string}`[] viewers: `npub1${string}`[] @@ -144,7 +144,14 @@ export const DisplayMeta = ({ }, [users, submittedBy, metadata]) const downloadFile = async (filename: string) => { - const arrayBuffer = await files[filename].file.arrayBuffer() + const file = files[filename] + + let arrayBuffer: ArrayBuffer + if ('pages' in file) { + arrayBuffer = await file.file.arrayBuffer() + } else { + arrayBuffer = await file.arrayBuffer() + } if (!arrayBuffer) return const blob = new Blob([arrayBuffer]) diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index 202064b..24bbc76 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -21,7 +21,8 @@ import { readContentOfZipEntry, signEventForMetaFile, shorten, - getCurrentUserFiles + getCurrentUserFiles, + extractFileExtension } from '../../utils' import styles from './style.module.scss' import { useLocation } from 'react-router-dom' @@ -32,7 +33,8 @@ import { convertToPdfBlob, convertToPdfFile, groupMarksByFileNamePage, - inPx + inPx, + toFile } from '../../utils/pdf.ts' import { State } from '../../store/rootReducer.ts' import { useSelector } from 'react-redux' @@ -85,41 +87,47 @@ const SlimPdfView = ({ ref={(el) => (pdfRefs.current[id] = el)} className={styles.fileWrapper} > - {pdfFile.pages.map((page, i) => { - const marks: Mark[] = [] + {'pages' in pdfFile ? ( + pdfFile.pages.map((page, i) => { + const marks: Mark[] = [] - signatureEvents.forEach((e) => { - const m = parsedSignatureEvents[ - e as `npub1${string}` - ].parsedContent?.marks.filter( - (m) => m.pdfFileHash == hash && m.location.page == i + signatureEvents.forEach((e) => { + const m = parsedSignatureEvents[ + e as `npub1${string}` + ].parsedContent?.marks.filter( + (m) => m.pdfFileHash == hash && m.location.page == i + ) + if (m) { + marks.push(...m) + } + }) + return ( +
+ + {marks.map((m) => { + return ( +
+ {m.value} +
+ ) + })} +
) - if (m) { - marks.push(...m) - } }) - return ( -
- - {marks.map((m) => { - return ( -
- {m.value} -
- ) - })} -
- ) - })} + ) : ( +
+ This is a {extractFileExtension(pdfFile.name)} file +
+ )}
{i < files.length - 1 && ( @@ -171,7 +179,7 @@ export const VerifyPage = () => { const [currentFileHashes, setCurrentFileHashes] = useState<{ [key: string]: string | null }>({}) - const [files, setFiles] = useState<{ [filename: string]: PdfFile }>({}) + const [files, setFiles] = useState<{ [filename: string]: PdfFile | File }>({}) const [currentFile, setCurrentFile] = useState(null) const [signatureFileHashes, setSignatureFileHashes] = useState<{ [key: string]: string @@ -230,7 +238,7 @@ export const VerifyPage = () => { if (!zip) return - const files: { [filename: string]: PdfFile } = {} + const files: { [filename: string]: PdfFile | File } = {} const fileHashes: { [key: string]: string | null } = {} const fileNames = Object.values(zip.files).map( (entry) => entry.name @@ -252,7 +260,11 @@ export const VerifyPage = () => { fileName! ) } catch (error) { - console.error('Not a .pdf file:', error) + files[fileName] = toFile( + arrayBuffer, + fileName, + 'application/' + extractFileExtension(fileName) + ) } const hash = await getHash(arrayBuffer) @@ -428,8 +440,13 @@ export const VerifyPage = () => { const marksByPage = groupMarksByFileNamePage(marks) for (const [fileName, pdf] of Object.entries(files)) { - const pages = await addMarks(pdf.file, marksByPage[fileName]) - const blob = await convertToPdfBlob(pages) + let blob: Blob + if ('pages' in pdf) { + const pages = await addMarks(pdf.file, marksByPage[fileName]) + blob = await convertToPdfBlob(pages) + } else { + blob = new Blob([pdf], { type: pdf.type }) + } zip.file(`files/${fileName}`, blob) } diff --git a/src/types/file.ts b/src/types/file.ts index cb1a7ff..bbb19b6 100644 --- a/src/types/file.ts +++ b/src/types/file.ts @@ -2,7 +2,7 @@ import { PdfFile } from './drawing.ts' export interface CurrentUserFile { id: number - pdfFile: PdfFile + pdfFile: PdfFile | File filename: string hash?: string isHashValid: boolean diff --git a/src/utils/file.ts b/src/utils/file.ts index 401d3c4..c50f2e9 100644 --- a/src/utils/file.ts +++ b/src/utils/file.ts @@ -6,15 +6,23 @@ import { PdfFile } from '../types/drawing.ts' const getZipWithFiles = async ( meta: Meta, - files: { [filename: string]: PdfFile } + files: { [filename: string]: PdfFile | File } ): Promise => { const zip = new JSZip() const marks = extractMarksFromSignedMeta(meta) const marksByFileNamePage = groupMarksByFileNamePage(marks) - for (const [fileName, pdf] of Object.entries(files)) { - const pages = await addMarks(pdf.file, marksByFileNamePage[fileName]) - const blob = await convertToPdfBlob(pages) + for (const [fileName, file] of Object.entries(files)) { + let blob: Blob + if ('pages' in file) { + // Handle PDF Files + const pages = await addMarks(file.file, marksByFileNamePage[fileName]) + blob = await convertToPdfBlob(pages) + } else { + // Handle other files + blob = new Blob([file], { type: file.type }) + } + zip.file(`files/${fileName}`, blob) } diff --git a/src/utils/pdf.ts b/src/utils/pdf.ts index ce2f132..05daa3e 100644 --- a/src/utils/pdf.ts +++ b/src/utils/pdf.ts @@ -30,10 +30,15 @@ const FONT_TYPE: string = 'Arial' * Converts a PDF ArrayBuffer to a generic PDF File * @param arrayBuffer of a PDF * @param fileName identifier of the pdf file + * @param type optional file type (defaults to pdf) */ -const toFile = (arrayBuffer: ArrayBuffer, fileName: string): File => { - const blob = new Blob([arrayBuffer], { type: 'application/pdf' }) - return new File([blob], fileName, { type: 'application/pdf' }) +const toFile = ( + arrayBuffer: ArrayBuffer, + fileName: string, + type: string = 'application/pdf' +): File => { + const blob = new Blob([arrayBuffer], { type }) + return new File([blob], fileName, { type }) } /** diff --git a/src/utils/utils.ts b/src/utils/utils.ts index bde528b..c16e232 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -75,7 +75,7 @@ export const timeout = (ms: number = 60000) => { * @param creatorFileHashes */ export const getCurrentUserFiles = ( - files: { [filename: string]: PdfFile }, + files: { [filename: string]: PdfFile | File }, fileHashes: { [key: string]: string | null }, creatorFileHashes: { [key: string]: string } ): CurrentUserFile[] => {