Merge pull request #565 from Skillkiller/translate-pdf-to-image

Implement missing i18n translations for PDF-to-Image modules
This commit is contained in:
Alam
2026-03-24 11:55:11 +05:30
committed by GitHub
27 changed files with 287 additions and 96 deletions

View File

@@ -250,11 +250,13 @@
"add": "Hinzufügen", "add": "Hinzufügen",
"remove": "Entfernen", "remove": "Entfernen",
"loading": "Laden...", "loading": "Laden...",
"loadingPageCount": "Seitenanzahl wird geladen...",
"error": "Fehler", "error": "Fehler",
"success": "Erfolgreich", "success": "Erfolgreich",
"file": "Datei", "file": "Datei",
"files": "Dateien", "files": "Dateien",
"close": "Schließen" "close": "Schließen",
"convert": "Konvertieren"
}, },
"about": { "about": {
"hero": { "hero": {

View File

@@ -263,23 +263,84 @@
}, },
"pdfToJpg": { "pdfToJpg": {
"name": "PDF zu JPG", "name": "PDF zu JPG",
"subtitle": "Jede PDF-Seite in ein JPG-Bild konvertieren." "subtitle": "Jede PDF-Seite in ein JPG-Bild konvertieren.",
"imageQuality": "Bildqualität",
"imageQualityExplanation": "Höhere Qualität = größere Dateigröße",
"alert": {
"invalidFile": "Ungültige Datei",
"invalidFileExplanation": "Bitte wähle eine PDF Datei aus.",
"noFile": "Keine Datei",
"noFileExplanation": "Bitte lade zuerst eine PDF-Datei hoch.",
"conversionSuccess": "PDF erfolgreich in JPGs konvertiert!",
"conversionError": "Konvertierung in JPG fehlgeschlagen. Die Datei könnte beschädigt sein."
},
"loader": {
"converting": "Wird in JPG konvertiert..."
}
}, },
"pdfToPng": { "pdfToPng": {
"name": "PDF zu PNG", "name": "PDF zu PNG",
"subtitle": "Jede PDF-Seite in ein PNG-Bild konvertieren." "subtitle": "Jede PDF-Seite in ein PNG-Bild konvertieren.",
"imageScale": "Bildskalierung",
"imageScaleExplanation": "Höhere Skalierung = bessere Qualität, aber größere Dateigröße",
"alert": {
"invalidFile": "Ungültige Datei",
"invalidFileExplanation": "Bitte wähle eine PDF Datei aus.",
"noFile": "Keine Datei",
"noFileExplanation": "Bitte lade zuerst eine PDF-Datei hoch.",
"conversionSuccess": "PDF erfolgreich in PNGs konvertiert!",
"conversionError": "Konvertierung in PNG fehlgeschlagen. Die Datei könnte beschädigt sein."
},
"loader": {
"converting": "Wird in PNG konvertiert..."
}
}, },
"pdfToWebp": { "pdfToWebp": {
"name": "PDF zu WebP", "name": "PDF zu WebP",
"subtitle": "Jede PDF-Seite in ein WebP-Bild konvertieren." "subtitle": "Jede PDF-Seite in ein WebP-Bild konvertieren.",
"imageQuality": "Bildqualität",
"imageQualityExplanation": "Höhere Qualität = größere Dateigröße",
"alert": {
"invalidFile": "Ungültige Datei",
"invalidFileExplanation": "Bitte wähle eine PDF Datei aus.",
"noFile": "Keine Datei",
"noFileExplanation": "Bitte lade zuerst eine PDF-Datei hoch.",
"conversionSuccess": "PDF erfolgreich in WebPs konvertiert!",
"conversionError": "Konvertierung in WebP fehlgeschlagen. Die Datei könnte beschädigt sein."
},
"loader": {
"converting": "Wird in WebP konvertiert..."
}
}, },
"pdfToBmp": { "pdfToBmp": {
"name": "PDF zu BMP", "name": "PDF zu BMP",
"subtitle": "Jede PDF-Seite in ein BMP-Bild konvertieren." "subtitle": "Jede PDF-Seite in ein BMP-Bild konvertieren.",
"alert": {
"invalidFile": "Ungültige Datei",
"invalidFileExplanation": "Bitte wähle eine PDF Datei aus.",
"noFile": "Keine Datei",
"noFileExplanation": "Bitte lade zuerst eine PDF-Datei hoch.",
"conversionSuccess": "PDF erfolgreich in BMPs konvertiert!",
"conversionError": "Konvertierung in BMP fehlgeschlagen. Die Datei könnte beschädigt sein."
},
"loader": {
"converting": "Wird in BMP konvertiert..."
}
}, },
"pdfToTiff": { "pdfToTiff": {
"name": "PDF zu TIFF", "name": "PDF zu TIFF",
"subtitle": "Jede PDF-Seite in ein TIFF-Bild konvertieren." "subtitle": "Jede PDF-Seite in ein TIFF-Bild konvertieren.",
"alert": {
"invalidFile": "Ungültige Datei",
"invalidFileExplanation": "Bitte wähle eine PDF Datei aus.",
"noFile": "Keine Datei",
"noFileExplanation": "Bitte lade zuerst eine PDF-Datei hoch.",
"conversionSuccess": "PDF erfolgreich in TIFFs konvertiert!",
"conversionError": "Konvertierung in TIFF fehlgeschlagen. Die Datei könnte beschädigt sein."
},
"loader": {
"converting": "Wird in TIFF konvertiert..."
}
}, },
"pdfToGreyscale": { "pdfToGreyscale": {
"name": "PDF zu Graustufen", "name": "PDF zu Graustufen",

View File

@@ -260,11 +260,13 @@
"add": "Add", "add": "Add",
"remove": "Remove", "remove": "Remove",
"loading": "Loading...", "loading": "Loading...",
"loadingPageCount": "Loading pages...",
"error": "Error", "error": "Error",
"success": "Success", "success": "Success",
"file": "File", "file": "File",
"files": "Files", "files": "Files",
"close": "Close" "close": "Close",
"convert": "Convert"
}, },
"about": { "about": {
"hero": { "hero": {

View File

@@ -263,23 +263,84 @@
}, },
"pdfToJpg": { "pdfToJpg": {
"name": "PDF to JPG", "name": "PDF to JPG",
"subtitle": "Convert each PDF page into a JPG image." "subtitle": "Convert each PDF page into a JPG image.",
"imageQuality": "Image Quality",
"imageQualityExplanation": "Higher quality = larger file size",
"alert": {
"invalidFile": "Invalid File",
"invalidFileExplanation": "Please upload a PDF file.",
"noFile": "No File",
"noFileExplanation": "Please upload a PDF file first.",
"conversionSuccess": "PDF converted to JPGs successfully!",
"conversionError": "Failed to convert PDF to JPG. The file might be corrupted."
},
"loader": {
"converting": "Converting to JPG..."
}
}, },
"pdfToPng": { "pdfToPng": {
"name": "PDF to PNG", "name": "PDF to PNG",
"subtitle": "Convert each PDF page into a PNG image." "subtitle": "Convert each PDF page into a PNG image.",
"imageScale": "Image Scale",
"imageScaleExplanation": "Higher scale = better quality but larger file size",
"alert": {
"invalidFile": "Invalid File",
"invalidFileExplanation": "Please upload a PDF file.",
"noFile": "No File",
"noFileExplanation": "Please upload a PDF file first.",
"conversionSuccess": "PDF converted to PNGs successfully!",
"conversionError": "Failed to convert PDF to PNG. The file might be corrupted."
},
"loader": {
"converting": "Converting to PNG..."
}
}, },
"pdfToWebp": { "pdfToWebp": {
"name": "PDF to WebP", "name": "PDF to WebP",
"subtitle": "Convert each PDF page into a WebP image." "subtitle": "Convert each PDF page into a WebP image.",
"imageQuality": "Image Quality",
"imageQualityExplanation": "Higher quality = larger file size",
"alert": {
"invalidFile": "Invalid File",
"invalidFileExplanation": "Please upload a PDF file.",
"noFile": "No File",
"noFileExplanation": "Please upload a PDF file first.",
"conversionSuccess": "PDF converted to WebPs successfully!",
"conversionError": "Failed to convert PDF to WebP. The file might be corrupted."
},
"loader": {
"converting": "Converting to WebP..."
}
}, },
"pdfToBmp": { "pdfToBmp": {
"name": "PDF to BMP", "name": "PDF to BMP",
"subtitle": "Convert each PDF page into a BMP image." "subtitle": "Convert each PDF page into a BMP image.",
"alert": {
"invalidFile": "Invalid File",
"invalidFileExplanation": "Please upload a PDF file.",
"noFile": "No File",
"noFileExplanation": "Please upload a PDF file first.",
"conversionSuccess": "PDF converted to BMPs successfully!",
"conversionError": "Failed to convert PDF to BMP. The file might be corrupted."
},
"loader": {
"converting": "Converting to BMP..."
}
}, },
"pdfToTiff": { "pdfToTiff": {
"name": "PDF to TIFF", "name": "PDF to TIFF",
"subtitle": "Convert each PDF page into a TIFF image." "subtitle": "Convert each PDF page into a TIFF image.",
"alert": {
"invalidFile": "Invalid File",
"invalidFileExplanation": "Please upload a PDF file.",
"noFile": "No File",
"noFileExplanation": "Please upload a PDF file first.",
"conversionSuccess": "PDF converted to TIFFs successfully!",
"conversionError": "Failed to convert PDF to TIFF. The file might be corrupted."
},
"loader": {
"converting": "Converting to TIFF..."
}
}, },
"pdfToGreyscale": { "pdfToGreyscale": {
"name": "PDF to Greyscale", "name": "PDF to Greyscale",

View File

@@ -10,6 +10,7 @@ import { PDFDocument } from 'pdf-lib';
import { applyColorAdjustments } from '../utils/image-effects.js'; import { applyColorAdjustments } from '../utils/image-effects.js';
import * as pdfjsLib from 'pdfjs-dist'; import * as pdfjsLib from 'pdfjs-dist';
import type { AdjustColorsSettings } from '../types/adjust-colors-type.js'; import type { AdjustColorsSettings } from '../types/adjust-colors-type.js';
import { t } from '../i18n/i18n';
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL( pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
'pdfjs-dist/build/pdf.worker.min.mjs', 'pdfjs-dist/build/pdf.worker.min.mjs',
@@ -123,7 +124,7 @@ const updateUI = () => {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(file.size)}Loading pages...`; metaSpan.textContent = `${formatBytes(file.size)}${t('common.loadingPageCount')}`;
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);
@@ -146,7 +147,7 @@ const updateUI = () => {
return getPDFDocument(buffer).promise; return getPDFDocument(buffer).promise;
}) })
.then((pdf: pdfjsLib.PDFDocumentProxy) => { .then((pdf: pdfjsLib.PDFDocumentProxy) => {
metaSpan.textContent = `${formatBytes(file.size)}${pdf.numPages} page${pdf.numPages !== 1 ? 's' : ''}`; metaSpan.textContent = `${formatBytes(file.size)}${pdf.numPages} ${pdf.numPages !== 1 ? t('common.pages') : t('common.page')}`;
}) })
.catch(() => { .catch(() => {
metaSpan.textContent = formatBytes(file.size); metaSpan.textContent = formatBytes(file.size);

View File

@@ -1,6 +1,7 @@
import { createIcons, icons } from 'lucide'; import { createIcons, icons } from 'lucide';
import { showAlert, showLoader, hideLoader } from '../ui.js'; import { showAlert, showLoader, hideLoader } from '../ui.js';
import { readFileAsArrayBuffer, formatBytes, downloadFile, getPDFDocument } from '../utils/helpers.js'; import { readFileAsArrayBuffer, formatBytes, downloadFile, getPDFDocument } from '../utils/helpers.js';
import { t } from '../i18n/i18n';
import { import {
signPdf, signPdf,
parsePfxFile, parsePfxFile,
@@ -253,7 +254,7 @@ async function updatePdfDisplay(): Promise<void> {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(state.pdfFile.size)}Loading pages...`; metaSpan.textContent = `${formatBytes(state.pdfFile.size)}${t('common.loadingPageCount')}`;
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);

View File

@@ -1,4 +1,5 @@
import { showLoader, hideLoader, showAlert } from '../ui.js'; import { showLoader, hideLoader, showAlert } from '../ui.js';
import { t } from '../i18n/i18n';
import { import {
downloadFile, downloadFile,
readFileAsArrayBuffer, readFileAsArrayBuffer,
@@ -66,7 +67,7 @@ document.addEventListener('DOMContentLoaded', () => {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(file.size)}Loading pages...`; metaSpan.textContent = `${formatBytes(file.size)}${t('common.loadingPageCount')}`;
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);

View File

@@ -1,4 +1,5 @@
import { showLoader, hideLoader, showAlert } from '../ui.js'; import { showLoader, hideLoader, showAlert } from '../ui.js';
import { t } from '../i18n/i18n';
import { import {
downloadFile, downloadFile,
readFileAsArrayBuffer, readFileAsArrayBuffer,
@@ -60,7 +61,7 @@ document.addEventListener('DOMContentLoaded', () => {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(currentFile.size)}Loading pages...`; metaSpan.textContent = `${formatBytes(currentFile.size)}${t('common.loadingPageCount')}`;
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);

View File

@@ -10,6 +10,7 @@ import { createIcons, icons } from 'lucide';
import JSZip from 'jszip'; import JSZip from 'jszip';
import * as pdfjsLib from 'pdfjs-dist'; import * as pdfjsLib from 'pdfjs-dist';
import { PDFPageProxy } from 'pdfjs-dist'; import { PDFPageProxy } from 'pdfjs-dist';
import { t } from '../i18n/i18n';
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL( pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
'pdfjs-dist/build/pdf.worker.min.mjs', 'pdfjs-dist/build/pdf.worker.min.mjs',
@@ -44,7 +45,7 @@ const updateUI = () => {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(file.size)}Loading pages...`; // Initial state metaSpan.textContent = `${formatBytes(file.size)}${t('common.loadingPageCount')}`; // Initial state
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);
@@ -67,7 +68,7 @@ const updateUI = () => {
return getPDFDocument(buffer).promise; return getPDFDocument(buffer).promise;
}) })
.then((pdf) => { .then((pdf) => {
metaSpan.textContent = `${formatBytes(file.size)}${pdf.numPages} page${pdf.numPages !== 1 ? 's' : ''}`; metaSpan.textContent = `${formatBytes(file.size)}${pdf.numPages} ${pdf.numPages !== 1 ? t('common.pages') : t('common.page')}`;
}) })
.catch((e) => { .catch((e) => {
console.warn('Error loading PDF page count:', e); console.warn('Error loading PDF page count:', e);
@@ -91,10 +92,13 @@ const resetState = () => {
async function convert() { async function convert() {
if (files.length === 0) { if (files.length === 0) {
showAlert('No File', 'Please upload a PDF file first.'); showAlert(
t('tools:pdfToBmp.alert.noFile'),
t('tools:pdfToBmp.alert.noFileExplanation')
);
return; return;
} }
showLoader('Converting to BMP...'); showLoader(t('tools:pdfToBmp.loader.converting'));
try { try {
const pdf = await getPDFDocument(await readFileAsArrayBuffer(files[0])) const pdf = await getPDFDocument(await readFileAsArrayBuffer(files[0]))
.promise; .promise;
@@ -118,8 +122,8 @@ async function convert() {
} }
showAlert( showAlert(
'Success', t('common.success'),
'PDF converted to BMPs successfully!', t('tools:pdfToBmp.alert.conversionSuccess'),
'success', 'success',
() => { () => {
resetState(); resetState();
@@ -127,10 +131,7 @@ async function convert() {
); );
} catch (e) { } catch (e) {
console.error(e); console.error(e);
showAlert( showAlert(t('common.error'), t('tools:pdfToBmp.alert.conversionError'));
'Error',
'Failed to convert PDF to BMP. The file might be corrupted.'
);
} finally { } finally {
hideLoader(); hideLoader();
} }
@@ -174,7 +175,10 @@ document.addEventListener('DOMContentLoaded', () => {
); );
if (validFiles.length === 0) { if (validFiles.length === 0) {
showAlert('Invalid File', 'Please upload a PDF file.'); showAlert(
t('tools:pdfToBmp.alert.invalidFile'),
t('tools:pdfToBmp.alert.invalidFileExplanation')
);
return; return;
} }

View File

@@ -1,4 +1,5 @@
import { showLoader, hideLoader, showAlert } from '../ui.js'; import { showLoader, hideLoader, showAlert } from '../ui.js';
import { t } from '../i18n/i18n';
import { import {
downloadFile, downloadFile,
readFileAsArrayBuffer, readFileAsArrayBuffer,
@@ -50,7 +51,7 @@ document.addEventListener('DOMContentLoaded', () => {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(file.size)}Loading pages...`; metaSpan.textContent = `${formatBytes(file.size)}${t('common.loadingPageCount')}`;
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);

View File

@@ -9,6 +9,7 @@ import { createIcons, icons } from 'lucide';
import { PDFDocument } from 'pdf-lib'; import { PDFDocument } from 'pdf-lib';
import { applyGreyscale } from '../utils/image-effects.js'; import { applyGreyscale } from '../utils/image-effects.js';
import * as pdfjsLib from 'pdfjs-dist'; import * as pdfjsLib from 'pdfjs-dist';
import { t } from '../i18n/i18n';
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL( pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
'pdfjs-dist/build/pdf.worker.min.mjs', 'pdfjs-dist/build/pdf.worker.min.mjs',
@@ -44,7 +45,7 @@ const updateUI = () => {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(file.size)}Loading pages...`; // Initial state metaSpan.textContent = `${formatBytes(file.size)}${t('common.loadingPageCount')}`; // Initial state
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);
@@ -66,7 +67,7 @@ const updateUI = () => {
return getPDFDocument(buffer).promise; return getPDFDocument(buffer).promise;
}) })
.then((pdf) => { .then((pdf) => {
metaSpan.textContent = `${formatBytes(file.size)}${pdf.numPages} page${pdf.numPages !== 1 ? 's' : ''}`; metaSpan.textContent = `${formatBytes(file.size)}${pdf.numPages} ${pdf.numPages !== 1 ? t('common.pages') : t('common.page')}`;
}) })
.catch((e) => { .catch((e) => {
console.warn('Error loading PDF page count:', e); console.warn('Error loading PDF page count:', e);

View File

@@ -10,6 +10,7 @@ import { createIcons, icons } from 'lucide';
import JSZip from 'jszip'; import JSZip from 'jszip';
import * as pdfjsLib from 'pdfjs-dist'; import * as pdfjsLib from 'pdfjs-dist';
import { PDFPageProxy } from 'pdfjs-dist'; import { PDFPageProxy } from 'pdfjs-dist';
import { t } from '../i18n/i18n';
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL( pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
'pdfjs-dist/build/pdf.worker.min.mjs', 'pdfjs-dist/build/pdf.worker.min.mjs',
@@ -44,7 +45,7 @@ const updateUI = () => {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(file.size)}Loading pages...`; // Initial state metaSpan.textContent = `${formatBytes(file.size)}${t('common.loadingPageCount')}`; // Initial state
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);
@@ -66,7 +67,7 @@ const updateUI = () => {
return getPDFDocument(buffer).promise; return getPDFDocument(buffer).promise;
}) })
.then((pdf) => { .then((pdf) => {
metaSpan.textContent = `${formatBytes(file.size)}${pdf.numPages} page${pdf.numPages !== 1 ? 's' : ''}`; metaSpan.textContent = `${formatBytes(file.size)}${pdf.numPages} ${pdf.numPages !== 1 ? t('common.pages') : t('common.page')}`;
}) })
.catch((e) => { .catch((e) => {
console.warn('Error loading PDF page count:', e); console.warn('Error loading PDF page count:', e);
@@ -96,10 +97,13 @@ const resetState = () => {
async function convert() { async function convert() {
if (files.length === 0) { if (files.length === 0) {
showAlert('No File', 'Please upload a PDF file first.'); showAlert(
t('tools:pdfToJpg.alert.noFile'),
t('tools:pdfToJpg.alert.noFileExplanation')
);
return; return;
} }
showLoader('Converting to JPG...'); showLoader(t('tools:pdfToJpg.loader.converting'));
try { try {
const pdf = await getPDFDocument(await readFileAsArrayBuffer(files[0])) const pdf = await getPDFDocument(await readFileAsArrayBuffer(files[0]))
.promise; .promise;
@@ -128,8 +132,8 @@ async function convert() {
} }
showAlert( showAlert(
'Success', t('common.success'),
'PDF converted to JPGs successfully!', t('tools:pdfToJpg.alert.conversionSuccess'),
'success', 'success',
() => { () => {
resetState(); resetState();
@@ -137,10 +141,7 @@ async function convert() {
); );
} catch (e) { } catch (e) {
console.error(e); console.error(e);
showAlert( showAlert(t('common.error'), t('tools:pdfToJpg.alert.conversionError'));
'Error',
'Failed to convert PDF to JPG. The file might be corrupted.'
);
} finally { } finally {
hideLoader(); hideLoader();
} }
@@ -197,7 +198,10 @@ document.addEventListener('DOMContentLoaded', () => {
); );
if (validFiles.length === 0) { if (validFiles.length === 0) {
showAlert('Invalid File', 'Please upload a PDF file.'); showAlert(
t('tools:pdfToJpg.alert.invalidFile'),
t('tools:pdfToJpg.alert.invalidFileExplanation')
);
return; return;
} }

View File

@@ -1,4 +1,5 @@
import { showLoader, hideLoader, showAlert } from '../ui.js'; import { showLoader, hideLoader, showAlert } from '../ui.js';
import { t } from '../i18n/i18n';
import { import {
downloadFile, downloadFile,
readFileAsArrayBuffer, readFileAsArrayBuffer,
@@ -53,7 +54,7 @@ document.addEventListener('DOMContentLoaded', () => {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(file.size)}Loading pages...`; metaSpan.textContent = `${formatBytes(file.size)}${t('common.loadingPageCount')}`;
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);

View File

@@ -1,4 +1,5 @@
import { showLoader, hideLoader, showAlert } from '../ui.js'; import { showLoader, hideLoader, showAlert } from '../ui.js';
import { t } from '../i18n/i18n';
import { import {
downloadFile, downloadFile,
readFileAsArrayBuffer, readFileAsArrayBuffer,
@@ -53,7 +54,7 @@ document.addEventListener('DOMContentLoaded', () => {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(file.size)}Loading pages...`; metaSpan.textContent = `${formatBytes(file.size)}${t('common.loadingPageCount')}`;
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);

View File

@@ -10,6 +10,7 @@ import { createIcons, icons } from 'lucide';
import JSZip from 'jszip'; import JSZip from 'jszip';
import * as pdfjsLib from 'pdfjs-dist'; import * as pdfjsLib from 'pdfjs-dist';
import { PDFPageProxy } from 'pdfjs-dist'; import { PDFPageProxy } from 'pdfjs-dist';
import { t } from '../i18n/i18n';
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL( pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
'pdfjs-dist/build/pdf.worker.min.mjs', 'pdfjs-dist/build/pdf.worker.min.mjs',
@@ -44,7 +45,7 @@ const updateUI = () => {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(file.size)}Loading pages...`; // Initial state metaSpan.textContent = `${formatBytes(file.size)}${t('common.loadingPageCount')}`; // Initial state
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);
@@ -66,7 +67,7 @@ const updateUI = () => {
return getPDFDocument(buffer).promise; return getPDFDocument(buffer).promise;
}) })
.then((pdf) => { .then((pdf) => {
metaSpan.textContent = `${formatBytes(file.size)}${pdf.numPages} page${pdf.numPages !== 1 ? 's' : ''}`; metaSpan.textContent = `${formatBytes(file.size)}${pdf.numPages} ${pdf.numPages !== 1 ? t('common.pages') : t('common.page')}`;
}) })
.catch((e) => { .catch((e) => {
console.warn('Error loading PDF page count:', e); console.warn('Error loading PDF page count:', e);
@@ -94,10 +95,13 @@ const resetState = () => {
async function convert() { async function convert() {
if (files.length === 0) { if (files.length === 0) {
showAlert('No File', 'Please upload a PDF file first.'); showAlert(
t('tools:pdfToPng.alert.noFile'),
t('tools:pdfToPng.alert.noFileExplanation')
);
return; return;
} }
showLoader('Converting to PNG...'); showLoader(t('tools:pdfToPng.loader.converting'));
try { try {
const pdf = await getPDFDocument(await readFileAsArrayBuffer(files[0])) const pdf = await getPDFDocument(await readFileAsArrayBuffer(files[0]))
.promise; .promise;
@@ -124,8 +128,8 @@ async function convert() {
} }
showAlert( showAlert(
'Success', t('common.success'),
'PDF converted to PNGs successfully!', t('tools:pdfToPng.alert.conversionSuccess'),
'success', 'success',
() => { () => {
resetState(); resetState();
@@ -133,10 +137,7 @@ async function convert() {
); );
} catch (e) { } catch (e) {
console.error(e); console.error(e);
showAlert( showAlert(t('common.error'), t('tools:pdfToPng.alert.conversionError'));
'Error',
'Failed to convert PDF to PNG. The file might be corrupted.'
);
} finally { } finally {
hideLoader(); hideLoader();
} }
@@ -191,7 +192,10 @@ document.addEventListener('DOMContentLoaded', () => {
); );
if (validFiles.length === 0) { if (validFiles.length === 0) {
showAlert('Invalid File', 'Please upload a PDF file.'); showAlert(
t('tools:pdfToPng.alert.invalidFile'),
t('tools:pdfToPng.alert.invalidFileExplanation')
);
return; return;
} }

View File

@@ -11,6 +11,7 @@ import JSZip from 'jszip';
import * as pdfjsLib from 'pdfjs-dist'; import * as pdfjsLib from 'pdfjs-dist';
import UTIF from 'utif'; import UTIF from 'utif';
import { PDFPageProxy } from 'pdfjs-dist'; import { PDFPageProxy } from 'pdfjs-dist';
import { t } from '../i18n/i18n';
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL( pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
'pdfjs-dist/build/pdf.worker.min.mjs', 'pdfjs-dist/build/pdf.worker.min.mjs',
@@ -45,7 +46,7 @@ const updateUI = () => {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(file.size)}Loading pages...`; // Initial state metaSpan.textContent = `${formatBytes(file.size)}${t('common.loadingPageCount')}`; // Initial state
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);
@@ -67,7 +68,7 @@ const updateUI = () => {
return getPDFDocument(buffer).promise; return getPDFDocument(buffer).promise;
}) })
.then((pdf) => { .then((pdf) => {
metaSpan.textContent = `${formatBytes(file.size)}${pdf.numPages} page${pdf.numPages !== 1 ? 's' : ''}`; metaSpan.textContent = `${formatBytes(file.size)}${pdf.numPages} ${pdf.numPages !== 1 ? t('common.pages') : t('common.page')}`;
}) })
.catch((e) => { .catch((e) => {
console.warn('Error loading PDF page count:', e); console.warn('Error loading PDF page count:', e);
@@ -91,10 +92,13 @@ const resetState = () => {
async function convert() { async function convert() {
if (files.length === 0) { if (files.length === 0) {
showAlert('No File', 'Please upload a PDF file first.'); showAlert(
t('tools:pdfToTiff.alert.noFile'),
t('tools:pdfToTiff.alert.noFileExplanation')
);
return; return;
} }
showLoader('Converting to TIFF...'); showLoader(t('tools:pdfToTiff.loader.converting'));
try { try {
const pdf = await getPDFDocument(await readFileAsArrayBuffer(files[0])) const pdf = await getPDFDocument(await readFileAsArrayBuffer(files[0]))
.promise; .promise;
@@ -121,8 +125,8 @@ async function convert() {
} }
showAlert( showAlert(
'Success', t('common.success'),
'PDF converted to TIFFs successfully!', t('tools:pdfToTiff.alert.conversionSuccess'),
'success', 'success',
() => { () => {
resetState(); resetState();
@@ -130,10 +134,7 @@ async function convert() {
); );
} catch (e) { } catch (e) {
console.error(e); console.error(e);
showAlert( showAlert(t('common.error'), t('tools:pdfToTiff.alert.conversionError'));
'Error',
'Failed to convert PDF to TIFF. The file might be corrupted.'
);
} finally { } finally {
hideLoader(); hideLoader();
} }
@@ -211,7 +212,10 @@ document.addEventListener('DOMContentLoaded', () => {
); );
if (validFiles.length === 0) { if (validFiles.length === 0) {
showAlert('Invalid File', 'Please upload a PDF file.'); showAlert(
t('tools:pdfToTiff.alert.invalidFile'),
t('tools:pdfToTiff.alert.invalidFileExplanation')
);
return; return;
} }

View File

@@ -10,6 +10,7 @@ import { createIcons, icons } from 'lucide';
import JSZip from 'jszip'; import JSZip from 'jszip';
import * as pdfjsLib from 'pdfjs-dist'; import * as pdfjsLib from 'pdfjs-dist';
import { PDFPageProxy } from 'pdfjs-dist'; import { PDFPageProxy } from 'pdfjs-dist';
import { t } from '../i18n/i18n';
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL( pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
'pdfjs-dist/build/pdf.worker.min.mjs', 'pdfjs-dist/build/pdf.worker.min.mjs',
@@ -44,7 +45,7 @@ const updateUI = () => {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(file.size)}Loading pages...`; // Initial state metaSpan.textContent = `${formatBytes(file.size)}${t('common.loadingPageCount')}`; // Initial state
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);
@@ -66,7 +67,7 @@ const updateUI = () => {
return getPDFDocument(buffer).promise; return getPDFDocument(buffer).promise;
}) })
.then((pdf) => { .then((pdf) => {
metaSpan.textContent = `${formatBytes(file.size)}${pdf.numPages} page${pdf.numPages !== 1 ? 's' : ''}`; metaSpan.textContent = `${formatBytes(file.size)}${pdf.numPages} ${pdf.numPages !== 1 ? t('common.pages') : t('common.page')}`;
}) })
.catch((e) => { .catch((e) => {
console.warn('Error loading PDF page count:', e); console.warn('Error loading PDF page count:', e);
@@ -96,10 +97,13 @@ const resetState = () => {
async function convert() { async function convert() {
if (files.length === 0) { if (files.length === 0) {
showAlert('No File', 'Please upload a PDF file first.'); showAlert(
t('tools:pdfToWebp.alert.noFile'),
t('tools:pdfToWebp.alert.noFileExplanation')
);
return; return;
} }
showLoader('Converting to WebP...'); showLoader(t('tools:pdfToWebp.loader.converting'));
try { try {
const pdf = await getPDFDocument(await readFileAsArrayBuffer(files[0])) const pdf = await getPDFDocument(await readFileAsArrayBuffer(files[0]))
.promise; .promise;
@@ -128,8 +132,8 @@ async function convert() {
} }
showAlert( showAlert(
'Success', t('common.success'),
'PDF converted to WebPs successfully!', t('tools:pdfToWebp.alert.conversionSuccess'),
'success', 'success',
() => { () => {
resetState(); resetState();
@@ -137,10 +141,7 @@ async function convert() {
); );
} catch (e) { } catch (e) {
console.error(e); console.error(e);
showAlert( showAlert(t('common.error'), t('tools:pdfToWebp.alert.conversionError'));
'Error',
'Failed to convert PDF to WebP. The file might be corrupted.'
);
} finally { } finally {
hideLoader(); hideLoader();
} }
@@ -197,7 +198,10 @@ document.addEventListener('DOMContentLoaded', () => {
); );
if (validFiles.length === 0) { if (validFiles.length === 0) {
showAlert('Invalid File', 'Please upload a PDF file.'); showAlert(
t('tools:pdfToWebp.alert.invalidFile'),
t('tools:pdfToWebp.alert.invalidFileExplanation')
);
return; return;
} }

View File

@@ -1,4 +1,5 @@
import { showLoader, hideLoader, showAlert } from '../ui.js'; import { showLoader, hideLoader, showAlert } from '../ui.js';
import { t } from '../i18n/i18n';
import { import {
downloadFile, downloadFile,
readFileAsArrayBuffer, readFileAsArrayBuffer,
@@ -50,7 +51,7 @@ document.addEventListener('DOMContentLoaded', () => {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(file.size)}Loading pages...`; metaSpan.textContent = `${formatBytes(file.size)}${t('common.loadingPageCount')}`;
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);

View File

@@ -1,4 +1,5 @@
import { showLoader, hideLoader, showAlert } from '../ui.js'; import { showLoader, hideLoader, showAlert } from '../ui.js';
import { t } from '../i18n/i18n';
import { import {
downloadFile, downloadFile,
readFileAsArrayBuffer, readFileAsArrayBuffer,
@@ -50,7 +51,7 @@ document.addEventListener('DOMContentLoaded', () => {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(file.size)}Loading pages...`; metaSpan.textContent = `${formatBytes(file.size)}${t('common.loadingPageCount')}`;
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);

View File

@@ -10,6 +10,7 @@ import { PDFDocument } from 'pdf-lib';
import { applyScannerEffect } from '../utils/image-effects.js'; import { applyScannerEffect } from '../utils/image-effects.js';
import * as pdfjsLib from 'pdfjs-dist'; import * as pdfjsLib from 'pdfjs-dist';
import type { ScanSettings } from '../types/scanner-effect-type.js'; import type { ScanSettings } from '../types/scanner-effect-type.js';
import { t } from '../i18n/i18n';
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL( pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
'pdfjs-dist/build/pdf.worker.min.mjs', 'pdfjs-dist/build/pdf.worker.min.mjs',
@@ -129,7 +130,7 @@ const updateUI = () => {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(file.size)}Loading pages...`; metaSpan.textContent = `${formatBytes(file.size)}${t('common.loadingPageCount')}`;
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);
@@ -152,7 +153,7 @@ const updateUI = () => {
return getPDFDocument(buffer).promise; return getPDFDocument(buffer).promise;
}) })
.then((pdf: pdfjsLib.PDFDocumentProxy) => { .then((pdf: pdfjsLib.PDFDocumentProxy) => {
metaSpan.textContent = `${formatBytes(file.size)}${pdf.numPages} page${pdf.numPages !== 1 ? 's' : ''}`; metaSpan.textContent = `${formatBytes(file.size)}${pdf.numPages} ${pdf.numPages !== 1 ? t('common.pages') : t('common.page')}`;
}) })
.catch(() => { .catch(() => {
metaSpan.textContent = formatBytes(file.size); metaSpan.textContent = formatBytes(file.size);

View File

@@ -2,6 +2,7 @@ import { createIcons, icons } from 'lucide';
import { showAlert, showLoader, hideLoader } from '../ui.js'; import { showAlert, showLoader, hideLoader } from '../ui.js';
import { readFileAsArrayBuffer, formatBytes, downloadFile, getPDFDocument } from '../utils/helpers.js'; import { readFileAsArrayBuffer, formatBytes, downloadFile, getPDFDocument } from '../utils/helpers.js';
import { PDFDocument } from 'pdf-lib'; import { PDFDocument } from 'pdf-lib';
import { t } from '../i18n/i18n';
interface SignState { interface SignState {
file: File | null; file: File | null;
@@ -108,7 +109,7 @@ async function updateFileDisplay() {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(signState.file.size)}Loading pages...`; metaSpan.textContent = `${formatBytes(signState.file.size)}${t('common.loadingPageCount')}`;
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);

View File

@@ -1,4 +1,5 @@
import { showLoader, hideLoader, showAlert } from '../ui.js'; import { showLoader, hideLoader, showAlert } from '../ui.js';
import { t } from '../i18n/i18n';
import { createIcons, icons } from 'lucide'; import { createIcons, icons } from 'lucide';
import * as pdfjsLib from 'pdfjs-dist'; import * as pdfjsLib from 'pdfjs-dist';
import { import {
@@ -71,7 +72,7 @@ document.addEventListener('DOMContentLoaded', () => {
const metaSpan = document.createElement('div'); const metaSpan = document.createElement('div');
metaSpan.className = 'text-xs text-gray-400'; metaSpan.className = 'text-xs text-gray-400';
metaSpan.textContent = `${formatBytes(file.size)}Loading pages...`; // Placeholder metaSpan.textContent = `${formatBytes(file.size)}${t('common.loadingPageCount')}`; // Placeholder
infoContainer.append(nameSpan, metaSpan); infoContainer.append(nameSpan, metaSpan);

View File

@@ -159,8 +159,12 @@
<div id="file-display-area" class="mt-4 space-y-2"></div> <div id="file-display-area" class="mt-4 space-y-2"></div>
<div id="options-panel" class="hidden mt-6"> <div id="options-panel" class="hidden mt-6">
<button id="process-btn" class="btn-gradient w-full"> <button
Download All id="process-btn"
class="btn-gradient w-full"
data-i18n="common.convert"
>
Convert
</button> </button>
</div> </div>
</div> </div>

View File

@@ -166,6 +166,7 @@
<label <label
for="jpg-quality" for="jpg-quality"
class="block mb-2 text-sm font-medium text-gray-300" class="block mb-2 text-sm font-medium text-gray-300"
data-i18n="tools:pdfToJpg.imageQuality"
>Image Quality</label >Image Quality</label
> >
<div class="flex items-center gap-4"> <div class="flex items-center gap-4">
@@ -184,13 +185,20 @@
>90%</span >90%</span
> >
</div> </div>
<p class="mt-1 text-xs text-gray-400"> <p
class="mt-1 text-xs text-gray-400"
data-i18n="tools:pdfToJpg.imageQualityExplanation"
>
Higher quality = larger file size Higher quality = larger file size
</p> </p>
</div> </div>
<button id="process-btn" class="btn-gradient w-full"> <button
Download All id="process-btn"
class="btn-gradient w-full"
data-i18n="common.convert"
>
Convert
</button> </button>
</div> </div>
</div> </div>

View File

@@ -163,6 +163,7 @@
<label <label
for="png-scale" for="png-scale"
class="block mb-2 text-sm font-medium text-gray-300" class="block mb-2 text-sm font-medium text-gray-300"
data-i18n="tools:pdfToPng.imageScale"
>Image Scale</label >Image Scale</label
> >
<div class="flex items-center gap-4"> <div class="flex items-center gap-4">
@@ -181,13 +182,20 @@
>2.0x</span >2.0x</span
> >
</div> </div>
<p class="mt-1 text-xs text-gray-400"> <p
class="mt-1 text-xs text-gray-400"
data-i18n="tools:pdfToPng.imageScaleExplanation"
>
Higher scale = better quality but larger file size Higher scale = better quality but larger file size
</p> </p>
</div> </div>
<button id="process-btn" class="btn-gradient w-full"> <button
Download All id="process-btn"
class="btn-gradient w-full"
data-i18n="common.convert"
>
Convert
</button> </button>
</div> </div>
</div> </div>

View File

@@ -154,8 +154,12 @@
</div> </div>
<div id="file-display-area" class="mt-4 space-y-2"></div> <div id="file-display-area" class="mt-4 space-y-2"></div>
<div id="options-panel" class="hidden mt-6"> <div id="options-panel" class="hidden mt-6">
<button id="process-btn" class="btn-gradient w-full"> <button
Download All id="process-btn"
class="btn-gradient w-full"
data-i18n="common.convert"
>
Convert
</button> </button>
</div> </div>
</div> </div>

View File

@@ -163,6 +163,7 @@
<label <label
for="webp-quality" for="webp-quality"
class="block mb-2 text-sm font-medium text-gray-300" class="block mb-2 text-sm font-medium text-gray-300"
data-i18n="tools:pdfToWebp.imageQuality"
>Image Quality</label >Image Quality</label
> >
<div class="flex items-center gap-4"> <div class="flex items-center gap-4">
@@ -181,13 +182,20 @@
>85%</span >85%</span
> >
</div> </div>
<p class="mt-1 text-xs text-gray-400"> <p
class="mt-1 text-xs text-gray-400"
data-i18n="tools:pdfToWebp.imageQualityExplanation"
>
Higher quality = larger file size Higher quality = larger file size
</p> </p>
</div> </div>
<button id="process-btn" class="btn-gradient w-full"> <button
Download All id="process-btn"
class="btn-gradient w-full"
data-i18n="common.convert"
>
Convert
</button> </button>
</div> </div>
</div> </div>