mirror of
https://github.com/blakeblackshear/frigate.git
synced 2025-12-08 14:25:41 +03:00
buttons should work with summary and grid view
This commit is contained in:
parent
8ed13c0b08
commit
a6d4ce02c5
@ -80,6 +80,15 @@ export default function SearchView({
|
|||||||
});
|
});
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const { data: exploreEvents } = useSWR<SearchResult[]>(
|
||||||
|
(!searchFilter || Object.keys(searchFilter).length === 0) &&
|
||||||
|
!searchTerm &&
|
||||||
|
defaultView === "summary"
|
||||||
|
? ["events/explore", { limit: isMobileOnly ? 5 : 10 }]
|
||||||
|
: null,
|
||||||
|
{ revalidateOnFocus: true },
|
||||||
|
);
|
||||||
|
|
||||||
// grid
|
// grid
|
||||||
|
|
||||||
const gridClassName = cn(
|
const gridClassName = cn(
|
||||||
@ -202,20 +211,24 @@ export default function SearchView({
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
// remove duplicate event ids
|
|
||||||
|
|
||||||
const uniqueResults = useMemo(() => {
|
|
||||||
return searchResults?.filter(
|
|
||||||
(value, index, self) =>
|
|
||||||
index === self.findIndex((v) => v.id === value.id),
|
|
||||||
);
|
|
||||||
}, [searchResults]);
|
|
||||||
|
|
||||||
// detail
|
// detail
|
||||||
|
|
||||||
const [searchDetail, setSearchDetail] = useState<SearchResult>();
|
const [searchDetail, setSearchDetail] = useState<SearchResult>();
|
||||||
const [page, setPage] = useState<SearchTab>("snapshot");
|
const [page, setPage] = useState<SearchTab>("snapshot");
|
||||||
|
|
||||||
|
// remove duplicate event ids
|
||||||
|
|
||||||
|
const uniqueResults = useMemo(() => {
|
||||||
|
if (!searchResults) return [];
|
||||||
|
|
||||||
|
const results = searchResults.filter(
|
||||||
|
(value, index, self) =>
|
||||||
|
index === self.findIndex((v) => v.id === value.id),
|
||||||
|
);
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}, [searchResults]);
|
||||||
|
|
||||||
// search interaction
|
// search interaction
|
||||||
|
|
||||||
const [selectedObjects, setSelectedObjects] = useState<string[]>([]);
|
const [selectedObjects, setSelectedObjects] = useState<string[]>([]);
|
||||||
@ -285,17 +298,23 @@ export default function SearchView({
|
|||||||
// update search detail when results change
|
// update search detail when results change
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (searchDetail && searchResults) {
|
if (searchDetail) {
|
||||||
const flattenedResults = searchResults.flat();
|
const results =
|
||||||
const updatedSearchDetail = flattenedResults.find(
|
defaultView === "summary" ? exploreEvents : searchResults?.flat();
|
||||||
(result) => result.id === searchDetail.id,
|
if (results) {
|
||||||
);
|
const updatedSearchDetail = results.find(
|
||||||
|
(result) => result.id === searchDetail.id,
|
||||||
|
);
|
||||||
|
|
||||||
if (updatedSearchDetail && !isEqual(updatedSearchDetail, searchDetail)) {
|
if (
|
||||||
setSearchDetail(updatedSearchDetail);
|
updatedSearchDetail &&
|
||||||
|
!isEqual(updatedSearchDetail, searchDetail)
|
||||||
|
) {
|
||||||
|
setSearchDetail(updatedSearchDetail);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [searchResults, searchDetail]);
|
}, [searchResults, exploreEvents, searchDetail, defaultView]);
|
||||||
|
|
||||||
const hasExistingSearch = useMemo(
|
const hasExistingSearch = useMemo(
|
||||||
() => searchResults != undefined || searchFilter != undefined,
|
() => searchResults != undefined || searchFilter != undefined,
|
||||||
@ -306,13 +325,49 @@ export default function SearchView({
|
|||||||
|
|
||||||
const [inputFocused, setInputFocused] = useState(false);
|
const [inputFocused, setInputFocused] = useState(false);
|
||||||
|
|
||||||
|
const goToPrevious = useCallback(() => {
|
||||||
|
const results =
|
||||||
|
exploreEvents && defaultView === "summary"
|
||||||
|
? exploreEvents.filter((event) => event.label === searchDetail?.label)
|
||||||
|
: uniqueResults;
|
||||||
|
if (results && results.length > 0) {
|
||||||
|
const currentIndex = searchDetail
|
||||||
|
? results.findIndex((result) => result.id === searchDetail.id)
|
||||||
|
: -1;
|
||||||
|
|
||||||
|
const newIndex =
|
||||||
|
currentIndex === -1
|
||||||
|
? results.length - 1
|
||||||
|
: (currentIndex - 1 + results.length) % results.length;
|
||||||
|
|
||||||
|
setSearchDetail(results[newIndex]);
|
||||||
|
}
|
||||||
|
}, [uniqueResults, exploreEvents, searchDetail, defaultView]);
|
||||||
|
|
||||||
|
const goToNext = useCallback(() => {
|
||||||
|
const results =
|
||||||
|
exploreEvents && defaultView === "summary"
|
||||||
|
? exploreEvents.filter((event) => event.label === searchDetail?.label)
|
||||||
|
: uniqueResults;
|
||||||
|
if (results && results.length > 0) {
|
||||||
|
const currentIndex = searchDetail
|
||||||
|
? results.findIndex((result) => result.id === searchDetail.id)
|
||||||
|
: -1;
|
||||||
|
|
||||||
|
const newIndex =
|
||||||
|
currentIndex === -1 ? 0 : (currentIndex + 1) % results.length;
|
||||||
|
|
||||||
|
setSearchDetail(results[newIndex]);
|
||||||
|
}
|
||||||
|
}, [uniqueResults, exploreEvents, searchDetail, defaultView]);
|
||||||
|
|
||||||
const onKeyboardShortcut = useCallback(
|
const onKeyboardShortcut = useCallback(
|
||||||
(key: string | null, modifiers: KeyModifiers) => {
|
(key: string | null, modifiers: KeyModifiers) => {
|
||||||
if (inputFocused) {
|
if (inputFocused) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!modifiers.down || !uniqueResults) {
|
if (!modifiers.down || (!uniqueResults && !exploreEvents)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,43 +382,23 @@ export default function SearchView({
|
|||||||
setSelectedObjects([]);
|
setSelectedObjects([]);
|
||||||
return true;
|
return true;
|
||||||
case "ArrowLeft":
|
case "ArrowLeft":
|
||||||
if (uniqueResults.length > 0) {
|
goToPrevious();
|
||||||
const currentIndex = searchDetail
|
|
||||||
? uniqueResults.findIndex(
|
|
||||||
(result) => result.id === searchDetail.id,
|
|
||||||
)
|
|
||||||
: -1;
|
|
||||||
|
|
||||||
const newIndex =
|
|
||||||
currentIndex === -1
|
|
||||||
? uniqueResults.length - 1
|
|
||||||
: (currentIndex - 1 + uniqueResults.length) %
|
|
||||||
uniqueResults.length;
|
|
||||||
|
|
||||||
setSearchDetail(uniqueResults[newIndex]);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
case "ArrowRight":
|
case "ArrowRight":
|
||||||
if (uniqueResults.length > 0) {
|
goToNext();
|
||||||
const currentIndex = searchDetail
|
|
||||||
? uniqueResults.findIndex(
|
|
||||||
(result) => result.id === searchDetail.id,
|
|
||||||
)
|
|
||||||
: -1;
|
|
||||||
|
|
||||||
const newIndex =
|
|
||||||
currentIndex === -1
|
|
||||||
? 0
|
|
||||||
: (currentIndex + 1) % uniqueResults.length;
|
|
||||||
|
|
||||||
setSearchDetail(uniqueResults[newIndex]);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
[uniqueResults, inputFocused, onSelectAllObjects, searchDetail],
|
[
|
||||||
|
uniqueResults,
|
||||||
|
exploreEvents,
|
||||||
|
inputFocused,
|
||||||
|
onSelectAllObjects,
|
||||||
|
goToPrevious,
|
||||||
|
goToNext,
|
||||||
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
useKeyboardListener(
|
useKeyboardListener(
|
||||||
@ -469,16 +504,22 @@ 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
|
<div className="relative">
|
||||||
search={searchDetail}
|
{searchDetail && (
|
||||||
page={page}
|
<SearchDetailDialog
|
||||||
setSearch={setSearchDetail}
|
search={searchDetail}
|
||||||
setSearchPage={setPage}
|
page={page}
|
||||||
setSimilarity={
|
setSearch={setSearchDetail}
|
||||||
searchDetail && (() => setSimilaritySearch(searchDetail))
|
setSearchPage={setPage}
|
||||||
}
|
setSimilarity={
|
||||||
setInputFocused={setInputFocused}
|
searchDetail && (() => setSimilaritySearch(searchDetail))
|
||||||
/>
|
}
|
||||||
|
setInputFocused={setInputFocused}
|
||||||
|
onPrevious={goToPrevious}
|
||||||
|
onNext={goToNext}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user