mirror of
https://github.com/immich-app/immich.git
synced 2024-11-21 18:16:55 +02:00
feat(web): Implement keep this delete others for asset stacks (#14217)
This commit is contained in:
parent
bcd17c2ebe
commit
1737013e66
@ -465,6 +465,7 @@
|
||||
"confirm": "Confirm",
|
||||
"confirm_admin_password": "Confirm Admin Password",
|
||||
"confirm_delete_shared_link": "Are you sure you want to delete this shared link?",
|
||||
"confirm_keep_this_delete_others": "All other assets in the stack will be deleted except for this asset. Are you sure you want to continue?",
|
||||
"confirm_password": "Confirm password",
|
||||
"contain": "Contain",
|
||||
"context": "Context",
|
||||
@ -514,6 +515,7 @@
|
||||
"delete_key": "Delete key",
|
||||
"delete_library": "Delete Library",
|
||||
"delete_link": "Delete link",
|
||||
"delete_others": "Delete others",
|
||||
"delete_shared_link": "Delete shared link",
|
||||
"delete_tag": "Delete tag",
|
||||
"delete_tag_confirmation_prompt": "Are you sure you want to delete {tagName} tag?",
|
||||
@ -610,6 +612,7 @@
|
||||
"failed_to_remove_product_key": "Failed to remove product key",
|
||||
"failed_to_stack_assets": "Failed to stack assets",
|
||||
"failed_to_unstack_assets": "Failed to un-stack assets",
|
||||
"failed_to_keep_this_delete_others": "Failed to keep this asset and delete the other assets",
|
||||
"import_path_already_exists": "This import path already exists.",
|
||||
"incorrect_email_or_password": "Incorrect email or password",
|
||||
"paths_validation_failed": "{paths, plural, one {# path} other {# paths}} failed validation",
|
||||
@ -1253,8 +1256,10 @@
|
||||
"unselect_all_duplicates": "Unselect all duplicates",
|
||||
"unstack": "Un-stack",
|
||||
"unstacked_assets_count": "Un-stacked {count, plural, one {# asset} other {# assets}}",
|
||||
"keep_this_delete_others": "Keep this, delete others",
|
||||
"untracked_files": "Untracked files",
|
||||
"untracked_files_decription": "These files are not tracked by the application. They can be the results of failed moves, interrupted uploads, or left behind due to a bug",
|
||||
"kept_this_deleted_others": "Kept this asset and deleted {count, plural, one {# asset} other {# assets}}",
|
||||
"up_next": "Up next",
|
||||
"updated_password": "Updated password",
|
||||
"upload": "Upload",
|
||||
|
@ -12,6 +12,7 @@ type ActionMap = {
|
||||
[AssetAction.ADD]: { asset: AssetResponseDto };
|
||||
[AssetAction.ADD_TO_ALBUM]: { asset: AssetResponseDto; album: AlbumResponseDto };
|
||||
[AssetAction.UNSTACK]: { assets: AssetResponseDto[] };
|
||||
[AssetAction.KEEP_THIS_DELETE_OTHERS]: { asset: AssetResponseDto };
|
||||
};
|
||||
|
||||
export type Action = {
|
||||
|
@ -0,0 +1,33 @@
|
||||
<script lang="ts">
|
||||
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||
import { AssetAction } from '$lib/constants';
|
||||
import { keepThisDeleteOthers } from '$lib/utils/asset-utils';
|
||||
import type { AssetResponseDto, StackResponseDto } from '@immich/sdk';
|
||||
import { mdiPinOutline } from '@mdi/js';
|
||||
import type { OnAction } from './action';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { dialogController } from '$lib/components/shared-components/dialog/dialog';
|
||||
|
||||
export let stack: StackResponseDto;
|
||||
export let asset: AssetResponseDto;
|
||||
export let onAction: OnAction;
|
||||
|
||||
const handleKeepThisDeleteOthers = async () => {
|
||||
const isConfirmed = await dialogController.show({
|
||||
title: $t('keep_this_delete_others'),
|
||||
prompt: $t('confirm_keep_this_delete_others'),
|
||||
confirmText: $t('delete_others'),
|
||||
});
|
||||
|
||||
if (!isConfirmed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const keptAsset = await keepThisDeleteOthers(asset, stack);
|
||||
if (keptAsset) {
|
||||
onAction({ type: AssetAction.UNSTACK, assets: [keptAsset] });
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<MenuOption icon={mdiPinOutline} onClick={handleKeepThisDeleteOthers} text={$t('keep_this_delete_others')} />
|
@ -13,6 +13,7 @@
|
||||
import ShareAction from '$lib/components/asset-viewer/actions/share-action.svelte';
|
||||
import ShowDetailAction from '$lib/components/asset-viewer/actions/show-detail-action.svelte';
|
||||
import UnstackAction from '$lib/components/asset-viewer/actions/unstack-action.svelte';
|
||||
import KeepThisDeleteOthersAction from '$lib/components/asset-viewer/actions/keep-this-delete-others.svelte';
|
||||
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
|
||||
import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte';
|
||||
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||
@ -166,6 +167,7 @@
|
||||
{#if isOwner}
|
||||
{#if stack}
|
||||
<UnstackAction {stack} {onAction} />
|
||||
<KeepThisDeleteOthersAction {stack} {asset} {onAction} />
|
||||
{/if}
|
||||
{#if album}
|
||||
<SetAlbumCoverAction {asset} {album} />
|
||||
|
@ -379,6 +379,7 @@
|
||||
break;
|
||||
}
|
||||
|
||||
case AssetAction.KEEP_THIS_DELETE_OTHERS:
|
||||
case AssetAction.UNSTACK: {
|
||||
closeViewer();
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ export enum AssetAction {
|
||||
ADD = 'add',
|
||||
ADD_TO_ALBUM = 'add-to-album',
|
||||
UNSTACK = 'unstack',
|
||||
KEEP_THIS_DELETE_OTHERS = 'keep-this-delete-others',
|
||||
}
|
||||
|
||||
export enum AppRoute {
|
||||
|
@ -14,6 +14,7 @@ import { getFormatter } from '$lib/utils/i18n';
|
||||
import {
|
||||
addAssetsToAlbum as addAssets,
|
||||
createStack,
|
||||
deleteAssets,
|
||||
deleteStacks,
|
||||
getAssetInfo,
|
||||
getBaseUrl,
|
||||
@ -27,6 +28,7 @@ import {
|
||||
type AssetResponseDto,
|
||||
type AssetTypeEnum,
|
||||
type DownloadInfoDto,
|
||||
type StackResponseDto,
|
||||
type UserPreferencesResponseDto,
|
||||
type UserResponseDto,
|
||||
} from '@immich/sdk';
|
||||
@ -438,6 +440,26 @@ export const deleteStack = async (stackIds: string[]) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const keepThisDeleteOthers = async (keepAsset: AssetResponseDto, stack: StackResponseDto) => {
|
||||
const $t = get(t);
|
||||
|
||||
try {
|
||||
const assetsToDeleteIds = stack.assets.filter((asset) => asset.id !== keepAsset.id).map((asset) => asset.id);
|
||||
await deleteAssets({ assetBulkDeleteDto: { ids: assetsToDeleteIds } });
|
||||
await deleteStacks({ bulkIdsDto: { ids: [stack.id] } });
|
||||
|
||||
notificationController.show({
|
||||
type: NotificationType.Info,
|
||||
message: $t('kept_this_deleted_others', { values: { count: assetsToDeleteIds.length } }),
|
||||
});
|
||||
|
||||
keepAsset.stack = null;
|
||||
return keepAsset;
|
||||
} catch (error) {
|
||||
handleError(error, $t('errors.failed_to_keep_this_delete_others'));
|
||||
}
|
||||
};
|
||||
|
||||
export const selectAllAssets = async (assetStore: AssetStore, assetInteractionStore: AssetInteractionStore) => {
|
||||
if (get(isSelectingAllAssets)) {
|
||||
// Selection is already ongoing
|
||||
|
Loading…
Reference in New Issue
Block a user