refactor: add to album (#26366)

This commit is contained in:
Jason Rasmussen
2026-02-19 15:27:30 -05:00
committed by GitHub
parent 8eec3c810e
commit 1d11106dd0
23 changed files with 202 additions and 242 deletions
@@ -14,7 +14,6 @@
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte';
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte';
import AddToAlbum from '$lib/components/timeline/actions/AddToAlbumAction.svelte';
import ArchiveAction from '$lib/components/timeline/actions/ArchiveAction.svelte';
import ChangeDate from '$lib/components/timeline/actions/ChangeDateAction.svelte';
import ChangeDescription from '$lib/components/timeline/actions/ChangeDescriptionAction.svelte';
@@ -45,6 +44,7 @@
handleDownloadAlbum,
} from '$lib/services/album.service';
import { getGlobalActions } from '$lib/services/app.service';
import { getAssetBulkActions } from '$lib/services/asset.service';
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
import { SlideshowNavigation, SlideshowState, slideshowStore } from '$lib/stores/slideshow.store';
@@ -438,9 +438,11 @@
assets={assetInteraction.selectedAssets}
clearSelect={() => assetInteraction.clearMultiselect()}
>
{@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())}
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
<CreateSharedLink />
<SelectAllAssets {timelineManager} {assetInteraction} />
<AddToAlbum />
<ActionButton action={Actions.AddToAlbum} />
{#if assetInteraction.isAllUserOwned}
<FavoriteAction
removeFavorite={assetInteraction.isAllFavorite}
@@ -2,7 +2,6 @@
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte';
import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
import AddToAlbum from '$lib/components/timeline/actions/AddToAlbumAction.svelte';
import ArchiveAction from '$lib/components/timeline/actions/ArchiveAction.svelte';
import CreateSharedLink from '$lib/components/timeline/actions/CreateSharedLinkAction.svelte';
import DeleteAssets from '$lib/components/timeline/actions/DeleteAssetsAction.svelte';
@@ -15,8 +14,10 @@
import SetVisibilityAction from '$lib/components/timeline/actions/SetVisibilityAction.svelte';
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
import { getAssetBulkActions } from '$lib/services/asset.service';
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
import { AssetVisibility } from '@immich/sdk';
import { ActionButton, CommandPaletteDefaultProvider } from '@immich/ui';
import { mdiDotsVertical } from '@mdi/js';
import { t } from 'svelte-i18n';
import type { PageData } from './$types';
@@ -64,13 +65,15 @@
assets={assetInteraction.selectedAssets}
clearSelect={() => assetInteraction.clearMultiselect()}
>
{@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())}
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
<ArchiveAction
unarchive
onArchive={(ids, visibility) => timelineManager.update(ids, (asset) => (asset.visibility = visibility))}
/>
<CreateSharedLink />
<SelectAllAssets {timelineManager} {assetInteraction} />
<AddToAlbum />
<ActionButton action={Actions.AddToAlbum} />
<FavoriteAction
removeFavorite={assetInteraction.isAllFavorite}
onFavorite={(ids, isFavorite) => timelineManager.update(ids, (asset) => (asset.isFavorite = isFavorite))}
@@ -2,7 +2,6 @@
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte';
import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
import AddToAlbum from '$lib/components/timeline/actions/AddToAlbumAction.svelte';
import ArchiveAction from '$lib/components/timeline/actions/ArchiveAction.svelte';
import ChangeDate from '$lib/components/timeline/actions/ChangeDateAction.svelte';
import ChangeDescription from '$lib/components/timeline/actions/ChangeDescriptionAction.svelte';
@@ -17,8 +16,10 @@
import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte';
import Timeline from '$lib/components/timeline/Timeline.svelte';
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
import { getAssetBulkActions } from '$lib/services/asset.service';
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
import { preferences } from '$lib/stores/user.store';
import { ActionButton, CommandPaletteDefaultProvider } from '@immich/ui';
import { mdiDotsVertical } from '@mdi/js';
import { t } from 'svelte-i18n';
import type { PageData } from './$types';
@@ -68,10 +69,12 @@
assets={assetInteraction.selectedAssets}
clearSelect={() => assetInteraction.clearMultiselect()}
>
{@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())}
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
<FavoriteAction removeFavorite onFavorite={(assetIds) => timelineManager.removeAssets(assetIds)} />
<CreateSharedLink />
<SelectAllAssets {timelineManager} {assetInteraction} />
<AddToAlbum />
<ActionButton action={Actions.AddToAlbum} />
<ButtonContextMenu icon={mdiDotsVertical} title={$t('menu')}>
<DownloadAction menuItem />
<ChangeDate menuItem />
@@ -8,7 +8,6 @@
import TreeItemThumbnails from '$lib/components/shared-components/tree/tree-item-thumbnails.svelte';
import TreeItems from '$lib/components/shared-components/tree/tree-items.svelte';
import Sidebar from '$lib/components/sidebar/sidebar.svelte';
import AddToAlbum from '$lib/components/timeline/actions/AddToAlbumAction.svelte';
import ArchiveAction from '$lib/components/timeline/actions/ArchiveAction.svelte';
import ChangeDate from '$lib/components/timeline/actions/ChangeDateAction.svelte';
import ChangeDescription from '$lib/components/timeline/actions/ChangeDescriptionAction.svelte';
@@ -27,10 +26,9 @@
import { foldersStore } from '$lib/stores/folders.svelte';
import { preferences } from '$lib/stores/user.store';
import { cancelMultiselect } from '$lib/utils/asset-utils';
import { getAssetControlContext } from '$lib/utils/context';
import { toTimelineAsset } from '$lib/utils/timeline-util';
import { joinPaths } from '$lib/utils/tree-utils';
import { IconButton, Text } from '@immich/ui';
import { ActionButton, CommandPaletteDefaultProvider, IconButton, Text } from '@immich/ui';
import { mdiDotsVertical, mdiFolder, mdiFolderHome, mdiFolderOutline, mdiSelectAll } from '@mdi/js';
import { t } from 'svelte-i18n';
import type { PageData } from './$types';
@@ -119,8 +117,8 @@
assets={assetInteraction.selectedAssets}
clearSelect={() => cancelMultiselect(assetInteraction)}
>
{@const Actions = getAssetBulkActions($t, getAssetControlContext())}
{@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())}
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
<CreateSharedLink />
<IconButton
shape="round"
@@ -130,7 +128,7 @@
icon={mdiSelectAll}
onclick={handleSelectAllAssets}
/>
<AddToAlbum onAddToAlbum={() => cancelMultiselect(assetInteraction)} />
<ActionButton action={Actions.AddToAlbum} />
<FavoriteAction
removeFavorite={assetInteraction.isAllFavorite}
onFavorite={function handleFavoriteUpdate(ids, isFavorite) {
@@ -1,17 +1,18 @@
<script lang="ts">
import { goto } from '$app/navigation';
import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte';
import AddToAlbum from '$lib/components/timeline/actions/AddToAlbumAction.svelte';
import CreateSharedLink from '$lib/components/timeline/actions/CreateSharedLinkAction.svelte';
import DownloadAction from '$lib/components/timeline/actions/DownloadAction.svelte';
import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte';
import Timeline from '$lib/components/timeline/Timeline.svelte';
import { Route } from '$lib/route';
import { getAssetBulkActions } from '$lib/services/asset.service';
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
import { AssetVisibility } from '@immich/sdk';
import { ActionButton, CommandPaletteDefaultProvider } from '@immich/ui';
import { mdiArrowLeft } from '@mdi/js';
import type { PageData } from './$types';
import { t } from 'svelte-i18n';
import type { PageData } from './$types';
interface Props {
data: PageData;
@@ -44,8 +45,10 @@
assets={assetInteraction.selectedAssets}
clearSelect={() => assetInteraction.clearMultiselect()}
>
{@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())}
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
<CreateSharedLink />
<AddToAlbum />
<ActionButton action={Actions.AddToAlbum} />
<DownloadAction />
</AssetSelectControlBar>
{:else}
@@ -12,7 +12,6 @@
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';
import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte';
import AddToAlbum from '$lib/components/timeline/actions/AddToAlbumAction.svelte';
import ArchiveAction from '$lib/components/timeline/actions/ArchiveAction.svelte';
import ChangeDate from '$lib/components/timeline/actions/ChangeDateAction.svelte';
import ChangeDescription from '$lib/components/timeline/actions/ChangeDescriptionAction.svelte';
@@ -31,6 +30,7 @@
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
import PersonMergeSuggestionModal from '$lib/modals/PersonMergeSuggestionModal.svelte';
import { Route } from '$lib/route';
import { getAssetBulkActions } from '$lib/services/asset.service';
import { getPersonActions } from '$lib/services/person.service';
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
import { locale } from '$lib/stores/preferences.store';
@@ -40,7 +40,15 @@
import { handleError } from '$lib/utils/handle-error';
import { isExternalUrl } from '$lib/utils/navigation';
import { AssetVisibility, searchPerson, updatePerson, type PersonResponseDto } from '@immich/sdk';
import { ContextMenuButton, LoadingSpinner, modalManager, toastManager, type ActionItem } from '@immich/ui';
import {
ActionButton,
CommandPaletteDefaultProvider,
ContextMenuButton,
LoadingSpinner,
modalManager,
toastManager,
type ActionItem,
} from '@immich/ui';
import { mdiAccountBoxOutline, mdiAccountMultipleCheckOutline, mdiArrowLeft, mdiDotsVertical } from '@mdi/js';
import { DateTime } from 'luxon';
import { onMount } from 'svelte';
@@ -455,9 +463,11 @@
assets={assetInteraction.selectedAssets}
clearSelect={() => assetInteraction.clearMultiselect()}
>
{@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())}
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
<CreateSharedLink />
<SelectAllAssets {timelineManager} {assetInteraction} />
<AddToAlbum />
<ActionButton action={Actions.AddToAlbum} />
<FavoriteAction
removeFavorite={assetInteraction.isAllFavorite}
onFavorite={(ids, isFavorite) => timelineManager.update(ids, (asset) => (asset.isFavorite = isFavorite))}
@@ -4,7 +4,6 @@
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte';
import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
import AddToAlbum from '$lib/components/timeline/actions/AddToAlbumAction.svelte';
import ArchiveAction from '$lib/components/timeline/actions/ArchiveAction.svelte';
import ChangeDate from '$lib/components/timeline/actions/ChangeDateAction.svelte';
import ChangeDescription from '$lib/components/timeline/actions/ChangeDescriptionAction.svelte';
@@ -36,12 +35,11 @@
type OnLink,
type OnUnlink,
} from '$lib/utils/actions';
import { getAssetControlContext } from '$lib/utils/context';
import { openFileUploadDialog } from '$lib/utils/file-uploader';
import { getAltText } from '$lib/utils/thumbnail-util';
import { toTimelineAsset } from '$lib/utils/timeline-util';
import { AssetVisibility } from '@immich/sdk';
import { ImageCarousel } from '@immich/ui';
import { ActionButton, CommandPaletteDefaultProvider, ImageCarousel } from '@immich/ui';
import { mdiDotsVertical } from '@mdi/js';
import { t } from 'svelte-i18n';
@@ -130,11 +128,12 @@
assets={assetInteraction.selectedAssets}
clearSelect={() => assetInteraction.clearMultiselect()}
>
{@const Actions = getAssetBulkActions($t, getAssetControlContext())}
{@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())}
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
<CreateSharedLink />
<SelectAllAssets {timelineManager} {assetInteraction} />
<AddToAlbum />
<ActionButton action={Actions.AddToAlbum} />
{#if isAllUserOwned}
<FavoriteAction
@@ -2,11 +2,11 @@
import { afterNavigate, goto } from '$app/navigation';
import { page } from '$app/state';
import ActionMenuItem from '$lib/components/ActionMenuItem.svelte';
import OnEvents from '$lib/components/OnEvents.svelte';
import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte';
import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte';
import GalleryViewer from '$lib/components/shared-components/gallery-viewer/gallery-viewer.svelte';
import SearchBar from '$lib/components/shared-components/search-bar/search-bar.svelte';
import AddToAlbum from '$lib/components/timeline/actions/AddToAlbumAction.svelte';
import ArchiveAction from '$lib/components/timeline/actions/ArchiveAction.svelte';
import ChangeDate from '$lib/components/timeline/actions/ChangeDateAction.svelte';
import ChangeDescription from '$lib/components/timeline/actions/ChangeDescriptionAction.svelte';
@@ -28,7 +28,6 @@
import { preferences, user } from '$lib/stores/user.store';
import { handlePromiseError } from '$lib/utils';
import { cancelMultiselect } from '$lib/utils/asset-utils';
import { getAssetControlContext } from '$lib/utils/context';
import { parseUtcDate } from '$lib/utils/date-time';
import { handleError } from '$lib/utils/handle-error';
import { isAlbumsRoute, isPeopleRoute } from '$lib/utils/navigation';
@@ -43,7 +42,7 @@
searchSmart,
type SmartSearchDto,
} from '@immich/sdk';
import { Icon, IconButton, LoadingSpinner } from '@immich/ui';
import { ActionButton, CommandPaletteDefaultProvider, Icon, IconButton, LoadingSpinner } from '@immich/ui';
import { mdiArrowLeft, mdiDotsVertical, mdiImageOffOutline, mdiSelectAll } from '@mdi/js';
import { tick, untrack } from 'svelte';
import { t } from 'svelte-i18n';
@@ -232,7 +231,7 @@
return tagNames.join(', ');
}
const onAddToAlbum = (assetIds: string[]) => {
const onAlbumAddAssets = ({ assetIds }: { assetIds: string[] }) => {
cancelMultiselect(assetInteraction);
if (terms.isNotInAlbum.toString() == 'true') {
@@ -248,6 +247,8 @@
<svelte:window bind:scrollY />
<OnEvents {onAlbumAddAssets} />
{#if terms}
<section
id="search-chips"
@@ -328,7 +329,8 @@
assets={assetInteraction.selectedAssets}
clearSelect={() => cancelMultiselect(assetInteraction)}
>
{@const Actions = getAssetBulkActions($t, getAssetControlContext())}
{@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())}
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
<CreateSharedLink />
<IconButton
@@ -339,7 +341,7 @@
icon={mdiSelectAll}
onclick={handleSelectAll}
/>
<AddToAlbum {onAddToAlbum} />
<ActionButton action={Actions.AddToAlbum} />
{#if isAllUserOwned}
<FavoriteAction
removeFavorite={assetInteraction.isAllFavorite}
@@ -354,7 +356,7 @@
/>
<ButtonContextMenu icon={mdiDotsVertical} title={$t('menu')}>
<AddToAlbum menuItem {onAddToAlbum} />
<ActionMenuItem action={Actions.AddToAlbum} />
<DownloadAction menuItem />
<ChangeDate menuItem />
<ChangeDescription menuItem />
@@ -9,7 +9,6 @@
import Sidebar from '$lib/components/sidebar/sidebar.svelte';
import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte';
import Timeline from '$lib/components/timeline/Timeline.svelte';
import AddToAlbum from '$lib/components/timeline/actions/AddToAlbumAction.svelte';
import ArchiveAction from '$lib/components/timeline/actions/ArchiveAction.svelte';
import ChangeDate from '$lib/components/timeline/actions/ChangeDateAction.svelte';
import ChangeDescription from '$lib/components/timeline/actions/ChangeDescriptionAction.svelte';
@@ -25,12 +24,13 @@
import SkipLink from '$lib/elements/SkipLink.svelte';
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
import { Route } from '$lib/route';
import { getAssetBulkActions } from '$lib/services/asset.service';
import { getTagActions } from '$lib/services/tag.service';
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
import { preferences, user } from '$lib/stores/user.store';
import { joinPaths, TreeNode } from '$lib/utils/tree-utils';
import { getAllTags, type TagResponseDto } from '@immich/sdk';
import { Text } from '@immich/ui';
import { ActionButton, CommandPaletteDefaultProvider, Text } from '@immich/ui';
import { mdiDotsVertical, mdiTag, mdiTagMultiple } from '@mdi/js';
import { t } from 'svelte-i18n';
import type { PageData } from './$types';
@@ -120,9 +120,11 @@
assets={assetInteraction.selectedAssets}
clearSelect={() => assetInteraction.clearMultiselect()}
>
{@const Actions = getAssetBulkActions($t, assetInteraction.asControlContext())}
<CommandPaletteDefaultProvider name={$t('assets')} actions={Object.values(Actions)} />
<CreateSharedLink />
<SelectAllAssets {timelineManager} {assetInteraction} />
<AddToAlbum />
<ActionButton action={Actions.AddToAlbum} />
<FavoriteAction
removeFavorite={assetInteraction.isAllFavorite}
onFavorite={(ids, isFavorite) => timelineManager.update(ids, (asset) => (asset.isFavorite = isFavorite))}