diff --git a/src/CAREUI/misc/Fullscreen.tsx b/src/CAREUI/misc/Fullscreen.tsx index 3bb7488ebf9..5cfa7865128 100644 --- a/src/CAREUI/misc/Fullscreen.tsx +++ b/src/CAREUI/misc/Fullscreen.tsx @@ -1,26 +1,28 @@ import { useEffect, useRef } from "react"; interface Props { + className?: string; + fullscreenClassName?: string; children: React.ReactNode; fullscreen: boolean; onExit: () => void; } -export default function Fullscreen({ children, fullscreen, onExit }: Props) { +export default function Fullscreen(props: Props) { const ref = useRef(null); useEffect(() => { - if (fullscreen) { + if (props.fullscreen) { ref.current?.requestFullscreen(); } else { document.exitFullscreen(); } - }, [fullscreen]); + }, [props.fullscreen]); useEffect(() => { const listener = () => { if (!document.fullscreenElement) { - onExit(); + props.onExit(); } }; @@ -28,7 +30,14 @@ export default function Fullscreen({ children, fullscreen, onExit }: Props) { return () => { document.removeEventListener("fullscreenchange", listener); }; - }, [onExit]); + }, [props.onExit]); - return
{children}
; + return ( +
+ {props.children} +
+ ); } diff --git a/src/Common/hooks/useFeedPTZ.ts b/src/Common/hooks/useFeedPTZ.ts index 4e7fbf27c86..b064e9180ee 100644 --- a/src/Common/hooks/useFeedPTZ.ts +++ b/src/Common/hooks/useFeedPTZ.ts @@ -5,7 +5,6 @@ * co-related PR. Will be removed in the future. */ -import { getPTZPayload } from "../../Components/Feed/utils"; import { operateAsset } from "../../Redux/actions"; export interface IAsset { @@ -164,6 +163,39 @@ const relativeMove = : options?.onError && options.onError(resp)); }; +export const getPTZPayload = ( + action: PTZ, + precision = 1, + value?: number +): PTZPayload => { + let x = 0; + let y = 0; + let zoom = 0; + const delta = !value ? 0.1 / Math.max(1, precision) : value; + switch (action) { + case PTZ.Up: + y = delta; + break; + case PTZ.Down: + y = -delta; + break; + case PTZ.Left: + x = -delta; + break; + case PTZ.Right: + x = delta; + break; + case PTZ.ZoomIn: + zoom = delta; + break; + case PTZ.ZoomOut: + zoom = -delta; + break; + } + + return { x, y, zoom }; +}; + export const useFeedPTZ = ({ config, dispatch, diff --git a/src/Components/Feed/CameraFeed.tsx b/src/Components/Feed/CameraFeed.tsx index b46f535e544..ad6df29f5d0 100644 --- a/src/Components/Feed/CameraFeed.tsx +++ b/src/Components/Feed/CameraFeed.tsx @@ -2,18 +2,19 @@ import { LegacyRef, useCallback, useEffect, useRef, useState } from "react"; import { AssetData } from "../Assets/AssetTypes"; import useOperateCamera, { PTZPayload } from "./useOperateCamera"; import usePlayer from "./usePlayer"; -import { getPTZPayload, getStreamUrl } from "./utils"; +import { getStreamUrl } from "./utils"; import ReactPlayer from "react-player"; import { classNames, isIOS } from "../../Utils/utils"; import FeedAlert, { FeedAlertState } from "./FeedAlert"; import FeedNetworkSignal from "./FeedNetworkSignal"; import NoFeedAvailable from "./NoFeedAvailable"; import FeedControls from "./FeedControls"; +import Fullscreen from "../../CAREUI/misc/Fullscreen"; interface Props { children?: React.ReactNode; asset: AssetData; - fallbackMiddleware: string; + fallbackMiddleware: string; // TODO: remove this in favour of `asset.resolved_middleware.hostname` once https://github.com/coronasafe/care/pull/1741 is merged preset?: PTZPayload; silent?: boolean; className?: string; @@ -31,11 +32,9 @@ export default function CameraFeed(props: Props) { const streamUrl = getStreamUrl(props.asset, props.fallbackMiddleware); const player = usePlayer(streamUrl, playerRef); - const { precision, togglePrecision, operate } = useOperateCamera( - props.asset.id, - props.silent - ); + const operate = useOperateCamera(props.asset.id, props.silent); + const [isFullscreen, setFullscreen] = useState(false); const [state, setState] = useState(); useEffect(() => setState(player.status), [player.status, setState]); @@ -82,117 +81,119 @@ export default function CameraFeed(props: Props) { // Start stream on mount useEffect(() => initializeStream(), [initializeStream]); + const resetStream = () => { setState("loading"); initializeStream(); }; - // console.log({ assetId: props.asset.id, state, precision }); return ( -
-
-
- - {props.asset.name} - -
- + setFullscreen(false)}> +
+
+
+ + {props.asset.name} + +
+ +
+ {props.children}
- {props.children} -
-
- {/* Notifications */} - +
+ {/* Notifications */} + - {/* No Feed informations */} - {state === "host_unreachable" && ( - - )} - {player.status === "offline" && ( - - )} + {/* No Feed informations */} + {state === "host_unreachable" && ( + + )} + {player.status === "offline" && ( + + )} - {/* Video Player */} - {isIOS ? ( - } - controls={false} - playsinline - playing - muted - width="100%" - height="100%" - onPlay={player.onPlayCB} - // onBuffer={props.onWait} - onEnded={() => player.setStatus("stop")} - onError={(e, _, hlsInstance) => { - if (e === "hlsError") { - const recovered = hlsInstance.recoverMediaError(); - console.info(recovered); - } - }} - /> - ) : ( -
-
+ ); } diff --git a/src/Components/Feed/FeedButton.tsx b/src/Components/Feed/FeedButton.tsx index 2e7c3b591e1..b1ad05f92e2 100644 --- a/src/Components/Feed/FeedButton.tsx +++ b/src/Components/Feed/FeedButton.tsx @@ -1,22 +1,21 @@ -import CareIcon from "../../CAREUI/icons/CareIcon"; import KeyboardShortcut from "../../CAREUI/interactive/KeyboardShortcut"; -import { classNames, isAppleDevice } from "../../Utils/utils"; +import { classNames } from "../../Utils/utils"; interface Props { className?: string; children?: React.ReactNode; - shortcut: string[]; + readonly shortcut?: string[]; onTrigger: () => void; helpText?: string; shortcutsDisabled?: boolean; tooltipClassName?: string; } -function FeedButton(props: Props) { +export default function FeedButton(props: Props) { const child = (