mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
refactor: adjust favorite, delete, and archive actions for timeline
- Pass TimelineManager instance to timeline action components instead of callbacks - Move asset update logic (delete, archive, favorite) into action components
This commit is contained in:
parent
e5fce47c0c
commit
98ab224791
12 changed files with 74 additions and 104 deletions
|
|
@ -161,7 +161,24 @@ export class NotificationService extends BaseService {
|
||||||
|
|
||||||
const [asset] = await this.assetRepository.getByIdsWithAllRelationsButStacks([assetId]);
|
const [asset] = await this.assetRepository.getByIdsWithAllRelationsButStacks([assetId]);
|
||||||
if (asset) {
|
if (asset) {
|
||||||
this.eventRepository.clientSend('on_asset_update', userId, mapAsset(asset));
|
// need to specify authDto to this mapAsset request, because it tries to prevent
|
||||||
|
// leaking information PR#7580 which expects a userId in the auth options object
|
||||||
|
this.eventRepository.clientSend(
|
||||||
|
'on_asset_update',
|
||||||
|
userId,
|
||||||
|
mapAsset(asset, {
|
||||||
|
auth: {
|
||||||
|
user: {
|
||||||
|
id: userId,
|
||||||
|
isAdmin: false,
|
||||||
|
name: '',
|
||||||
|
email: '',
|
||||||
|
quotaUsageInBytes: 0,
|
||||||
|
quotaSizeInBytes: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getAssetControlContext } from '$lib/components/timeline/AssetSelectControlBar.svelte';
|
import { getAssetControlContext } from '$lib/components/timeline/AssetSelectControlBar.svelte';
|
||||||
|
import type { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
|
||||||
import type { OnArchive } from '$lib/utils/actions';
|
import type { OnArchive } from '$lib/utils/actions';
|
||||||
import { archiveAssets } from '$lib/utils/asset-utils';
|
import { archiveAssets } from '$lib/utils/asset-utils';
|
||||||
import { AssetVisibility } from '@immich/sdk';
|
import { AssetVisibility } from '@immich/sdk';
|
||||||
|
|
@ -12,9 +13,10 @@
|
||||||
onArchive?: OnArchive;
|
onArchive?: OnArchive;
|
||||||
menuItem?: boolean;
|
menuItem?: boolean;
|
||||||
unarchive?: boolean;
|
unarchive?: boolean;
|
||||||
|
manager?: TimelineManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { onArchive, menuItem = false, unarchive = false }: Props = $props();
|
let { onArchive, menuItem = false, unarchive = false, manager }: Props = $props();
|
||||||
|
|
||||||
let text = $derived(unarchive ? $t('unarchive') : $t('to_archive'));
|
let text = $derived(unarchive ? $t('unarchive') : $t('to_archive'));
|
||||||
let icon = $derived(unarchive ? mdiArchiveArrowUpOutline : mdiArchiveArrowDownOutline);
|
let icon = $derived(unarchive ? mdiArchiveArrowUpOutline : mdiArchiveArrowDownOutline);
|
||||||
|
|
@ -24,12 +26,13 @@
|
||||||
const { clearSelect, getOwnedAssets } = getAssetControlContext();
|
const { clearSelect, getOwnedAssets } = getAssetControlContext();
|
||||||
|
|
||||||
const handleArchive = async () => {
|
const handleArchive = async () => {
|
||||||
const isArchived = unarchive ? AssetVisibility.Timeline : AssetVisibility.Archive;
|
const visibility = unarchive ? AssetVisibility.Timeline : AssetVisibility.Archive;
|
||||||
const assets = [...getOwnedAssets()].filter((asset) => asset.visibility !== isArchived);
|
const assets = [...getOwnedAssets()].filter((asset) => asset.visibility !== visibility);
|
||||||
loading = true;
|
loading = true;
|
||||||
const ids = await archiveAssets(assets, isArchived as AssetVisibility);
|
const ids = await archiveAssets(assets, visibility as AssetVisibility);
|
||||||
if (ids) {
|
if (ids) {
|
||||||
onArchive?.(ids, isArchived ? AssetVisibility.Archive : AssetVisibility.Timeline);
|
manager?.updateAssetOperation(ids, (asset) => ((asset.visibility = visibility), void 0));
|
||||||
|
onArchive?.(ids, visibility ? AssetVisibility.Archive : AssetVisibility.Timeline);
|
||||||
clearSelect();
|
clearSelect();
|
||||||
}
|
}
|
||||||
loading = false;
|
loading = false;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import DeleteAssetDialog from '$lib/components/photos-page/delete-asset-dialog.svelte';
|
import DeleteAssetDialog from '$lib/components/photos-page/delete-asset-dialog.svelte';
|
||||||
import { getAssetControlContext } from '$lib/components/timeline/AssetSelectControlBar.svelte';
|
import { getAssetControlContext } from '$lib/components/timeline/AssetSelectControlBar.svelte';
|
||||||
|
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
|
||||||
|
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
|
||||||
import { featureFlags } from '$lib/stores/server-config.store';
|
import { featureFlags } from '$lib/stores/server-config.store';
|
||||||
import { type OnDelete, type OnUndoDelete, deleteAssets } from '$lib/utils/actions';
|
import { type OnDelete, type OnUndoDelete, deleteAssets } from '$lib/utils/actions';
|
||||||
import { IconButton } from '@immich/ui';
|
import { IconButton } from '@immich/ui';
|
||||||
|
|
@ -9,13 +11,14 @@
|
||||||
import MenuOption from '../../shared-components/context-menu/menu-option.svelte';
|
import MenuOption from '../../shared-components/context-menu/menu-option.svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onAssetDelete: OnDelete;
|
onAssetDelete?: OnDelete;
|
||||||
onUndoDelete?: OnUndoDelete | undefined;
|
onUndoDelete?: OnUndoDelete;
|
||||||
menuItem?: boolean;
|
menuItem?: boolean;
|
||||||
force?: boolean;
|
force?: boolean;
|
||||||
|
manager?: TimelineManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { onAssetDelete, onUndoDelete = undefined, menuItem = false, force = !$featureFlags.trash }: Props = $props();
|
let { onAssetDelete, onUndoDelete, menuItem = false, force = !$featureFlags.trash, manager }: Props = $props();
|
||||||
|
|
||||||
const { clearSelect, getOwnedAssets } = getAssetControlContext();
|
const { clearSelect, getOwnedAssets } = getAssetControlContext();
|
||||||
|
|
||||||
|
|
@ -36,7 +39,12 @@
|
||||||
const handleDelete = async () => {
|
const handleDelete = async () => {
|
||||||
loading = true;
|
loading = true;
|
||||||
const assets = [...getOwnedAssets()];
|
const assets = [...getOwnedAssets()];
|
||||||
await deleteAssets(force, onAssetDelete, assets, onUndoDelete);
|
const undo = (assets: TimelineAsset[]) => {
|
||||||
|
manager?.addAssets(assets);
|
||||||
|
onUndoDelete?.(assets);
|
||||||
|
};
|
||||||
|
await deleteAssets(force, onAssetDelete, assets, undo);
|
||||||
|
manager?.removeAssets(assets.map((asset) => asset.id));
|
||||||
clearSelect();
|
clearSelect();
|
||||||
isShowConfirmation = false;
|
isShowConfirmation = false;
|
||||||
loading = false;
|
loading = false;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
notificationController,
|
notificationController,
|
||||||
} from '$lib/components/shared-components/notification/notification';
|
} from '$lib/components/shared-components/notification/notification';
|
||||||
import { getAssetControlContext } from '$lib/components/timeline/AssetSelectControlBar.svelte';
|
import { getAssetControlContext } from '$lib/components/timeline/AssetSelectControlBar.svelte';
|
||||||
|
import type { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
|
||||||
import type { OnFavorite } from '$lib/utils/actions';
|
import type { OnFavorite } from '$lib/utils/actions';
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
import { updateAssets } from '@immich/sdk';
|
import { updateAssets } from '@immich/sdk';
|
||||||
|
|
@ -16,9 +17,10 @@
|
||||||
onFavorite?: OnFavorite;
|
onFavorite?: OnFavorite;
|
||||||
menuItem?: boolean;
|
menuItem?: boolean;
|
||||||
removeFavorite: boolean;
|
removeFavorite: boolean;
|
||||||
|
manager?: TimelineManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { onFavorite, menuItem = false, removeFavorite }: Props = $props();
|
let { onFavorite, menuItem = false, removeFavorite, manager }: Props = $props();
|
||||||
|
|
||||||
let text = $derived(removeFavorite ? $t('remove_from_favorites') : $t('to_favorite'));
|
let text = $derived(removeFavorite ? $t('remove_from_favorites') : $t('to_favorite'));
|
||||||
let icon = $derived(removeFavorite ? mdiHeartMinusOutline : mdiHeartOutline);
|
let icon = $derived(removeFavorite ? mdiHeartMinusOutline : mdiHeartOutline);
|
||||||
|
|
@ -39,11 +41,7 @@
|
||||||
if (ids.length > 0) {
|
if (ids.length > 0) {
|
||||||
await updateAssets({ assetBulkUpdateDto: { ids, isFavorite } });
|
await updateAssets({ assetBulkUpdateDto: { ids, isFavorite } });
|
||||||
}
|
}
|
||||||
|
manager?.updateAssetOperation(ids, (asset) => ((asset.isFavorite = isFavorite), void 0));
|
||||||
for (const asset of assets) {
|
|
||||||
asset.isFavorite = isFavorite;
|
|
||||||
}
|
|
||||||
|
|
||||||
onFavorite?.(ids, isFavorite);
|
onFavorite?.(ids, isFavorite);
|
||||||
|
|
||||||
notificationController.show({
|
notificationController.show({
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ export class DayGroup {
|
||||||
|
|
||||||
const asset = this.viewerAssets[index].asset!;
|
const asset = this.viewerAssets[index].asset!;
|
||||||
const oldTime = { ...asset.localDateTime };
|
const oldTime = { ...asset.localDateTime };
|
||||||
let { remove } = operation(asset);
|
let { remove } = operation(asset) ?? { remove: false };
|
||||||
const newTime = asset.localDateTime;
|
const newTime = asset.localDateTime;
|
||||||
if (oldTime.year !== newTime.year || oldTime.month !== newTime.month || oldTime.day !== newTime.day) {
|
if (oldTime.year !== newTime.year || oldTime.month !== newTime.month || oldTime.day !== newTime.day) {
|
||||||
const { year, month, day } = newTime;
|
const { year, month, day } = newTime;
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ export type TimelineAsset = {
|
||||||
longitude?: number | null;
|
longitude?: number | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AssetOperation = (asset: TimelineAsset) => { remove: boolean };
|
export type AssetOperation = (asset: TimelineAsset) => { remove: boolean } | void;
|
||||||
|
|
||||||
export type MoveAsset = { asset: TimelineAsset; date: TimelineDate };
|
export type MoveAsset = { asset: TimelineAsset; date: TimelineDate };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,15 +21,15 @@ export type OnSetVisibility = (ids: string[]) => void;
|
||||||
|
|
||||||
export const deleteAssets = async (
|
export const deleteAssets = async (
|
||||||
force: boolean,
|
force: boolean,
|
||||||
onAssetDelete: OnDelete,
|
onAssetDelete: OnDelete | undefined,
|
||||||
assets: TimelineAsset[],
|
assets: TimelineAsset[],
|
||||||
onUndoDelete: OnUndoDelete | undefined = undefined,
|
onUndoDelete: OnUndoDelete | undefined,
|
||||||
) => {
|
) => {
|
||||||
const $t = get(t);
|
const $t = get(t);
|
||||||
try {
|
try {
|
||||||
const ids = assets.map((a) => a.id);
|
const ids = assets.map((a) => a.id);
|
||||||
await deleteBulk({ assetBulkDeleteDto: { ids, force } });
|
await deleteBulk({ assetBulkDeleteDto: { ids, force } });
|
||||||
onAssetDelete(ids);
|
onAssetDelete?.(ids);
|
||||||
|
|
||||||
notificationController.show({
|
notificationController.show({
|
||||||
message: force
|
message: force
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@
|
||||||
import { AlbumPageViewMode, AppRoute } from '$lib/constants';
|
import { AlbumPageViewMode, AppRoute } from '$lib/constants';
|
||||||
import { activityManager } from '$lib/managers/activity-manager.svelte';
|
import { activityManager } from '$lib/managers/activity-manager.svelte';
|
||||||
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
|
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
|
||||||
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
|
|
||||||
import AlbumOptionsModal from '$lib/modals/AlbumOptionsModal.svelte';
|
import AlbumOptionsModal from '$lib/modals/AlbumOptionsModal.svelte';
|
||||||
import AlbumShareModal from '$lib/modals/AlbumShareModal.svelte';
|
import AlbumShareModal from '$lib/modals/AlbumShareModal.svelte';
|
||||||
import AlbumUsersModal from '$lib/modals/AlbumUsersModal.svelte';
|
import AlbumUsersModal from '$lib/modals/AlbumUsersModal.svelte';
|
||||||
|
|
@ -262,18 +261,15 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSetVisibility = (assetIds: string[]) => {
|
const handleSetVisibility = () => {
|
||||||
timelineManager.removeAssets(assetIds);
|
|
||||||
assetInteraction.clearMultiselect();
|
assetInteraction.clearMultiselect();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRemoveAssets = async (assetIds: string[]) => {
|
const handleRemoveAssets = async () => {
|
||||||
timelineManager.removeAssets(assetIds);
|
|
||||||
await refreshAlbum();
|
await refreshAlbum();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUndoRemoveAssets = async (assets: TimelineAsset[]) => {
|
const handleUndoRemoveAssets = async () => {
|
||||||
timelineManager.addAssets(assets);
|
|
||||||
await refreshAlbum();
|
await refreshAlbum();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -572,14 +568,7 @@
|
||||||
<AddToAlbum shared />
|
<AddToAlbum shared />
|
||||||
</ButtonContextMenu>
|
</ButtonContextMenu>
|
||||||
{#if assetInteraction.isAllUserOwned}
|
{#if assetInteraction.isAllUserOwned}
|
||||||
<FavoriteAction
|
<FavoriteAction removeFavorite={assetInteraction.isAllFavorite} manager={timelineManager}></FavoriteAction>
|
||||||
removeFavorite={assetInteraction.isAllFavorite}
|
|
||||||
onFavorite={(ids, isFavorite) =>
|
|
||||||
timelineManager.updateAssetOperation(ids, (asset) => {
|
|
||||||
asset.isFavorite = isFavorite;
|
|
||||||
return { remove: false };
|
|
||||||
})}
|
|
||||||
></FavoriteAction>
|
|
||||||
{/if}
|
{/if}
|
||||||
<ButtonContextMenu icon={mdiDotsVertical} title={$t('menu')} offset={{ x: 175, y: 25 }}>
|
<ButtonContextMenu icon={mdiDotsVertical} title={$t('menu')} offset={{ x: 175, y: 25 }}>
|
||||||
<DownloadAction menuItem filename="{album.albumName}.zip" />
|
<DownloadAction menuItem filename="{album.albumName}.zip" />
|
||||||
|
|
@ -594,7 +583,7 @@
|
||||||
onClick={() => updateThumbnailUsingCurrentSelection()}
|
onClick={() => updateThumbnailUsingCurrentSelection()}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
<ArchiveAction menuItem unarchive={assetInteraction.isAllArchived} />
|
<ArchiveAction menuItem unarchive={assetInteraction.isAllArchived} manager={timelineManager} />
|
||||||
<SetVisibilityAction menuItem onVisibilitySet={handleSetVisibility} />
|
<SetVisibilityAction menuItem onVisibilitySet={handleSetVisibility} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|
@ -606,7 +595,12 @@
|
||||||
<RemoveFromAlbum menuItem bind:album onRemove={handleRemoveAssets} />
|
<RemoveFromAlbum menuItem bind:album onRemove={handleRemoveAssets} />
|
||||||
{/if}
|
{/if}
|
||||||
{#if assetInteraction.isAllUserOwned}
|
{#if assetInteraction.isAllUserOwned}
|
||||||
<DeleteAssets menuItem onAssetDelete={handleRemoveAssets} onUndoDelete={handleUndoRemoveAssets} />
|
<DeleteAssets
|
||||||
|
menuItem
|
||||||
|
onAssetDelete={handleRemoveAssets}
|
||||||
|
onUndoDelete={handleUndoRemoveAssets}
|
||||||
|
manager={timelineManager}
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</ButtonContextMenu>
|
</ButtonContextMenu>
|
||||||
</AssetSelectControlBar>
|
</AssetSelectControlBar>
|
||||||
|
|
|
||||||
|
|
@ -65,32 +65,18 @@
|
||||||
assets={assetInteraction.selectedAssets}
|
assets={assetInteraction.selectedAssets}
|
||||||
clearSelect={() => assetInteraction.clearMultiselect()}
|
clearSelect={() => assetInteraction.clearMultiselect()}
|
||||||
>
|
>
|
||||||
<ArchiveAction
|
<ArchiveAction unarchive manager={timelineManager} />
|
||||||
unarchive
|
|
||||||
onArchive={(ids, visibility) =>
|
|
||||||
timelineManager.updateAssetOperation(ids, (asset) => {
|
|
||||||
asset.visibility = visibility;
|
|
||||||
return { remove: false };
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
<CreateSharedLink />
|
<CreateSharedLink />
|
||||||
<SelectAllAssets {timelineManager} {assetInteraction} />
|
<SelectAllAssets {timelineManager} {assetInteraction} />
|
||||||
<ButtonContextMenu icon={mdiPlus} title={$t('add_to')}>
|
<ButtonContextMenu icon={mdiPlus} title={$t('add_to')}>
|
||||||
<AddToAlbum />
|
<AddToAlbum />
|
||||||
<AddToAlbum shared />
|
<AddToAlbum shared />
|
||||||
</ButtonContextMenu>
|
</ButtonContextMenu>
|
||||||
<FavoriteAction
|
<FavoriteAction removeFavorite={assetInteraction.isAllFavorite} manager={timelineManager} />
|
||||||
removeFavorite={assetInteraction.isAllFavorite}
|
|
||||||
onFavorite={(ids, isFavorite) =>
|
|
||||||
timelineManager.updateAssetOperation(ids, (asset) => {
|
|
||||||
asset.isFavorite = isFavorite;
|
|
||||||
return { remove: false };
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
<ButtonContextMenu icon={mdiDotsVertical} title={$t('menu')}>
|
<ButtonContextMenu icon={mdiDotsVertical} title={$t('menu')}>
|
||||||
<DownloadAction menuItem />
|
<DownloadAction menuItem />
|
||||||
<SetVisibilityAction menuItem onVisibilitySet={handleSetVisibility} />
|
<SetVisibilityAction menuItem onVisibilitySet={handleSetVisibility} />
|
||||||
<DeleteAssets menuItem onAssetDelete={(assetIds) => timelineManager.removeAssets(assetIds)} />
|
<DeleteAssets menuItem manager={timelineManager} />
|
||||||
</ButtonContextMenu>
|
</ButtonContextMenu>
|
||||||
</AssetSelectControlBar>
|
</AssetSelectControlBar>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@
|
||||||
assets={assetInteraction.selectedAssets}
|
assets={assetInteraction.selectedAssets}
|
||||||
clearSelect={() => assetInteraction.clearMultiselect()}
|
clearSelect={() => assetInteraction.clearMultiselect()}
|
||||||
>
|
>
|
||||||
<FavoriteAction removeFavorite onFavorite={(assetIds) => timelineManager.removeAssets(assetIds)} />
|
<FavoriteAction removeFavorite manager={timelineManager} />
|
||||||
<CreateSharedLink />
|
<CreateSharedLink />
|
||||||
<SelectAllAssets {timelineManager} {assetInteraction} />
|
<SelectAllAssets {timelineManager} {assetInteraction} />
|
||||||
<ButtonContextMenu icon={mdiPlus} title={$t('add_to')}>
|
<ButtonContextMenu icon={mdiPlus} title={$t('add_to')}>
|
||||||
|
|
@ -83,20 +83,12 @@
|
||||||
<ChangeDate menuItem />
|
<ChangeDate menuItem />
|
||||||
<ChangeDescription menuItem />
|
<ChangeDescription menuItem />
|
||||||
<ChangeLocation menuItem />
|
<ChangeLocation menuItem />
|
||||||
<ArchiveAction
|
<ArchiveAction menuItem unarchive={assetInteraction.isAllArchived} manager={timelineManager} />
|
||||||
menuItem
|
|
||||||
unarchive={assetInteraction.isAllArchived}
|
|
||||||
onArchive={(assetIds) => timelineManager.removeAssets(assetIds)}
|
|
||||||
/>
|
|
||||||
{#if $preferences.tags.enabled}
|
{#if $preferences.tags.enabled}
|
||||||
<TagAction menuItem />
|
<TagAction menuItem />
|
||||||
{/if}
|
{/if}
|
||||||
<SetVisibilityAction menuItem onVisibilitySet={handleSetVisibility} />
|
<SetVisibilityAction menuItem onVisibilitySet={handleSetVisibility} />
|
||||||
<DeleteAssets
|
<DeleteAssets menuItem manager={timelineManager} />
|
||||||
menuItem
|
|
||||||
onAssetDelete={(assetIds) => timelineManager.removeAssets(assetIds)}
|
|
||||||
onUndoDelete={(assets) => timelineManager.addAssets(assets)}
|
|
||||||
/>
|
|
||||||
</ButtonContextMenu>
|
</ButtonContextMenu>
|
||||||
</AssetSelectControlBar>
|
</AssetSelectControlBar>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
||||||
|
|
@ -349,15 +349,8 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteAssets = async (assetIds: string[]) => {
|
const handleDeleteAssets = async () => await updateAssetCount();
|
||||||
timelineManager.removeAssets(assetIds);
|
const handleUndoDeleteAssets = async () => await updateAssetCount();
|
||||||
await updateAssetCount();
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleUndoDeleteAssets = async (assets: TimelineAsset[]) => {
|
|
||||||
timelineManager.addAssets(assets);
|
|
||||||
await updateAssetCount();
|
|
||||||
};
|
|
||||||
|
|
||||||
let person = $derived(data.person);
|
let person = $derived(data.person);
|
||||||
|
|
||||||
|
|
@ -511,14 +504,7 @@
|
||||||
<AddToAlbum />
|
<AddToAlbum />
|
||||||
<AddToAlbum shared />
|
<AddToAlbum shared />
|
||||||
</ButtonContextMenu>
|
</ButtonContextMenu>
|
||||||
<FavoriteAction
|
<FavoriteAction removeFavorite={assetInteraction.isAllFavorite} manager={timelineManager} />
|
||||||
removeFavorite={assetInteraction.isAllFavorite}
|
|
||||||
onFavorite={(ids, isFavorite) =>
|
|
||||||
timelineManager.updateAssetOperation(ids, (asset) => {
|
|
||||||
asset.isFavorite = isFavorite;
|
|
||||||
return { remove: false };
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
<ButtonContextMenu icon={mdiDotsVertical} title={$t('menu')}>
|
<ButtonContextMenu icon={mdiDotsVertical} title={$t('menu')}>
|
||||||
<DownloadAction menuItem filename="{person.name || 'immich'}.zip" />
|
<DownloadAction menuItem filename="{person.name || 'immich'}.zip" />
|
||||||
<MenuOption
|
<MenuOption
|
||||||
|
|
@ -529,19 +515,16 @@
|
||||||
<ChangeDate menuItem />
|
<ChangeDate menuItem />
|
||||||
<ChangeDescription menuItem />
|
<ChangeDescription menuItem />
|
||||||
<ChangeLocation menuItem />
|
<ChangeLocation menuItem />
|
||||||
<ArchiveAction
|
<ArchiveAction menuItem unarchive={assetInteraction.isAllArchived} manager={timelineManager} />
|
||||||
menuItem
|
|
||||||
unarchive={assetInteraction.isAllArchived}
|
|
||||||
onArchive={(assetIds) => timelineManager.removeAssets(assetIds)}
|
|
||||||
/>
|
|
||||||
{#if $preferences.tags.enabled && assetInteraction.isAllUserOwned}
|
{#if $preferences.tags.enabled && assetInteraction.isAllUserOwned}
|
||||||
<TagAction menuItem />
|
<TagAction menuItem />
|
||||||
{/if}
|
{/if}
|
||||||
<SetVisibilityAction menuItem onVisibilitySet={handleSetVisibility} />
|
<SetVisibilityAction menuItem onVisibilitySet={handleSetVisibility} />
|
||||||
<DeleteAssets
|
<DeleteAssets
|
||||||
menuItem
|
menuItem
|
||||||
onAssetDelete={(assetIds) => handleDeleteAssets(assetIds)}
|
manager={timelineManager}
|
||||||
onUndoDelete={(assets) => handleUndoDeleteAssets(assets)}
|
onAssetDelete={handleDeleteAssets}
|
||||||
|
onUndoDelete={handleUndoDeleteAssets}
|
||||||
/>
|
/>
|
||||||
</ButtonContextMenu>
|
</ButtonContextMenu>
|
||||||
</AssetSelectControlBar>
|
</AssetSelectControlBar>
|
||||||
|
|
|
||||||
|
|
@ -118,14 +118,7 @@
|
||||||
<AddToAlbum />
|
<AddToAlbum />
|
||||||
<AddToAlbum shared />
|
<AddToAlbum shared />
|
||||||
</ButtonContextMenu>
|
</ButtonContextMenu>
|
||||||
<FavoriteAction
|
<FavoriteAction removeFavorite={assetInteraction.isAllFavorite} manager={timelineManager}></FavoriteAction>
|
||||||
removeFavorite={assetInteraction.isAllFavorite}
|
|
||||||
onFavorite={(ids, isFavorite) =>
|
|
||||||
timelineManager.updateAssetOperation(ids, (asset) => {
|
|
||||||
asset.isFavorite = isFavorite;
|
|
||||||
return { remove: false };
|
|
||||||
})}
|
|
||||||
></FavoriteAction>
|
|
||||||
<ButtonContextMenu icon={mdiDotsVertical} title={$t('menu')}>
|
<ButtonContextMenu icon={mdiDotsVertical} title={$t('menu')}>
|
||||||
<DownloadAction menuItem />
|
<DownloadAction menuItem />
|
||||||
{#if assetInteraction.selectedAssets.length > 1 || isAssetStackSelected}
|
{#if assetInteraction.selectedAssets.length > 1 || isAssetStackSelected}
|
||||||
|
|
@ -146,15 +139,11 @@
|
||||||
<ChangeDate menuItem />
|
<ChangeDate menuItem />
|
||||||
<ChangeDescription menuItem />
|
<ChangeDescription menuItem />
|
||||||
<ChangeLocation menuItem />
|
<ChangeLocation menuItem />
|
||||||
<ArchiveAction menuItem onArchive={(assetIds) => timelineManager.removeAssets(assetIds)} />
|
<ArchiveAction menuItem manager={timelineManager} />
|
||||||
{#if $preferences.tags.enabled}
|
{#if $preferences.tags.enabled}
|
||||||
<TagAction menuItem />
|
<TagAction menuItem />
|
||||||
{/if}
|
{/if}
|
||||||
<DeleteAssets
|
<DeleteAssets menuItem manager={timelineManager} />
|
||||||
menuItem
|
|
||||||
onAssetDelete={(assetIds) => timelineManager.removeAssets(assetIds)}
|
|
||||||
onUndoDelete={(assets) => timelineManager.addAssets(assets)}
|
|
||||||
/>
|
|
||||||
<SetVisibilityAction menuItem onVisibilitySet={handleSetVisibility} />
|
<SetVisibilityAction menuItem onVisibilitySet={handleSetVisibility} />
|
||||||
<hr />
|
<hr />
|
||||||
<AssetJobActions />
|
<AssetJobActions />
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue