mirror of
https://github.com/immich-app/immich.git
synced 2025-01-21 00:52:43 -05:00
feat: "add to album" shortcut and generic menu option shortcuts (#15056)
* Add shortcut prop to MenuOption * Add "add to album" shortcut in photo grid
This commit is contained in:
parent
c148a28a82
commit
fa0b352bd0
3 changed files with 45 additions and 2 deletions
|
@ -16,6 +16,26 @@ export type ShortcutOptions<T = HTMLElement> = {
|
|||
preventDefault?: boolean;
|
||||
};
|
||||
|
||||
export const shortcutLabel = (shortcut: Shortcut) => {
|
||||
let label = '';
|
||||
|
||||
if (shortcut.ctrl) {
|
||||
label += 'Ctrl ';
|
||||
}
|
||||
if (shortcut.alt) {
|
||||
label += 'Alt ';
|
||||
}
|
||||
if (shortcut.meta) {
|
||||
label += 'Cmd ';
|
||||
}
|
||||
if (shortcut.shift) {
|
||||
label += '⇧';
|
||||
}
|
||||
label += shortcut.key.toUpperCase();
|
||||
|
||||
return label;
|
||||
};
|
||||
|
||||
/** Determines whether an event should be ignored. The event will be ignored if:
|
||||
* - The element dispatching the event is not the same as the element which the event listener is attached to
|
||||
* - The element dispatching the event is an input field
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
onClick={() => (showAlbumPicker = true)}
|
||||
text={shared ? $t('add_to_shared_album') : $t('add_to_album')}
|
||||
icon={shared ? mdiShareVariantOutline : mdiImageAlbum}
|
||||
shortcut={{ key: 'l', shift: shared }}
|
||||
/>
|
||||
|
||||
{#if showAlbumPicker}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { generateId } from '$lib/utils/generate-id';
|
||||
import { optionClickCallbackStore, selectedIdStore } from '$lib/stores/context-menu.store';
|
||||
import type { Shortcut } from '$lib/actions/shortcut';
|
||||
import { shortcutLabel as computeShortcutLabel, shortcut as bindShortcut } from '$lib/actions/shortcut';
|
||||
|
||||
interface Props {
|
||||
text: string;
|
||||
|
@ -10,6 +12,8 @@
|
|||
activeColor?: string;
|
||||
textColor?: string;
|
||||
onClick: () => void;
|
||||
shortcut?: Shortcut | null;
|
||||
shortcutLabel?: string;
|
||||
}
|
||||
|
||||
let {
|
||||
|
@ -19,6 +23,8 @@
|
|||
activeColor = 'bg-slate-300',
|
||||
textColor = 'text-immich-fg dark:text-immich-dark-bg',
|
||||
onClick,
|
||||
shortcut = null,
|
||||
shortcutLabel = '',
|
||||
}: Props = $props();
|
||||
|
||||
let id: string = generateId();
|
||||
|
@ -29,8 +35,17 @@
|
|||
$optionClickCallbackStore?.();
|
||||
onClick();
|
||||
};
|
||||
|
||||
if (shortcut && !shortcutLabel) {
|
||||
shortcutLabel = computeShortcutLabel(shortcut);
|
||||
}
|
||||
const bindShortcutIfSet = shortcut
|
||||
? (n: HTMLElement) => bindShortcut(n, { shortcut, onShortcut: onClick })
|
||||
: () => {};
|
||||
</script>
|
||||
|
||||
<svelte:window use:bindShortcutIfSet />
|
||||
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<!-- svelte-ignore a11y_mouse_events_have_key_events -->
|
||||
<li
|
||||
|
@ -46,8 +61,15 @@
|
|||
{#if icon}
|
||||
<Icon path={icon} ariaHidden={true} size="18" />
|
||||
{/if}
|
||||
<div>
|
||||
<div class="w-full">
|
||||
<div class="flex justify-between">
|
||||
{text}
|
||||
{#if shortcutLabel}
|
||||
<span class="text-gray-500 pl-4">
|
||||
{shortcutLabel}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
{#if subtitle}
|
||||
<p class="text-xs text-gray-500">
|
||||
{subtitle}
|
||||
|
|
Loading…
Add table
Reference in a new issue