mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-13 06:35:24 +03:00
Implement similarity search
This commit is contained in:
parent
2418111cd4
commit
ebcae504cd
@ -16,10 +16,12 @@ import { toast } from "sonner";
|
|||||||
type SearchDetailDialogProps = {
|
type SearchDetailDialogProps = {
|
||||||
search?: SearchResult;
|
search?: SearchResult;
|
||||||
setSearch: (search: SearchResult | undefined) => void;
|
setSearch: (search: SearchResult | undefined) => void;
|
||||||
|
setSimilarity?: () => void;
|
||||||
};
|
};
|
||||||
export default function SearchDetailDialog({
|
export default function SearchDetailDialog({
|
||||||
search,
|
search,
|
||||||
setSearch,
|
setSearch,
|
||||||
|
setSimilarity,
|
||||||
}: SearchDetailDialogProps) {
|
}: SearchDetailDialogProps) {
|
||||||
const { data: config } = useSWR<FrigateConfig>("config", {
|
const { data: config } = useSWR<FrigateConfig>("config", {
|
||||||
revalidateOnFocus: false,
|
revalidateOnFocus: false,
|
||||||
@ -31,6 +33,7 @@ export default function SearchDetailDialog({
|
|||||||
|
|
||||||
const [desc, setDesc] = useState(search?.description);
|
const [desc, setDesc] = useState(search?.description);
|
||||||
|
|
||||||
|
// we have to make sure the current selected search item stays in sync
|
||||||
useEffect(() => setDesc(search?.description), [search]);
|
useEffect(() => setDesc(search?.description), [search]);
|
||||||
|
|
||||||
const formattedDate = useFormattedTimestamp(
|
const formattedDate = useFormattedTimestamp(
|
||||||
@ -129,7 +132,17 @@ export default function SearchDetailDialog({
|
|||||||
: `${apiHost}api/events/${search.id}/thumbnail.jpg`
|
: `${apiHost}api/events/${search.id}/thumbnail.jpg`
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Button>Find Similar</Button>
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
setSearch(undefined);
|
||||||
|
|
||||||
|
if (setSimilarity) {
|
||||||
|
setSimilarity();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Find Similar
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-1.5">
|
<div className="flex flex-col gap-1.5">
|
||||||
|
|||||||
@ -38,7 +38,13 @@ export default function Search() {
|
|||||||
|
|
||||||
// search api
|
// search api
|
||||||
|
|
||||||
|
const [similaritySearch, setSimilaritySearch] = useState<SearchResult>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (similaritySearch) {
|
||||||
|
setSimilaritySearch(undefined);
|
||||||
|
}
|
||||||
|
|
||||||
if (searchTimeout) {
|
if (searchTimeout) {
|
||||||
clearTimeout(searchTimeout);
|
clearTimeout(searchTimeout);
|
||||||
}
|
}
|
||||||
@ -53,9 +59,28 @@ export default function Search() {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [search]);
|
}, [search]);
|
||||||
|
|
||||||
const { data: searchResults, isLoading } = useSWR<SearchResult[]>(
|
const searchQuery = useMemo(() => {
|
||||||
searchTerm.length > 0
|
if (searchTerm.length == 0) {
|
||||||
? [
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (similaritySearch) {
|
||||||
|
return [
|
||||||
|
"events/search",
|
||||||
|
{
|
||||||
|
query: similaritySearch.id,
|
||||||
|
cameras: searchSearchParams["cameras"],
|
||||||
|
labels: searchSearchParams["labels"],
|
||||||
|
zones: searchSearchParams["zones"],
|
||||||
|
before: searchSearchParams["before"],
|
||||||
|
after: searchSearchParams["after"],
|
||||||
|
include_thumbnails: 0,
|
||||||
|
search_type: "thumbnail",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
"events/search",
|
"events/search",
|
||||||
{
|
{
|
||||||
query: searchTerm,
|
query: searchTerm,
|
||||||
@ -66,9 +91,11 @@ export default function Search() {
|
|||||||
after: searchSearchParams["after"],
|
after: searchSearchParams["after"],
|
||||||
include_thumbnails: 0,
|
include_thumbnails: 0,
|
||||||
},
|
},
|
||||||
]
|
];
|
||||||
: null,
|
}, [searchTerm, searchSearchParams, similaritySearch]);
|
||||||
);
|
|
||||||
|
const { data: searchResults, isLoading } =
|
||||||
|
useSWR<SearchResult[]>(searchQuery);
|
||||||
|
|
||||||
const previewTimeRange = useMemo<TimeRange>(() => {
|
const previewTimeRange = useMemo<TimeRange>(() => {
|
||||||
if (!searchResults) {
|
if (!searchResults) {
|
||||||
@ -164,6 +191,7 @@ export default function Search() {
|
|||||||
allPreviews={allPreviews}
|
allPreviews={allPreviews}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
setSearch={setSearch}
|
setSearch={setSearch}
|
||||||
|
setSimilaritySearch={setSimilaritySearch}
|
||||||
onUpdateFilter={onUpdateFilter}
|
onUpdateFilter={onUpdateFilter}
|
||||||
onOpenSearch={onOpenSearch}
|
onOpenSearch={onOpenSearch}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -18,6 +18,7 @@ type SearchViewProps = {
|
|||||||
allPreviews?: Preview[];
|
allPreviews?: Preview[];
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
setSearch: (search: string) => void;
|
setSearch: (search: string) => void;
|
||||||
|
setSimilaritySearch: (search: SearchResult) => void;
|
||||||
onUpdateFilter: (filter: SearchFilter) => void;
|
onUpdateFilter: (filter: SearchFilter) => void;
|
||||||
onOpenSearch: (item: SearchResult) => void;
|
onOpenSearch: (item: SearchResult) => void;
|
||||||
};
|
};
|
||||||
@ -29,6 +30,7 @@ export default function SearchView({
|
|||||||
allPreviews,
|
allPreviews,
|
||||||
isLoading,
|
isLoading,
|
||||||
setSearch,
|
setSearch,
|
||||||
|
setSimilaritySearch,
|
||||||
onUpdateFilter,
|
onUpdateFilter,
|
||||||
onOpenSearch,
|
onOpenSearch,
|
||||||
}: SearchViewProps) {
|
}: SearchViewProps) {
|
||||||
@ -52,7 +54,13 @@ export default function SearchView({
|
|||||||
return (
|
return (
|
||||||
<div className="flex size-full flex-col pt-2 md:py-2">
|
<div className="flex size-full flex-col pt-2 md:py-2">
|
||||||
<Toaster closeButton={true} />
|
<Toaster closeButton={true} />
|
||||||
<SearchDetailDialog search={searchDetail} setSearch={setSearchDetail} />
|
<SearchDetailDialog
|
||||||
|
search={searchDetail}
|
||||||
|
setSearch={setSearchDetail}
|
||||||
|
setSimilarity={
|
||||||
|
searchDetail && (() => setSimilaritySearch(searchDetail))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
<div className="relative mb-2 flex h-11 items-center justify-between pl-2 pr-2 md:pl-3">
|
<div className="relative mb-2 flex h-11 items-center justify-between pl-2 pr-2 md:pl-3">
|
||||||
<Input
|
<Input
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user