Skip to content

Commit f36efd1

Browse files
authored
fix(web): prevent thumbhashes from covering search bar (#20720)
The thumbhash had a z-index setting which meant it would cover the search bar, and would always cause weird animations when scrolling up in search results. This is fixable by removing the z-index and moving it in front the other elements to get a naturally higher higher z-index preference.
1 parent f1c494e commit f36efd1

File tree

4 files changed

+25
-57
lines changed

4 files changed

+25
-57
lines changed

web/src/lib/components/assets/thumbnail/__test__/image-thumbnail.spec.ts

Lines changed: 0 additions & 22 deletions
This file was deleted.

web/src/lib/components/assets/thumbnail/__test__/thumbnail.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,15 @@ describe('Thumbnail component', () => {
4545
const tabbables = getTabbable(container!);
4646
expect(tabbables.length).toBe(0);
4747
});
48+
49+
it('shows thumbhash while image is loading', () => {
50+
const asset = assetFactory.build({ originalPath: 'image.jpg', originalMimeType: 'image/jpeg' });
51+
const sut = render(Thumbnail, {
52+
asset,
53+
selected: true,
54+
});
55+
56+
const thumbhash = sut.getByTestId('thumbhash');
57+
expect(thumbhash).not.toBeFalsy();
58+
});
4859
});

web/src/lib/components/assets/thumbnail/image-thumbnail.svelte

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
<script lang="ts">
2-
import { thumbhash } from '$lib/actions/thumbhash';
32
import BrokenAsset from '$lib/components/assets/broken-asset.svelte';
43
import Icon from '$lib/components/elements/icon.svelte';
54
import { cancelImageUrl } from '$lib/utils/sw-messaging';
6-
import { TUNABLES } from '$lib/utils/tunables';
75
import { mdiEyeOffOutline } from '@mdi/js';
86
import type { ActionReturn } from 'svelte/action';
97
import type { ClassValue } from 'svelte/elements';
10-
import { fade } from 'svelte/transition';
118
129
interface Props {
1310
url: string;
1411
altText: string | undefined;
1512
title?: string | null;
1613
heightStyle?: string | undefined;
1714
widthStyle: string;
18-
base64ThumbHash?: string | null;
1915
curve?: boolean;
2016
shadow?: boolean;
2117
circle?: boolean;
@@ -33,7 +29,6 @@
3329
title = null,
3430
heightStyle = undefined,
3531
widthStyle,
36-
base64ThumbHash = null,
3732
curve = false,
3833
shadow = false,
3934
circle = false,
@@ -45,10 +40,6 @@
4540
brokenAssetClass = '',
4641
}: Props = $props();
4742
48-
let {
49-
IMAGE_THUMBNAIL: { THUMBHASH_FADE_DURATION },
50-
} = TUNABLES;
51-
5243
let loaded = $state(false);
5344
let errored = $state(false);
5445
@@ -100,7 +91,6 @@
10091
alt={loaded || errored ? altText : ''}
10192
{title}
10293
class={['object-cover', optionalClasses, imageClass]}
103-
class:opacity-0={!thumbhash && !loaded}
10494
draggable="false"
10595
/>
10696
{/if}
@@ -110,19 +100,3 @@
110100
<Icon {title} path={mdiEyeOffOutline} size="2em" class={hiddenIconClass} />
111101
</div>
112102
{/if}
113-
114-
{#if base64ThumbHash && (!loaded || errored)}
115-
<canvas
116-
use:thumbhash={{ base64ThumbHash }}
117-
data-testid="thumbhash"
118-
style:width={widthStyle}
119-
style:height={heightStyle}
120-
{title}
121-
class="absolute top-0 object-cover"
122-
class:rounded-xl={curve}
123-
class:shadow-lg={shadow}
124-
class:rounded-full={circle}
125-
draggable="false"
126-
out:fade={{ duration: THUMBHASH_FADE_DURATION }}
127-
></canvas>
128-
{/if}

web/src/lib/components/assets/thumbnail/thumbnail.svelte

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -230,15 +230,6 @@
230230
]}
231231
data-outline
232232
></div>
233-
{#if (!loaded || thumbError) && asset.thumbhash}
234-
<canvas
235-
use:thumbhash={{ base64ThumbHash: asset.thumbhash }}
236-
class="absolute object-cover z-1"
237-
style:width="{width}px"
238-
style:height="{height}px"
239-
out:fade={{ duration: THUMBHASH_FADE_DURATION }}
240-
></canvas>
241-
{/if}
242233

243234
<div
244235
class={['group absolute -top-[0px] -bottom-[0px]', { 'cursor-not-allowed': disabled, 'cursor-pointer': !disabled }]}
@@ -352,7 +343,21 @@
352343
/>
353344
</div>
354345
{/if}
346+
347+
{#if (!loaded || thumbError) && asset.thumbhash}
348+
<canvas
349+
use:thumbhash={{ base64ThumbHash: asset.thumbhash }}
350+
data-testid="thumbhash"
351+
class="absolute top-0 object-cover"
352+
style:width="{width}px"
353+
style:height="{height}px"
354+
class:rounded-xl={selected}
355+
draggable="false"
356+
out:fade={{ duration: THUMBHASH_FADE_DURATION }}
357+
></canvas>
358+
{/if}
355359
</div>
360+
356361
{#if selectionCandidate}
357362
<div
358363
class="absolute top-0 h-full w-full bg-immich-primary opacity-40"

0 commit comments

Comments
 (0)