From 7302510870508dc709bc5f34e1289f61ea0881d2 Mon Sep 17 00:00:00 2001 From: Lean Miguel Date: Tue, 10 Dec 2024 21:09:39 +0900 Subject: [PATCH] delete all assets associated with stack on asset delete --- .../asset-viewer/actions/delete-action.svelte | 13 +++++-- .../photos-page/actions/delete-assets.svelte | 35 +++++++++++++++++-- 2 files changed, 44 insertions(+), 4 deletions(-) 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 c0f163634a..670f9fe6e8 100644 --- a/web/src/lib/components/asset-viewer/actions/delete-action.svelte +++ b/web/src/lib/components/asset-viewer/actions/delete-action.svelte @@ -11,7 +11,7 @@ import { showDeleteModal } from '$lib/stores/preferences.store'; import { featureFlags } from '$lib/stores/server-config.store'; import { handleError } from '$lib/utils/handle-error'; - import { deleteAssets, type AssetResponseDto } from '@immich/sdk'; + import { deleteStack, getStack, deleteAssets, type AssetResponseDto } from '@immich/sdk'; import { mdiDeleteForeverOutline, mdiDeleteOutline } from '@mdi/js'; import { t } from 'svelte-i18n'; import type { OnAction } from './action'; @@ -41,7 +41,16 @@ const trashAsset = async () => { try { - await deleteAssets({ assetBulkDeleteDto: { ids: [asset.id] } }); + if (asset.stack) { + const { assets } = await getStack({ id: asset.stack.id }); + const assetIds = assets.map((asset) => asset.id); + + await deleteStack({ id: asset.stack.id }); + await deleteAssets({ assetBulkDeleteDto: { ids: assetIds } }); + } else { + await deleteAssets({ assetBulkDeleteDto: { ids: [asset.id] } }); + } + onAction({ type: AssetAction.TRASH, asset }); notificationController.show({ diff --git a/web/src/lib/components/photos-page/actions/delete-assets.svelte b/web/src/lib/components/photos-page/actions/delete-assets.svelte index bdd442e50c..e40d1283d2 100644 --- a/web/src/lib/components/photos-page/actions/delete-assets.svelte +++ b/web/src/lib/components/photos-page/actions/delete-assets.svelte @@ -7,6 +7,9 @@ import { type OnDelete, deleteAssets } from '$lib/utils/actions'; import DeleteAssetDialog from '../delete-asset-dialog.svelte'; import { t } from 'svelte-i18n'; + import { deleteStacks, getStack } from '@immich/sdk'; + + import { handleError } from '$lib/utils/handle-error'; interface Props { onAssetDelete: OnDelete; @@ -34,8 +37,36 @@ const handleDelete = async () => { loading = true; - const ids = [...getOwnedAssets()].map((a) => a.id); - await deleteAssets(force, onAssetDelete, ids); + const ownedAssets = [...getOwnedAssets()]; + + try { + const stackIds: string[] = []; + const pendingAssetIds: Array> = []; + const assetIds: string[] = []; + for (const asset of ownedAssets) { + let stackId = asset.stack?.id; + + if (stackId) { + stackIds.push(stackId); + + const assetIds = getStack({ id: stackId }).then((stack) => stack.assets.map((asset) => asset.id)); + pendingAssetIds.push(assetIds); + } else { + assetIds.push(asset.id); + } + } + + let fetchedAssetIds = await Promise.all(pendingAssetIds); + const ids = assetIds.concat(...fetchedAssetIds.flat()); + + if (stackIds.length > 0) { + await deleteStacks({ bulkIdsDto: { ids: stackIds } }); + } + await deleteAssets(force, onAssetDelete, ids); + } catch (error) { + handleError(error, $t('errors.unable_to_delete_assets')); + } + clearSelect(); isShowConfirmation = false; loading = false;