diff --git a/i18n/en.json b/i18n/en.json
index fafa137f4d..d61116f2a6 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -464,7 +464,6 @@
"assets": "Assets",
"assets_added_count": "Added {count, plural, one {# asset} other {# assets}}",
"assets_added_to_album_count": "Added {count, plural, one {# asset} other {# assets}} to the album",
- "assets_added_to_name_count": "Added {count, plural, one {# asset} other {# assets}} to {hasName, select, true {{name}} other {new album}}",
"assets_cannot_be_added_to_album_count": "{count, plural, one {Asset} other {Assets}} cannot be added to the album",
"assets_count": "{count, plural, one {# asset} other {# assets}}",
"assets_deleted_permanently": "{count} asset(s) deleted permanently",
diff --git a/web/src/lib/components/asset-viewer/actions/add-to-album-action.svelte b/web/src/lib/components/asset-viewer/actions/add-to-album-action.svelte
index 0fbd1c8529..8fe765ab2d 100644
--- a/web/src/lib/components/asset-viewer/actions/add-to-album-action.svelte
+++ b/web/src/lib/components/asset-viewer/actions/add-to-album-action.svelte
@@ -1,13 +1,13 @@
- (showSelectionModal = true) }}
-/>
+
(showSelectionModal = true)}
+ {onClick}
/>
-
-{#if showSelectionModal}
-
- (showSelectionModal = false)}
- />
-
-{/if}
diff --git a/web/src/lib/components/photos-page/actions/add-to-album.svelte b/web/src/lib/components/photos-page/actions/add-to-album.svelte
index 1918dc6c20..c00fd2e1c9 100644
--- a/web/src/lib/components/photos-page/actions/add-to-album.svelte
+++ b/web/src/lib/components/photos-page/actions/add-to-album.svelte
@@ -1,12 +1,12 @@
(showAlbumPicker = true)}
+ {onClick}
text={shared ? $t('add_to_shared_album') : $t('add_to_album')}
icon={shared ? mdiShareVariantOutline : mdiImageAlbum}
shortcut={{ key: 'l', shift: shared }}
/>
-
-{#if showAlbumPicker}
-
-{/if}
diff --git a/web/src/lib/components/shared-components/album-selection/album-selection-modal.svelte b/web/src/lib/modals/AlbumPickerModal.svelte
similarity index 78%
rename from web/src/lib/components/shared-components/album-selection/album-selection-modal.svelte
rename to web/src/lib/modals/AlbumPickerModal.svelte
index ab763546af..3e16e03b80 100644
--- a/web/src/lib/components/shared-components/album-selection/album-selection-modal.svelte
+++ b/web/src/lib/modals/AlbumPickerModal.svelte
@@ -6,12 +6,12 @@
isSelectableRowType,
} from '$lib/components/shared-components/album-selection/album-selection-utils';
import { albumViewSettings } from '$lib/stores/preferences.store';
- import { type AlbumResponseDto, getAllAlbums } from '@immich/sdk';
+ import { type AlbumResponseDto, createAlbum, getAllAlbums } from '@immich/sdk';
import { Modal, ModalBody } from '@immich/ui';
import { onMount } from 'svelte';
import { t } from 'svelte-i18n';
- import AlbumListItem from '../../asset-viewer/album-list-item.svelte';
- import NewAlbumListItem from './new-album-list-item.svelte';
+ import AlbumListItem from '../components/asset-viewer/album-list-item.svelte';
+ import NewAlbumListItem from '../components/shared-components/album-selection/new-album-list-item.svelte';
let albums: AlbumResponseDto[] = $state([]);
let recentAlbums: AlbumResponseDto[] = $state([]);
@@ -20,13 +20,11 @@
let selectedRowIndex: number = $state(-1);
interface Props {
- onNewAlbum: (search: string) => void;
- onAlbumClick: (album: AlbumResponseDto) => void;
shared: boolean;
- onClose: () => void;
+ onClose: (album?: AlbumResponseDto) => void;
}
- let { onNewAlbum, onAlbumClick, shared, onClose }: Props = $props();
+ let { shared, onClose }: Props = $props();
onMount(async () => {
albums = await getAllAlbums({ shared: shared || undefined });
@@ -38,7 +36,34 @@
const albumModalRows = $derived(rowConverter.toModalRows(search, recentAlbums, albums, selectedRowIndex));
const selectableRowCount = $derived(albumModalRows.filter((row) => isSelectableRowType(row.type)).length);
- const onkeydown = (e: KeyboardEvent) => {
+ const onNewAlbum = async (name: string) => {
+ const album = await createAlbum({ createAlbumDto: { albumName: name } });
+ onClose(album);
+ };
+
+ const onEnter = async () => {
+ const item = albumModalRows.find(({ selected }) => selected);
+ if (!item) {
+ return;
+ }
+
+ switch (item.type) {
+ case AlbumModalRowType.NEW_ALBUM: {
+ await onNewAlbum(search);
+ break;
+ }
+ case AlbumModalRowType.ALBUM_ITEM: {
+ if (item.album) {
+ onClose(item.album);
+ }
+ break;
+ }
+ }
+
+ selectedRowIndex = -1;
+ };
+
+ const onkeydown = async (e: KeyboardEvent) => {
switch (e.key) {
case 'ArrowUp': {
e.preventDefault();
@@ -60,15 +85,7 @@
}
case 'Enter': {
e.preventDefault();
- const selectedRow = albumModalRows.find((row) => row.selected);
- if (selectedRow) {
- if (selectedRow.type === AlbumModalRowType.NEW_ALBUM) {
- onNewAlbum(search);
- } else if (selectedRow.type === AlbumModalRowType.ALBUM_ITEM && selectedRow.album) {
- onAlbumClick(selectedRow.album);
- }
- selectedRowIndex = -1;
- }
+ await onEnter();
break;
}
default: {
@@ -76,8 +93,6 @@
}
}
};
-
- const handleAlbumClick = (album: AlbumResponseDto) => () => onAlbumClick(album);
@@ -119,7 +134,7 @@
album={row.album}
selected={row.selected || false}
searchQuery={search}
- onAlbumClick={handleAlbumClick(row.album)}
+ onAlbumClick={() => onClose(row.album)}
/>
{/if}
{/each}
diff --git a/web/src/lib/utils/asset-utils.ts b/web/src/lib/utils/asset-utils.ts
index 9c22b9a8f3..0083343709 100644
--- a/web/src/lib/utils/asset-utils.ts
+++ b/web/src/lib/utils/asset-utils.ts
@@ -1,6 +1,4 @@
import { goto } from '$app/navigation';
-import FormatBoldMessage from '$lib/components/i18n/format-bold-message.svelte';
-import type { InterpolationValues } from '$lib/components/i18n/format-message';
import { notificationController, NotificationType } from '$lib/components/shared-components/notification/notification';
import { AppRoute } from '$lib/constants';
import { authManager } from '$lib/managers/auth-manager.svelte';
@@ -12,7 +10,6 @@ import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
import { isSelectingAllAssets } from '$lib/stores/assets-store.svelte';
import { preferences } from '$lib/stores/user.store';
import { downloadRequest, withError } from '$lib/utils';
-import { createAlbum } from '$lib/utils/album-utils';
import { getByteUnitString } from '$lib/utils/byte-units';
import { getFormatter } from '$lib/utils/i18n';
import { navigate } from '$lib/utils/navigation';
@@ -39,7 +36,7 @@ import {
type UserResponseDto,
} from '@immich/sdk';
import { DateTime } from 'luxon';
-import { t, type Translations } from 'svelte-i18n';
+import { t } from 'svelte-i18n';
import { get } from 'svelte/store';
import { handleError } from './handle-error';
@@ -122,47 +119,6 @@ export const removeTag = async ({
return assetIds;
};
-export const addAssetsToNewAlbum = async (albumName: string, assetIds: string[]) => {
- const album = await createAlbum(albumName, assetIds);
- if (!album) {
- return;
- }
- const $t = get(t);
- // for reasons beyond me > doesn't work, even though it's (afaik) exactly this object
- if (album.assets.length === 0) {
- notificationController.show({
- type: NotificationType.Info,
- timeout: 5000,
- message: $t('assets_cannot_be_added_to_album_count', { values: { count: assetIds.length } }),
- button: {
- text: $t('view_album'),
- onClick() {
- return goto(`${AppRoute.ALBUMS}/${album.id}`);
- },
- },
- });
- } else {
- notificationController.show<{ key: Translations; values: InterpolationValues }>({
- type: NotificationType.Info,
- timeout: 5000,
- component: {
- type: FormatBoldMessage,
- props: {
- key: 'assets_added_to_name_count',
- values: { count: album.assets.length, name: albumName, hasName: !!albumName },
- },
- },
- button: {
- text: $t('view_album'),
- onClick() {
- return goto(`${AppRoute.ALBUMS}/${album.id}`);
- },
- },
- });
- }
- return album;
-};
-
export const downloadAlbum = async (album: AlbumResponseDto) => {
await downloadArchive(`${album.albumName}.zip`, {
albumId: album.id,