forked from Github/frigate
stay in fullscreen when navigating to a camera (#11666)
This commit is contained in:
@@ -45,6 +45,7 @@ import { VideoResolutionType } from "@/types/live";
|
||||
import { ASPECT_VERTICAL_LAYOUT, ASPECT_WIDE_LAYOUT } from "@/types/record";
|
||||
import { useResizeObserver } from "@/hooks/resize-observer";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useFullscreen } from "@/hooks/use-fullscreen";
|
||||
|
||||
const SEGMENT_DURATION = 30;
|
||||
|
||||
@@ -227,32 +228,7 @@ export function RecordingView({
|
||||
|
||||
// fullscreen
|
||||
|
||||
const [fullscreen, setFullscreen] = useState(false);
|
||||
|
||||
const onToggleFullscreen = useCallback(
|
||||
(full: boolean) => {
|
||||
if (full) {
|
||||
mainLayoutRef.current?.requestFullscreen();
|
||||
} else {
|
||||
document.exitFullscreen();
|
||||
}
|
||||
},
|
||||
[mainLayoutRef],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (mainLayoutRef.current == null) {
|
||||
return;
|
||||
}
|
||||
const fsListener = () => {
|
||||
setFullscreen(document.fullscreenElement != null);
|
||||
};
|
||||
document.addEventListener("fullscreenchange", fsListener);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("fullscreenchange", fsListener);
|
||||
};
|
||||
}, [mainLayoutRef]);
|
||||
const { fullscreen, toggleFullscreen } = useFullscreen(mainLayoutRef);
|
||||
|
||||
// layout
|
||||
|
||||
@@ -535,7 +511,7 @@ export function RecordingView({
|
||||
}}
|
||||
isScrubbing={scrubbing || exportMode == "timeline"}
|
||||
setFullResolution={setFullResolution}
|
||||
setFullscreen={onToggleFullscreen}
|
||||
toggleFullscreen={toggleFullscreen}
|
||||
/>
|
||||
</div>
|
||||
{isDesktop && (
|
||||
|
||||
@@ -40,8 +40,6 @@ import {
|
||||
TooltipTrigger,
|
||||
TooltipContent,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { useFullscreen } from "@/hooks/use-fullscreen";
|
||||
import { toast } from "sonner";
|
||||
import { Toaster } from "@/components/ui/sonner";
|
||||
|
||||
type DraggableGridLayoutProps = {
|
||||
@@ -55,6 +53,8 @@ type DraggableGridLayoutProps = {
|
||||
visibleCameras: string[];
|
||||
isEditMode: boolean;
|
||||
setIsEditMode: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
fullscreen: boolean;
|
||||
toggleFullscreen: () => void;
|
||||
};
|
||||
export default function DraggableGridLayout({
|
||||
cameras,
|
||||
@@ -67,6 +67,8 @@ export default function DraggableGridLayout({
|
||||
visibleCameras,
|
||||
isEditMode,
|
||||
setIsEditMode,
|
||||
fullscreen,
|
||||
toggleFullscreen,
|
||||
}: DraggableGridLayoutProps) {
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
const birdseyeConfig = useMemo(() => config?.birdseye, [config]);
|
||||
@@ -289,20 +291,6 @@ export default function DraggableGridLayout({
|
||||
}
|
||||
}, [containerRef, containerHeight]);
|
||||
|
||||
// fullscreen state
|
||||
|
||||
const { fullscreen, toggleFullscreen, error, clearError } =
|
||||
useFullscreen(gridContainerRef);
|
||||
|
||||
useEffect(() => {
|
||||
if (error !== null) {
|
||||
toast.error(`Error attempting fullscreen mode: ${error}`, {
|
||||
position: "top-center",
|
||||
});
|
||||
clearError();
|
||||
}
|
||||
}, [error, clearError]);
|
||||
|
||||
const cellHeight = useMemo(() => {
|
||||
const aspectRatio = 16 / 9;
|
||||
// subtract container margin, 1 camera takes up at least 4 rows
|
||||
@@ -463,21 +451,23 @@ export default function DraggableGridLayout({
|
||||
</Tooltip>
|
||||
{!isEditMode && (
|
||||
<>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<div
|
||||
className="cursor-pointer rounded-lg bg-secondary text-secondary-foreground opacity-60 transition-all duration-300 hover:bg-muted hover:opacity-100"
|
||||
onClick={() =>
|
||||
setEditGroup((prevEditGroup) => !prevEditGroup)
|
||||
}
|
||||
>
|
||||
<LuPencil className="size-5 md:m-[6px]" />
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
{isEditMode ? "Exit Editing" : "Edit Camera Group"}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
{!fullscreen && (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<div
|
||||
className="cursor-pointer rounded-lg bg-secondary text-secondary-foreground opacity-60 transition-all duration-300 hover:bg-muted hover:opacity-100"
|
||||
onClick={() =>
|
||||
setEditGroup((prevEditGroup) => !prevEditGroup)
|
||||
}
|
||||
>
|
||||
<LuPencil className="size-5 md:m-[6px]" />
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
{isEditMode ? "Exit Editing" : "Edit Camera Group"}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
)}
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<div
|
||||
|
||||
@@ -4,7 +4,6 @@ import BirdseyeLivePlayer from "@/components/player/BirdseyeLivePlayer";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import { useResizeObserver } from "@/hooks/resize-observer";
|
||||
import { useFullscreen } from "@/hooks/use-fullscreen";
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import { useMemo, useRef } from "react";
|
||||
import {
|
||||
@@ -19,7 +18,15 @@ import { useNavigate } from "react-router-dom";
|
||||
import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch";
|
||||
import useSWR from "swr";
|
||||
|
||||
export default function LiveBirdseyeView() {
|
||||
type LiveBirdseyeViewProps = {
|
||||
fullscreen: boolean;
|
||||
toggleFullscreen: () => void;
|
||||
};
|
||||
|
||||
export default function LiveBirdseyeView({
|
||||
fullscreen,
|
||||
toggleFullscreen,
|
||||
}: LiveBirdseyeViewProps) {
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
const navigate = useNavigate();
|
||||
const { isPortrait } = useMobileOrientation();
|
||||
@@ -28,10 +35,6 @@ export default function LiveBirdseyeView() {
|
||||
const [{ width: windowWidth, height: windowHeight }] =
|
||||
useResizeObserver(window);
|
||||
|
||||
// fullscreen state
|
||||
|
||||
const { fullscreen, toggleFullscreen } = useFullscreen(mainRef);
|
||||
|
||||
// playback state
|
||||
|
||||
const cameraAspectRatio = useMemo(() => {
|
||||
|
||||
@@ -72,15 +72,18 @@ import {
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch";
|
||||
import useSWR from "swr";
|
||||
import { useFullscreen } from "@/hooks/use-fullscreen";
|
||||
|
||||
type LiveCameraViewProps = {
|
||||
config?: FrigateConfig;
|
||||
camera: CameraConfig;
|
||||
fullscreen: boolean;
|
||||
toggleFullscreen: () => void;
|
||||
};
|
||||
export default function LiveCameraView({
|
||||
config,
|
||||
camera,
|
||||
fullscreen,
|
||||
toggleFullscreen,
|
||||
}: LiveCameraViewProps) {
|
||||
const navigate = useNavigate();
|
||||
const { isPortrait } = useMobileOrientation();
|
||||
@@ -175,9 +178,7 @@ export default function LiveCameraView({
|
||||
[clickOverlayRef, clickOverlay, sendPtz],
|
||||
);
|
||||
|
||||
// fullscreen / pip state
|
||||
|
||||
const { fullscreen, toggleFullscreen } = useFullscreen(mainRef);
|
||||
// pip state
|
||||
|
||||
useEffect(() => {
|
||||
setPip(document.pictureInPictureElement != null);
|
||||
@@ -314,6 +315,18 @@ export default function LiveCameraView({
|
||||
<div
|
||||
className={`flex flex-row items-center gap-2 *:rounded-lg ${isMobile ? "landscape:flex-col" : ""}`}
|
||||
>
|
||||
{fullscreen && (
|
||||
<Button
|
||||
className="bg-gray-500 bg-gradient-to-br from-gray-400 to-gray-500 text-primary"
|
||||
size="sm"
|
||||
onClick={() => navigate(-1)}
|
||||
>
|
||||
<IoMdArrowRoundBack className="size-5 text-secondary-foreground" />
|
||||
{isDesktop && (
|
||||
<div className="text-secondary-foreground">Back</div>
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
{!isIOS && (
|
||||
<CameraFeatureToggle
|
||||
className="p-2 md:p-0"
|
||||
|
||||
@@ -30,12 +30,16 @@ type LiveDashboardViewProps = {
|
||||
cameraGroup?: string;
|
||||
includeBirdseye: boolean;
|
||||
onSelectCamera: (camera: string) => void;
|
||||
fullscreen: boolean;
|
||||
toggleFullscreen: () => void;
|
||||
};
|
||||
export default function LiveDashboardView({
|
||||
cameras,
|
||||
cameraGroup,
|
||||
includeBirdseye,
|
||||
onSelectCamera,
|
||||
fullscreen,
|
||||
toggleFullscreen,
|
||||
}: LiveDashboardViewProps) {
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
|
||||
@@ -214,7 +218,7 @@ export default function LiveDashboardView({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{events && events.length > 0 && (
|
||||
{!fullscreen && events && events.length > 0 && (
|
||||
<ScrollArea>
|
||||
<TooltipProvider>
|
||||
<div className="flex items-center gap-2 px-1">
|
||||
@@ -281,6 +285,8 @@ export default function LiveDashboardView({
|
||||
visibleCameras={visibleCameras}
|
||||
isEditMode={isEditMode}
|
||||
setIsEditMode={setIsEditMode}
|
||||
fullscreen={fullscreen}
|
||||
toggleFullscreen={toggleFullscreen}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user