diff --git a/app.js b/app.js index 38824a1..cfe068f 100644 --- a/app.js +++ b/app.js @@ -1834,6 +1834,13 @@ function openFileViewer({ url, blob, mime }, filename, relpath) { } async function openPdfViewer(blob, filename, relpath) { + console.log('[PDF] Opening:', filename, 'size:', blob.size, 'type:', blob.type); + + if (blob.size === 0) { + showToast('❌ PDF-Datei ist leer oder nicht gefunden', 'error'); + return; + } + const modal = document.createElement('div'); modal.className = 'fullscreen-modal pdf-viewer-modal'; modal.innerHTML = ` @@ -1857,25 +1864,37 @@ async function openPdfViewer(blob, filename, relpath) { let pdf, currentPage = 1; try { - pdf = await pdfjs.getDocument(new Uint8Array(await blob.arrayBuffer())).promise; + const arrayBuffer = await blob.arrayBuffer(); + console.log('[PDF] ArrayBuffer size:', arrayBuffer.byteLength); + + if (arrayBuffer.byteLength === 0) { + throw new Error('PDF-Datei ist leer'); + } + + pdf = await pdfjs.getDocument(new Uint8Array(arrayBuffer)).promise; + console.log('[PDF] Loaded:', pdf.numPages, 'pages'); pageInfo.textContent = `1 / ${pdf.numPages}`; async function renderPage(num) { if (num < 1 || num > pdf.numPages) return; currentPage = num; - const page = await pdf.getPage(num); - const viewport = page.getViewport({ scale: window.devicePixelRatio }); - canvas.width = viewport.width; - canvas.height = viewport.height; - await page.render({ canvasContext: ctx, viewport }).promise; - pageInfo.textContent = `${num} / ${pdf.numPages}`; + try { + const page = await pdf.getPage(num); + const viewport = page.getViewport({ scale: window.devicePixelRatio }); + canvas.width = viewport.width; + canvas.height = viewport.height; + await page.render({ canvasContext: ctx, viewport }).promise; + pageInfo.textContent = `${num} / ${pdf.numPages}`; + } catch (e) { + console.error('[PDF] Render error on page', num, e); + pageInfo.textContent = `❌ Seite ${num} Fehler`; + } } await renderPage(1); modal.querySelector('#pdf-prev').onclick = () => renderPage(currentPage - 1); modal.querySelector('#pdf-next').onclick = () => renderPage(currentPage + 1); modal.querySelector('#pdf-download').onclick = async () => { - // Download über API mit Content-Disposition: attachment (kein Dialog-Spam) const t = await api.getToken(); const params = new URLSearchParams({ relpath, jwt: t, download: 1 }); window.location.href = window.location.origin + '/custom/bericht/api/photo.php?' + params.toString(); @@ -1883,8 +1902,9 @@ async function openPdfViewer(blob, filename, relpath) { modal.querySelector('#pdf-prev').disabled = false; modal.querySelector('#pdf-next').disabled = pdf.numPages === 1; } catch (err) { - pageInfo.textContent = '❌ PDF-Fehler'; - console.error('PDF load error:', err); + pageInfo.textContent = '❌ ' + (err.message || 'PDF-Fehler'); + console.error('[PDF] Load error:', err); + showToast('PDF-Fehler: ' + err.message, 'error'); } modal.querySelector('#pdf-close').onclick = () => { diff --git a/lib/api.js b/lib/api.js index 848613b..44a08c1 100644 --- a/lib/api.js +++ b/lib/api.js @@ -253,12 +253,15 @@ const t = await getToken(); if (!t) return null; const params = new URLSearchParams({ relpath, jwt: t }); - const r = await fetch(API_BASE + '/photo.php?' + params.toString()); + const url = API_BASE + '/photo.php?' + params.toString(); + console.log('[API] Fetching file:', relpath); + const r = await fetch(url); if (!r.ok) { - console.warn('getFileBlobUrl failed', r.status, relpath); + console.warn('[API] File fetch failed', r.status, relpath); return null; } const blob = await r.blob(); + console.log('[API] Got blob:', blob.size, 'bytes, type:', blob.type); return { url: URL.createObjectURL(blob), blob, mime: r.headers.get('Content-Type') || '' }; }