@ -32,6 +32,7 @@
import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
import Plus from 'svelte-material-icons/Plus.svelte';
import type { PageData } from './$types';
import { clickOutside } from '$lib/utils/click-outside';
export let data: PageData;
@ -58,12 +59,27 @@
let people = data.people.people;
let personMerge1: PersonResponseDto;
let personMerge2: PersonResponseDto;
let potentialMergePeople: PersonResponseDto[] = [];
let personName = '';
let name: string = data.person.name;
let suggestedPeople: PersonResponseDto[] = [];
$: isAllArchive = Array.from($selectedAssets).every((asset) => asset.isArchived);
$: isAllFavorite = Array.from($selectedAssets).every((asset) => asset.isFavorite);
$: {
suggestedPeople = !name
? []
: people
.filter(
(person: PersonResponseDto) =>
person.name.toLowerCase().startsWith(name.toLowerCase()) & & person.id !== data.person.id,
)
.slice(0, 5);
}
onMount(() => {
const action = $page.url.searchParams.get('action');
if (action == 'merge') {
@ -147,6 +163,14 @@
}
};
const handleSuggestPeople = (person: PersonResponseDto) => {
isEditingName = false;
potentialMergePeople = [];
personMerge1 = data.person;
personMerge2 = person;
viewMode = ViewMode.SUGGEST_MERGE;
};
const changeName = async () => {
viewMode = ViewMode.VIEW_ASSETS;
data.person.name = personName;
@ -183,6 +207,7 @@
};
const handleNameChange = async (name: string) => {
potentialMergePeople = [];
personName = name;
if (data.person.name === personName) {
@ -196,6 +221,15 @@
if (existingPerson) {
personMerge2 = existingPerson;
personMerge1 = data.person;
potentialMergePeople = people
.filter(
(person: PersonResponseDto) =>
personMerge2.name.toLowerCase() === person.name.toLowerCase() & &
person.id !== personMerge2.id & &
person.id !== personMerge1.id & &
!person.isHidden,
)
.slice(0, 3);
viewMode = ViewMode.SUGGEST_MERGE;
return;
}
@ -238,7 +272,7 @@
< MergeSuggestionModal
{ personMerge1 }
{ personMerge2 }
{ p eople}
{ p otentialMergeP eople}
on:close={() => ( viewMode = ViewMode . VIEW_ASSETS )}
on:reject={() => changeName ()}
on:confirm={( event ) => handleMergeSameFace ( event . detail )}
@ -306,39 +340,70 @@
>
{ #if viewMode === ViewMode . VIEW_ASSETS || viewMode === ViewMode . SUGGEST_MERGE || viewMode === ViewMode . BIRTH_DATE }
<!-- Face information block -->
< section class = "flex place-items-center p-4 sm:px-6" >
{ #if isEditingName }
< EditNameInput
person={ data . person }
on:change={( event ) => handleNameChange ( event . detail )}
on:cancel={() => handleCancelEditName ()}
/>
{ : else }
< button on:click = {() => ( viewMode = ViewMode . VIEW_ASSETS )} >
< ImageThumbnail
circle
shadow
url={ api . getPeopleThumbnailUrl ( data . person . id )}
altText={ data . person . name }
widthStyle="3.375rem"
heightStyle="3.375rem"
< div
role="button"
class="relative w-fit p-4 sm:px-6"
use:clickOutside
on:outclick={() => handleCancelEditName ()}
>
< section class = "flex w-96 place-items-center border-black" >
{ #if isEditingName }
< EditNameInput
person={ data . person }
suggestedPeople={ suggestedPeople . length > 0 }
bind:name
on:change={( event ) => handleNameChange ( event . detail )}
/>
< / button >
< button
title="Edit name"
class="px-4 text-immich-primary dark:text-immich-dark-primary"
on:click={() => ( isEditingName = true )}
>
{ #if data . person . name }
< p class = "py-2 font-medium" > { data . person . name } </ p >
{ : else }
< p class = "w-fit font-medium" > Add a name< / p >
< p class = "text-sm text-gray-500 dark:text-immich-gray" > Find them fast by name with search< / p >
{ /if }
< / button >
{ : else }
< button on:click = {() => ( viewMode = ViewMode . VIEW_ASSETS )} >
< ImageThumbnail
circle
shadow
url={ api . getPeopleThumbnailUrl ( data . person . id )}
altText={ data . person . name }
widthStyle="3.375rem"
heightStyle="3.375rem"
/>
< / button >
< button
title="Edit name"
class="px-4 text-immich-primary dark:text-immich-dark-primary"
on:click={() => ( isEditingName = true )}
>
{ #if data . person . name }
< p class = "py-2 font-medium" > { data . person . name } </ p >
{ : else }
< p class = "w-fit font-medium" > Add a name< / p >
< p class = "text-sm text-gray-500 dark:text-immich-gray" > Find them fast by name with search< / p >
{ /if }
< / button >
{ /if }
< / section >
{ #if isEditingName }
< div class = "absolute z-[999] w-96" >
{ #each suggestedPeople as person , index ( person . id )}
< div
class="flex { index === suggestedPeople . length - 1
? 'rounded-b-lg'
: 'border-b dark:border-immich-dark-gray'} place-items-center bg-gray-100 p-2 dark:bg-gray-700"
>
< 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 >
{ /each }
< / div >
{ /if }
< / section >
< / div >
{ /if }
< / AssetGrid >
{ /key }