From 8ed6ed4d2b840c28a4af6a65b1d6fe06d8c53ce5 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Thu, 21 Mar 2024 19:39:33 +0100 Subject: [PATCH] feat(web): rework context menus: add icons and reorder items (#8090) --- .../asset-viewer/asset-viewer-nav-bar.svelte | 58 ++++++++++++++----- .../components/faces-page/people-card.svelte | 24 ++++++-- .../photos-page/actions/add-to-album.svelte | 7 ++- .../photos-page/actions/archive-action.svelte | 2 +- .../actions/asset-job-actions.svelte | 4 +- .../actions/change-date-action.svelte | 3 +- .../actions/change-location-action.svelte | 7 ++- .../photos-page/actions/delete-assets.svelte | 6 +- .../actions/download-action.svelte | 6 +- .../actions/favorite-action.svelte | 4 +- .../actions/remove-from-album.svelte | 4 +- .../photos-page/actions/stack-action.svelte | 3 +- .../asset-select-context-menu.svelte | 4 +- .../context-menu/context-menu.svelte | 6 +- .../context-menu/menu-option.svelte | 12 +++- web/src/lib/utils.ts | 11 ++++ .../(user)/albums/[albumId]/+page.svelte | 45 +++++++++----- web/src/routes/(user)/archive/+page.svelte | 6 +- web/src/routes/(user)/favorites/+page.svelte | 6 +- .../(user)/people/[personId]/+page.svelte | 42 ++++++++++---- web/src/routes/(user)/photos/+page.svelte | 16 ++--- web/src/routes/(user)/search/+page.svelte | 8 +-- web/src/routes/(user)/trash/+page.svelte | 4 +- 23 files changed, 204 insertions(+), 84 deletions(-) diff --git a/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte index 4d09e17050..3a51056298 100644 --- a/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte +++ b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte @@ -5,20 +5,31 @@ import { getAssetJobName } from '$lib/utils'; import { clickOutside } from '$lib/utils/click-outside'; import { getContextMenuPosition } from '$lib/utils/context-menu'; - import { AssetJobName, AssetTypeEnum, type AssetResponseDto } from '@immich/sdk'; + import { AssetJobName, AssetTypeEnum, type AssetResponseDto, type AlbumResponseDto } from '@immich/sdk'; import { + mdiAccountCircleOutline, mdiAlertOutline, + mdiArchiveArrowDownOutline, + mdiArchiveArrowUpOutline, mdiArrowLeft, + mdiCogRefreshOutline, mdiContentCopy, + mdiDatabaseRefreshOutline, mdiDeleteOutline, mdiDotsVertical, + mdiFolderDownloadOutline, mdiHeart, mdiHeartOutline, + mdiImageAlbum, + mdiImageMinusOutline, + mdiImageOutline, + mdiImageRefreshOutline, mdiInformationOutline, mdiMagnifyMinusOutline, mdiMagnifyPlusOutline, mdiMotionPauseOutline, mdiPlaySpeed, + mdiPresentationPlay, mdiShareVariantOutline, } from '@mdi/js'; import { createEventDispatcher } from 'svelte'; @@ -26,6 +37,7 @@ import MenuOption from '../shared-components/context-menu/menu-option.svelte'; export let asset: AssetResponseDto; + export let album: AlbumResponseDto | null = null; export let showCopyButton: boolean; export let showZoomButton: boolean; export let showMotionPlayButton: boolean; @@ -42,6 +54,7 @@ | 'addToAlbum' | 'addToSharedAlbum' | 'asProfileImage' + | 'setAsAlbumCover' | 'download' | 'playSlideShow' | 'runJob' @@ -59,6 +72,7 @@ addToAlbum: void; addToSharedAlbum: void; asProfileImage: void; + setAsAlbumCover: void; runJob: AssetJobName; playSlideShow: void; unstack: void; @@ -173,37 +187,55 @@ {#if isShowAssetOptions} {#if showSlideshow} - onMenuClick('playSlideShow')} text="Slideshow" /> + onMenuClick('playSlideShow')} text="Slideshow" /> {/if} {#if showDownloadButton} - onMenuClick('download')} text="Download" /> + onMenuClick('download')} text="Download" /> {/if} - onMenuClick('addToAlbum')} text="Add to Album" /> - onMenuClick('addToSharedAlbum')} text="Add to Shared Album" /> + onMenuClick('addToAlbum')} text="Add to album" /> + onMenuClick('addToSharedAlbum')} + text="Add to shared album" + /> {#if isOwner} + {#if hasStackChildren} + onMenuClick('unstack')} text="Un-stack" /> + {/if} + {#if album} + onMenuClick('setAsAlbumCover')} + /> + {/if} + {#if asset.type === AssetTypeEnum.Image} + onMenuClick('asProfileImage')} + text="Set as profile picture" + /> + {/if} dispatch('toggleArchive')} + icon={asset.isArchived ? mdiArchiveArrowUpOutline : mdiArchiveArrowDownOutline} text={asset.isArchived ? 'Unarchive' : 'Archive'} /> - {#if asset.type === AssetTypeEnum.Image} - onMenuClick('asProfileImage')} text="As profile picture" /> - {/if} - - {#if hasStackChildren} - onMenuClick('unstack')} text="Un-Stack" /> - {/if} - +
onJobClick(AssetJobName.RefreshMetadata)} text={getAssetJobName(AssetJobName.RefreshMetadata)} /> onJobClick(AssetJobName.RegenerateThumbnail)} text={getAssetJobName(AssetJobName.RegenerateThumbnail)} /> {#if asset.type === AssetTypeEnum.Video} onJobClick(AssetJobName.TranscodeVideo)} text={getAssetJobName(AssetJobName.TranscodeVideo)} /> diff --git a/web/src/lib/components/faces-page/people-card.svelte b/web/src/lib/components/faces-page/people-card.svelte index 4bb4947127..e8287991bb 100644 --- a/web/src/lib/components/faces-page/people-card.svelte +++ b/web/src/lib/components/faces-page/people-card.svelte @@ -4,7 +4,13 @@ import { getPeopleThumbnailUrl } from '$lib/utils'; import { getContextMenuPosition } from '$lib/utils/context-menu'; import { type PersonResponseDto } from '@immich/sdk'; - import { mdiDotsVertical } from '@mdi/js'; + import { + mdiAccountEditOutline, + mdiAccountMultipleCheckOutline, + mdiCalendarEditOutline, + mdiDotsVertical, + mdiEyeOffOutline, + } from '@mdi/js'; import { createEventDispatcher } from 'svelte'; import ImageThumbnail from '../assets/thumbnail/image-thumbnail.svelte'; import IconButton from '../elements/buttons/icon-button.svelte'; @@ -83,10 +89,18 @@ {#if showContextMenu} onMenuExit()}> - onMenuClick('hide-person')} text="Hide Person" /> - onMenuClick('change-name')} text="Change name" /> - onMenuClick('set-birth-date')} text="Set date of birth" /> - onMenuClick('merge-people')} text="Merge People" /> + onMenuClick('hide-person')} icon={mdiEyeOffOutline} text="Hide person" /> + onMenuClick('change-name')} icon={mdiAccountEditOutline} text="Change name" /> + onMenuClick('set-birth-date')} + icon={mdiCalendarEditOutline} + text="Set date of birth" + /> + onMenuClick('merge-people')} + icon={mdiAccountMultipleCheckOutline} + text="Merge people" + /> {/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 cb059947bb..063d3bdb81 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 @@ -11,6 +11,7 @@ import { createAlbum, type AlbumResponseDto } from '@immich/sdk'; import { getMenuContext } from '../asset-select-context-menu.svelte'; import { getAssetControlContext } from '../asset-select-control-bar.svelte'; + import { mdiImageAlbum, mdiShareVariantOutline } from '@mdi/js'; export let shared = false; let showAlbumPicker = false; @@ -53,7 +54,11 @@ }; - (showAlbumPicker = true)} text={shared ? 'Add to Shared Album' : 'Add to Album'} /> + (showAlbumPicker = true)} + text={shared ? 'Add to shared album' : 'Add to album'} + icon={shared ? mdiShareVariantOutline : mdiImageAlbum} +/> {#if showAlbumPicker} {#if menuItem} - + {/if} {#if !menuItem} diff --git a/web/src/lib/components/photos-page/actions/asset-job-actions.svelte b/web/src/lib/components/photos-page/actions/asset-job-actions.svelte index 7b79cb36c0..0dddaf7938 100644 --- a/web/src/lib/components/photos-page/actions/asset-job-actions.svelte +++ b/web/src/lib/components/photos-page/actions/asset-job-actions.svelte @@ -4,7 +4,7 @@ NotificationType, notificationController, } from '$lib/components/shared-components/notification/notification'; - import { getAssetJobMessage, getAssetJobName } from '$lib/utils'; + import { getAssetJobIcon, getAssetJobMessage, getAssetJobName } from '$lib/utils'; import { handleError } from '$lib/utils/handle-error'; import { AssetJobName, AssetTypeEnum, runAssetJobs } from '@immich/sdk'; import { getAssetControlContext } from '../asset-select-control-bar.svelte'; @@ -33,6 +33,6 @@ {#each jobs as job} {#if isAllVideos || job !== AssetJobName.TranscodeVideo} - handleRunJob(job)} /> + handleRunJob(job)} /> {/if} {/each} diff --git a/web/src/lib/components/photos-page/actions/change-date-action.svelte b/web/src/lib/components/photos-page/actions/change-date-action.svelte index 42e4aad68d..412a2f2ca7 100644 --- a/web/src/lib/components/photos-page/actions/change-date-action.svelte +++ b/web/src/lib/components/photos-page/actions/change-date-action.svelte @@ -7,6 +7,7 @@ import { DateTime } from 'luxon'; import MenuOption from '../../shared-components/context-menu/menu-option.svelte'; import { getAssetControlContext } from '../asset-select-control-bar.svelte'; + import { mdiCalendarEditOutline } from '@mdi/js'; export let menuItem = false; const { clearSelect, getOwnedAssets } = getAssetControlContext(); @@ -26,7 +27,7 @@ {#if menuItem} - (isShowChangeDate = true)} /> + (isShowChangeDate = true)} /> {/if} {#if isShowChangeDate} {#if menuItem} - (isShowChangeLocation = true)} /> + (isShowChangeLocation = true)} + /> {/if} {#if isShowChangeLocation} { if (force) { isShowConfirmation = true; @@ -46,11 +48,11 @@ {#if menuItem} - + {:else if loading} {:else} - + {/if} {#if isShowConfirmation} diff --git a/web/src/lib/components/photos-page/actions/download-action.svelte b/web/src/lib/components/photos-page/actions/download-action.svelte index 3619db950e..fbdf4ae53d 100644 --- a/web/src/lib/components/photos-page/actions/download-action.svelte +++ b/web/src/lib/components/photos-page/actions/download-action.svelte @@ -3,7 +3,7 @@ import { downloadArchive, downloadFile } from '$lib/utils/asset-utils'; import MenuOption from '../../shared-components/context-menu/menu-option.svelte'; import { getAssetControlContext } from '../asset-select-control-bar.svelte'; - import { mdiCloudDownloadOutline } from '@mdi/js'; + import { mdiCloudDownloadOutline, mdiFileDownloadOutline, mdiFolderDownloadOutline } from '@mdi/js'; export let filename = 'immich.zip'; export let menuItem = false; @@ -21,10 +21,12 @@ clearSelect(); await downloadArchive(filename, { assetIds: assets.map((asset) => asset.id) }); }; + + $: menuItemIcon = getAssets().size === 1 ? mdiFileDownloadOutline : mdiFolderDownloadOutline; {#if menuItem} - + {:else} {/if} diff --git a/web/src/lib/components/photos-page/actions/favorite-action.svelte b/web/src/lib/components/photos-page/actions/favorite-action.svelte index ea573ffd7f..520dd46564 100644 --- a/web/src/lib/components/photos-page/actions/favorite-action.svelte +++ b/web/src/lib/components/photos-page/actions/favorite-action.svelte @@ -16,7 +16,7 @@ export let menuItem = false; export let removeFavorite: boolean; - $: text = removeFavorite ? 'Remove from Favorites' : 'Favorite'; + $: text = removeFavorite ? 'Remove from favorites' : 'Favorite'; $: icon = removeFavorite ? mdiHeartMinusOutline : mdiHeartOutline; let loading = false; @@ -57,7 +57,7 @@ {#if menuItem} - + {/if} {#if !menuItem} diff --git a/web/src/lib/components/photos-page/actions/remove-from-album.svelte b/web/src/lib/components/photos-page/actions/remove-from-album.svelte index 8fbc5e6ad0..5d59fcf1c4 100644 --- a/web/src/lib/components/photos-page/actions/remove-from-album.svelte +++ b/web/src/lib/components/photos-page/actions/remove-from-album.svelte @@ -6,7 +6,7 @@ notificationController, } from '$lib/components/shared-components/notification/notification'; import { getAlbumInfo, removeAssetFromAlbum, type AlbumResponseDto } from '@immich/sdk'; - import { mdiDeleteOutline } from '@mdi/js'; + import { mdiDeleteOutline, mdiImageRemoveOutline } from '@mdi/js'; import MenuOption from '../../shared-components/context-menu/menu-option.svelte'; import { getAssetControlContext } from '../asset-select-control-bar.svelte'; @@ -50,7 +50,7 @@ {#if menuItem} - (isShowConfirmation = true)} /> + (isShowConfirmation = true)} /> {:else} (isShowConfirmation = true)} /> {/if} diff --git a/web/src/lib/components/photos-page/actions/stack-action.svelte b/web/src/lib/components/photos-page/actions/stack-action.svelte index 9e0bb2dc53..1df6cce30a 100644 --- a/web/src/lib/components/photos-page/actions/stack-action.svelte +++ b/web/src/lib/components/photos-page/actions/stack-action.svelte @@ -8,6 +8,7 @@ import { handleError } from '$lib/utils/handle-error'; import { updateAssets } from '@immich/sdk'; import { getAssetControlContext } from '../asset-select-control-bar.svelte'; + import { mdiImageMultipleOutline } from '@mdi/js'; export let onStack: OnStack | undefined; @@ -55,4 +56,4 @@ }; - + diff --git a/web/src/lib/components/photos-page/asset-select-context-menu.svelte b/web/src/lib/components/photos-page/asset-select-context-menu.svelte index 9af4ff9319..d2d9ea399b 100644 --- a/web/src/lib/components/photos-page/asset-select-context-menu.svelte +++ b/web/src/lib/components/photos-page/asset-select-context-menu.svelte @@ -29,9 +29,7 @@ {#if showContextMenu} -
- -
+
{/if} diff --git a/web/src/lib/components/shared-components/context-menu/context-menu.svelte b/web/src/lib/components/shared-components/context-menu/context-menu.svelte index c10371d830..aabf8c25c2 100644 --- a/web/src/lib/components/shared-components/context-menu/context-menu.svelte +++ b/web/src/lib/components/shared-components/context-menu/context-menu.svelte @@ -23,12 +23,14 @@ diff --git a/web/src/lib/components/shared-components/context-menu/menu-option.svelte b/web/src/lib/components/shared-components/context-menu/menu-option.svelte index d2e2eb69b7..6d5adc4197 100644 --- a/web/src/lib/components/shared-components/context-menu/menu-option.svelte +++ b/web/src/lib/components/shared-components/context-menu/menu-option.svelte @@ -1,6 +1,9 @@