mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
8e97c584cf
Consolidates asset operation logic within TimelineManager class and removes the now redundant
operations-support.svelte.ts file.
Combines addAsset/updateAsset to be upsertAsset.
Changes:
- Move `addAssetsToMonthGroups` logic into TimelineManager's `addAssetsToSegments`, `upsertAssetIntoSegment`, `postCreateSegments`, and `postUpsert` methods
- Move `runAssetOperation` from operations-support into TimelineManager's private `#runAssetOperation` method
- Rename public `addAssets`/`updateAssets` methods to unified `upsertAssets` for consistency
- Delete internal/operations-support.svelte.ts
- Update WebsocketSupport to use `upsertAssets` for both add and update operations
- Fix AssetOperation return type to allow undefined/void operations (not just `{ remove: boolean }`)
- Update MonthGroup constructor to accept `loaded` parameter for better initialization control
- Update all test references from `addAssets`/`updateAssets` to `upsertAssets`
This refactoring improves code maintainability by eliminating duplicate logic and consolidating all asset operations within the TimelineManager class where they belong.
114 lines
4.2 KiB
TypeScript
114 lines
4.2 KiB
TypeScript
import ToastAction from '$lib/components/ToastAction.svelte';
|
|
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
|
|
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
|
|
import type { StackResponse } from '$lib/utils/asset-utils';
|
|
import { AssetVisibility, deleteAssets as deleteBulk, restoreAssets } from '@immich/sdk';
|
|
import { toastManager } from '@immich/ui';
|
|
import { t } from 'svelte-i18n';
|
|
import { get } from 'svelte/store';
|
|
import { handleError } from './handle-error';
|
|
|
|
export type OnDelete = (assetIds: string[]) => void;
|
|
export type OnUndoDelete = (assets: TimelineAsset[]) => void;
|
|
export type OnRestore = (ids: string[]) => void;
|
|
export type OnLink = (assets: { still: TimelineAsset; motion: TimelineAsset }) => void;
|
|
export type OnUnlink = (assets: { still: TimelineAsset; motion: TimelineAsset }) => void;
|
|
export type OnAddToAlbum = (ids: string[], albumId: string) => void;
|
|
export type OnArchive = (ids: string[], visibility: AssetVisibility) => void;
|
|
export type OnFavorite = (ids: string[], favorite: boolean) => void;
|
|
export type OnStack = (result: StackResponse) => void;
|
|
export type OnUnstack = (assets: TimelineAsset[]) => void;
|
|
export type OnSetVisibility = (ids: string[]) => void;
|
|
|
|
export const deleteAssets = async (
|
|
force: boolean,
|
|
onAssetDelete: OnDelete,
|
|
assets: TimelineAsset[],
|
|
onUndoDelete: OnUndoDelete | undefined = undefined,
|
|
) => {
|
|
const $t = get(t);
|
|
try {
|
|
const ids = assets.map((a) => a.id);
|
|
await deleteBulk({ assetBulkDeleteDto: { ids, force } });
|
|
onAssetDelete(ids);
|
|
|
|
toastManager.custom(
|
|
{
|
|
component: ToastAction,
|
|
props: {
|
|
title: $t('success'),
|
|
description: force
|
|
? $t('assets_permanently_deleted_count')
|
|
: $t('assets_trashed_count', { values: { count: ids.length } }),
|
|
color: 'success',
|
|
button:
|
|
onUndoDelete && !force
|
|
? {
|
|
color: 'secondary',
|
|
text: $t('undo'),
|
|
onClick: () => undoDeleteAssets(onUndoDelete, assets),
|
|
}
|
|
: undefined,
|
|
},
|
|
},
|
|
{ timeout: 5000 },
|
|
);
|
|
} catch (error) {
|
|
handleError(error, $t('errors.unable_to_delete_assets'));
|
|
}
|
|
};
|
|
|
|
const undoDeleteAssets = async (onUndoDelete: OnUndoDelete, assets: TimelineAsset[]) => {
|
|
const $t = get(t);
|
|
try {
|
|
const ids = assets.map((a) => a.id);
|
|
await restoreAssets({ bulkIdsDto: { ids } });
|
|
onUndoDelete?.(assets);
|
|
} catch (error) {
|
|
handleError(error, $t('errors.unable_to_restore_assets'));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Update the asset stack state in the asset store based on the provided stack response.
|
|
* This function updates the stack information so that the icon is shown for the primary asset
|
|
* and removes any assets from the timeline that are marked for deletion.
|
|
*
|
|
* @param {TimelineManager} timelineManager - The timeline manager to update.
|
|
* @param {StackResponse} stackResponse - The stack response containing the stack and assets to delete.
|
|
*/
|
|
export function updateStackedAssetInTimeline(timelineManager: TimelineManager, { stack, toDeleteIds }: StackResponse) {
|
|
if (stack != undefined) {
|
|
timelineManager.updateAssetOperation([stack.primaryAssetId], (asset) => {
|
|
asset.stack = {
|
|
id: stack.id,
|
|
primaryAssetId: stack.primaryAssetId,
|
|
assetCount: stack.assets.length,
|
|
};
|
|
return { remove: false };
|
|
});
|
|
|
|
timelineManager.removeAssets(toDeleteIds);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update the timeline manager to reflect the unstacked state of assets.
|
|
* This function updates the stack property of each asset to undefined, effectively unstacking them.
|
|
* It also adds the unstacked assets back to the timeline manager.
|
|
*
|
|
* @param timelineManager - The timeline manager to update.
|
|
* @param assets - The array of asset response DTOs to update in the timeline manager.
|
|
*/
|
|
export function updateUnstackedAssetInTimeline(timelineManager: TimelineManager, assets: TimelineAsset[]) {
|
|
timelineManager.updateAssetOperation(
|
|
assets.map((asset) => asset.id),
|
|
(asset) => {
|
|
asset.stack = null;
|
|
return { remove: false };
|
|
},
|
|
);
|
|
|
|
timelineManager.upsertAssets(assets);
|
|
}
|