diff --git a/web/src/lib/components/faces-page/merge-face-selector.svelte b/web/src/lib/components/faces-page/merge-face-selector.svelte index 9a7bb025e7..1456459a5b 100644 --- a/web/src/lib/components/faces-page/merge-face-selector.svelte +++ b/web/src/lib/components/faces-page/merge-face-selector.svelte @@ -12,15 +12,21 @@ import { handleError } from '$lib/utils/handle-error'; import { goto } from '$app/navigation'; import { AppRoute } from '$lib/constants'; - import { mdiCallMerge, mdiMerge, mdiSwapHorizontal } from '@mdi/js'; + import { mdiCallMerge, mdiClose, mdiMagnify, mdiMerge, mdiSwapHorizontal } from '@mdi/js'; import Icon from '$lib/components/elements/icon.svelte'; import CircleIconButton from '../elements/buttons/circle-icon-button.svelte'; + import { cloneDeep } from 'lodash-es'; + import LoadingSpinner from '../shared-components/loading-spinner.svelte'; export let person: PersonResponseDto; let people: PersonResponseDto[] = []; + let peopleCopy: PersonResponseDto[] = []; let selectedPeople: PersonResponseDto[] = []; let screenHeight: number; let isShowConfirmation = false; + let name = ''; + let searchWord: string; + let isSearchingPeople = false; let dispatch = createEventDispatcher(); $: hasSelection = selectedPeople.length > 0; @@ -31,12 +37,49 @@ onMount(async () => { const { data } = await api.personApi.getAllPeople({ withHidden: false }); people = data.people; + peopleCopy = cloneDeep(people); }); const onClose = () => { dispatch('go-back'); }; + const resetSearch = () => { + name = ''; + people = peopleCopy; + }; + + const searchPeople = async (force: boolean) => { + if (name === '') { + people = peopleCopy; + return; + } + if (!force) { + if (people.length < 20 && name.startsWith(searchWord)) { + people = peopleCopy + .filter((person: PersonResponseDto) => { + const nameParts = person.name.split(' '); + return nameParts.some((splitName) => splitName.toLowerCase().startsWith(name.toLowerCase())); + }) + .slice(0, 10); + return; + } + } + + const timeout = setTimeout(() => (isSearchingPeople = true), 100); + try { + const { data } = await api.searchApi.searchPerson({ name }); + people = data; + searchWord = name; + } catch (error) { + handleError(error, "Can't search people"); + } finally { + clearTimeout(timeout); + } + + isSearchingPeople = false; + }; + const handleSwapPeople = () => { [person, selectedPeople[0]] = [selectedPeople[0], person]; goto(`${AppRoute.PEOPLE}/${person.id}?action=merge`); @@ -136,9 +179,39 @@ +
+ + + searchPeople(false)} + /> + {#if name} + + {/if} + {#if isSearchingPeople} +
+ +
+ {/if} +
+ +
{#each unselectedPeople as person (person.id)}