mirror of
https://github.com/immich-app/immich.git
synced 2026-09-30 13:23:21 +08:00
refactor(web): a few more album actions (#31839)
This commit is contained in:
@@ -27,6 +27,7 @@ import {
|
||||
mdiTrashCanOutline,
|
||||
mdiExitToApp,
|
||||
mdiUpload,
|
||||
mdiCogOutline,
|
||||
} from '@mdi/js';
|
||||
import { type MessageFormatter } from 'svelte-i18n';
|
||||
import { goto } from '$app/navigation';
|
||||
@@ -73,7 +74,7 @@ export const getAlbumActions = ($t: MessageFormatter, album: AlbumResponseDto) =
|
||||
};
|
||||
|
||||
const Delete: ActionItem = {
|
||||
title: $t('delete'),
|
||||
title: $t('delete_album'),
|
||||
icon: mdiTrashCanOutline,
|
||||
$if: () => isOwned,
|
||||
onAction: () => handleDeleteAlbum(album),
|
||||
@@ -82,16 +83,10 @@ export const getAlbumActions = ($t: MessageFormatter, album: AlbumResponseDto) =
|
||||
const Download: ActionItem = {
|
||||
title: $t('download'),
|
||||
icon: mdiDownload,
|
||||
$if: () => album.assetCount > 0,
|
||||
onAction: () => handleDownloadAlbum(album),
|
||||
};
|
||||
|
||||
const Leave: ActionItem = {
|
||||
title: $t('leave_album'),
|
||||
icon: mdiExitToApp,
|
||||
$if: () => !isOwned,
|
||||
onAction: () => handleLeaveAlbum(album),
|
||||
};
|
||||
|
||||
const Edit: ActionItem = {
|
||||
title: $t('edit_album'),
|
||||
icon: mdiRenameOutline,
|
||||
@@ -99,6 +94,20 @@ export const getAlbumActions = ($t: MessageFormatter, album: AlbumResponseDto) =
|
||||
onAction: () => modalManager.show(AlbumEditModal, { album }),
|
||||
};
|
||||
|
||||
const Leave: ActionItem = {
|
||||
title: $t('leave_album'),
|
||||
icon: mdiExitToApp,
|
||||
$if: () => !isOwned,
|
||||
onAction: () => handleLeaveAlbum(album),
|
||||
};
|
||||
|
||||
const Options: ActionItem = {
|
||||
title: $t('options'),
|
||||
icon: mdiCogOutline,
|
||||
$if: () => album.assetCount > 0,
|
||||
onAction: () => modalManager.show(AlbumOptionsModal, { album, readOnly: !isOwned }),
|
||||
};
|
||||
|
||||
const Share: ActionItem = {
|
||||
title: $t('share'),
|
||||
icon: mdiShareVariantOutline,
|
||||
@@ -106,7 +115,7 @@ export const getAlbumActions = ($t: MessageFormatter, album: AlbumResponseDto) =
|
||||
onAction: () => modalManager.show(AlbumOptionsModal, { album }),
|
||||
};
|
||||
|
||||
return { AddUsers, CreateSharedLink, Delete, Download, Edit, Leave, Share };
|
||||
return { AddUsers, CreateSharedLink, Delete, Download, Edit, Leave, Options, Share };
|
||||
};
|
||||
|
||||
export const getAlbumAssetActions = ($t: MessageFormatter, album: AlbumResponseDto, asset: AssetResponseDto) => {
|
||||
|
||||
+13
-53
@@ -34,14 +34,8 @@
|
||||
import { featureFlagsManager } from '$lib/managers/feature-flags-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 { Route } from '$lib/route';
|
||||
import {
|
||||
getAlbumActions,
|
||||
getAlbumAssetsActions,
|
||||
handleDeleteAlbum,
|
||||
handleDownloadAlbum,
|
||||
} from '$lib/services/album.service';
|
||||
import { getAlbumActions, getAlbumAssetsActions, handleDeleteAlbum } from '$lib/services/album.service';
|
||||
import { getGlobalActions } from '$lib/services/app.service';
|
||||
import { getAssetBulkActions } from '$lib/services/asset.service';
|
||||
import { SlideshowNavigation, SlideshowState, slideshowStore } from '$lib/stores/slideshow.store';
|
||||
@@ -49,23 +43,13 @@
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { isAlbumsRoute, navigate, type AssetGridRouteSearchParams } from '$lib/utils/navigation';
|
||||
import { AlbumUserRole, AssetVisibility, getAlbumInfo, updateAlbumInfo, type AlbumResponseDto } from '@immich/sdk';
|
||||
import {
|
||||
ActionButton,
|
||||
CommandPaletteDefaultProvider,
|
||||
Icon,
|
||||
IconButton,
|
||||
modalManager,
|
||||
toastManager,
|
||||
} from '@immich/ui';
|
||||
import { ActionButton, CommandPaletteDefaultProvider, Icon, IconButton, toastManager } from '@immich/ui';
|
||||
import {
|
||||
mdiAccountEye,
|
||||
mdiAccountEyeOutline,
|
||||
mdiArrowLeft,
|
||||
mdiCogOutline,
|
||||
mdiDeleteOutline,
|
||||
mdiDotsHorizontal,
|
||||
mdiDotsVertical,
|
||||
mdiDownload,
|
||||
mdiImageOutline,
|
||||
mdiImagePlusOutline,
|
||||
mdiLink,
|
||||
@@ -218,6 +202,7 @@
|
||||
let album = $state(data.album);
|
||||
let albumId = $derived(album.id);
|
||||
|
||||
const albumHasViewers = $derived(album.albumUsers.some(({ role }) => role === AlbumUserRole.Viewer));
|
||||
const containsEditors = $derived(album?.shared && album.albumUsers.some(({ role }) => role === AlbumUserRole.Editor));
|
||||
const albumUsers = $derived(showAlbumUsers && containsEditors ? album.albumUsers.map(({ user }) => user) : []);
|
||||
|
||||
@@ -261,7 +246,6 @@
|
||||
album.albumUsers.find(({ user: { id } }) => id === authManager.user.id)?.role === AlbumUserRole.Editor || isOwned,
|
||||
);
|
||||
|
||||
let albumHasViewers = $derived(album.albumUsers.some(({ role }) => role === AlbumUserRole.Viewer));
|
||||
const isSelectionMode = $derived(
|
||||
viewMode === AlbumPageViewMode.SELECT_ASSETS ? true : viewMode === AlbumPageViewMode.SELECT_THUMBNAIL,
|
||||
);
|
||||
@@ -278,10 +262,6 @@
|
||||
viewMode === AlbumPageViewMode.SELECT_ASSETS ? timelineMultiSelectManager : assetMultiSelectManager,
|
||||
);
|
||||
|
||||
const onSharedLinkCreate = async () => {
|
||||
await refreshAlbum();
|
||||
};
|
||||
|
||||
const onAlbumDelete = async ({ id }: AlbumResponseDto) => {
|
||||
if (id !== album.id) {
|
||||
return;
|
||||
@@ -328,7 +308,7 @@
|
||||
};
|
||||
|
||||
const { Cast } = $derived(getGlobalActions($t));
|
||||
const { Share, Leave } = $derived(getAlbumActions($t, album));
|
||||
const Actions = $derived(getAlbumActions($t, album));
|
||||
const { AddAssets, Upload } = $derived(getAlbumAssetsActions($t, album, timelineMultiSelectManager.assets));
|
||||
|
||||
const Close = $derived({
|
||||
@@ -341,7 +321,7 @@
|
||||
</script>
|
||||
|
||||
<OnEvents
|
||||
{onSharedLinkCreate}
|
||||
onSharedLinkCreate={refreshAlbum}
|
||||
onSharedLinkDelete={refreshAlbum}
|
||||
{onAlbumDelete}
|
||||
{onAlbumAddAssets}
|
||||
@@ -351,7 +331,7 @@
|
||||
onAlbumUserDelete={refreshAlbum}
|
||||
{onAlbumUpdate}
|
||||
/>
|
||||
<CommandPaletteDefaultProvider name={$t('album')} actions={[AddAssets, Upload, Close]} />
|
||||
<CommandPaletteDefaultProvider name={$t('album')} actions={[AddAssets, Upload, Close, ...Object.values(Actions)]} />
|
||||
|
||||
<div class="flex overflow-hidden" use:scrollMemoryClearer={{ routeStartsWith: Route.albums() }}>
|
||||
<div class="relative w-full shrink">
|
||||
@@ -392,7 +372,7 @@
|
||||
<button
|
||||
class="flex gap-x-1"
|
||||
type="button"
|
||||
onclick={() => modalManager.show(AlbumOptionsModal, { album, readOnly: !isOwned })}
|
||||
onclick={(event) => Actions.Options.onAction({ event, action: Actions.Options })}
|
||||
>
|
||||
<!-- owner & users with write access (collaborators) -->
|
||||
{#each album.albumUsers.filter(({ role }) => role === AlbumUserRole.Editor || role === AlbumUserRole.Owner) as { user } (user.id)}
|
||||
@@ -421,9 +401,7 @@
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
{#if isOwned}
|
||||
<ActionButton action={Share} />
|
||||
{/if}
|
||||
<ActionButton action={Actions.Share} />
|
||||
</div>
|
||||
{/if}
|
||||
<AlbumDescription
|
||||
@@ -536,7 +514,7 @@
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<ActionButton action={Share} />
|
||||
<ActionButton action={Actions.Share} />
|
||||
|
||||
{#if featureFlagsManager.value.map}
|
||||
<AlbumMap {album} />
|
||||
@@ -551,15 +529,8 @@
|
||||
onclick={handleStartSlideshow}
|
||||
icon={mdiPresentationPlay}
|
||||
/>
|
||||
<IconButton
|
||||
shape="round"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
aria-label={$t('download')}
|
||||
onclick={() => handleDownloadAlbum(album)}
|
||||
icon={mdiDownload}
|
||||
/>
|
||||
{/if}
|
||||
<ActionButton action={Actions.Download} />
|
||||
|
||||
{#if isOwned || album.albumUsers.length > 1}
|
||||
<ButtonContextMenu
|
||||
@@ -575,28 +546,17 @@
|
||||
onClick={() => timelineManager.toggleShowAssetOwners()}
|
||||
/>
|
||||
{/if}
|
||||
<ActionMenuItem action={Actions.Options} />
|
||||
{#if isOwned && album.assetCount > 0}
|
||||
<MenuOption
|
||||
icon={mdiImageOutline}
|
||||
text={$t('select_album_cover')}
|
||||
onClick={() => (viewMode = AlbumPageViewMode.SELECT_THUMBNAIL)}
|
||||
/>
|
||||
<MenuOption
|
||||
icon={mdiCogOutline}
|
||||
text={$t('options')}
|
||||
onClick={() => modalManager.show(AlbumOptionsModal, { album })}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if isOwned}
|
||||
<MenuOption
|
||||
icon={mdiDeleteOutline}
|
||||
text={$t('delete_album')}
|
||||
onClick={() => handleDeleteAlbum(album)}
|
||||
/>
|
||||
{:else}
|
||||
<ActionMenuItem action={Leave} />
|
||||
{/if}
|
||||
<ActionMenuItem action={Actions.Delete} />
|
||||
<ActionMenuItem action={Actions.Leave} />
|
||||
</ButtonContextMenu>
|
||||
{/if}
|
||||
{/snippet}
|
||||
|
||||
Reference in New Issue
Block a user