Merge branch 'fix-selected-outline' of https://github.com/blakeblackshear/frigate into fix-selected-outline

This commit is contained in:
Josh Hawkins 2024-10-15 07:49:50 -05:00
commit d7d2b75ff2
3 changed files with 32 additions and 11 deletions

View File

@ -31,12 +31,14 @@ type SearchThumbnailProps = {
searchResult: SearchResult; searchResult: SearchResult;
findSimilar: () => void; findSimilar: () => void;
refreshResults: () => void; refreshResults: () => void;
showObjectLifecycle: () => void;
}; };
export default function SearchThumbnailFooter({ export default function SearchThumbnailFooter({
searchResult, searchResult,
findSimilar, findSimilar,
refreshResults, refreshResults,
showObjectLifecycle,
}: SearchThumbnailProps) { }: SearchThumbnailProps) {
const { data: config } = useSWR<FrigateConfig>("config"); const { data: config } = useSWR<FrigateConfig>("config");
@ -146,7 +148,7 @@ export default function SearchThumbnailFooter({
</a> </a>
</DropdownMenuItem> </DropdownMenuItem>
)} )}
<DropdownMenuItem> <DropdownMenuItem onClick={showObjectLifecycle}>
<FaArrowsRotate className="mr-2 size-4" /> <FaArrowsRotate className="mr-2 size-4" />
<span>View object lifecycle</span> <span>View object lifecycle</span>
</DropdownMenuItem> </DropdownMenuItem>

View File

@ -69,16 +69,20 @@ const SEARCH_TABS = [
"video", "video",
"object lifecycle", "object lifecycle",
] as const; ] as const;
type SearchTab = (typeof SEARCH_TABS)[number]; export type SearchTab = (typeof SEARCH_TABS)[number];
type SearchDetailDialogProps = { type SearchDetailDialogProps = {
search?: SearchResult; search?: SearchResult;
page: SearchTab;
setSearch: (search: SearchResult | undefined) => void; setSearch: (search: SearchResult | undefined) => void;
setSearchPage: (page: SearchTab) => void;
setSimilarity?: () => void; setSimilarity?: () => void;
}; };
export default function SearchDetailDialog({ export default function SearchDetailDialog({
search, search,
page,
setSearch, setSearch,
setSearchPage,
setSimilarity, setSimilarity,
}: SearchDetailDialogProps) { }: SearchDetailDialogProps) {
const { data: config } = useSWR<FrigateConfig>("config", { const { data: config } = useSWR<FrigateConfig>("config", {
@ -87,8 +91,11 @@ export default function SearchDetailDialog({
// tabs // tabs
const [page, setPage] = useState<SearchTab>("details"); const [pageToggle, setPageToggle] = useOptimisticState(
const [pageToggle, setPageToggle] = useOptimisticState(page, setPage, 100); page,
setSearchPage,
100,
);
// dialog and mobile page // dialog and mobile page
@ -130,9 +137,9 @@ export default function SearchDetailDialog({
} }
if (!searchTabs.includes(pageToggle)) { if (!searchTabs.includes(pageToggle)) {
setPage("details"); setSearchPage("details");
} }
}, [pageToggle, searchTabs]); }, [pageToggle, searchTabs, setSearchPage]);
if (!search) { if (!search) {
return; return;

View File

@ -1,7 +1,9 @@
import SearchThumbnail from "@/components/card/SearchThumbnail"; import SearchThumbnail from "@/components/card/SearchThumbnail";
import SearchFilterGroup from "@/components/filter/SearchFilterGroup"; import SearchFilterGroup from "@/components/filter/SearchFilterGroup";
import ActivityIndicator from "@/components/indicators/activity-indicator"; import ActivityIndicator from "@/components/indicators/activity-indicator";
import SearchDetailDialog from "@/components/overlay/detail/SearchDetailDialog"; import SearchDetailDialog, {
SearchTab,
} from "@/components/overlay/detail/SearchDetailDialog";
import { Toaster } from "@/components/ui/sonner"; import { Toaster } from "@/components/ui/sonner";
import { import {
Tooltip, Tooltip,
@ -160,16 +162,21 @@ export default function SearchView({
// detail // detail
const [searchDetail, setSearchDetail] = useState<SearchResult>(); const [searchDetail, setSearchDetail] = useState<SearchResult>();
const [page, setPage] = useState<SearchTab>("details");
// search interaction // search interaction
const [selectedIndex, setSelectedIndex] = useState<number | null>(null); const [selectedIndex, setSelectedIndex] = useState<number | null>(null);
const itemRefs = useRef<(HTMLDivElement | null)[]>([]); const itemRefs = useRef<(HTMLDivElement | null)[]>([]);
const onSelectSearch = useCallback((item: SearchResult, index: number) => { const onSelectSearch = useCallback(
setSearchDetail(item); (item: SearchResult, index: number, page: SearchTab = "details") => {
setSelectedIndex(index); setPage(page);
}, []); setSearchDetail(item);
setSelectedIndex(index);
},
[],
);
useEffect(() => { useEffect(() => {
setSelectedIndex(0); setSelectedIndex(0);
@ -298,7 +305,9 @@ export default function SearchView({
<Toaster closeButton={true} /> <Toaster closeButton={true} />
<SearchDetailDialog <SearchDetailDialog
search={searchDetail} search={searchDetail}
page={page}
setSearch={setSearchDetail} setSearch={setSearchDetail}
setSearchPage={setPage}
setSimilarity={ setSimilarity={
searchDetail && (() => setSimilaritySearch(searchDetail)) searchDetail && (() => setSimilaritySearch(searchDetail))
} }
@ -396,6 +405,9 @@ export default function SearchView({
} }
}} }}
refreshResults={refresh} refreshResults={refresh}
showObjectLifecycle={() =>
onSelectSearch(value, index, "object lifecycle")
}
/> />
</div> </div>
</div> </div>