0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2025-02-04 01:09:14 -05:00
This commit is contained in:
martabal 2023-12-10 02:51:48 +01:00
parent 5f98f12731
commit 565cac16d7
No known key found for this signature in database
GPG key ID: C00196E3148A52BD
4 changed files with 64 additions and 51 deletions

View file

@ -11,7 +11,7 @@
| 'transparent-gray' | 'transparent-gray'
| 'dark-gray' | 'dark-gray'
| 'overlay-primary'; | 'overlay-primary';
export type Size = 'tiny' | 'icon' | 'link' | 'sm' | 'base' | 'lg'; export type Size = 'tiny' | 'xs' | 'icon' | 'link' | 'sm' | 'base' | 'lg';
export type Rounded = 'lg' | '3xl' | 'full' | false; export type Rounded = 'lg' | '3xl' | 'full' | false;
export type Shadow = 'md' | false; export type Shadow = 'md' | false;
</script> </script>
@ -47,6 +47,7 @@
const sizeClasses: Record<Size, string> = { const sizeClasses: Record<Size, string> = {
tiny: 'p-0 ml-2 mr-0 align-top', tiny: 'p-0 ml-2 mr-0 align-top',
xs: 'p-2',
icon: 'p-2.5', icon: 'p-2.5',
link: 'p-2 font-medium', link: 'p-2 font-medium',
sm: 'px-4 py-2 text-sm font-medium', sm: 'px-4 py-2 text-sm font-medium',

View file

@ -22,9 +22,19 @@
let searchedPeople: PersonResponseDto[] = []; let searchedPeople: PersonResponseDto[] = [];
let searchedPeopleCopy: PersonResponseDto[] = []; let searchedPeopleCopy: PersonResponseDto[] = [];
let searchWord: string; let searchWord: string;
let searchFaces = false; let isSearchingPerson = false;
let searchName = ''; let searchName = '';
$: {
searchedPeople = searchedPeopleCopy.filter(
(person) => personWithFace.person && personWithFace.person.id !== person.id,
);
if (searchName) {
searchedPeople = searchNameLocal(searchName, searchedPeople, 10);
}
}
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
const handleBackButton = () => { const handleBackButton = () => {
dispatch('close'); dispatch('close');
@ -63,10 +73,6 @@
isShowLoadingSearch = false; isShowLoadingSearch = false;
}; };
$: {
searchedPeople = searchNameLocal(searchName, searchedPeopleCopy, 10);
}
const initInput = (element: HTMLInputElement) => { const initInput = (element: HTMLInputElement) => {
element.focus(); element.focus();
}; };
@ -77,7 +83,7 @@
class="absolute top-0 z-[2002] h-full w-[360px] overflow-x-hidden p-2 bg-immich-bg dark:bg-immich-dark-bg dark:text-immich-dark-fg" class="absolute top-0 z-[2002] h-full w-[360px] overflow-x-hidden p-2 bg-immich-bg dark:bg-immich-dark-bg dark:text-immich-dark-fg"
> >
<div class="flex place-items-center justify-between gap-2"> <div class="flex place-items-center justify-between gap-2">
{#if !searchFaces} {#if !isSearchingPerson}
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<button <button
class="flex place-content-center rounded-full p-3 transition-colors hover:bg-gray-200 dark:text-immich-dark-fg dark:hover:bg-gray-900" class="flex place-content-center rounded-full p-3 transition-colors hover:bg-gray-200 dark:text-immich-dark-fg dark:hover:bg-gray-900"
@ -94,7 +100,7 @@
class="flex place-content-center place-items-center rounded-full p-3 transition-colors hover:bg-gray-200 dark:text-immich-dark-fg dark:hover:bg-gray-900" class="flex place-content-center place-items-center rounded-full p-3 transition-colors hover:bg-gray-200 dark:text-immich-dark-fg dark:hover:bg-gray-900"
title="Search existing person" title="Search existing person"
on:click={() => { on:click={() => {
searchFaces = true; isSearchingPerson = true;
}} }}
> >
<div> <div>
@ -143,7 +149,7 @@
</div> </div>
<button <button
class="flex place-content-center place-items-center rounded-full p-3 transition-colors hover:bg-gray-200 dark:text-immich-dark-fg dark:hover:bg-gray-900" class="flex place-content-center place-items-center rounded-full p-3 transition-colors hover:bg-gray-200 dark:text-immich-dark-fg dark:hover:bg-gray-900"
on:click={() => (searchFaces = false)} on:click={() => (isSearchingPerson = false)}
> >
<div> <div>
<Icon path={mdiClose} size="24" /> <Icon path={mdiClose} size="24" />
@ -182,7 +188,6 @@
{/each} {/each}
{:else} {:else}
{#each searchedPeople as person (person.id)} {#each searchedPeople as person (person.id)}
{#if person.id !== personWithFace.person?.id}
<div class="w-fit"> <div class="w-fit">
<button class="w-[90px]" on:click={() => dispatch('reassign', person)}> <button class="w-[90px]" on:click={() => dispatch('reassign', person)}>
<div class="relative"> <div class="relative">
@ -201,7 +206,6 @@
<p class="mt-1 truncate font-medium" title={person.name}>{person.name}</p> <p class="mt-1 truncate font-medium" title={person.name}>{person.name}</p>
</button> </button>
</div> </div>
{/if}
{/each} {/each}
{/if} {/if}
</div> </div>

View file

@ -16,6 +16,7 @@
import { currentAsset, photoViewer } from '$lib/stores/assets.store'; import { currentAsset, photoViewer } from '$lib/stores/assets.store';
import UnassignedFacesSidePannel from './unassigned-faces-side-pannel.svelte'; import UnassignedFacesSidePannel from './unassigned-faces-side-pannel.svelte';
import type { FaceWithGeneretedThumbnail } from '$lib/utils/people-utils'; import type { FaceWithGeneretedThumbnail } from '$lib/utils/people-utils';
import Button from '../elements/buttons/button.svelte';
// keep track of the changes // keep track of the changes
let idsOfPersonToCreate: string[] = []; let idsOfPersonToCreate: string[] = [];
@ -28,7 +29,7 @@
let selectedPersonToAdd: FaceWithGeneretedThumbnail[] = []; let selectedPersonToAdd: FaceWithGeneretedThumbnail[] = [];
let selectedPersonToUnassign: FaceWithGeneretedThumbnail[] = []; let selectedPersonToUnassign: FaceWithGeneretedThumbnail[] = [];
let selectedPersonToRemove: boolean[] = []; let selectedPersonToRemove: boolean[] = [];
let unassignedFaces: (FaceWithGeneretedThumbnail | null)[] = []; let unassignedFaces: FaceWithGeneretedThumbnail[] = [];
let editedPersonIndex: number; let editedPersonIndex: number;
let shouldRefresh: boolean = false; let shouldRefresh: boolean = false;
@ -83,7 +84,8 @@
selectedPersonToCreate = new Array<string | null>(peopleWithFaces.length); selectedPersonToCreate = new Array<string | null>(peopleWithFaces.length);
selectedPersonToReassign = new Array<PersonResponseDto | null>(peopleWithFaces.length); selectedPersonToReassign = new Array<PersonResponseDto | null>(peopleWithFaces.length);
selectedPersonToRemove = new Array<boolean>(peopleWithFaces.length); selectedPersonToRemove = new Array<boolean>(peopleWithFaces.length);
unassignedFaces = await Promise.all( unassignedFaces = (
await Promise.all(
peopleWithFaces.map(async (personWithFace) => { peopleWithFaces.map(async (personWithFace) => {
if (personWithFace.person || $currentAsset === null) { if (personWithFace.person || $currentAsset === null) {
return null; return null;
@ -92,7 +94,8 @@
return image ? { ...personWithFace, customThumbnail: image } : null; return image ? { ...personWithFace, customThumbnail: image } : null;
} }
}), }),
); )
).filter((item): item is FaceWithGeneretedThumbnail => item !== null);
} catch (error) { } catch (error) {
handleError(error, "Can't get faces"); handleError(error, "Can't get faces");
} finally { } finally {
@ -149,9 +152,10 @@
const handleAddRemovedFace = (indexToRemove: number) => { const handleAddRemovedFace = (indexToRemove: number) => {
$boundingBoxesArray = []; $boundingBoxesArray = [];
unassignedFaces = unassignedFaces.map((obj) => unassignedFaces = unassignedFaces
obj && obj.id === selectedPersonToUnassign[indexToRemove].id ? null : obj, .map((obj) => (obj && obj.id === selectedPersonToUnassign[indexToRemove].id ? null : obj))
); .filter((item): item is FaceWithGeneretedThumbnail => item !== null) as FaceWithGeneretedThumbnail[];
selectedPersonToUnassign = selectedPersonToUnassign.filter((_, index) => index !== indexToRemove); selectedPersonToUnassign = selectedPersonToUnassign.filter((_, index) => index !== indexToRemove);
}; };
@ -343,16 +347,20 @@
</div> </div>
</div> </div>
{:else} {:else}
<div>Visible faces</div> <div>Faces visible</div>
{/if} {/if}
{#if isSelectingFaces && selectedPersonToRemove && selectedPersonToRemove.filter((value) => value).length > 0} {#if isSelectingFaces && selectedPersonToRemove && selectedPersonToRemove.filter((value) => value).length > 0}
<button <Button
class="justify-self-end rounded-lg p-2 hover:bg-immich-dark-primary hover:dark:bg-immich-dark-primary/50" size="xs"
color="red"
title="Unassign faces"
shadow={false}
rounded="full"
on:click={handleUnassignFaces} on:click={handleUnassignFaces}
> >
Unassign faces Unassign Faces
</button> </Button>
{/if} {/if}
</div> </div>
<div class="mt-2 flex flex-wrap gap-2"> <div class="mt-2 flex flex-wrap gap-2">
@ -362,7 +370,7 @@
</div> </div>
{:else} {:else}
{#each peopleWithFaces as face, index} {#each peopleWithFaces as face, index}
{#if face.person && unassignedFaces[index] === null && !selectedPersonToUnassign.some((unassignedFace) => unassignedFace.id === face.id)} {#if face.person && !unassignedFaces.some((unassignedFace) => unassignedFace.id === face.id) && !selectedPersonToUnassign.some((unassignedFace) => unassignedFace.id === face.id)}
<div class="relative z-[20001] h-[115px] w-[95px]"> <div class="relative z-[20001] h-[115px] w-[95px]">
<div <div
role="button" role="button"

View file

@ -13,7 +13,7 @@
import type { FaceWithGeneretedThumbnail } from '$lib/utils/people-utils'; import type { FaceWithGeneretedThumbnail } from '$lib/utils/people-utils';
import { boundingBoxesArray } from '$lib/stores/people.store'; import { boundingBoxesArray } from '$lib/stores/people.store';
export let unassignedFaces: (FaceWithGeneretedThumbnail | null)[]; export let unassignedFaces: FaceWithGeneretedThumbnail[];
export let allPeople: PersonResponseDto[]; export let allPeople: PersonResponseDto[];
export let selectedPersonToAdd: FaceWithGeneretedThumbnail[]; export let selectedPersonToAdd: FaceWithGeneretedThumbnail[];
@ -74,7 +74,7 @@
<div class="px-4 py-4 text-sm"> <div class="px-4 py-4 text-sm">
<div class="mt-4 flex flex-wrap gap-2"> <div class="mt-4 flex flex-wrap gap-2">
{#each unassignedFaces as face, index} {#each unassignedFaces as face, index}
{#if face && !selectedPersonToAdd.some((faceToAdd) => face && faceToAdd.id === face.id)} {#if !selectedPersonToAdd.some((faceToAdd) => face && faceToAdd.id === face.id)}
<div class="relative z-[20001] h-[115px] w-[95px]"> <div class="relative z-[20001] h-[115px] w-[95px]">
<button <button
tabindex={index} tabindex={index}