feat: Add internationalization support and introduce a new PDF multi-tool.

This commit is contained in:
cxllxc
2025-12-12 12:54:06 +00:00
parent 3c0fbc8f8f
commit ab122e19df
7 changed files with 186 additions and 48 deletions

View File

@@ -6,6 +6,7 @@ import { icons, createIcons } from 'lucide';
import Sortable from 'sortablejs';
import { getRotationState, updateRotationState } from './utils/rotation-state.js';
import * as pdfjsLib from 'pdfjs-dist';
import { t } from './i18n/i18n';
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.min.mjs', import.meta.url).toString();
@@ -43,7 +44,7 @@ export const dom = {
warningConfirmBtn: document.getElementById('warning-confirm-btn'),
};
export const showLoader = (text = 'Processing...') => {
export const showLoader = (text = t('common.loading')) => {
if (dom.loaderText) dom.loaderText.textContent = text;
if (dom.loaderModal) dom.loaderModal.classList.remove('hidden');
};
@@ -152,7 +153,7 @@ export const renderPageThumbnails = async (toolId: any, pdfDoc: any) => {
const currentRenderId = Date.now();
container.dataset.renderId = currentRenderId.toString();
showLoader('Rendering page previews...');
showLoader(t('multiTool.renderingTitle'));
const pdfData = await pdfDoc.save();
const pdf = await getPDFDocument({ data: pdfData }).promise;
@@ -373,7 +374,7 @@ export const renderPageThumbnails = async (toolId: any, pdfDoc: any) => {
createIcons({ icons });
} catch (error) {
console.error('Error rendering page thumbnails:', error);
showAlert('Error', 'Failed to render page thumbnails');
showAlert(t('multiTool.error'), t('multiTool.errorRendering'));
} finally {
hideLoader();
}
@@ -418,9 +419,9 @@ const createFileInputHTML = (options = {}) => {
<div id="drop-zone" class="relative flex flex-col items-center justify-center w-full h-48 border-2 border-dashed border-gray-600 rounded-xl cursor-pointer bg-gray-900 hover:bg-gray-700 transition-colors duration-300">
<div class="flex flex-col items-center justify-center pt-5 pb-6">
<i data-lucide="upload-cloud" class="w-10 h-10 mb-3 text-gray-400"></i>
<p class="mb-2 text-sm text-gray-400"><span class="font-semibold">Click to select a file</span> or drag and drop</p>
<p class="text-xs text-gray-500">${multiple ? 'PDFs or Images' : 'A single PDF file'}</p>
<p class="text-xs text-gray-500">Your files never leave your device.</p>
<p class="mb-2 text-sm text-gray-400"><span class="font-semibold">${t('upload.clickToSelect')}</span> ${t('upload.orDragAndDrop')}</p>
<p class="text-xs text-gray-500">${multiple ? t('upload.pdfOrImages') : 'A single PDF file'}</p>
<p class="text-xs text-gray-500">${t('upload.filesNeverLeave')}</p>
</div>
<input id="file-input" type="file" class="absolute top-0 left-0 w-full h-full opacity-0 cursor-pointer" ${multiple} accept="${acceptedFiles}">
</div>
@@ -430,10 +431,10 @@ const createFileInputHTML = (options = {}) => {
<!-- NEW: Add control buttons for multi-file uploads -->
<div id="file-controls" class="hidden mt-4 flex gap-3">
<button id="add-more-btn" class="btn bg-indigo-600 hover:bg-indigo-700 text-white font-semibold px-4 py-2 rounded-lg flex items-center gap-2">
<i data-lucide="plus"></i> Add More Files
<i data-lucide="plus"></i> ${t('upload.addMore')}
</button>
<button id="clear-files-btn" class="btn bg-red-600 hover:bg-red-700 text-white font-semibold px-4 py-2 rounded-lg flex items-center gap-2">
<i data-lucide="x"></i> Clear All
<i data-lucide="x"></i> ${t('upload.clearAll')}
</button>
</div>
`