mirror of
https://github.com/blakeblackshear/frigate.git
synced 2025-12-12 16:16:42 +03:00
Compare commits
2 Commits
c61bb8f8ae
...
24a1874225
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
24a1874225 | ||
|
|
f4e7549311 |
@ -50,6 +50,27 @@ export function AnimatedEventCard({
|
||||
fetchPreviews: !currentHour,
|
||||
});
|
||||
|
||||
const tooltipText = useMemo(() => {
|
||||
if (event?.data?.metadata?.title) {
|
||||
return event.data.metadata.title;
|
||||
}
|
||||
|
||||
return (
|
||||
`${[
|
||||
...new Set([
|
||||
...(event.data.objects || []),
|
||||
...(event.data.sub_labels || []),
|
||||
...(event.data.audio || []),
|
||||
]),
|
||||
]
|
||||
.filter((item) => item !== undefined && !item.includes("-verified"))
|
||||
.map((text) => text.charAt(0).toUpperCase() + text.substring(1))
|
||||
.sort()
|
||||
.join(", ")
|
||||
.replaceAll("-verified", "")} ` + t("detected")
|
||||
);
|
||||
}, [event, t]);
|
||||
|
||||
// visibility
|
||||
|
||||
const [windowVisible, setWindowVisible] = useState(true);
|
||||
@ -220,20 +241,7 @@ export function AnimatedEventCard({
|
||||
)}
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
{`${[
|
||||
...new Set([
|
||||
...(event.data.objects || []),
|
||||
...(event.data.sub_labels || []),
|
||||
...(event.data.audio || []),
|
||||
]),
|
||||
]
|
||||
.filter((item) => item !== undefined && !item.includes("-verified"))
|
||||
.map((text) => text.charAt(0).toUpperCase() + text.substring(1))
|
||||
.sort()
|
||||
.join(", ")
|
||||
.replaceAll("-verified", "")} ` + t("detected")}
|
||||
</TooltipContent>
|
||||
<TooltipContent>{tooltipText}</TooltipContent>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
@ -355,9 +355,7 @@ export default function LiveContextMenu({
|
||||
<div
|
||||
className="flex w-full cursor-pointer items-center justify-start gap-2"
|
||||
onClick={
|
||||
isEnabled
|
||||
? () => navigate(`/settings?page=debug&camera=${camera}`)
|
||||
: undefined
|
||||
isEnabled ? () => navigate(`?debug=true#${camera}`) : undefined
|
||||
}
|
||||
>
|
||||
<div className="text-primary">
|
||||
|
||||
@ -222,7 +222,7 @@ export function MobilePageHeader({
|
||||
type MobilePageTitleProps = React.HTMLAttributes<HTMLHeadingElement>;
|
||||
|
||||
export function MobilePageTitle({ className, ...props }: MobilePageTitleProps) {
|
||||
return <h2 className={cn("text-lg font-semibold", className)} {...props} />;
|
||||
return <h2 className={cn("text-lg", className)} {...props} />;
|
||||
}
|
||||
|
||||
type MobilePageDescriptionProps = React.HTMLAttributes<HTMLParagraphElement>;
|
||||
|
||||
@ -42,7 +42,7 @@ export default function RoleChangeDialog({
|
||||
<Dialog open={show} onOpenChange={onCancel}>
|
||||
<DialogContent className="sm:max-w-[425px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-xl font-semibold">
|
||||
<DialogTitle className="text-xl">
|
||||
{t("users.dialog.changeRole.title")}
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
|
||||
@ -1170,11 +1170,7 @@ export function ObjectSnapshotTab({
|
||||
<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"
|
||||
}
|
||||
>
|
||||
<div className={"text-lg leading-none"}>
|
||||
{t("explore.plus.submitToPlus.label")}
|
||||
</div>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import * as React from "react"
|
||||
import { cva, type VariantProps } from "class-variance-authority"
|
||||
import * as React from "react";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const alertVariants = cva(
|
||||
"relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
|
||||
@ -16,8 +16,8 @@ const alertVariants = cva(
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
},
|
||||
}
|
||||
)
|
||||
},
|
||||
);
|
||||
|
||||
const Alert = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
@ -29,8 +29,8 @@ const Alert = React.forwardRef<
|
||||
className={cn(alertVariants({ variant }), className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
Alert.displayName = "Alert"
|
||||
));
|
||||
Alert.displayName = "Alert";
|
||||
|
||||
const AlertTitle = React.forwardRef<
|
||||
HTMLParagraphElement,
|
||||
@ -38,11 +38,11 @@ const AlertTitle = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<h5
|
||||
ref={ref}
|
||||
className={cn("mb-1 font-medium leading-none tracking-tight", className)}
|
||||
className={cn("mb-1 font-medium leading-none", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
AlertTitle.displayName = "AlertTitle"
|
||||
));
|
||||
AlertTitle.displayName = "AlertTitle";
|
||||
|
||||
const AlertDescription = React.forwardRef<
|
||||
HTMLParagraphElement,
|
||||
@ -53,7 +53,7 @@ const AlertDescription = React.forwardRef<
|
||||
className={cn("text-sm [&_p]:leading-relaxed", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
AlertDescription.displayName = "AlertDescription"
|
||||
));
|
||||
AlertDescription.displayName = "AlertDescription";
|
||||
|
||||
export { Alert, AlertTitle, AlertDescription }
|
||||
export { Alert, AlertTitle, AlertDescription };
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import * as React from "react"
|
||||
import * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const Card = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
@ -10,12 +10,12 @@ const Card = React.forwardRef<
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"rounded-lg border bg-card text-card-foreground shadow-sm",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
Card.displayName = "Card"
|
||||
));
|
||||
Card.displayName = "Card";
|
||||
|
||||
const CardHeader = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
@ -26,8 +26,8 @@ const CardHeader = React.forwardRef<
|
||||
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
CardHeader.displayName = "CardHeader"
|
||||
));
|
||||
CardHeader.displayName = "CardHeader";
|
||||
|
||||
const CardTitle = React.forwardRef<
|
||||
HTMLParagraphElement,
|
||||
@ -35,14 +35,11 @@ const CardTitle = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<h3
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"text-2xl font-semibold leading-none tracking-tight",
|
||||
className
|
||||
)}
|
||||
className={cn("text-2xl font-semibold leading-none", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
CardTitle.displayName = "CardTitle"
|
||||
));
|
||||
CardTitle.displayName = "CardTitle";
|
||||
|
||||
const CardDescription = React.forwardRef<
|
||||
HTMLParagraphElement,
|
||||
@ -53,16 +50,16 @@ const CardDescription = React.forwardRef<
|
||||
className={cn("text-sm text-muted-foreground", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
CardDescription.displayName = "CardDescription"
|
||||
));
|
||||
CardDescription.displayName = "CardDescription";
|
||||
|
||||
const CardContent = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
||||
))
|
||||
CardContent.displayName = "CardContent"
|
||||
));
|
||||
CardContent.displayName = "CardContent";
|
||||
|
||||
const CardFooter = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
@ -73,7 +70,14 @@ const CardFooter = React.forwardRef<
|
||||
className={cn("flex items-center p-6 pt-0", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
CardFooter.displayName = "CardFooter"
|
||||
));
|
||||
CardFooter.displayName = "CardFooter";
|
||||
|
||||
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
|
||||
export {
|
||||
Card,
|
||||
CardHeader,
|
||||
CardFooter,
|
||||
CardTitle,
|
||||
CardDescription,
|
||||
CardContent,
|
||||
};
|
||||
|
||||
@ -149,10 +149,7 @@ const DialogTitle = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Title
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"text-lg font-semibold leading-none tracking-tight",
|
||||
className,
|
||||
)}
|
||||
className={cn("text-lg font-semibold leading-none", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
@ -85,10 +85,7 @@ const DrawerTitle = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DrawerPrimitive.Title
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"text-lg font-semibold leading-none tracking-tight",
|
||||
className,
|
||||
)}
|
||||
className={cn("text-lg font-semibold leading-none", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
@ -14,12 +14,7 @@ const Heading = ({
|
||||
switch (as) {
|
||||
case "h1":
|
||||
return (
|
||||
<h1
|
||||
className={cn(
|
||||
"scroll-m-20 text-3xl font-extrabold tracking-tight",
|
||||
className
|
||||
)}
|
||||
>
|
||||
<h1 className={cn("scroll-m-20 text-3xl font-extrabold", className)}>
|
||||
{children}
|
||||
</h1>
|
||||
);
|
||||
@ -27,8 +22,8 @@ const Heading = ({
|
||||
return (
|
||||
<h2
|
||||
className={cn(
|
||||
"scroll-m-20 text-3xl font-semibold tracking-tight transition-colors first:mt-0 mb-3",
|
||||
className
|
||||
"mb-3 scroll-m-20 text-3xl font-semibold transition-colors first:mt-0",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
@ -36,34 +31,19 @@ const Heading = ({
|
||||
);
|
||||
case "h3":
|
||||
return (
|
||||
<h3
|
||||
className={cn(
|
||||
"scroll-m-20 text-2xl font-semibold tracking-tight mb-3",
|
||||
className
|
||||
)}
|
||||
>
|
||||
<h3 className={cn("mb-3 scroll-m-20 text-2xl font-medium", className)}>
|
||||
{children}
|
||||
</h3>
|
||||
);
|
||||
case "h4":
|
||||
return (
|
||||
<h4
|
||||
className={cn(
|
||||
"scroll-m-20 text-xl font-semibold tracking-tight",
|
||||
className
|
||||
)}
|
||||
>
|
||||
<h4 className={cn("scroll-m-20 text-xl font-medium", className)}>
|
||||
{children}
|
||||
</h4>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<h1
|
||||
className={cn(
|
||||
"scroll-m-20 text-3xl font-extrabold tracking-tight",
|
||||
className
|
||||
)}
|
||||
>
|
||||
<h1 className={cn("scroll-m-20 text-3xl font-extrabold", className)}>
|
||||
{children}
|
||||
</h1>
|
||||
);
|
||||
|
||||
@ -112,7 +112,8 @@ export function useSearchEffect(
|
||||
callback: (value: string) => boolean,
|
||||
) {
|
||||
const location = useLocation();
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const navigate = useNavigate();
|
||||
const [searchParams] = useSearchParams();
|
||||
|
||||
const param = useMemo(() => {
|
||||
const param = searchParams.get(key);
|
||||
@ -132,7 +133,17 @@ export function useSearchEffect(
|
||||
const remove = callback(param[1]);
|
||||
|
||||
if (remove) {
|
||||
setSearchParams(undefined, { state: location.state, replace: true });
|
||||
navigate(location.pathname + location.hash, {
|
||||
state: location.state,
|
||||
replace: true,
|
||||
});
|
||||
}
|
||||
}, [param, location.state, callback, setSearchParams]);
|
||||
}, [
|
||||
param,
|
||||
location.state,
|
||||
location.pathname,
|
||||
location.hash,
|
||||
callback,
|
||||
navigate,
|
||||
]);
|
||||
}
|
||||
|
||||
@ -292,7 +292,7 @@ export default function Settings() {
|
||||
<Logo className="h-8" />
|
||||
</div>
|
||||
<div className="flex flex-row text-center">
|
||||
<h2 className="ml-2 text-lg font-semibold">
|
||||
<h2 className="ml-2 text-lg">
|
||||
{t("menu.settings", { ns: "common" })}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
@ -30,7 +30,7 @@ type FrigateObjectState = {
|
||||
};
|
||||
|
||||
export interface FrigateReview {
|
||||
type: "new" | "update" | "end";
|
||||
type: "new" | "update" | "end" | "genai";
|
||||
before: ReviewSegment;
|
||||
after: ReviewSegment;
|
||||
}
|
||||
|
||||
@ -111,6 +111,7 @@ import { Trans, useTranslation } from "react-i18next";
|
||||
import { useDocDomain } from "@/hooks/use-doc-domain";
|
||||
import PtzControlPanel from "@/components/overlay/PtzControlPanel";
|
||||
import ObjectSettingsView from "../settings/ObjectSettingsView";
|
||||
import { useSearchEffect } from "@/hooks/use-overlay-state";
|
||||
|
||||
type LiveCameraViewProps = {
|
||||
config?: FrigateConfig;
|
||||
@ -274,6 +275,14 @@ export default function LiveCameraView({
|
||||
const [showStats, setShowStats] = useState(false);
|
||||
const [debug, setDebug] = useState(false);
|
||||
|
||||
useSearchEffect("debug", (value: string) => {
|
||||
if (value === "true") {
|
||||
setDebug(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
const [fullResolution, setFullResolution] = useState<VideoResolutionType>({
|
||||
width: 0,
|
||||
height: 0,
|
||||
|
||||
@ -114,7 +114,11 @@ export default function LiveDashboardView({
|
||||
|
||||
// if event is ended and was saved, update events list
|
||||
if (eventUpdate.after.severity == "alert") {
|
||||
if (eventUpdate.type == "end" || eventUpdate.type == "new") {
|
||||
if (
|
||||
eventUpdate.type == "end" ||
|
||||
eventUpdate.type == "new" ||
|
||||
eventUpdate.type == "genai"
|
||||
) {
|
||||
setTimeout(
|
||||
() => updateEvents(),
|
||||
eventUpdate.type == "end" ? 1000 : 6000,
|
||||
|
||||
@ -162,9 +162,9 @@ export default function ObjectSettingsView({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex size-full flex-col md:flex-row">
|
||||
<div className="mt-1 flex size-full flex-col md:flex-row">
|
||||
<Toaster position="top-center" closeButton={true} />
|
||||
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:w-3/12">
|
||||
<div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mb-0 md:mr-2 md:mt-0 md:w-3/12">
|
||||
<Heading as="h4" className="mb-2">
|
||||
{t("debug.title")}
|
||||
</Heading>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user