fix: fallback thumbnail dashboard - placeholder DOM au lieu de SVG cassé

- Remplace le onerror SVG data URI (cassé) par un vrai div placeholder
- Affiche 🖼️ + 'Pas d'aperçu' quand le thumbnail est indisponible
- Même fallback dans la modale detail
This commit is contained in:
2026-06-23 09:39:24 -04:00
parent 80fc4f6bce
commit 29b4390844
+15 -4
View File
@@ -97,7 +97,17 @@
.card:hover { transform: translateY(-2px); border-color: var(--accent); box-shadow: var(--shadow); }
.card-thumb {
width: 100%; aspect-ratio: 16/10; object-fit: cover;
display: block; background: #0d1117;
display: block; background: #161b22;
}
.card-thumb.placeholder {
display: flex; flex-direction: column;
align-items: center; justify-content: center;
aspect-ratio: 16/10;
background: #161b22; color: var(--fg-dim); font-size: 32px;
text-align: center; padding: 16px; gap: 4px;
}
.card-thumb.placeholder small {
font-size: 12px; color: #484f58;
}
.card-body { padding: 10px 12px; }
.card-filename { font-size: 13px; font-weight: 500; color: var(--fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@@ -254,9 +264,10 @@ function renderGallery(images, total, page) {
const desc = img.description || img.ocr_text || '';
const thumb = `/api/images/${img.id}/thumbnail`;
const dims = (img.width && img.height) ? `${img.width}×${img.height}` : '';
const cardId = `card-${img.id}`;
return `
<div class="card" onclick="openImage('${img.id}')">
<img class="card-thumb" src="${thumb}" alt="${escHtml(img.filename || '')}" loading="lazy" onerror="this.src='data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%22220%22 height=%22138%22><rect fill=%22%23161b22%22 width=%22220%22 height=%22138%22/><text x=%2250%25%22 y=%2250%25%22 fill=%22%238b949e%22 text-anchor=%22middle%22 dy=%22.3em%22 font-size=%2212%22>Pas d'aperçu</text></svg>'">
<div class="card" id="${cardId}" onclick="openImage('${img.id}')">
<img class="card-thumb" src="${thumb}" alt="${escHtml(img.filename || '')}" loading="lazy" onerror="var t=document.getElementById('${cardId}').querySelector('.card-thumb');if(t){t.outerHTML='<div class=\\'card-thumb placeholder\\'>🖼️<br><small>Pas d\\'aperçu</small></div>'}">
<div class="card-body">
<div class="card-filename">${escHtml(img.filename || img.id)}</div>
<div class="card-meta">
@@ -292,7 +303,7 @@ async function openImage(id) {
const tags = (img.tags || []).map(t => `<span class="tag">${escHtml(t)}</span>`).join(' ');
modal.innerHTML = `
<button class="modal-close" onclick="closeModal()">✕</button>
<img src="/api/images/${id}/thumbnail?full=1" alt="${escHtml(img.filename)}" onerror="this.style.display='none'">
<img src="/api/images/${id}/thumbnail?full=1" alt="${escHtml(img.filename)}" onerror="this.outerHTML='<div style=\\'aspect-ratio:16/10;background:#161b22;display:flex;align-items:center;justify-content:center;color:#8b949e;border-radius:8px;margin-bottom:16px\\'><span style=\\'font-size:48px\\'>🖼️</span></div>'">
<div class="modal-details">
<h2>${escHtml(img.filename || img.id)}</h2>
${img.description ? `<p class="desc">${escHtml(img.description)}</p>` : ''}