From 7a20282c97a4ddb2b2a181780ac9c321326a10f2 Mon Sep 17 00:00:00 2001 From: cbochs Date: Sun, 14 Dec 2025 15:26:24 -0700 Subject: [PATCH 1/5] feat(web): rating shortcuts (1-5) for asset view --- i18n/en.json | 4 +- .../components/asset-viewer/actions/action.ts | 1 + .../asset-viewer/actions/rating-action.svelte | 62 +++++++++++++++++++ .../asset-viewer/asset-viewer-nav-bar.svelte | 2 + .../asset-viewer/asset-viewer.svelte | 10 +++ web/src/lib/constants.ts | 1 + 6 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 web/src/lib/components/asset-viewer/actions/rating-action.svelte diff --git a/i18n/en.json b/i18n/en.json index 5903d7850e..01fdd360ba 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -1074,7 +1074,8 @@ "unable_to_update_settings": "Unable to update settings", "unable_to_update_timeline_display_status": "Unable to update timeline display status", "unable_to_update_user": "Unable to update user", - "unable_to_upload_file": "Unable to upload file" + "unable_to_upload_file": "Unable to upload file", + "unable_to_set_rating": "Unable to set rating" }, "exclusion_pattern": "Exclusion pattern", "exif": "Exif", @@ -1671,6 +1672,7 @@ "rating_clear": "Clear rating", "rating_count": "{count, plural, one {# star} other {# stars}}", "rating_description": "Display the EXIF rating in the info panel", + "rating_set": "Rating set to {rating} stars", "reaction_options": "Reaction options", "read_changelog": "Read Changelog", "readonly_mode_disabled": "Read-only mode disabled", diff --git a/web/src/lib/components/asset-viewer/actions/action.ts b/web/src/lib/components/asset-viewer/actions/action.ts index 6a807d2766..df61b5d073 100644 --- a/web/src/lib/components/asset-viewer/actions/action.ts +++ b/web/src/lib/components/asset-viewer/actions/action.ts @@ -20,6 +20,7 @@ type ActionMap = { [AssetAction.SET_VISIBILITY_LOCKED]: { asset: TimelineAsset }; [AssetAction.SET_VISIBILITY_TIMELINE]: { asset: TimelineAsset }; [AssetAction.SET_PERSON_FEATURED_PHOTO]: { asset: AssetResponseDto; person: PersonResponseDto }; + [AssetAction.RATING]: { asset: TimelineAsset; rating: number | null }; }; export type Action = { diff --git a/web/src/lib/components/asset-viewer/actions/rating-action.svelte b/web/src/lib/components/asset-viewer/actions/rating-action.svelte new file mode 100644 index 0000000000..4da89f204a --- /dev/null +++ b/web/src/lib/components/asset-viewer/actions/rating-action.svelte @@ -0,0 +1,62 @@ + + + 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 0dad2793bf..09cbf2736b 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 @@ -11,6 +11,7 @@ import DownloadAction from '$lib/components/asset-viewer/actions/download-action.svelte'; import FavoriteAction from '$lib/components/asset-viewer/actions/favorite-action.svelte'; import KeepThisDeleteOthersAction from '$lib/components/asset-viewer/actions/keep-this-delete-others.svelte'; + import RatingAction from '$lib/components/asset-viewer/actions/rating-action.svelte'; import RemoveAssetFromStack from '$lib/components/asset-viewer/actions/remove-asset-from-stack.svelte'; import RestoreAction from '$lib/components/asset-viewer/actions/restore-action.svelte'; import SetAlbumCoverAction from '$lib/components/asset-viewer/actions/set-album-cover-action.svelte'; @@ -179,6 +180,7 @@ {#if isOwner} + {/if} {#if isOwner} diff --git a/web/src/lib/components/asset-viewer/asset-viewer.svelte b/web/src/lib/components/asset-viewer/asset-viewer.svelte index b657f34ece..c077bd6273 100644 --- a/web/src/lib/components/asset-viewer/asset-viewer.svelte +++ b/web/src/lib/components/asset-viewer/asset-viewer.svelte @@ -353,6 +353,16 @@ asset = { ...asset, people: assetInfo.people }; break; } + case AssetAction.RATING: { + asset = { + ...asset, + exifInfo: { + ...asset.exifInfo, + rating: action.rating + } + }; + break; + } case AssetAction.KEEP_THIS_DELETE_OTHERS: case AssetAction.UNSTACK: { closeViewer(); diff --git a/web/src/lib/constants.ts b/web/src/lib/constants.ts index 5e74214e78..15e9009b99 100644 --- a/web/src/lib/constants.ts +++ b/web/src/lib/constants.ts @@ -16,6 +16,7 @@ export enum AssetAction { SET_VISIBILITY_LOCKED = 'set-visibility-locked', SET_VISIBILITY_TIMELINE = 'set-visibility-timeline', SET_PERSON_FEATURED_PHOTO = 'set-person-featured-photo', + RATING = 'rating', } export enum AppRoute { From 6878d1a5b17c2369b431d68bdeb7ab9dc957ef83 Mon Sep 17 00:00:00 2001 From: cbochs Date: Tue, 16 Dec 2025 07:09:19 -0700 Subject: [PATCH 2/5] fix: only permit rating shortcut when rating is enabled --- .../asset-viewer/actions/rating-action.svelte | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/web/src/lib/components/asset-viewer/actions/rating-action.svelte b/web/src/lib/components/asset-viewer/actions/rating-action.svelte index 4da89f204a..23e3ffb407 100644 --- a/web/src/lib/components/asset-viewer/actions/rating-action.svelte +++ b/web/src/lib/components/asset-viewer/actions/rating-action.svelte @@ -2,6 +2,7 @@ import { shortcuts } from '$lib/actions/shortcut'; import type { OnAction } from '$lib/components/asset-viewer/actions/action'; import { AssetAction } from '$lib/constants'; + import { preferences } from '$lib/stores/user.store'; import { handleError } from '$lib/utils/handle-error'; import { toTimelineAsset } from '$lib/utils/timeline-util'; import { updateAsset, type AssetResponseDto } from '@immich/sdk'; @@ -52,11 +53,13 @@ From f4d9d715e8f19799dee4a8d6a978b4030954dac1 Mon Sep 17 00:00:00 2001 From: cbochs Date: Tue, 16 Dec 2025 07:44:46 -0700 Subject: [PATCH 3/5] fix: add '0' shortcut for clearing ratings --- .../asset-viewer/actions/rating-action.svelte | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/web/src/lib/components/asset-viewer/actions/rating-action.svelte b/web/src/lib/components/asset-viewer/actions/rating-action.svelte index 23e3ffb407..0c3ad70a48 100644 --- a/web/src/lib/components/asset-viewer/actions/rating-action.svelte +++ b/web/src/lib/components/asset-viewer/actions/rating-action.svelte @@ -16,9 +16,9 @@ let { asset, onAction }: Props = $props(); - const rateAsset = async (rating: number) => { + const rateAsset = async (rating: number | null) => { try { - const updateAssetDto = { rating }; + const updateAssetDto = rating === null ? {} : { rating }; await updateAsset({ id: asset.id, @@ -39,12 +39,17 @@ rating, }); - toastManager.success($t('rating_set', { values: { rating } })); + if (rating === null) { + toastManager.success($t('rating_clear')); + } else { + toastManager.success($t('rating_set', { values: { rating } })); + } } catch (error) { handleError(error, $t('errors.unable_to_set_rating')); } }; + const onShortcut0 = () => rateAsset(null); const onShortcut1 = () => rateAsset(1); const onShortcut2 = () => rateAsset(2); const onShortcut3 = () => rateAsset(3); @@ -55,6 +60,7 @@ Date: Tue, 16 Dec 2025 08:12:31 -0700 Subject: [PATCH 4/5] fix: add shortcut to ShortcutModal --- i18n/en.json | 2 ++ web/src/lib/modals/ShortcutsModal.svelte | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/i18n/en.json b/i18n/en.json index 01fdd360ba..90f5897ed9 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -1668,6 +1668,7 @@ "purchase_settings_server_activated": "The server product key is managed by the admin", "query_asset_id": "Query Asset ID", "queue_status": "Queuing {count}/{total}", + "rate_asset": "Rate Asset", "rating": "Star rating", "rating_clear": "Clear rating", "rating_count": "{count, plural, one {# star} other {# stars}}", @@ -2233,6 +2234,7 @@ "yes": "Yes", "you_dont_have_any_shared_links": "You don't have any shared links", "your_wifi_name": "Your Wi-Fi name", + "zero_to_clear_rating": "press 0 to clear asset rating", "zoom_image": "Zoom Image", "zoom_to_bounds": "Zoom to bounds" } diff --git a/web/src/lib/modals/ShortcutsModal.svelte b/web/src/lib/modals/ShortcutsModal.svelte index ebb5ea3c60..c5b09ffa1a 100644 --- a/web/src/lib/modals/ShortcutsModal.svelte +++ b/web/src/lib/modals/ShortcutsModal.svelte @@ -1,4 +1,5 @@