PWA: PDF-Viewer mit ausführlichem Debug-Logging [deploy]
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 5s

This commit is contained in:
Eddy 2026-04-17 13:04:11 +02:00
parent e579523020
commit 69f50b0fe5
2 changed files with 35 additions and 12 deletions

40
app.js
View file

@ -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 = () => {

View file

@ -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') || '' };
}