mirror of
https://github.com/immich-app/immich.git
synced 2025-02-04 01:09:14 -05:00
simplify
This commit is contained in:
parent
5f98f12731
commit
565cac16d7
4 changed files with 64 additions and 51 deletions
|
@ -11,7 +11,7 @@
|
|||
| 'transparent-gray'
|
||||
| 'dark-gray'
|
||||
| '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 Shadow = 'md' | false;
|
||||
</script>
|
||||
|
@ -47,6 +47,7 @@
|
|||
|
||||
const sizeClasses: Record<Size, string> = {
|
||||
tiny: 'p-0 ml-2 mr-0 align-top',
|
||||
xs: 'p-2',
|
||||
icon: 'p-2.5',
|
||||
link: 'p-2 font-medium',
|
||||
sm: 'px-4 py-2 text-sm font-medium',
|
||||
|
|
|
@ -22,9 +22,19 @@
|
|||
let searchedPeople: PersonResponseDto[] = [];
|
||||
let searchedPeopleCopy: PersonResponseDto[] = [];
|
||||
let searchWord: string;
|
||||
let searchFaces = false;
|
||||
let isSearchingPerson = false;
|
||||
let searchName = '';
|
||||
|
||||
$: {
|
||||
searchedPeople = searchedPeopleCopy.filter(
|
||||
(person) => personWithFace.person && personWithFace.person.id !== person.id,
|
||||
);
|
||||
|
||||
if (searchName) {
|
||||
searchedPeople = searchNameLocal(searchName, searchedPeople, 10);
|
||||
}
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
const handleBackButton = () => {
|
||||
dispatch('close');
|
||||
|
@ -63,10 +73,6 @@
|
|||
isShowLoadingSearch = false;
|
||||
};
|
||||
|
||||
$: {
|
||||
searchedPeople = searchNameLocal(searchName, searchedPeopleCopy, 10);
|
||||
}
|
||||
|
||||
const initInput = (element: HTMLInputElement) => {
|
||||
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"
|
||||
>
|
||||
<div class="flex place-items-center justify-between gap-2">
|
||||
{#if !searchFaces}
|
||||
{#if !isSearchingPerson}
|
||||
<div class="flex items-center gap-2">
|
||||
<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"
|
||||
|
@ -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"
|
||||
title="Search existing person"
|
||||
on:click={() => {
|
||||
searchFaces = true;
|
||||
isSearchingPerson = true;
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
|
@ -143,7 +149,7 @@
|
|||
</div>
|
||||
<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"
|
||||
on:click={() => (searchFaces = false)}
|
||||
on:click={() => (isSearchingPerson = false)}
|
||||
>
|
||||
<div>
|
||||
<Icon path={mdiClose} size="24" />
|
||||
|
@ -182,26 +188,24 @@
|
|||
{/each}
|
||||
{:else}
|
||||
{#each searchedPeople as person (person.id)}
|
||||
{#if person.id !== personWithFace.person?.id}
|
||||
<div class="w-fit">
|
||||
<button class="w-[90px]" on:click={() => dispatch('reassign', person)}>
|
||||
<div class="relative">
|
||||
<ImageThumbnail
|
||||
curve
|
||||
shadow
|
||||
url={api.getPeopleThumbnailUrl(person.id)}
|
||||
altText={getPersonNameWithHiddenValue(person.name, person.isHidden)}
|
||||
title={getPersonNameWithHiddenValue(person.name, person.isHidden)}
|
||||
widthStyle="90px"
|
||||
heightStyle="90px"
|
||||
thumbhash={null}
|
||||
hidden={person.isHidden}
|
||||
/>
|
||||
</div>
|
||||
<p class="mt-1 truncate font-medium" title={person.name}>{person.name}</p>
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="w-fit">
|
||||
<button class="w-[90px]" on:click={() => dispatch('reassign', person)}>
|
||||
<div class="relative">
|
||||
<ImageThumbnail
|
||||
curve
|
||||
shadow
|
||||
url={api.getPeopleThumbnailUrl(person.id)}
|
||||
altText={getPersonNameWithHiddenValue(person.name, person.isHidden)}
|
||||
title={getPersonNameWithHiddenValue(person.name, person.isHidden)}
|
||||
widthStyle="90px"
|
||||
heightStyle="90px"
|
||||
thumbhash={null}
|
||||
hidden={person.isHidden}
|
||||
/>
|
||||
</div>
|
||||
<p class="mt-1 truncate font-medium" title={person.name}>{person.name}</p>
|
||||
</button>
|
||||
</div>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
import { currentAsset, photoViewer } from '$lib/stores/assets.store';
|
||||
import UnassignedFacesSidePannel from './unassigned-faces-side-pannel.svelte';
|
||||
import type { FaceWithGeneretedThumbnail } from '$lib/utils/people-utils';
|
||||
import Button from '../elements/buttons/button.svelte';
|
||||
|
||||
// keep track of the changes
|
||||
let idsOfPersonToCreate: string[] = [];
|
||||
|
@ -28,7 +29,7 @@
|
|||
let selectedPersonToAdd: FaceWithGeneretedThumbnail[] = [];
|
||||
let selectedPersonToUnassign: FaceWithGeneretedThumbnail[] = [];
|
||||
let selectedPersonToRemove: boolean[] = [];
|
||||
let unassignedFaces: (FaceWithGeneretedThumbnail | null)[] = [];
|
||||
let unassignedFaces: FaceWithGeneretedThumbnail[] = [];
|
||||
let editedPersonIndex: number;
|
||||
let shouldRefresh: boolean = false;
|
||||
|
||||
|
@ -83,16 +84,18 @@
|
|||
selectedPersonToCreate = new Array<string | null>(peopleWithFaces.length);
|
||||
selectedPersonToReassign = new Array<PersonResponseDto | null>(peopleWithFaces.length);
|
||||
selectedPersonToRemove = new Array<boolean>(peopleWithFaces.length);
|
||||
unassignedFaces = await Promise.all(
|
||||
peopleWithFaces.map(async (personWithFace) => {
|
||||
if (personWithFace.person || $currentAsset === null) {
|
||||
return null;
|
||||
} else {
|
||||
const image = await zoomImageToBase64(personWithFace, $photoViewer, $currentAsset.type, $currentAsset.id);
|
||||
return image ? { ...personWithFace, customThumbnail: image } : null;
|
||||
}
|
||||
}),
|
||||
);
|
||||
unassignedFaces = (
|
||||
await Promise.all(
|
||||
peopleWithFaces.map(async (personWithFace) => {
|
||||
if (personWithFace.person || $currentAsset === null) {
|
||||
return null;
|
||||
} else {
|
||||
const image = await zoomImageToBase64(personWithFace, $photoViewer, $currentAsset.type, $currentAsset.id);
|
||||
return image ? { ...personWithFace, customThumbnail: image } : null;
|
||||
}
|
||||
}),
|
||||
)
|
||||
).filter((item): item is FaceWithGeneretedThumbnail => item !== null);
|
||||
} catch (error) {
|
||||
handleError(error, "Can't get faces");
|
||||
} finally {
|
||||
|
@ -149,9 +152,10 @@
|
|||
|
||||
const handleAddRemovedFace = (indexToRemove: number) => {
|
||||
$boundingBoxesArray = [];
|
||||
unassignedFaces = unassignedFaces.map((obj) =>
|
||||
obj && obj.id === selectedPersonToUnassign[indexToRemove].id ? null : obj,
|
||||
);
|
||||
unassignedFaces = unassignedFaces
|
||||
.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);
|
||||
};
|
||||
|
||||
|
@ -343,16 +347,20 @@
|
|||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div>Visible faces</div>
|
||||
<div>Faces visible</div>
|
||||
{/if}
|
||||
|
||||
{#if isSelectingFaces && selectedPersonToRemove && selectedPersonToRemove.filter((value) => value).length > 0}
|
||||
<button
|
||||
class="justify-self-end rounded-lg p-2 hover:bg-immich-dark-primary hover:dark:bg-immich-dark-primary/50"
|
||||
<Button
|
||||
size="xs"
|
||||
color="red"
|
||||
title="Unassign faces"
|
||||
shadow={false}
|
||||
rounded="full"
|
||||
on:click={handleUnassignFaces}
|
||||
>
|
||||
Unassign faces
|
||||
</button>
|
||||
Unassign Faces
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="mt-2 flex flex-wrap gap-2">
|
||||
|
@ -362,7 +370,7 @@
|
|||
</div>
|
||||
{:else}
|
||||
{#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
|
||||
role="button"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
import type { FaceWithGeneretedThumbnail } from '$lib/utils/people-utils';
|
||||
import { boundingBoxesArray } from '$lib/stores/people.store';
|
||||
|
||||
export let unassignedFaces: (FaceWithGeneretedThumbnail | null)[];
|
||||
export let unassignedFaces: FaceWithGeneretedThumbnail[];
|
||||
export let allPeople: PersonResponseDto[];
|
||||
export let selectedPersonToAdd: FaceWithGeneretedThumbnail[];
|
||||
|
||||
|
@ -74,7 +74,7 @@
|
|||
<div class="px-4 py-4 text-sm">
|
||||
<div class="mt-4 flex flex-wrap gap-2">
|
||||
{#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]">
|
||||
<button
|
||||
tabindex={index}
|
||||
|
|
Loading…
Add table
Reference in a new issue