Skip to content

Commit

Permalink
Merge branch 'blakeblackshear:dev' into testing
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanjx authored Oct 7, 2024
2 parents 5d3a40b + dcaed0e commit 5007332
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 8 deletions.
2 changes: 1 addition & 1 deletion frigate/detectors/plugins/tensorrt.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ def __init__(self, detector_config: TensorRTDetectorConfig):
raise RuntimeError("fail to allocate CUDA resources") from e

logger.debug("TensorRT loaded. Input shape is %s", self.input_shape)
logger.debug("TensorRT version is %s", trt.__version__[0])
logger.debug("TensorRT version is %s", TRT_VERSION)

def __del__(self):
"""Free CUDA memories."""
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/overlay/detail/ReviewDetailDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ function EventItem({
<>
<div
className={cn(
"relative",
"relative mr-auto",
!event.has_snapshot && "flex flex-row items-center justify-center",
)}
onMouseEnter={isDesktop ? () => setHovered(true) : undefined}
Expand Down
146 changes: 140 additions & 6 deletions web/src/components/overlay/detail/SearchDetailDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isDesktop, isIOS, isMobile } from "react-device-detect";
import { isDesktop, isIOS, isMobile, isSafari } from "react-device-detect";
import { SearchResult } from "@/types/search";
import useSWR from "swr";
import { FrigateConfig } from "@/types/frigateConfig";
Expand All @@ -20,14 +20,14 @@ import {
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { FrigatePlusDialog } from "../dialog/FrigatePlusDialog";
import { Event } from "@/types/event";
import HlsVideoPlayer from "@/components/player/HlsVideoPlayer";
import { baseUrl } from "@/api/baseUrl";
import { cn } from "@/lib/utils";
import ActivityIndicator from "@/components/indicators/activity-indicator";
import { ASPECT_VERTICAL_LAYOUT, ASPECT_WIDE_LAYOUT } from "@/types/record";
import {
FaCheckCircle,
FaChevronDown,
FaHistory,
FaImage,
Expand Down Expand Up @@ -59,6 +59,10 @@ import {
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch";
import { Card, CardContent } from "@/components/ui/card";
import useImageLoaded from "@/hooks/use-image-loaded";
import ImageLoadingIndicator from "@/components/indicators/ImageLoadingIndicator";

const SEARCH_TABS = [
"details",
Expand Down Expand Up @@ -209,15 +213,13 @@ export default function SearchDetailDialog({
/>
)}
{page == "snapshot" && (
<FrigatePlusDialog
upload={
<ObjectSnapshotTab
search={
{
...search,
plus_id: config?.plus?.enabled ? search.plus_id : "not_enabled",
} as unknown as Event
}
dialog={false}
onClose={() => {}}
onEventUploaded={() => {
search.plus_id = "new_upload";
}}
Expand Down Expand Up @@ -459,6 +461,138 @@ function ObjectDetailsTab({
);
}

type ObjectSnapshotTabProps = {
search: Event;
onEventUploaded: () => void;
};
function ObjectSnapshotTab({
search,
onEventUploaded,
}: ObjectSnapshotTabProps) {
type SubmissionState = "reviewing" | "uploading" | "submitted";

const [imgRef, imgLoaded, onImgLoad] = useImageLoaded();

// upload

const [state, setState] = useState<SubmissionState>(
search?.plus_id ? "submitted" : "reviewing",
);

useEffect(
() => setState(search?.plus_id ? "submitted" : "reviewing"),
[search],
);

const onSubmitToPlus = useCallback(
async (falsePositive: boolean) => {
if (!search) {
return;
}

falsePositive
? axios.put(`events/${search.id}/false_positive`)
: axios.post(`events/${search.id}/plus`, {
include_annotation: 1,
});

setState("submitted");
onEventUploaded();
},
[search, onEventUploaded],
);

return (
<div className="relative size-full">
<ImageLoadingIndicator
className="absolute inset-0 aspect-video min-h-[60dvh] w-full"
imgLoaded={imgLoaded}
/>
<div className={`${imgLoaded ? "visible" : "invisible"}`}>
<TransformWrapper minScale={1.0} wheel={{ smoothStep: 0.005 }}>
<div className="flex flex-col space-y-3">
<TransformComponent
wrapperStyle={{
width: "100%",
height: "100%",
}}
contentStyle={{
position: "relative",
width: "100%",
height: "100%",
}}
>
{search?.id && (
<img
ref={imgRef}
className={`mx-auto max-h-[60dvh] bg-black object-contain`}
src={`${baseUrl}api/events/${search?.id}/snapshot.jpg`}
alt={`${search?.label}`}
loading={isSafari ? "eager" : "lazy"}
onLoad={() => {
onImgLoad();
}}
/>
)}
</TransformComponent>
<Card className="p-1 text-sm md:p-2">
<CardContent className="flex flex-col items-center justify-between gap-3 p-2 md:flex-row">
<div className={cn("flex flex-col space-y-3")}>
<div
className={
"text-lg font-semibold leading-none tracking-tight"
}
>
Submit To Frigate+
</div>
<div className="text-sm text-muted-foreground">
Objects in locations you want to avoid are not false
positives. Submitting them as false positives will confuse
the model.
</div>
</div>

<div className="flex flex-row justify-center gap-2 md:justify-end">
{state == "reviewing" && (
<>
<Button
className="bg-success"
onClick={() => {
setState("uploading");
onSubmitToPlus(false);
}}
>
This is a {search?.label}
</Button>
<Button
className="text-white"
variant="destructive"
onClick={() => {
setState("uploading");
onSubmitToPlus(true);
}}
>
This is not a {search?.label}
</Button>
</>
)}
{state == "uploading" && <ActivityIndicator />}
{state == "submitted" && (
<div className="flex flex-row items-center justify-center gap-2">
<FaCheckCircle className="text-success" />
Submitted
</div>
)}
</div>
</CardContent>
</Card>
</div>
</TransformWrapper>
</div>
</div>
);
}

type VideoTabProps = {
search: SearchResult;
config?: FrigateConfig;
Expand Down

0 comments on commit 5007332

Please sign in to comment.