// PDF Tools - JavaScript Functionality let pdfToolsFiles = []; let mergeSortable = null; let currentPdfFile = null; // DOM elements let mergeUploadArea, mergeFileInput, mergeFileList, mergeFilesContainer, mergePdfsBtn; let splitUploadArea, splitFileInput, splitFileInfo, convertToImagesBtn; let mergeResult, splitResult, mergeDownloadLink, splitDownloadLink; let processingModal, errorArea, errorMessage; // Initialize when page loads document.addEventListener('DOMContentLoaded', function() { initializeDOMElements(); setupEventListeners(); setupDragAndDrop(); // Überprüfe Abhängigkeiten beim Laden setTimeout(() => { checkDependencies(); }, 1000); }); function initializeDOMElements() { // Merge elements mergeUploadArea = document.getElementById('merge-upload-area'); mergeFileInput = document.getElementById('merge-file-input'); mergeFileList = document.getElementById('merge-file-list'); mergeFilesContainer = document.getElementById('merge-files-container'); mergePdfsBtn = document.getElementById('merge-pdfs-btn'); mergeResult = document.getElementById('merge-result'); mergeDownloadLink = document.getElementById('merge-download-link'); // Split elements splitUploadArea = document.getElementById('split-upload-area'); splitFileInput = document.getElementById('split-file-input'); splitFileInfo = document.getElementById('split-file-info'); convertToImagesBtn = document.getElementById('convert-to-images-btn'); splitResult = document.getElementById('split-result'); splitDownloadLink = document.getElementById('split-download-link'); // Common elements processingModal = new bootstrap.Modal(document.getElementById('processing-modal')); errorArea = document.getElementById('pdf-tools-error'); errorMessage = document.getElementById('pdf-tools-error-message'); } function setupEventListeners() { // Merge PDF events mergeFileInput.addEventListener('change', function(e) { handleMergeFiles(Array.from(e.target.files)); }); mergeUploadArea.addEventListener('click', function() { mergeFileInput.click(); }); mergePdfsBtn.addEventListener('click', mergePdfs); // Split PDF events splitFileInput.addEventListener('change', function(e) { if (e.target.files.length > 0) { handleSplitFile(e.target.files[0]); } }); splitUploadArea.addEventListener('click', function() { splitFileInput.click(); }); convertToImagesBtn.addEventListener('click', convertPdfToImages); // Tab change events document.querySelectorAll('[data-bs-toggle="pill"]').forEach(tab => { tab.addEventListener('shown.bs.tab', function(e) { hideAllResults(); }); }); } function setupDragAndDrop() { // Merge area drag and drop setupDragAndDrop(mergeUploadArea, handleMergeFiles); // Split area drag and drop setupDragAndDrop(splitUploadArea, function(files) { if (files.length > 0) { handleSplitFile(files[0]); } }); } // Merge PDF functions async function handleMergeFiles(files) { hideAllResults(); if (!files || files.length === 0) { showError('Keine Dateien ausgewählt.'); return; } // Filter PDF files const pdfFiles = files.filter(file => file.type === 'application/pdf'); if (pdfFiles.length === 0) { showError('Keine PDF-Dateien gefunden.'); return; } if (pdfFiles.length < 2) { showError('Mindestens 2 PDF-Dateien erforderlich.'); return; } // Upload files one by one pdfToolsFiles = []; for (const file of pdfFiles) { try { const response = await uploadSinglePdf(file); if (response.success) { pdfToolsFiles.push(response); } } catch (error) { showError(`Fehler beim Upload von ${file.name}: ${error.message}`); return; } } displayMergeFiles(); showNotification(`${pdfToolsFiles.length} PDF-Dateien erfolgreich hochgeladen.`, 'success'); } async function uploadSinglePdf(file) { const formData = new FormData(); formData.append('file', file); const response = await fetch('/api/upload-pdf', { method: 'POST', body: formData }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } function displayMergeFiles() { mergeFilesContainer.innerHTML = ''; pdfToolsFiles.forEach((file, index) => { const fileItem = createMergeFileItem(file, index); mergeFilesContainer.appendChild(fileItem); }); mergeFileList.style.display = 'block'; mergePdfsBtn.disabled = pdfToolsFiles.length < 2; // Setup sortable setupMergeSortable(); } function createMergeFileItem(file, index) { const div = document.createElement('div'); div.className = 'list-group-item pdf-item-enhanced'; div.dataset.index = index; // Initialize rotation if not set if (file.rotation === undefined) { file.rotation = 0; } // Create preview element const previewElement = file.preview ? `${file.original_name}` : `
`; div.innerHTML = `
${previewElement}
${file.original_name}
${file.page_count} Seiten • ${formatFileSize(file.size)}
${file.rotation}°
`; return div; } function setupMergeSortable() { if (mergeSortable) { mergeSortable.destroy(); } mergeSortable = setupSortable(mergeFilesContainer, function(evt) { const item = pdfToolsFiles.splice(evt.oldIndex, 1)[0]; pdfToolsFiles.splice(evt.newIndex, 0, item); displayMergeFiles(); }); } function removeMergeFile(index) { pdfToolsFiles.splice(index, 1); if (pdfToolsFiles.length === 0) { mergeFileList.style.display = 'none'; mergePdfsBtn.disabled = true; } else { displayMergeFiles(); } showNotification('PDF-Datei entfernt.', 'info'); } function rotatePdf(index, degrees) { if (index >= 0 && index < pdfToolsFiles.length) { pdfToolsFiles[index].rotation = (pdfToolsFiles[index].rotation + degrees) % 360; if (pdfToolsFiles[index].rotation < 0) { pdfToolsFiles[index].rotation += 360; } displayMergeFiles(); showNotification(`PDF um ${degrees}° gedreht.`, 'info'); } } function movePdfUp(index) { if (index > 0) { [pdfToolsFiles[index], pdfToolsFiles[index - 1]] = [pdfToolsFiles[index - 1], pdfToolsFiles[index]]; displayMergeFiles(); } } function movePdfDown(index) { if (index < pdfToolsFiles.length - 1) { [pdfToolsFiles[index], pdfToolsFiles[index + 1]] = [pdfToolsFiles[index + 1], pdfToolsFiles[index]]; displayMergeFiles(); } } function showPdfModal(previewFilename, originalName, index) { // Create modal if it doesn't exist let modal = document.getElementById('pdf-modal'); if (!modal) { modal = document.createElement('div'); modal.className = 'modal fade image-modal'; modal.id = 'pdf-modal'; modal.setAttribute('tabindex', '-1'); modal.setAttribute('aria-hidden', 'true'); modal.innerHTML = ` `; document.body.appendChild(modal); } else { // Update existing modal document.getElementById('pdf-modal-title').textContent = originalName; const modalPreview = document.getElementById('modal-pdf-preview'); modalPreview.src = `/uploads/${previewFilename}`; modalPreview.alt = originalName; modalPreview.className = `img-fluid rotate-${pdfToolsFiles[index].rotation}`; // Update rotation buttons const rotateButtons = modal.querySelectorAll('.btn-outline-danger'); rotateButtons[0].onclick = () => rotatePdfInModal(index, -90); rotateButtons[1].onclick = () => rotatePdfInModal(index, 90); } // Show modal const bootstrapModal = new bootstrap.Modal(modal); bootstrapModal.show(); } function rotatePdfInModal(index, degrees) { rotatePdf(index, degrees); // Update modal preview const modalPreview = document.getElementById('modal-pdf-preview'); modalPreview.className = `img-fluid rotate-${pdfToolsFiles[index].rotation}`; } function updatePdfPreviewSize() { const previewSize = document.getElementById('pdf-preview-size')?.value || 'medium'; const previews = document.querySelectorAll('.pdf-preview'); previews.forEach(preview => { // Remove existing size classes preview.classList.remove('size-small', 'size-medium', 'size-large'); // Add new size class preview.classList.add('size-' + previewSize); }); } async function mergePdfs() { if (pdfToolsFiles.length < 2) { showError('Mindestens 2 PDF-Dateien erforderlich.'); return; } hideAllResults(); processingModal.show(); try { // Include rotation data for each file const filesWithRotation = pdfToolsFiles.map(file => ({ filename: file.filename, rotation: file.rotation || 0, original_name: file.original_name })); const response = await makeRequest('/api/merge-pdfs', { method: 'POST', body: JSON.stringify({ files: filesWithRotation }) }); if (response.success) { showMergeResult(response.filename, response.message); showNotification(response.message, 'success'); } else { throw new Error(response.error || 'Zusammenführung fehlgeschlagen'); } } catch (error) { showError(`Fehler beim Zusammenführen: ${error.message}`); } finally { processingModal.hide(); } } function showMergeResult(filename, message) { mergeResult.style.display = 'block'; mergeDownloadLink.href = `/download/${filename}`; if (message) { mergeResult.querySelector('p').textContent = message; } } // Split PDF functions async function handleSplitFile(file) { hideAllResults(); if (!file) { showError('Keine Datei ausgewählt.'); return; } if (file.type !== 'application/pdf') { showError('Nur PDF-Dateien sind erlaubt.'); return; } try { const response = await uploadSinglePdf(file); if (response.success) { currentPdfFile = response; displaySplitFile(); showNotification('PDF-Datei erfolgreich hochgeladen.', 'success'); } else { throw new Error(response.error || 'Upload fehlgeschlagen'); } } catch (error) { showError(`Upload-Fehler: ${error.message}`); } } function displaySplitFile() { document.getElementById('split-filename').textContent = currentPdfFile.original_name; document.getElementById('split-file-details').textContent = `${currentPdfFile.page_count} Seiten • ${formatFileSize(currentPdfFile.size)}`; // PDF-Vorschau anzeigen falls verfügbar const previewContainer = document.getElementById('split-preview-container'); if (currentPdfFile.preview) { previewContainer.innerHTML = ` ${currentPdfFile.original_name} `; } else { previewContainer.innerHTML = `
`; } splitFileInfo.style.display = 'block'; } function showSplitPdfModal() { if (currentPdfFile && currentPdfFile.preview) { showPdfModal(currentPdfFile.preview, currentPdfFile.original_name, 0); } } async function convertPdfToImages() { if (!currentPdfFile) { showError('Keine PDF-Datei ausgewählt.'); return; } hideAllResults(); processingModal.show(); try { const response = await makeRequest('/api/pdf-to-images', { method: 'POST', body: JSON.stringify({ filename: currentPdfFile.filename }) }); if (response.success) { showSplitResult(response.filename, response.message); showNotification(response.message, 'success'); } else { throw new Error(response.error || 'Konvertierung fehlgeschlagen'); } } catch (error) { showError(`Konvertierungs-Fehler: ${error.message}`); } finally { processingModal.hide(); } } function showSplitResult(filename, message) { splitResult.style.display = 'block'; splitDownloadLink.href = `/download/${filename}`; if (message) { splitResult.querySelector('p').textContent = message; } } // Utility functions function hideAllResults() { if (mergeResult) mergeResult.style.display = 'none'; if (splitResult) splitResult.style.display = 'none'; if (errorArea) errorArea.style.display = 'none'; } function showError(message) { errorArea.style.display = 'block'; errorMessage.textContent = message; // Scroll to error errorArea.scrollIntoView({ behavior: 'smooth', block: 'center' }); } function handlePreviewError(img, originalName) { // Ersetze fehlgeschlagenes Bild durch Fallback const container = img.parentElement; container.innerHTML = `
`; console.warn(`PDF-Vorschau konnte nicht geladen werden: ${originalName}`); showNotification(`Vorschau für ${originalName} nicht verfügbar`, 'warning'); } // Debug-Funktion für PDF-Vorschau-Probleme async function debugPdfPreview(filename) { try { const response = await fetch(`/debug/pdf-preview/${filename}`); const data = await response.json(); console.log('PDF-Vorschau Debug:', data); return data; } catch (error) { console.error('Debug-Fehler:', error); return null; } } // Überprüfe Abhängigkeiten async function checkDependencies() { try { const response = await fetch('/debug/check-dependencies'); const data = await response.json(); console.log('Abhängigkeiten:', data); // Warne bei fehlenden Abhängigkeiten if (data.pdf2image !== 'verfügbar') { showNotification('pdf2image nicht verfügbar - PDF-Vorschauen funktionieren möglicherweise nicht', 'warning'); } if (data.poppler === 'nicht gefunden') { showNotification('Poppler nicht gefunden - Installieren Sie Poppler für PDF-Vorschauen', 'warning'); } return data; } catch (error) { console.error('Abhängigkeits-Check fehlgeschlagen:', error); return null; } } // Global functions window.removeMergeFile = removeMergeFile; window.rotatePdf = rotatePdf; window.movePdfUp = movePdfUp; window.movePdfDown = movePdfDown; window.showPdfModal = showPdfModal; window.rotatePdfInModal = rotatePdfInModal; window.updatePdfPreviewSize = updatePdfPreviewSize; window.showSplitPdfModal = showSplitPdfModal; window.handlePreviewError = handlePreviewError; window.debugPdfPreview = debugPdfPreview; window.checkDependencies = checkDependencies;