diff --git a/web/src/lib/components/elements/buttons/button.svelte b/web/src/lib/components/elements/buttons/button.svelte index 6ef2f76bb4..dccecccd36 100644 --- a/web/src/lib/components/elements/buttons/button.svelte +++ b/web/src/lib/components/elements/buttons/button.svelte @@ -27,6 +27,7 @@ export let fullwidth = false; export let border = false; export let title: string | undefined = ''; + let className = ''; export { className as class }; diff --git a/web/src/lib/components/faces-page/merge-suggestion-modal.svelte b/web/src/lib/components/faces-page/merge-suggestion-modal.svelte index ab77a0df03..8f6bbc1f5c 100644 --- a/web/src/lib/components/faces-page/merge-suggestion-modal.svelte +++ b/web/src/lib/components/faces-page/merge-suggestion-modal.svelte @@ -8,12 +8,6 @@ import { mdiArrowLeft, mdiClose, mdiMerge } from '@mdi/js'; import Icon from '$lib/components/elements/icon.svelte'; - const dispatch = createEventDispatcher<{ - reject: void; - confirm: [PersonResponseDto, PersonResponseDto]; - close: void; - }>(); - export let personMerge1: PersonResponseDto; export let personMerge2: PersonResponseDto; export let potentialMergePeople: PersonResponseDto[]; @@ -22,6 +16,21 @@ const title = personMerge2.name; + const dispatch = createEventDispatcher<{ + reject: void; + confirm: [PersonResponseDto, PersonResponseDto]; + close: void; + }>(); + + const handleKeyboardPress = (event: KeyboardEvent) => { + switch (event.key) { + case 'Escape': { + dispatch('close'); + return; + } + } + }; + const changePersonToMerge = (newperson: PersonResponseDto) => { const index = potentialMergePeople.indexOf(newperson); [potentialMergePeople[index], personMerge2] = [personMerge2, potentialMergePeople[index]]; @@ -29,6 +38,8 @@ }; + + dispatch('close')}>
They will be merged together

- +
diff --git a/web/src/routes/(user)/people/[personId]/+page.svelte b/web/src/routes/(user)/people/[personId]/+page.svelte index 3d96387659..c6cac370c7 100644 --- a/web/src/routes/(user)/people/[personId]/+page.svelte +++ b/web/src/routes/(user)/people/[personId]/+page.svelte @@ -88,6 +88,8 @@ **/ let searchWord: string; let isSearchingPeople = false; + let focusedElements: (HTMLButtonElement | null)[] = Array.from({ length: maximumLengthSearchPeople }, () => null); + let indexFocus: number | null = null; const searchPeople = async () => { if ((people.length < maximumLengthSearchPeople && name.startsWith(searchWord)) || name === '') { @@ -116,6 +118,7 @@ $: { if (people) { suggestedPeople = name ? searchNameLocal(name, people, 5, data.person.id) : []; + indexFocus = null; } } @@ -129,8 +132,51 @@ viewMode = ViewMode.MERGE_PEOPLE; } }); + + const handleKeyboardPress = (event: KeyboardEvent) => { + if (suggestedPeople.length === 0) { + return; + } + if (!$showAssetViewer) { + event.stopPropagation(); + switch (event.key) { + case 'ArrowDown': { + event.preventDefault(); + if (indexFocus === null) { + indexFocus = 0; + } else if (indexFocus === suggestedPeople.length - 1) { + indexFocus = 0; + } else { + indexFocus++; + } + focusedElements[indexFocus]?.focus(); + return; + } + case 'ArrowUp': { + if (indexFocus === null) { + indexFocus = 0; + return; + } + if (indexFocus === 0) { + indexFocus = suggestedPeople.length - 1; + } else { + indexFocus--; + } + focusedElements[indexFocus]?.focus(); + + return; + } + case 'Enter': { + if (indexFocus !== null) { + handleSuggestPeople(suggestedPeople[indexFocus]); + } + } + } + } + }; + const handleEscape = () => { - if ($showAssetViewer) { + if ($showAssetViewer || viewMode === ViewMode.SUGGEST_MERGE) { return; } if ($isMultiSelectState) { @@ -350,6 +396,7 @@ }; + {#if viewMode === ViewMode.UNASSIGN_ASSETS} a.id)} @@ -499,24 +546,24 @@ {:else} {#each suggestedPeople as person, index (person.id)} -
handleSuggestPeople(person)} > - -
+ +

{person.name}

+ {/each} {/if}