context menu for explore summary thumbnail images

This commit is contained in:
Josh Hawkins 2024-10-22 08:13:59 -05:00
parent 2a8a1a1b1b
commit 92efc4a3dc
2 changed files with 83 additions and 38 deletions

View File

@ -18,15 +18,22 @@ import ActivityIndicator from "@/components/indicators/activity-indicator";
import { useEventUpdate } from "@/api/ws"; import { useEventUpdate } from "@/api/ws";
import { isEqual } from "lodash"; import { isEqual } from "lodash";
import TimeAgo from "@/components/dynamic/TimeAgo"; import TimeAgo from "@/components/dynamic/TimeAgo";
import SearchResultActions from "@/components/menu/SearchResultActions";
import { SearchTab } from "@/components/overlay/detail/SearchDetailDialog";
import { FrigateConfig } from "@/types/frigateConfig";
type ExploreViewProps = { type ExploreViewProps = {
searchDetail: SearchResult | undefined; searchDetail: SearchResult | undefined;
setSearchDetail: (search: SearchResult | undefined) => void; setSearchDetail: (search: SearchResult | undefined) => void;
setSimilaritySearch: (search: SearchResult) => void;
onSelectSearch: (item: SearchResult, index: number, page?: SearchTab) => void;
}; };
export default function ExploreView({ export default function ExploreView({
searchDetail, searchDetail,
setSearchDetail, setSearchDetail,
setSimilaritySearch,
onSelectSearch,
}: ExploreViewProps) { }: ExploreViewProps) {
// title // title
@ -102,6 +109,9 @@ export default function ExploreView({
isValidating={isValidating} isValidating={isValidating}
objectType={label} objectType={label}
setSearchDetail={setSearchDetail} setSearchDetail={setSearchDetail}
mutate={mutate}
setSimilaritySearch={setSimilaritySearch}
onSelectSearch={onSelectSearch}
/> />
))} ))}
</div> </div>
@ -113,6 +123,9 @@ type ThumbnailRowType = {
searchResults?: SearchResult[]; searchResults?: SearchResult[];
isValidating: boolean; isValidating: boolean;
setSearchDetail: (search: SearchResult | undefined) => void; setSearchDetail: (search: SearchResult | undefined) => void;
mutate: () => void;
setSimilaritySearch: (search: SearchResult) => void;
onSelectSearch: (item: SearchResult, index: number, page?: SearchTab) => void;
}; };
function ThumbnailRow({ function ThumbnailRow({
@ -120,6 +133,9 @@ function ThumbnailRow({
searchResults, searchResults,
isValidating, isValidating,
setSearchDetail, setSearchDetail,
mutate,
setSimilaritySearch,
onSelectSearch,
}: ThumbnailRowType) { }: ThumbnailRowType) {
const navigate = useNavigate(); const navigate = useNavigate();
@ -155,6 +171,9 @@ function ThumbnailRow({
<ExploreThumbnailImage <ExploreThumbnailImage
event={event} event={event}
setSearchDetail={setSearchDetail} setSearchDetail={setSearchDetail}
mutate={mutate}
setSimilaritySearch={setSimilaritySearch}
onSelectSearch={onSelectSearch}
/> />
</div> </div>
))} ))}
@ -184,25 +203,49 @@ function ThumbnailRow({
type ExploreThumbnailImageProps = { type ExploreThumbnailImageProps = {
event: SearchResult; event: SearchResult;
setSearchDetail: (search: SearchResult | undefined) => void; setSearchDetail: (search: SearchResult | undefined) => void;
mutate: () => void;
setSimilaritySearch: (search: SearchResult) => void;
onSelectSearch: (item: SearchResult, index: number, page?: SearchTab) => void;
}; };
function ExploreThumbnailImage({ function ExploreThumbnailImage({
event, event,
setSearchDetail, setSearchDetail,
mutate,
setSimilaritySearch,
onSelectSearch,
}: ExploreThumbnailImageProps) { }: ExploreThumbnailImageProps) {
const apiHost = useApiHost(); const apiHost = useApiHost();
const { data: config } = useSWR<FrigateConfig>("config");
const [imgRef, imgLoaded, onImgLoad] = useImageLoaded(); const [imgRef, imgLoaded, onImgLoad] = useImageLoaded();
const handleFindSimilar = () => {
if (config?.semantic_search.enabled) {
setSimilaritySearch(event);
}
};
const handleShowObjectLifecycle = () => {
onSelectSearch(event, 0, "object lifecycle");
};
return ( return (
<> <SearchResultActions
searchResult={event}
findSimilar={handleFindSimilar}
refreshResults={mutate}
showObjectLifecycle={handleShowObjectLifecycle}
isContextMenu={true}
>
<div className="relative size-full">
<ImageLoadingIndicator <ImageLoadingIndicator
className="absolute inset-0" className="absolute inset-0"
imgLoaded={imgLoaded} imgLoaded={imgLoaded}
/> />
<img <img
ref={imgRef} ref={imgRef}
className={cn( className={cn(
"absolute h-full w-full cursor-pointer rounded-lg object-cover transition-all duration-300 ease-in-out lg:rounded-2xl", "absolute size-full cursor-pointer rounded-lg object-cover transition-all duration-300 ease-in-out lg:rounded-2xl",
!imgLoaded && "invisible",
)} )}
style={ style={
isIOS isIOS
@ -216,9 +259,8 @@ function ExploreThumbnailImage({
draggable={false} draggable={false}
src={`${apiHost}api/events/${event.id}/thumbnail.jpg`} src={`${apiHost}api/events/${event.id}/thumbnail.jpg`}
onClick={() => setSearchDetail(event)} onClick={() => setSearchDetail(event)}
onLoad={() => { onLoad={onImgLoad}
onImgLoad(); alt={`${event.label} thumbnail`}
}}
/> />
{isDesktop && ( {isDesktop && (
<div className="absolute bottom-1 right-1 z-10 rounded-lg bg-black/50 px-2 py-1 text-xs text-white"> <div className="absolute bottom-1 right-1 z-10 rounded-lg bg-black/50 px-2 py-1 text-xs text-white">
@ -231,7 +273,8 @@ function ExploreThumbnailImage({
)} )}
</div> </div>
)} )}
</> </div>
</SearchResultActions>
); );
} }

View File

@ -489,6 +489,8 @@ export default function SearchView({
<ExploreView <ExploreView
searchDetail={searchDetail} searchDetail={searchDetail}
setSearchDetail={setSearchDetail} setSearchDetail={setSearchDetail}
setSimilaritySearch={setSimilaritySearch}
onSelectSearch={onSelectSearch}
/> />
</div> </div>
)} )}