@@ -18,8 +18,6 @@ import {
|
||||
searchPeople,
|
||||
} from "@/handlers/api/people.handler";
|
||||
import { IPerson } from "@/types/person";
|
||||
import { set } from "date-fns";
|
||||
import { CommandLoading } from "cmdk";
|
||||
import { Avatar } from "../ui/avatar";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useToast } from "../ui/use-toast";
|
||||
@@ -31,7 +29,7 @@ import {
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "../ui/dropdown-menu";
|
||||
import { CaretDownIcon, FaceIcon } from "@radix-ui/react-icons";
|
||||
import { CaretDownIcon } from "@radix-ui/react-icons";
|
||||
import FaceThumbnail from "./merge/FaceThumbnail";
|
||||
import ErrorBlock from "../shared/ErrorBlock";
|
||||
|
||||
@@ -103,6 +101,7 @@ export function PersonMergeDropdown({
|
||||
const isAlreadySelected = selectedPeople.some((p) => p.id === value.id);
|
||||
if (isAlreadySelected) {
|
||||
setSelectedPeople(selectedPeople.filter((p) => p.id !== value.id));
|
||||
return;
|
||||
}
|
||||
if (selectedPeople.length >= 5) {
|
||||
toast({
|
||||
@@ -168,7 +167,7 @@ export function PersonMergeDropdown({
|
||||
|
||||
useEffect(() => {
|
||||
if (open && !similarPeople.length) fetchSuggestions();
|
||||
}, [open, person.id]);
|
||||
}, [open, person.id, similarPeople]);
|
||||
|
||||
const renderPeopleList = (people: IPerson[], title: string) => {
|
||||
return (
|
||||
@@ -286,7 +285,7 @@ export function PersonMergeDropdown({
|
||||
{selectedPeople.map((person) => (
|
||||
<div
|
||||
key={person.id}
|
||||
className="flex border px-1 items-center gap-1 bg-zinc-900 rounded-lg p-1"
|
||||
className="flex border px-1 items-center gap-1 dark:bg-zinc-900 rounded-lg p-1"
|
||||
>
|
||||
<Avatar
|
||||
src={person.thumbnailPath}
|
||||
@@ -297,7 +296,7 @@ export function PersonMergeDropdown({
|
||||
{person.name ? person.name : <span>Untagged person</span>}
|
||||
</p>
|
||||
<button
|
||||
className="rounded-full hover:bg-zinc-800 p-1"
|
||||
className="rounded-full dark:hover:bg-zinc-800 hover:bg-zinc-200 p-1"
|
||||
onClick={() => handleRemove(person)}
|
||||
>
|
||||
<X className="w-4 h-4" />
|
||||
|
||||
@@ -11,23 +11,30 @@ const FaceThumbnail = ({ person, onSelect, selected }: FaceThumbnailProps) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"col-span-1 flex flex-col items-center p-2 border-2 text-center rounded-lg hover:bg-zinc-900 gap-2 justify-center",
|
||||
" col-span-1 group flex flex-col items-center p-2 border-2 text-center rounded-lg dark:hover:bg-zinc-900 hover:bg-zinc-100 gap-2 justify-center",
|
||||
{
|
||||
"border-zinc-500": selected,
|
||||
}
|
||||
)}
|
||||
onClick={() => onSelect(person)}
|
||||
>
|
||||
<div className="relative">
|
||||
<Avatar
|
||||
src={person.thumbnailPath}
|
||||
alt={person.name}
|
||||
className="w-20 h-20"
|
||||
|
||||
className="w-full h-full rounded-lg"
|
||||
/>
|
||||
<p className="absolute text-[9px] top-1 right-1 bg-amber-300 px-1 text-zinc-900 rounded-lg group-hover:hidden">
|
||||
{person.similarity ? `${Math.round(person.similarity * 100)}%` : ""}
|
||||
</p>
|
||||
</div>
|
||||
{person.name ? (
|
||||
<p className="text-xs">{person.name}</p>
|
||||
<p className="text-[12px]">{person.name}</p>
|
||||
) : (
|
||||
<p className="text-xs italic text-gray-400">Untagged Person</p>
|
||||
<p className="text-[12px] italic text-gray-400">Untagged Person</p>
|
||||
)}
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -41,5 +41,5 @@ export const mergePerson = (id: string, targetIds: string[]) => {
|
||||
}
|
||||
|
||||
export const listSimilarFaces = (id: string) => {
|
||||
return API.get(SIMILAR_FACES_PATH(id)).then((response) => response.map(cleanUpPerson));
|
||||
return API.get(SIMILAR_FACES_PATH(id)).then((response) => response.map((person: any) => cleanUpPerson(person, true)));
|
||||
}
|
||||
@@ -7,10 +7,11 @@ interface IAPIPerson extends Omit<IPerson, 'birthDate' | 'updatedAt'> {
|
||||
birthDate: string | null;
|
||||
}
|
||||
|
||||
export const cleanUpPerson = (person: IAPIPerson): IPerson => {
|
||||
export const cleanUpPerson = (person: IAPIPerson, skipMock?: boolean): IPerson => {
|
||||
return {
|
||||
...person,
|
||||
thumbnailPath: PERSON_THUBNAIL_PATH(person.id),
|
||||
// thumbnailPath: PERSON_THUBNAIL_PATH(person.id),
|
||||
thumbnailPath: person.name === "Varun Raj" || skipMock === true ? PERSON_THUBNAIL_PATH(person.id) : "https://i.pravatar.cc/150?u=" + person.id,
|
||||
|
||||
birthDate: person.birthDate ? new Date(person.birthDate) : null,
|
||||
updatedAt: new Date(person.updatedAt),
|
||||
|
||||
Vendored
+1
-1
@@ -6,7 +6,7 @@ export interface IPerson {
|
||||
isHidden: boolean;
|
||||
updatedAt: Date;
|
||||
assetCount: number;
|
||||
|
||||
similarity?: number;
|
||||
}
|
||||
|
||||
interface IPeopleListResponse extends IListData{
|
||||
|
||||
Reference in New Issue
Block a user