diff --git a/src/lib/actions/cachedImage.ts b/src/lib/actions/cachedImage.ts index 1e19ceb6b..ce5532999 100644 --- a/src/lib/actions/cachedImage.ts +++ b/src/lib/actions/cachedImage.ts @@ -4,8 +4,8 @@ * Usage: * ... * - * Loads the image through the backend cache. Shows nothing until resolved, - * then sets the src attribute. Falls back to original URL on error. + * Hides the image until the cached URL is resolved, preventing + * broken image icons. The placeholder behind it remains visible. */ import { getCachedImageUrl } from '$lib/services/imageCacheService'; @@ -13,21 +13,29 @@ import { getCachedImageUrl } from '$lib/services/imageCacheService'; export function cachedSrc(node: HTMLImageElement, url: string | undefined) { let currentUrl = url; + // Hide until resolved so placeholder shows through + node.style.opacity = '0'; + node.removeAttribute('src'); + async function resolve(imageUrl: string | undefined) { if (!imageUrl) { - node.src = ''; + node.removeAttribute('src'); + node.style.opacity = '0'; return; } + node.style.opacity = '0'; + try { const resolved = await getCachedImageUrl(imageUrl); - // Only apply if still the current URL (avoid race conditions) if (imageUrl === currentUrl) { node.src = resolved; + node.style.opacity = '1'; } } catch { if (imageUrl === currentUrl) { - node.src = imageUrl; // Fallback to original + node.src = imageUrl; + node.style.opacity = '1'; } } } diff --git a/src/lib/components/AlbumCard.svelte b/src/lib/components/AlbumCard.svelte index 2f00fe482..700dd90fc 100644 --- a/src/lib/components/AlbumCard.svelte +++ b/src/lib/components/AlbumCard.svelte @@ -361,6 +361,7 @@ object-fit: cover; border-radius: inherit; z-index: 1; + transition: opacity 0.15s ease-in; } .artwork-placeholder {