mirror of
https://github.com/immich-app/immich.git
synced 2025-05-24 01:12:58 -04:00
feat: show thumbhash behind load error, if possible (#17554)
* feat: show thumbhash behind load error, if possible * forgot this
This commit is contained in:
parent
40e3322b25
commit
c62fc155c8
@ -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) => {
|
||||
|
@ -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" />
|
||||
|
@ -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
|
||||
>
|
||||
|
@ -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(' '),
|
||||
|
@ -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">
|
||||
|
Loading…
x
Reference in New Issue
Block a user