feat(web): enable the shortcut "f" to favorite/unfavorite in multiselection mode (#31411)
Co-authored-by: Daniel Dietzler <mail@ddietzler.dev> (cherry picked from commit aeee9be333f4faac877b99cacd355329a5001c25)
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
<script lang="ts">
|
||||
import MenuOption from '#lib/components/shared-components/context-menu/MenuOption.svelte';
|
||||
import { assetMultiSelectManager } from '#lib/managers/asset-multi-select-manager.svelte.ts';
|
||||
import { toggleFavoriteAssets } from '#lib/services/asset.service.ts';
|
||||
import type { OnFavorite } from '#lib/utils/actions.ts';
|
||||
import { handleError } from '#lib/utils/handle-error.ts';
|
||||
import { updateAssets } from '@immich/sdk';
|
||||
import { IconButton, toastManager } from '@immich/ui';
|
||||
import { IconButton } from '@immich/ui';
|
||||
import { mdiHeartMinusOutline, mdiHeartOutline, mdiTimerSand } from '@mdi/js';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
@@ -27,28 +26,8 @@
|
||||
|
||||
try {
|
||||
const assets = assetMultiSelectManager.ownedAssets.filter((asset) => asset.isFavorite !== isFavorite);
|
||||
|
||||
const ids = assets.map(({ id }) => id);
|
||||
|
||||
if (ids.length > 0) {
|
||||
await updateAssets({ assetBulkUpdateDto: { ids, isFavorite } });
|
||||
}
|
||||
|
||||
for (const asset of assets) {
|
||||
asset.isFavorite = isFavorite;
|
||||
}
|
||||
|
||||
onFavorite?.(ids, isFavorite);
|
||||
|
||||
toastManager.primary(
|
||||
isFavorite
|
||||
? $t('added_to_favorites_count', { values: { count: ids.length } })
|
||||
: $t('removed_from_favorites_count', { values: { count: ids.length } }),
|
||||
);
|
||||
|
||||
await toggleFavoriteAssets(assets, isFavorite, onFavorite);
|
||||
assetMultiSelectManager.clear();
|
||||
} catch (error) {
|
||||
handleError(error, $t('errors.unable_to_add_remove_favorites', { values: { favorite: isFavorite } }));
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { shortcuts, type ShortcutOptions } from '#lib/actions/shortcut.ts';
|
||||
import {
|
||||
setFocusToAsset as setFocusAssetInit,
|
||||
@@ -14,6 +13,7 @@
|
||||
import NavigateToDateModal from '#lib/modals/NavigateToDateModal.svelte';
|
||||
import ShortcutsModal from '#lib/modals/ShortcutsModal.svelte';
|
||||
import { Route } from '#lib/route.ts';
|
||||
import { toggleFavoriteAssets } from '#lib/services/asset.service.ts';
|
||||
import { handleStack } from '#lib/services/stack.service.ts';
|
||||
import { keyboardManager } from '#lib/stores/keyboard-manager.svelte.ts';
|
||||
import { showDeleteModal } from '#lib/stores/preferences.store.ts';
|
||||
@@ -21,6 +21,7 @@
|
||||
import { handlePromiseError } from '#lib/utils.ts';
|
||||
import { deleteAssets } from '#lib/utils/actions.ts';
|
||||
import { selectAllAssets } from '#lib/utils/asset-utils.ts';
|
||||
import { goto } from '$app/navigation';
|
||||
import { isModalOpen, modalManager } from '@immich/ui';
|
||||
|
||||
type Props = {
|
||||
@@ -62,6 +63,14 @@
|
||||
onEscape?.();
|
||||
};
|
||||
|
||||
const toggleFavoriteSelected = async () => {
|
||||
const allAssets = assetInteraction.ownedAssets;
|
||||
const isFavorite = allAssets.some((a) => !a.isFavorite);
|
||||
const assetsToUpdate = allAssets.filter((asset) => asset.isFavorite !== isFavorite);
|
||||
await toggleFavoriteAssets(assetsToUpdate, isFavorite);
|
||||
assetInteraction.clear();
|
||||
};
|
||||
|
||||
const onSelectStart = (e: Event) => {
|
||||
if (!searchStore.isSearchEnabled && assetInteraction.selectionActive && keyboardManager.shift) {
|
||||
e.preventDefault();
|
||||
@@ -125,6 +134,7 @@
|
||||
{ shortcut: { key: 'Delete', shift: true }, onShortcut: () => trashOrDelete(true) },
|
||||
{ shortcut: { key: 'D', ctrl: true }, onShortcut: () => assetInteraction.clear() },
|
||||
{ shortcut: { key: 's' }, onShortcut: () => onStackAssets() },
|
||||
{ shortcut: { key: 'f' }, onShortcut: () => toggleFavoriteSelected() },
|
||||
);
|
||||
} else {
|
||||
// conflicting shortcuts
|
||||
|
||||
@@ -15,6 +15,7 @@ import { Route } from '#lib/route.ts';
|
||||
import { SlideshowState, slideshowStore } from '#lib/stores/slideshow.store.ts';
|
||||
import { getAssetMediaUrl, getSharedLink, sleep } from '#lib/utils.ts';
|
||||
import { downloadUrl } from '#lib/utils.ts';
|
||||
import type { OnFavorite } from '#lib/utils/actions.ts';
|
||||
import { handleError } from '#lib/utils/handle-error.ts';
|
||||
import { getFormatter } from '#lib/utils/i18n.ts';
|
||||
import {
|
||||
@@ -63,6 +64,8 @@ import {
|
||||
mdiTune,
|
||||
} from '@mdi/js';
|
||||
import type { MessageFormatter } from 'svelte-i18n';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { get } from 'svelte/store';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
export const getAssetBulkActions = ($t: MessageFormatter, album?: AlbumResponseDto) => {
|
||||
@@ -496,6 +499,35 @@ const handleUnfavorite = async (asset: AssetResponseDto) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const toggleFavoriteAssets = async (
|
||||
assets: Pick<AssetResponseDto, 'id' | 'isFavorite'>[],
|
||||
isFavorite: boolean,
|
||||
onFavorite?: OnFavorite,
|
||||
) => {
|
||||
const ids = assets.map((a) => a.id);
|
||||
const $t = get(t);
|
||||
|
||||
try {
|
||||
if (ids.length > 0) {
|
||||
await updateAssets({ assetBulkUpdateDto: { ids, isFavorite } });
|
||||
}
|
||||
|
||||
for (const asset of assets) {
|
||||
asset.isFavorite = isFavorite;
|
||||
}
|
||||
|
||||
onFavorite?.(ids, isFavorite);
|
||||
|
||||
toastManager.primary(
|
||||
isFavorite
|
||||
? $t('added_to_favorites_count', { values: { count: ids.length } })
|
||||
: $t('removed_from_favorites_count', { values: { count: ids.length } }),
|
||||
);
|
||||
} catch (error) {
|
||||
handleError(error, $t('errors.unable_to_add_remove_favorites', { values: { favorite: isFavorite } }));
|
||||
}
|
||||
};
|
||||
|
||||
const handleRate = async (asset: AssetResponseDto, rating: number) => {
|
||||
const $t = await getFormatter();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user