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,