diff --git a/web/src/lib/components/asset-viewer/actions/action.ts b/web/src/lib/components/asset-viewer/actions/action.ts index f8cfd447f0b94..40b189080ff97 100644 --- a/web/src/lib/components/asset-viewer/actions/action.ts +++ b/web/src/lib/components/asset-viewer/actions/action.ts @@ -19,3 +19,4 @@ export type Action = { [K in AssetAction]: { type: K } & ActionMap[K]; }[AssetAction]; export type OnAction = (action: Action) => void; +export type PreAction = (action: Action) => void; diff --git a/web/src/lib/components/asset-viewer/actions/delete-action.svelte b/web/src/lib/components/asset-viewer/actions/delete-action.svelte index c0f163634a83b..24ba2c845dc49 100644 --- a/web/src/lib/components/asset-viewer/actions/delete-action.svelte +++ b/web/src/lib/components/asset-viewer/actions/delete-action.svelte @@ -14,14 +14,15 @@ import { deleteAssets, type AssetResponseDto } from '@immich/sdk'; import { mdiDeleteForeverOutline, mdiDeleteOutline } from '@mdi/js'; import { t } from 'svelte-i18n'; - import type { OnAction } from './action'; + import type { OnAction, PreAction } from './action'; interface Props { asset: AssetResponseDto; onAction: OnAction; + preAction: PreAction; } - let { asset, onAction }: Props = $props(); + let { asset, onAction, preAction }: Props = $props(); let showConfirmModal = $state(false); @@ -41,6 +42,7 @@ const trashAsset = async () => { try { + preAction({ type: AssetAction.TRASH, asset }); await deleteAssets({ assetBulkDeleteDto: { ids: [asset.id] } }); onAction({ type: AssetAction.TRASH, asset }); diff --git a/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte index 442302198b673..a164a9e64718f 100644 --- a/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte +++ b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte @@ -1,6 +1,6 @@ <script lang="ts"> import { goto } from '$app/navigation'; - import type { OnAction } from '$lib/components/asset-viewer/actions/action'; + import type { OnAction, PreAction } from '$lib/components/asset-viewer/actions/action'; import AddToAlbumAction from '$lib/components/asset-viewer/actions/add-to-album-action.svelte'; import ArchiveAction from '$lib/components/asset-viewer/actions/archive-action.svelte'; import CloseAction from '$lib/components/asset-viewer/actions/close-action.svelte'; @@ -58,6 +58,7 @@ showSlideshow?: boolean; onZoomImage: () => void; onCopyImage?: () => Promise<void>; + preAction: PreAction; onAction: OnAction; onRunJob: (name: AssetJobName) => void; onPlaySlideshow: () => void; @@ -76,6 +77,7 @@ showSlideshow = false, onZoomImage, onCopyImage, + preAction, onAction, onRunJob, onPlaySlideshow, @@ -149,7 +151,7 @@ {/if} --> {#if isOwner} - <DeleteAction {asset} {onAction} /> + <DeleteAction {asset} {onAction} {preAction} /> <ButtonContextMenu direction="left" align="top-right" color="opaque" title={$t('more')} icon={mdiDotsVertical}> {#if showSlideshow} diff --git a/web/src/lib/components/asset-viewer/asset-viewer.svelte b/web/src/lib/components/asset-viewer/asset-viewer.svelte index ea5d6e92759cb..495a325518a53 100644 --- a/web/src/lib/components/asset-viewer/asset-viewer.svelte +++ b/web/src/lib/components/asset-viewer/asset-viewer.svelte @@ -1,6 +1,6 @@ <script lang="ts"> import { focusTrap } from '$lib/actions/focus-trap'; - import type { Action, OnAction } from '$lib/components/asset-viewer/actions/action'; + import type { Action, OnAction, PreAction } from '$lib/components/asset-viewer/actions/action'; import MotionPhotoAction from '$lib/components/asset-viewer/actions/motion-photo-action.svelte'; import NextAssetAction from '$lib/components/asset-viewer/actions/next-asset-action.svelte'; import PreviousAssetAction from '$lib/components/asset-viewer/actions/previous-asset-action.svelte'; @@ -58,6 +58,7 @@ isShared?: boolean; album?: AlbumResponseDto | null; person?: PersonResponseDto | null; + preAction?: PreAction | undefined; onAction?: OnAction | undefined; reactions?: ActivityResponseDto[]; onClose: (dto: { asset: AssetResponseDto }) => void; @@ -75,6 +76,7 @@ isShared = false, album = null, person = null, + preAction = undefined, onAction = undefined, reactions = $bindable([]), onClose, @@ -366,7 +368,9 @@ const handleStackedAssetMouseEvent = (isMouseOver: boolean, asset: AssetResponseDto) => { previewStackedAsset = isMouseOver ? asset : undefined; }; - + const handlePreAction = (action: Action) => { + preAction?.(action); + }; const handleAction = async (action: Action) => { switch (action.type) { case AssetAction.ADD_TO_ALBUM: { @@ -430,6 +434,7 @@ showSlideshow={true} onZoomImage={zoomToggle} onCopyImage={copyImage} + preAction={handlePreAction} onAction={handleAction} onRunJob={handleRunJob} onPlaySlideshow={() => ($slideshowState = SlideshowState.PlaySlideshow)} diff --git a/web/src/lib/components/photos-page/asset-grid.svelte b/web/src/lib/components/photos-page/asset-grid.svelte index fd98f7e6a3a10..db2c491dbdef6 100644 --- a/web/src/lib/components/photos-page/asset-grid.svelte +++ b/web/src/lib/components/photos-page/asset-grid.svelte @@ -517,7 +517,6 @@ const handleNext = async () => { const nextAsset = await $assetStore.getNextAsset($viewingAsset); - if (nextAsset) { const preloadAsset = await $assetStore.getNextAsset(nextAsset); assetViewingStore.setAsset(nextAsset, preloadAsset ? [preloadAsset] : []); @@ -546,7 +545,7 @@ await navigate({ targetRoute: 'current', assetId: null, assetGridRouteSearchParams: $gridScrollTarget }); }; - const handleAction = async (action: Action) => { + const handlePreAction = async (action: Action) => { switch (action.type) { case removeAction: case AssetAction.TRASH: @@ -560,7 +559,10 @@ assetStore.removeAssets([action.asset.id]); break; } - + } + }; + const handleAction = (action: Action) => { + switch (action.type) { case AssetAction.ARCHIVE: case AssetAction.UNARCHIVE: case AssetAction.FAVORITE: @@ -928,6 +930,7 @@ {isShared} {album} {person} + preAction={handlePreAction} onAction={handleAction} onPrevious={handlePrevious} onNext={handleNext}