fix: thershold option and fix hide person
This commit is contained in:
1 parent
7639de9e45
commit
e0f96cea0d
4 files changed
+38
-14
No files matched your search
@@ -10,7 +10,7 @@ import { ArrowUpRight, Info, Search } from "lucide-react";
|
|||||||
import { useConfig } from "@/contexts/ConfigContext";
|
import { useConfig } from "@/contexts/ConfigContext";
|
||||||
import { useToast } from "../ui/use-toast";
|
import { useToast } from "../ui/use-toast";
|
||||||
import { Badge } from "../ui/badge";
|
import { Badge } from "../ui/badge";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
interface IProps {
|
interface IProps {
|
||||||
person: IPerson;
|
person: IPerson;
|
||||||
onRemove: (person: IPerson) => void;
|
onRemove: (person: IPerson) => void;
|
||||||
@@ -78,18 +78,11 @@ export default function PersonItem({ person, onRemove }: IProps) {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="relative w-full h-auto group">
|
<div className="relative w-full h-auto group">
|
||||||
<div
|
|
||||||
onClick={() => {
|
|
||||||
handleHide(!formData.isHidden);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Avatar
|
<Avatar
|
||||||
className="w-full min-h-full h-auto rounded-lg"
|
className="w-full min-h-full h-auto rounded-lg"
|
||||||
src={person.thumbnailPath}
|
src={person.thumbnailPath}
|
||||||
alt={person.name}
|
alt={person.name}
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="absolute bottom-2 w-full flex justify-center items-center">
|
<div className="absolute bottom-2 w-full flex justify-center items-center">
|
||||||
<Badge variant={"secondary"} className="text-xs !font-medium font-mono">{person.assetCount} Assets</Badge>
|
<Badge variant={"secondary"} className="text-xs !font-medium font-mono">{person.assetCount} Assets</Badge>
|
||||||
</div>
|
</div>
|
||||||
@@ -108,8 +101,13 @@ export default function PersonItem({ person, onRemove }: IProps) {
|
|||||||
<Info size={16} />
|
<Info size={16} />
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="absolute top-2 right-2 ">
|
<div className="absolute top-2 right-2 flex flex-col gap-2">
|
||||||
<PersonMergeDropdown person={person} onRemove={onRemove}/>
|
<PersonMergeDropdown person={person} onRemove={onRemove}/>
|
||||||
|
<Button variant="outline" className="!py-0.5 !px-2 text-xs h-7" onClick={() => {
|
||||||
|
handleHide(!formData.isHidden);
|
||||||
|
}}>
|
||||||
|
Hide
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{!editMode ? (
|
{!editMode ? (
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ export function PersonMergeDropdown({
|
|||||||
const [selectedPeople, setSelectedPeople] = useState<IPerson[]>([]);
|
const [selectedPeople, setSelectedPeople] = useState<IPerson[]>([]);
|
||||||
const [primaryPerson, setPrimaryPerson] = useState<IPerson>(person);
|
const [primaryPerson, setPrimaryPerson] = useState<IPerson>(person);
|
||||||
const [merging, setMerging] = useState(false);
|
const [merging, setMerging] = useState(false);
|
||||||
|
const [threshold, setThreshold] = useState(0.5);
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
|
|
||||||
const selectedIds = useMemo(
|
const selectedIds = useMemo(
|
||||||
@@ -89,7 +90,7 @@ export function PersonMergeDropdown({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const fetchSuggestions = () => {
|
const fetchSuggestions = () => {
|
||||||
return listSimilarFaces(person.id)
|
return listSimilarFaces(person.id, threshold)
|
||||||
.then(setSimilarPeople)
|
.then(setSimilarPeople)
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
toast({
|
toast({
|
||||||
@@ -161,6 +162,13 @@ export function PersonMergeDropdown({
|
|||||||
setSelectedPeople(newSelected);
|
setSelectedPeople(newSelected);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (open) {
|
||||||
|
setSimilarLoading(true);
|
||||||
|
fetchSuggestions();
|
||||||
|
}
|
||||||
|
}, [threshold, open]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open && !similarPeople.length) fetchSuggestions();
|
if (open && !similarPeople.length) fetchSuggestions();
|
||||||
}, [open, person.id, similarPeople]);
|
}, [open, person.id, similarPeople]);
|
||||||
@@ -279,6 +287,21 @@ export function PersonMergeDropdown({
|
|||||||
handleSearch(e.target.value);
|
handleSearch(e.target.value);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="threshold" className="block text-sm font-medium text-gray-300">
|
||||||
|
Threshold
|
||||||
|
</label>
|
||||||
|
<Input
|
||||||
|
type="number"
|
||||||
|
step="0.01"
|
||||||
|
min="0"
|
||||||
|
max="1"
|
||||||
|
value={threshold}
|
||||||
|
onChange={(e) => setThreshold(parseFloat(e.target.value))}
|
||||||
|
placeholder="Threshold (0 to 1)"
|
||||||
|
className="mt-2"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{selectedPeople.length > 0 ? (
|
{selectedPeople.length > 0 ? (
|
||||||
<div className="flex flex-nowrap overflow-x-auto gap-2 py-2">
|
<div className="flex flex-nowrap overflow-x-auto gap-2 py-2">
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ export const mergePerson = (id: string, targetIds: string[]) => {
|
|||||||
return API.post(MERGE_PERSON_PATH(id), { ids: targetIds })
|
return API.post(MERGE_PERSON_PATH(id), { ids: targetIds })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const listSimilarFaces = (id: string) => {
|
export const listSimilarFaces = (id: string, threshold: number) => {
|
||||||
return API.get(SIMILAR_FACES_PATH(id)).then((response) => response.map((person: any) => cleanUpPerson(person, true)));
|
return API.get(SIMILAR_FACES_PATH(id), { threshold: threshold })
|
||||||
|
.then((response) => response.map((person: any) => cleanUpPerson(person, true)));
|
||||||
}
|
}
|
||||||
@@ -18,6 +18,7 @@ interface IQuery {
|
|||||||
minimumAssetCount: number;
|
minimumAssetCount: number;
|
||||||
sort: ISortField;
|
sort: ISortField;
|
||||||
sortOrder: "asc" | "desc";
|
sortOrder: "asc" | "desc";
|
||||||
|
threshold?: number;
|
||||||
}
|
}
|
||||||
export default async function handler(
|
export default async function handler(
|
||||||
req: NextApiRequest,
|
req: NextApiRequest,
|
||||||
@@ -26,9 +27,10 @@ export default async function handler(
|
|||||||
try {
|
try {
|
||||||
const {
|
const {
|
||||||
id,
|
id,
|
||||||
|
threshold = 0.5,
|
||||||
} = req.query as any as IQuery;
|
} = req.query as any as IQuery;
|
||||||
|
|
||||||
const currentUser = await getCurrentUser(req);
|
const currentUser = await getCurrentUser(req);
|
||||||
const personRecords = await db
|
const personRecords = await db
|
||||||
.select()
|
.select()
|
||||||
.from(person)
|
.from(person)
|
||||||
@@ -92,7 +94,7 @@ export default async function handler(
|
|||||||
and(
|
and(
|
||||||
ne(person.id, id),
|
ne(person.id, id),
|
||||||
eq(person.ownerId, currentUser.id),
|
eq(person.ownerId, currentUser.id),
|
||||||
gt(similarity, 0.5)
|
gt(similarity, threshold)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.limit(12);
|
.limit(12);
|
||||||
|
|||||||
Reference in new issue
Block a user