forked from Github/frigate
Camera group layout fixes (#11334)
* camera group layout changes and tweaks * lock aspect ratio * no compacting * prevent collisions * revert * readd limit aspect
This commit is contained in:
146
web/src/hooks/use-fullscreen.ts
Normal file
146
web/src/hooks/use-fullscreen.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
import { RefObject, useCallback, useEffect, useState } from "react";
|
||||
|
||||
function getFullscreenElement(): HTMLElement | null {
|
||||
return (
|
||||
document.fullscreenElement ||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(document as any).webkitFullscreenElement ||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(document as any).mozFullScreenElement ||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(document as any).msFullscreenElement
|
||||
);
|
||||
}
|
||||
|
||||
function exitFullscreen(): Promise<void> | null {
|
||||
if (document.exitFullscreen) return document.exitFullscreen();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
if ((document as any).msExitFullscreen)
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return (document as any).msExitFullscreen();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
if ((document as any).webkitExitFullscreen)
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return (document as any).webkitExitFullscreen();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
if ((document as any).mozCancelFullScreen)
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return (document as any).mozCancelFullScreen();
|
||||
return null;
|
||||
}
|
||||
|
||||
function enterFullScreen(element: HTMLElement): Promise<void> | null {
|
||||
if (element.requestFullscreen) return element.requestFullscreen();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
if ((element as any).msRequestFullscreen)
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return (element as any).msRequestFullscreen();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
if ((element as any).webkitEnterFullscreen)
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return (element as any).webkitEnterFullscreen();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
if ((element as any).webkitRequestFullscreen)
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return (element as any).webkitRequestFullscreen();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
if ((element as any).mozRequestFullscreen)
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return (element as any).mozRequestFullscreen();
|
||||
return null;
|
||||
}
|
||||
|
||||
const prefixes = ["", "webkit", "moz", "ms"];
|
||||
|
||||
function addEventListeners(
|
||||
element: HTMLElement,
|
||||
onFullScreen: (event: Event) => void,
|
||||
onError: (event: Event) => void,
|
||||
) {
|
||||
prefixes.forEach((prefix) => {
|
||||
element.addEventListener(`${prefix}fullscreenchange`, onFullScreen);
|
||||
element.addEventListener(`${prefix}fullscreenerror`, onError);
|
||||
});
|
||||
}
|
||||
|
||||
function removeEventListeners(
|
||||
element: HTMLElement,
|
||||
onFullScreen: (event: Event) => void,
|
||||
onError: (event: Event) => void,
|
||||
) {
|
||||
prefixes.forEach((prefix) => {
|
||||
element.removeEventListener(`${prefix}fullscreenchange`, onFullScreen);
|
||||
element.removeEventListener(`${prefix}fullscreenerror`, onError);
|
||||
});
|
||||
}
|
||||
|
||||
export function useFullscreen<T extends HTMLElement = HTMLElement>(
|
||||
elementRef: RefObject<T>,
|
||||
) {
|
||||
const [fullscreen, setFullscreen] = useState<boolean>(false);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
|
||||
const handleFullscreenChange = useCallback((event: Event) => {
|
||||
setFullscreen(event.target === getFullscreenElement());
|
||||
}, []);
|
||||
|
||||
const handleFullscreenError = useCallback((event: Event) => {
|
||||
setFullscreen(false);
|
||||
setError(
|
||||
new Error(
|
||||
`Error attempting full-screen mode: ${event} (${event.target})`,
|
||||
),
|
||||
);
|
||||
}, []);
|
||||
|
||||
const toggleFullscreen = useCallback(async () => {
|
||||
try {
|
||||
if (!getFullscreenElement()) {
|
||||
await enterFullScreen(elementRef.current!);
|
||||
} else {
|
||||
await exitFullscreen();
|
||||
}
|
||||
setError(null);
|
||||
} catch (err) {
|
||||
setError(err as Error);
|
||||
}
|
||||
}, [elementRef]);
|
||||
|
||||
const clearError = useCallback(() => {
|
||||
setError(null);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.code === "F11") {
|
||||
toggleFullscreen();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("keydown", handleKeyDown);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("keydown", handleKeyDown);
|
||||
};
|
||||
}, [toggleFullscreen]);
|
||||
|
||||
useEffect(() => {
|
||||
const currentElement = elementRef.current;
|
||||
if (currentElement) {
|
||||
addEventListeners(
|
||||
currentElement,
|
||||
handleFullscreenChange,
|
||||
handleFullscreenError,
|
||||
);
|
||||
return () => {
|
||||
removeEventListeners(
|
||||
currentElement,
|
||||
handleFullscreenChange,
|
||||
handleFullscreenError,
|
||||
);
|
||||
};
|
||||
}
|
||||
}, [elementRef, handleFullscreenChange, handleFullscreenError]);
|
||||
|
||||
return { fullscreen, toggleFullscreen, error, clearError };
|
||||
}
|
||||
Reference in New Issue
Block a user