diff --git a/src/components/file-management-dialog/UppyDashboardDialog.jsx b/src/components/file-management-dialog/UppyDashboardDialog.jsx index 2ed7d9a..004b744 100644 --- a/src/components/file-management-dialog/UppyDashboardDialog.jsx +++ b/src/components/file-management-dialog/UppyDashboardDialog.jsx @@ -4,7 +4,8 @@ import "@uppy/image-editor/dist/style.min.css"; import { useEffect, useRef, useCallback } from "preact/hooks"; import { useUppyContext, useAppContext, useWorker } from "../../hooks"; -import czechLocale from "../../utils/czechLocale"; +import czechLocale from "../../utils/locales/czechLocale"; +import englishLocale from "../../utils/locales/englishLocale"; import { debugLogger } from "@uppy/core"; import { DashboardModal } from "@uppy/react"; @@ -56,7 +57,7 @@ const UppyDashboardDialog = ({ async (file) => { if (window.Worker) { if (isProcessing.current) { - this.uppy.info("Still processing previous file.", "info", 3000); + uppy.info(uppy.i18n("Still processing previous file."), "info", 3000); return; } // TODO: Alert error only in Debug @@ -73,19 +74,25 @@ const UppyDashboardDialog = ({ } catch (error) { isProcessing.current = false; uppy.info( - "There was an error when uploading file:\n" + error, + `${uppy.i18n("There was an error when uploading file")}:\n ${error}`, "error", 5000 ); } } else { - uppy.info("Web Worker is not supported", "info", 5000); + uppy.info(uppy.i18n("Web Worker is not supported"), "info", 5000); } }, [uppy, extractImageWorker, isProcessing] ); useEffect(() => { + const customLocale = locale?.startsWith("cs") ? + { + strings: Object.assign(cs_CZ.strings, czechLocale.strings) + } : { + strings: Object.assign(en_US.strings, englishLocale.strings) + } uppy.setOptions({ debug: debug, logger: debug @@ -97,7 +104,7 @@ const UppyDashboardDialog = ({ console.error(...args); }, }, - locale: locale?.startsWith("cs") ? cs_CZ : en_US, + locale: customLocale, restrictions: { allowedFileTypes: allowedFileTypes, }, @@ -123,9 +130,10 @@ const UppyDashboardDialog = ({ !modifyExistingFiles && autoExtractImagesFromPDFs ? // eslint-disable-next-line no-unused-vars (currentFile, _files) => { + console.log(currentFile, _files); if (currentFile.type === "application/pdf") { uppy.info( - "PDF image extraction processing, please wait...", + uppy.i18n("PDF image extraction processing, please wait..."), "info", 3000 ); @@ -200,7 +208,7 @@ const UppyDashboardDialog = ({ }) .catch((error) => { uppy.info({ - message: "Error loading files.", + message: uppy.i18n("Error loading files."), details: error.message, }, "error", 7000); }) @@ -253,13 +261,13 @@ const UppyDashboardDialog = ({ extractImageWorker.onmessage = (event) => { if (event.data?.type === "done") { isProcessing.current = false; - uppy.info("Image extraction completed.", "success", 3000); + uppy.info(`[${event.data.sourcePdf}] ${uppy.i18n("Image extraction completed")}. ${uppy.i18n("Image count")}: ${event.data.imageCount}`, "success", 5000); return; } else if (event.data?.type === "error") { isProcessing.current = false; uppy.info( { - message: `Error extracting images from ${event.data.sourcePdf}`, + message: `${uppy.i18n("Error extracting images from")}: ${event.data.sourcePdf}`, details: `${event.data.message}`, }, "error", @@ -287,10 +295,15 @@ const UppyDashboardDialog = ({ alert("Error: " + event.message); }; } else { - uppy.info("Web Worker is not supported.", "error", 5000); + uppy.info(uppy.i18n("Web Worker is not supported"), "error", 5000); } }, [extractImageWorker, uppy, debug]); + const manualI18n = (key) => { + const localeStrings = locale?.startsWith("cs") ? czechLocale.strings : englishLocale.strings; + return localeStrings[key]; + } + return ( <> { @@ -315,12 +328,12 @@ const UppyDashboardDialog = ({ if (file.type.startsWith("image/")) { fields.push({ id: "caption", - name: "Caption", - placeholder: "Set the Caption here", + name: manualI18n("Caption"), + placeholder: manualI18n("Set the Caption here"), }); fields.push({ id: "featureImage", - name: "Feature Image", + name: manualI18n("Feature Image"), render: ({ value, onChange, required, form }, h) => { return h("input", { type: "checkbox", diff --git a/src/utils/czechLocale.js b/src/utils/czechLocale.js deleted file mode 100644 index f3c5069..0000000 --- a/src/utils/czechLocale.js +++ /dev/null @@ -1,8 +0,0 @@ -export default { - strings: { - noSearchResults: "Pro vaše hledání nejsou k dispozici žádné výsledky.", - selectPdfs: "Vyberte soubory PDF, ze kterých chcete extrahovat obrázky.", - uploadStalled: "Nahrávání neproběhlo po dobu %{seconds} sekund. Možná jej budete chtít zopakovat.", - }, - }; - \ No newline at end of file diff --git a/src/utils/locales/czechLocale.js b/src/utils/locales/czechLocale.js new file mode 100644 index 0000000..94412c9 --- /dev/null +++ b/src/utils/locales/czechLocale.js @@ -0,0 +1,20 @@ +export default { + strings: { + noSearchResults: "Pro vaše hledání nejsou k dispozici žádné výsledky.", + selectPdfs: "Vyberte soubory PDF, ze kterých chcete extrahovat obrázky.", + uploadStalled: "Nahrávání neproběhlo po dobu %{seconds} sekund. Možná jej budete chtít zopakovat.", + "Still processing previous file.": "Stále zpracováváme předchozí soubor.", + "PDF image extraction processing, please wait...": "Zpracování extrakce obrázků z PDF, počkejte prosím...", + "There was an error when uploading file": "Při nahrávání souboru došlo k chybě", + "Web Worker is not supported": "Web Worker není podporován", + "Error loading files.": "Chyba při načítání souborů.", + "Image extraction completed": "Extrakce obrázků dokončena", + "Image count": "Počet obrázků", + "Error extracting images from": "Chyba při extrakci obrázků z", + "Select existing files to modify metadata.": "Vyberte existující soubory pro úpravu metadat.", + "Select files to upload.": "Vyberte soubory, které chcete nahrát.", + "Set the Caption here": "Zde nastavte Titulek", + "Caption": "Titulek", + "Feature Image": "Hlavní obrázek" + }, +}; diff --git a/src/utils/locales/englishLocale.js b/src/utils/locales/englishLocale.js new file mode 100644 index 0000000..c1bbd94 --- /dev/null +++ b/src/utils/locales/englishLocale.js @@ -0,0 +1,17 @@ +export default { + strings: { + "Still processing previous file.": "Still processing previous file.", + "PDF image extraction processing, please wait...": "PDF image extraction processing, please wait...", + "There was an error when uploading file": "There was an error when uploading file", + "Web Worker is not supported": "Web Worker is not supported", + "Error loading files.": "Error loading files.", + "Image extraction completed": "Image extraction completed", + "Image count": "Image count", + "Error extracting images from": "Error extracting images from", + "Select existing files to modify metadata.": "Select existing files to modify metadata.", + "Select files to upload.": "Select files to upload.", + "Set the Caption here": "Set the Caption here", + "Caption": "Caption", + "Feature Image": "Feature Image", + }, +}; diff --git a/src/utils/pdf-extract-images.js b/src/utils/pdf-extract-images.js index 3eabec7..d4cb2eb 100644 --- a/src/utils/pdf-extract-images.js +++ b/src/utils/pdf-extract-images.js @@ -204,4 +204,6 @@ export default async function extractPdfImages(pdfFileName, pdfBytes) { postMessage(imageObj, [imageObj.imageData.buffer]); } } + + return imagesInDoc.length; } diff --git a/src/workers/extract-images-worker.js b/src/workers/extract-images-worker.js index c68a658..9a535cc 100644 --- a/src/workers/extract-images-worker.js +++ b/src/workers/extract-images-worker.js @@ -3,8 +3,8 @@ import extractPdfImages from "../utils/pdf-extract-images.js"; addEventListener("message", async (event) => { const { pdfFileName, data } = event.data; try { - await extractPdfImages(pdfFileName, data); - postMessage({ type: "done" }); + const imageCount = await extractPdfImages(pdfFileName, data); + postMessage({ type: "done", imageCount: imageCount, sourcePdf: pdfFileName }); } catch (error) { postMessage({ type: "error", message: error.message, sourcePdf: pdfFileName }); console.error(error); diff --git a/todo.md b/todo.md deleted file mode 100644 index 10d7ab7..0000000 --- a/todo.md +++ /dev/null @@ -1,98 +0,0 @@ -Issue: - -Implement React file-input based component, that: -- displays a button that allows user to pick a PDF file -- scans the file for any web-compatible embedded images/graphics (JPG, PNG, SVG, TIFF?) -- extract found images data (optionally/where possible, also extract image captions) -- displays a grid of images found in a file: - - only with images larger than a configurable threshold of a few pixels - - grouped by PDF page on which they appeared - - each grid item shows editable caption with extracted caption value (user can also provide his own caption here) -- lets user select, which images should be uploaded, the rest will be ignored -- when user clicks "Upload {n} images" submit button, it calls the (mocked) upload function passing selected image data & metadata - -- For PDF scanning, use PDF.js library or similar. -- Account for displaying processing & error states. -- Consider using webworkers to optimize for possibly long running tasks (scanning & extraction). - -1. How to extract image captions from .pdf? - - Metadata? - - OCR? - - Under-image text? -2. What's the policy about external libraries? - - PDF.js is a big library - - must handle different file types, alpha channels, svg, buffers manually - - base64 encoding - - https://www.npmjs.com/package/pdf-img-convert - - https://www.npmjs.com/package/pdf-extractor -3. What's the metadata of a image? (caption, page, size, type, name, ...) - - caption, page - -Bugs: -Computer-organization-and-design.pdf: -``` -Uncaught (in promise) TypeError: Cannot read properties of undefined (reading '0') - at pdf-extract-images.js:146:49 - at new Promise () - at savePng (pdf-extract-images.js:106:5) - at Module.extractPdfImages (pdf-extract-images.js:189:27) - at async self.onmessage (extract-images-worker.js?type=classic&worker_file:6:3) -``` - - -## TODO -1. key that already exist - update - - for images -2. Upload process: - - New images: - - Upload photos btn - - change metadata: - - deselected - - modal: do you want to delete the image? - - when clicked on image - - save changes - - IIIF - smaller images for preview - -### 8.8.2023 -- ImageSelection outputs only selected images -- alert with semantic ui alerts -- FullScreen preview for ImageCard component - - -## 17.8.2023 -- Add Metadata modifier. -- NPM package - create react library -- Functional decomposition for FileManagementDialog component - - extract based props - -## 24.8.2023 -- BUG: handle metadata upload from OARepoUpload plugin - - revise key-value pairs -```json -{ - "key": "test_pattern.png", - "updated": "2020-11-27 11:17:11.002624", - "created": "2020-11-27 11:17:10.998919", - "metadata": { - "relativePath": null, // should be removed - "name": "test_pattern.png", // should be removed - "type": "image/png", // should be removed - "caption": "test pattern", - "featureImage": true - }, - "status": "pending", - "links": { - "content": "/api/records/8t29q-nfr77/draft/files/test_pattern.png/content", - "self": "/api/records/8t29q-nfr77/draft/files/test_pattern.png", - "commit": "/api/records/8t29q-nfr77/draft/files/test_pattern.png/commit" - } -} -``` - -# 15.11.2023 - -BUGS: -1. when PDF is invalid, Uppy Error occurs after another PDF upload and another PDF cannot be uploaded -2. use api record.links.files instead of record.files -3. onClick on TriggerComponent -4. \ No newline at end of file