diff --git a/webui/static/downloads.js b/webui/static/downloads.js index ce20e659..0f89ed7d 100644 --- a/webui/static/downloads.js +++ b/webui/static/downloads.js @@ -5333,13 +5333,13 @@ function _gsRenderFromState(state) { if (dbArtists.length) { h += '
๐Ÿ“š In Your Library
'; - h += dbArtists.map(a => `
${a.image_url ? `` : '๐ŸŽค'}
${_escToast(a.name)}
Library
`).join(''); + h += dbArtists.map(a => `
${a.image_url ? `` : '๐ŸŽค'}
${_escToast(a.name)}
Library
`).join(''); h += '
'; } if (artists.length) { h += `
๐ŸŽค Artists ${srcLabel}
`; - h += artists.map(a => `
${a.image_url ? `` : '๐ŸŽค'}
${_escToast(a.name)}
`).join(''); + h += artists.map(a => `
${a.image_url ? `` : '๐ŸŽค'}
${_escToast(a.name)}
`).join(''); h += '
'; } @@ -5349,7 +5349,7 @@ function _gsRenderFromState(state) { const ar = a.artist || (a.artists ? a.artists.join(', ') : ''); const yr = a.release_date ? a.release_date.substring(0, 4) : ''; const img = (a.image_url || '').replace(/'/g, "\\'"); - return `
${a.image_url ? `` : '๐Ÿ’ฟ'}
${_escToast(a.name)}
${_escToast(ar)}${yr ? ` ยท ${yr}` : ''}
`; + return `
${a.image_url ? `` : '๐Ÿ’ฟ'}
${_escToast(a.name)}
${_escToast(ar)}${yr ? ` ยท ${yr}` : ''}
`; }).join(''); h += ''; } @@ -5359,7 +5359,7 @@ function _gsRenderFromState(state) { h += singles.map(a => { const ar = a.artist || (a.artists ? a.artists.join(', ') : ''); const img = (a.image_url || '').replace(/'/g, "\\'"); - return `
${a.image_url ? `` : '๐ŸŽถ'}
${_escToast(a.name)}
${_escToast(ar)}
`; + return `
${a.image_url ? `` : '๐ŸŽถ'}
${_escToast(a.name)}
${_escToast(ar)}
`; }).join(''); h += ''; } @@ -5369,7 +5369,7 @@ function _gsRenderFromState(state) { h += tracks.map(t => { const ar = t.artist || (t.artists ? t.artists.join(', ') : ''); const dur = t.duration_ms ? `${Math.floor(t.duration_ms / 60000)}:${String(Math.floor((t.duration_ms % 60000) / 1000)).padStart(2, '0')}` : ''; - return `
${t.image_url ? `` : '๐ŸŽต'}
${_escToast(t.name)}
${_escToast(ar)}${t.album ? ` ยท ${_escToast(t.album)}` : ''}
${dur}
`; + return `
${t.image_url ? `` : '๐ŸŽต'}
${_escToast(t.name)}
${_escToast(ar)}${t.album ? ` ยท ${_escToast(t.album)}` : ''}
${dur}
`; }).join(''); h += ''; } diff --git a/webui/static/shared-helpers.js b/webui/static/shared-helpers.js index 660ef01c..ce65a412 100644 --- a/webui/static/shared-helpers.js +++ b/webui/static/shared-helpers.js @@ -559,9 +559,15 @@ function renderCompactSection(sectionId, listId, countId, items, mapItem) { placeholderClass += ' track-placeholder'; } + // Fallback placeholder used when the image 404s (common for MB + // Cover Art Archive URLs โ€” we construct them deterministically + // without probing first, so some will miss). Without onerror the + // browser shows its broken-image icon. + const placeholderHtml = `
${config.placeholder}
`; + const escapedFallback = placeholderHtml.replace(/"/g, '"'); const imageHtml = config.image - ? `${escapeHtml(config.name)}` - : `
${config.placeholder}
`; + ? `${escapeHtml(config.name)}` + : placeholderHtml; const badgeHtml = config.badge ? `
${config.badge.text}
`