diff --git a/web/src/components/icons/FrigatePlusIcon.tsx b/web/src/components/icons/FrigatePlusIcon.tsx
index 24ee06eb5..15e196cd1 100644
--- a/web/src/components/icons/FrigatePlusIcon.tsx
+++ b/web/src/components/icons/FrigatePlusIcon.tsx
@@ -1,3 +1,4 @@
+import { forwardRef } from "react";
import { LuPlus } from "react-icons/lu";
import Logo from "../Logo";
import { cn } from "@/lib/utils";
@@ -6,17 +7,20 @@ type FrigatePlusIconProps = {
className?: string;
onClick?: () => void;
};
-export default function FrigatePlusIcon({
- className,
- onClick,
-}: FrigatePlusIconProps) {
- return (
-
-
-
-
- );
-}
+
+const FrigatePlusIcon = forwardRef(
+ ({ className, onClick }, ref) => {
+ return (
+
+
+
+
+ );
+ },
+);
+
+export default FrigatePlusIcon;
diff --git a/web/src/components/player/HlsVideoPlayer.tsx b/web/src/components/player/HlsVideoPlayer.tsx
index 2086402cd..5562303b2 100644
--- a/web/src/components/player/HlsVideoPlayer.tsx
+++ b/web/src/components/player/HlsVideoPlayer.tsx
@@ -40,6 +40,7 @@ type HlsVideoPlayerProps = {
setFullResolution?: React.Dispatch>;
onUploadFrame?: (playTime: number) => Promise | undefined;
toggleFullscreen?: () => void;
+ containerRef?: React.MutableRefObject;
};
export default function HlsVideoPlayer({
videoRef,
@@ -54,6 +55,7 @@ export default function HlsVideoPlayer({
setFullResolution,
onUploadFrame,
toggleFullscreen,
+ containerRef,
}: HlsVideoPlayerProps) {
const { data: config } = useSWR("config");
@@ -225,6 +227,7 @@ export default function HlsVideoPlayer({
}}
fullscreen={fullscreen}
toggleFullscreen={toggleFullscreen}
+ containerRef={containerRef}
/>
void;
onUploadFrame?: () => void;
toggleFullscreen?: () => void;
+ containerRef?: React.MutableRefObject;
};
export default function VideoControls({
className,
@@ -91,10 +92,11 @@ export default function VideoControls({
onSetPlaybackRate,
onUploadFrame,
toggleFullscreen,
+ containerRef,
}: VideoControlsProps) {
// layout
- const containerRef = useRef(null);
+ const controlsContainerRef = useRef(null);
// controls
@@ -197,7 +199,7 @@ export default function VideoControls({
MIN_ITEMS_WRAP &&
"min-w-[75%] flex-wrap",
)}
- ref={containerRef}
+ ref={controlsContainerRef}
>
{video && features.volume && (
@@ -247,7 +249,7 @@ export default function VideoControls({
>
{`${playbackRate}x`}
onSetPlaybackRate(parseFloat(rate))}
@@ -281,6 +283,7 @@ export default function VideoControls({
}
}}
onUploadFrame={onUploadFrame}
+ containerRef={containerRef}
/>
)}
{features.fullscreen && toggleFullscreen && (
@@ -297,12 +300,14 @@ type FrigatePlusUploadButtonProps = {
onOpen: () => void;
onClose: () => void;
onUploadFrame: () => void;
+ containerRef?: React.MutableRefObject;
};
function FrigatePlusUploadButton({
video,
onOpen,
onClose,
onUploadFrame,
+ containerRef,
}: FrigatePlusUploadButtonProps) {
const [videoImg, setVideoImg] = useState();
@@ -336,7 +341,10 @@ function FrigatePlusUploadButton({
}}
/>
-
+
Submit this frame to Frigate+?
diff --git a/web/src/components/player/dynamic/DynamicVideoPlayer.tsx b/web/src/components/player/dynamic/DynamicVideoPlayer.tsx
index 62f8a75d7..2f347404f 100644
--- a/web/src/components/player/dynamic/DynamicVideoPlayer.tsx
+++ b/web/src/components/player/dynamic/DynamicVideoPlayer.tsx
@@ -30,6 +30,7 @@ type DynamicVideoPlayerProps = {
onClipEnded?: () => void;
setFullResolution: React.Dispatch>;
toggleFullscreen: () => void;
+ containerRef?: React.MutableRefObject;
};
export default function DynamicVideoPlayer({
className,
@@ -45,6 +46,7 @@ export default function DynamicVideoPlayer({
onClipEnded,
setFullResolution,
toggleFullscreen,
+ containerRef,
}: DynamicVideoPlayerProps) {
const apiHost = useApiHost();
const { data: config } = useSWR("config");
@@ -208,6 +210,7 @@ export default function DynamicVideoPlayer({
setFullResolution={setFullResolution}
onUploadFrame={onUploadFrameToPlus}
toggleFullscreen={toggleFullscreen}
+ containerRef={containerRef}
/>
,
@@ -17,31 +17,33 @@ const AlertDialogOverlay = React.forwardRef<
-))
-AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName
+));
+AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
const AlertDialogContent = React.forwardRef<
React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
+ React.ComponentPropsWithoutRef & {
+ portalProps?: AlertDialogPrimitive.AlertDialogPortalProps;
+ }
+>(({ className, portalProps, ...props }, ref) => (
+
-))
-AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName
+));
+AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
const AlertDialogHeader = ({
className,
@@ -50,12 +52,12 @@ const AlertDialogHeader = ({
-)
-AlertDialogHeader.displayName = "AlertDialogHeader"
+);
+AlertDialogHeader.displayName = "AlertDialogHeader";
const AlertDialogFooter = ({
className,
@@ -64,12 +66,12 @@ const AlertDialogFooter = ({
-)
-AlertDialogFooter.displayName = "AlertDialogFooter"
+);
+AlertDialogFooter.displayName = "AlertDialogFooter";
const AlertDialogTitle = React.forwardRef<
React.ElementRef,
@@ -80,8 +82,8 @@ const AlertDialogTitle = React.forwardRef<
className={cn("text-lg font-semibold", className)}
{...props}
/>
-))
-AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName
+));
+AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
const AlertDialogDescription = React.forwardRef<
React.ElementRef,
@@ -92,9 +94,9 @@ const AlertDialogDescription = React.forwardRef<
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
-))
+));
AlertDialogDescription.displayName =
- AlertDialogPrimitive.Description.displayName
+ AlertDialogPrimitive.Description.displayName;
const AlertDialogAction = React.forwardRef<
React.ElementRef,
@@ -105,8 +107,8 @@ const AlertDialogAction = React.forwardRef<
className={cn(buttonVariants(), className)}
{...props}
/>
-))
-AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName
+));
+AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
const AlertDialogCancel = React.forwardRef<
React.ElementRef,
@@ -117,12 +119,12 @@ const AlertDialogCancel = React.forwardRef<
className={cn(
buttonVariants({ variant: "outline" }),
"mt-2 sm:mt-0",
- className
+ className,
)}
{...props}
/>
-))
-AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName
+));
+AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
export {
AlertDialog,
@@ -136,4 +138,4 @@ export {
AlertDialogDescription,
AlertDialogAction,
AlertDialogCancel,
-}
+};
diff --git a/web/src/views/events/RecordingView.tsx b/web/src/views/events/RecordingView.tsx
index e0dcb65aa..aceb96cfb 100644
--- a/web/src/views/events/RecordingView.tsx
+++ b/web/src/views/events/RecordingView.tsx
@@ -542,6 +542,7 @@ export function RecordingView({
isScrubbing={scrubbing || exportMode == "timeline"}
setFullResolution={setFullResolution}
toggleFullscreen={toggleFullscreen}
+ containerRef={mainLayoutRef}
/>
{isDesktop && (