feat: show thumbhash behind load error, if possible (#17554)

* feat: show thumbhash behind load error, if possible

* forgot this
This commit is contained in:
Min Idzelis 2025-04-11 18:01:51 -04:00 committed by GitHub
parent 40e3322b25
commit c62fc155c8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 20 additions and 10 deletions

View File

@ -595,7 +595,7 @@
id="stack-slideshow"
class="z-[1002] flex place-item-center place-content-center absolute bottom-0 w-full col-span-4 col-start-1 overflow-x-auto horizontal-scrollbar"
>
<div class="relative w-full whitespace-nowrap">
<div class="relative w-full">
{#each stackedAssets as stackedAsset (stackedAsset.id)}
<div
class={['inline-block px-1 relative transition-all pb-2']}
@ -603,6 +603,7 @@
>
<Thumbnail
imageClass={{ 'border-2 border-white': stackedAsset.id === asset.id }}
brokenAssetClass="text-xs"
dimmed={stackedAsset.id !== asset.id}
asset={stackedAsset}
onClick={(stackedAsset) => {

View File

@ -184,7 +184,9 @@
]}
/>
{#if imageError}
<BrokenAsset class="text-xl" />
<div class="h-full w-full">
<BrokenAsset class="text-xl h-full w-full" />
</div>
{/if}
<!-- svelte-ignore a11y_missing_attribute -->
<img bind:this={loader} style="display:none" src={imageLoaderUrl} aria-hidden="true" />

View File

@ -14,7 +14,7 @@
</script>
<div
class="flex flex-col overflow-hidden max-h-full max-w-full justify-center items-center bg-gray-100 dark:bg-gray-700 dark:text-gray-100 p-4 {className}"
class="flex flex-col overflow-hidden max-h-full max-w-full justify-center items-center bg-gray-100/40 dark:bg-gray-700/40 dark:text-gray-100 p-4 {className}"
style:width
style:height
>

View File

@ -21,7 +21,8 @@
border?: boolean;
hiddenIconClass?: string;
class?: ClassValue;
onComplete?: (() => void) | undefined;
brokenAssetClass?: ClassValue;
onComplete?: ((errored: boolean) => void) | undefined;
}
let {
@ -39,6 +40,7 @@
hiddenIconClass = 'text-white',
onComplete = undefined,
class: imageClass = '',
brokenAssetClass = '',
}: Props = $props();
let {
@ -50,17 +52,17 @@
const setLoaded = () => {
loaded = true;
onComplete?.();
onComplete?.(false);
};
const setErrored = () => {
errored = true;
onComplete?.();
onComplete?.(true);
};
function mount(elem: HTMLImageElement) {
if (elem.complete) {
loaded = true;
onComplete?.();
onComplete?.(false);
}
}
@ -71,6 +73,7 @@
shadow && 'shadow-lg',
(circle || !heightStyle) && 'aspect-square',
border && 'border-[3px] border-immich-dark-primary/80 hover:border-immich-primary',
brokenAssetClass,
]
.filter(Boolean)
.join(' '),

View File

@ -40,6 +40,7 @@
showArchiveIcon?: boolean;
showStackedIcon?: boolean;
imageClass?: ClassValue;
brokenAssetClass?: ClassValue;
dimmed?: boolean;
onClick?: ((asset: AssetResponseDto) => void) | undefined;
onSelect?: ((asset: AssetResponseDto) => void) | undefined;
@ -66,6 +67,7 @@
onMouseEvent = undefined,
handleFocus = undefined,
imageClass = '',
brokenAssetClass = '',
dimmed = false,
}: Props = $props();
@ -77,6 +79,7 @@
let focussableElement: HTMLElement | undefined = $state();
let mouseOver = $state(false);
let loaded = $state(false);
let thumbError = $state(false);
$effect(() => {
if (focussed && document.activeElement !== focussableElement) {
@ -153,10 +156,10 @@
style:width="{width}px"
style:height="{height}px"
>
{#if !loaded && asset.thumbhash}
{#if (!loaded || thumbError) && asset.thumbhash}
<canvas
use:thumbhash={{ base64ThumbHash: asset.thumbhash }}
class="absolute object-cover z-10"
class="absolute object-cover"
style:width="{width}px"
style:height="{height}px"
out:fade={{ duration: THUMBHASH_FADE_DURATION }}
@ -296,12 +299,13 @@
</div>
<ImageThumbnail
class={imageClass}
{brokenAssetClass}
url={getAssetThumbnailUrl({ id: asset.id, size: AssetMediaSize.Thumbnail, cacheKey: asset.thumbhash })}
altText={$getAltText(asset)}
widthStyle="{width}px"
heightStyle="{height}px"
curve={selected}
onComplete={() => (loaded = true)}
onComplete={(errored) => ((loaded = true), (thumbError = errored))}
/>
{#if asset.type === AssetTypeEnum.Video}
<div class="absolute top-0 h-full w-full">