Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion web/src/lib/components/asset-viewer/asset-viewer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -595,14 +595,15 @@
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']}
style:bottom={stackedAsset.id === asset.id ? '0' : '-10px'}
>
<Thumbnail
imageClass={{ 'border-2 border-white': stackedAsset.id === asset.id }}
brokenAssetClass="text-xs"
dimmed={stackedAsset.id !== asset.id}
asset={stackedAsset}
onClick={(stackedAsset) => {
Expand Down
4 changes: 3 additions & 1 deletion web/src/lib/components/asset-viewer/photo-viewer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down
2 changes: 1 addition & 1 deletion web/src/lib/components/assets/broken-asset.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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
>
Expand Down
11 changes: 7 additions & 4 deletions web/src/lib/components/assets/thumbnail/image-thumbnail.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
border?: boolean;
hiddenIconClass?: string;
class?: ClassValue;
onComplete?: (() => void) | undefined;
brokenAssetClass?: ClassValue;
onComplete?: ((errored: boolean) => void) | undefined;
}

let {
Expand All @@ -39,6 +40,7 @@
hiddenIconClass = 'text-white',
onComplete = undefined,
class: imageClass = '',
brokenAssetClass = '',
}: Props = $props();

let {
Expand All @@ -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);
}
}

Expand All @@ -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(' '),
Expand Down
10 changes: 7 additions & 3 deletions web/src/lib/components/assets/thumbnail/thumbnail.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
showArchiveIcon?: boolean;
showStackedIcon?: boolean;
imageClass?: ClassValue;
brokenAssetClass?: ClassValue;
dimmed?: boolean;
onClick?: ((asset: AssetResponseDto) => void) | undefined;
onSelect?: ((asset: AssetResponseDto) => void) | undefined;
Expand All @@ -66,6 +67,7 @@
onMouseEvent = undefined,
handleFocus = undefined,
imageClass = '',
brokenAssetClass = '',
dimmed = false,
}: Props = $props();

Expand All @@ -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) {
Expand Down Expand Up @@ -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 }}
Expand Down Expand Up @@ -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">
Expand Down