Skip to content

Commit

Permalink
feat(web): navigate with keyboard on person page (#5486)
Browse files Browse the repository at this point in the history
* feat: navigate with keyboard on person page

* pr feedback

* pr feedback

* pr feedback

* fix: remove unused import
  • Loading branch information
martabal committed Feb 13, 2024
1 parent b4579e7 commit dcfd1f9
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 22 deletions.
1 change: 1 addition & 0 deletions web/src/lib/components/elements/buttons/button.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
export let fullwidth = false;
export let border = false;
export let title: string | undefined = '';
let className = '';
export { className as class };
Expand Down
25 changes: 18 additions & 7 deletions web/src/lib/components/faces-page/merge-suggestion-modal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
Expand All @@ -22,13 +16,30 @@
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]];
choosePersonToMerge = false;
};
</script>

<svelte:document on:keypress={handleKeyboardPress} />

<FullScreenModal on:clickOutside={() => dispatch('close')}>
<div class="flex h-full w-full place-content-center place-items-center overflow-hidden">
<div
Expand Down Expand Up @@ -114,7 +125,7 @@
<p class="text-sm text-gray-500 dark:text-gray-300">They will be merged together</p>
</div>
<div class="mt-8 flex w-full gap-4 px-4 pb-4">
<Button color="gray" fullwidth on:click={() => dispatch('reject')}>No</Button>
<Button fullwidth color="gray" on:click={() => dispatch('reject')}>No</Button>
<Button fullwidth on:click={() => dispatch('confirm', [personMerge1, personMerge2])}>Yes</Button>
</div>
</div>
Expand Down
77 changes: 62 additions & 15 deletions web/src/routes/(user)/people/[personId]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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 === '') {
Expand Down Expand Up @@ -116,6 +118,7 @@
$: {
if (people) {
suggestedPeople = name ? searchNameLocal(name, people, 5, data.person.id) : [];
indexFocus = null;
}
}
Expand All @@ -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) {
Expand Down Expand Up @@ -350,6 +396,7 @@
};
</script>

<svelte:document on:keydown={handleKeyboardPress} />
{#if viewMode === ViewMode.UNASSIGN_ASSETS}
<UnMergeFaceSelector
assetIds={[...$selectedAssets].map((a) => a.id)}
Expand Down Expand Up @@ -499,24 +546,24 @@
</div>
{:else}
{#each suggestedPeople as person, index (person.id)}
<div
class="flex border-t border-x border-gray-400 dark:border-immich-dark-gray h-14 place-items-center bg-gray-200 p-2 dark:bg-gray-700 hover:bg-gray-300 hover:dark:bg-[#232932] {index ===
<button
bind:this={focusedElements[index]}
class="flex w-full border-t border-gray-400 dark:border-immich-dark-gray h-14 place-items-center bg-gray-200 p-2 dark:bg-gray-700 hover:bg-gray-300 hover:dark:bg-[#232932] focus:bg-gray-300 focus:dark:bg-[#232932] {index ===
suggestedPeople.length - 1
? 'rounded-b-lg border-b'
: ''}"
on:click={() => handleSuggestPeople(person)}
>
<button class="flex w-full place-items-center" on:click={() => handleSuggestPeople(person)}>
<ImageThumbnail
circle
shadow
url={api.getPeopleThumbnailUrl(person.id)}
altText={person.name}
widthStyle="2rem"
heightStyle="2rem"
/>
<p class="ml-4 text-gray-700 dark:text-gray-100">{person.name}</p>
</button>
</div>
<ImageThumbnail
circle
shadow
url={api.getPeopleThumbnailUrl(person.id)}
altText={person.name}
widthStyle="2rem"
heightStyle="2rem"
/>
<p class="ml-4 text-gray-700 dark:text-gray-100">{person.name}</p>
</button>
{/each}
{/if}
</div>
Expand Down

0 comments on commit dcfd1f9

Please sign in to comment.