diff --git a/web/src/lib/components/album-page/__tests__/album-card.spec.ts b/web/src/lib/components/album-page/__tests__/album-card.spec.ts index 8cca2f8c01..b273271ced 100644 --- a/web/src/lib/components/album-page/__tests__/album-card.spec.ts +++ b/web/src/lib/components/album-page/__tests__/album-card.spec.ts @@ -13,6 +13,7 @@ vi.mock('@immich/sdk', async (originalImport) => { }); const sdkMock: MockedObject = sdk as MockedObject; +const onShowContextMenu = vi.fn(); describe('AlbumCard component', () => { let sut: RenderResult; @@ -90,34 +91,30 @@ describe('AlbumCard component', () => { expect(albumDetailsElement).toHaveTextContent('0 items'); }); + it('hides context menu when "onShowContextMenu" is undefined', () => { + const album = Object.freeze(albumFactory.build({ albumThumbnailAssetId: null })); + sut = render(AlbumCard, { album }); + + const contextButtonParent = sut.queryByTestId('context-button-parent'); + expect(contextButtonParent).not.toBeInTheDocument(); + }); + describe('with rendered component - no thumbnail', () => { const album = Object.freeze(albumFactory.build({ albumThumbnailAssetId: null })); beforeEach(async () => { - sut = render(AlbumCard, { album }); + sut = render(AlbumCard, { album, onShowContextMenu }); const albumImgElement = sut.getByTestId('album-image'); await waitFor(() => expect(albumImgElement).toHaveAttribute('src')); }); - it('dispatches custom "click" event with the album in context', async () => { - const onClickHandler = vi.fn(); - sut.component.$on('click', onClickHandler); - const albumCardElement = sut.getByTestId('album-card'); - - await fireEvent.click(albumCardElement); - expect(onClickHandler).toHaveBeenCalledTimes(1); - expect(onClickHandler).toHaveBeenCalledWith(expect.objectContaining({ detail: album })); - }); - - it('dispatches custom "click" event on context menu click with mouse coordinates', async () => { - const onClickHandler = vi.fn(); - sut.component.$on('showalbumcontextmenu', onClickHandler); - - const contextMenuButtonParent = sut.getByTestId('context-button-parent'); + it('dispatches "onShowContextMenu" event on context menu click with mouse coordinates', async () => { + const contextMenuButton = sut.getByTestId('context-button-parent').children[0]; + expect(contextMenuButton).toBeDefined(); // Mock getBoundingClientRect to return a bounding rectangle that will result in the expected position - contextMenuButtonParent.getBoundingClientRect = () => ({ + contextMenuButton.getBoundingClientRect = () => ({ x: 123, y: 456, width: 0, @@ -130,14 +127,14 @@ describe('AlbumCard component', () => { }); await fireEvent( - contextMenuButtonParent, + contextMenuButton, new MouseEvent('click', { clientX: 123, clientY: 456, }), ); - expect(onClickHandler).toHaveBeenCalledTimes(1); - expect(onClickHandler).toHaveBeenCalledWith(expect.objectContaining({ detail: { x: 123, y: 456 } })); + expect(onShowContextMenu).toHaveBeenCalledTimes(1); + expect(onShowContextMenu).toHaveBeenCalledWith(expect.objectContaining({ x: 123, y: 456 })); }); }); }); diff --git a/web/src/lib/components/album-page/album-card.svelte b/web/src/lib/components/album-page/album-card.svelte index 8e54af18ca..2958660771 100644 --- a/web/src/lib/components/album-page/album-card.svelte +++ b/web/src/lib/components/album-page/album-card.svelte @@ -5,25 +5,20 @@ import { getAssetThumbnailUrl } from '$lib/utils'; import { ThumbnailFormat, getAssetThumbnail, getUserById, type AlbumResponseDto } from '@immich/sdk'; import { mdiDotsVertical } from '@mdi/js'; - import { createEventDispatcher, onMount } from 'svelte'; - import { getContextMenuPosition } from '../../utils/context-menu'; + import { onMount } from 'svelte'; + import { getContextMenuPosition, type ContextMenuPosition } from '../../utils/context-menu'; import IconButton from '../elements/buttons/icon-button.svelte'; - import type { OnClick, OnShowContextMenu } from './album-card'; export let album: AlbumResponseDto; export let isSharingView = false; export let showItemCount = true; - export let showContextMenu = true; export let preload = false; - let showVerticalDots = false; + export let onShowContextMenu: ((position: ContextMenuPosition) => void) | undefined = undefined; $: imageData = album.albumThumbnailAssetId ? getAssetThumbnailUrl(album.albumThumbnailAssetId, ThumbnailFormat.Webp) : null; - const dispatchClick = createEventDispatcher(); - const dispatchShowContextMenu = createEventDispatcher(); - const loadHighQualityThumbnail = async (assetId: string | null) => { if (!assetId) { return; @@ -33,8 +28,11 @@ return URL.createObjectURL(data); }; - const showAlbumContextMenu = (e: MouseEvent) => - dispatchShowContextMenu('showalbumcontextmenu', getContextMenuPosition(e)); + const showAlbumContextMenu = (e: MouseEvent) => { + e.stopPropagation(); + e.preventDefault(); + onShowContextMenu?.(getContextMenuPosition(e)); + }; onMount(async () => { imageData = (await loadHighQualityThumbnail(album.albumThumbnailAssetId)) || null; @@ -43,25 +41,17 @@ const getAlbumOwnerInfo = () => getUserById({ id: album.ownerId }); -
dispatchClick('click', album)} - on:keydown={() => dispatchClick('click', album)} - on:mouseenter={() => (showVerticalDots = true)} - on:mouseleave={() => (showVerticalDots = false)} + class="group relative rounded-2xl border border-transparent p-5 hover:bg-gray-100 hover:border-gray-200 dark:hover:border-gray-800 dark:hover:bg-gray-900" data-testid="album-card" > - - {#if showContextMenu} + {#if onShowContextMenu}
- +
diff --git a/web/src/lib/components/album-page/album-card.ts b/web/src/lib/components/album-page/album-card.ts deleted file mode 100644 index deb98e976d..0000000000 --- a/web/src/lib/components/album-page/album-card.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { AlbumResponseDto } from '@immich/sdk'; - -export type OnShowContextMenu = { - showalbumcontextmenu: OnShowContextMenuDetail; -}; - -export type OnClick = { - click: OnClickDetail; -}; - -export type OnShowContextMenuDetail = { x: number; y: number }; -export type OnClickDetail = AlbumResponseDto; diff --git a/web/src/lib/components/album-page/albums-list.svelte b/web/src/lib/components/album-page/albums-list.svelte index 1a681a884b..607457e1c0 100644 --- a/web/src/lib/components/album-page/albums-list.svelte +++ b/web/src/lib/components/album-page/albums-list.svelte @@ -1,7 +1,6 @@