forked from Github/frigate
Mobile recordings redesign (#10711)
* Only show back button text on desktop * Add mobile camera drawer to separate component * Use bottom sheet for export on mobile * Add intermediary mobile bottom sheet * fix filter * Fix mobile layout jumping * Fix desktop vertical camera view * Fix horizontal camera list * Add overlay instead of using same button for timeline exports * Don't use native hls for now * Fix export bottom sheet * Fix scrolling * Simplify checks * Adjust hls compat approach * Fix events shadow * Make corners consistent * Make corners consistent * fix max drawer height * Use separate buttons for export control * Add icons * Fix list views * Fix new items to review * bottom padding on bottom sheets * bottom padding on bottom sheets
This commit is contained in:
@@ -88,29 +88,36 @@ export default function HlsVideoPlayer({
|
||||
const [controlsOpen, setControlsOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`relative ${visible ? "visible" : "hidden"}`}
|
||||
onMouseOver={
|
||||
isDesktop
|
||||
? () => {
|
||||
setControls(true);
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
onMouseOut={
|
||||
isDesktop
|
||||
? () => {
|
||||
setControls(controlsOpen);
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
onClick={isDesktop ? undefined : () => setControls(!controls)}
|
||||
>
|
||||
<TransformWrapper minScale={1.0}>
|
||||
<TransformComponent>
|
||||
<TransformWrapper minScale={1.0}>
|
||||
<div
|
||||
className={`relative w-full ${className ?? ""} ${visible ? "visible" : "hidden"}`}
|
||||
onMouseOver={
|
||||
isDesktop
|
||||
? () => {
|
||||
setControls(true);
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
onMouseOut={
|
||||
isDesktop
|
||||
? () => {
|
||||
setControls(controlsOpen);
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
onClick={isDesktop ? undefined : () => setControls(!controls)}
|
||||
>
|
||||
<TransformComponent
|
||||
wrapperStyle={{
|
||||
width: "100%",
|
||||
}}
|
||||
contentStyle={{
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<video
|
||||
ref={videoRef}
|
||||
className={`${className ?? ""} bg-black rounded-2xl ${loadedMetadata ? "" : "invisible"}`}
|
||||
className={`size-full bg-black rounded-2xl ${loadedMetadata ? "" : "invisible"}`}
|
||||
preload="auto"
|
||||
autoPlay
|
||||
controls={false}
|
||||
@@ -149,46 +156,47 @@ export default function HlsVideoPlayer({
|
||||
unsupportedErrorCodes.includes(e.target.error.code) &&
|
||||
videoRef.current
|
||||
) {
|
||||
setLoadedMetadata(false);
|
||||
setUseHlsCompat(true);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</TransformComponent>
|
||||
</TransformWrapper>
|
||||
<VideoControls
|
||||
className="absolute bottom-5 left-1/2 -translate-x-1/2"
|
||||
video={videoRef.current}
|
||||
isPlaying={isPlaying}
|
||||
show={controls}
|
||||
controlsOpen={controlsOpen}
|
||||
setControlsOpen={setControlsOpen}
|
||||
playbackRate={videoRef.current?.playbackRate ?? 1}
|
||||
hotKeys={hotKeys}
|
||||
onPlayPause={(play) => {
|
||||
if (!videoRef.current) {
|
||||
return;
|
||||
}
|
||||
<VideoControls
|
||||
className="absolute bottom-5 left-1/2 -translate-x-1/2"
|
||||
video={videoRef.current}
|
||||
isPlaying={isPlaying}
|
||||
show={controls}
|
||||
controlsOpen={controlsOpen}
|
||||
setControlsOpen={setControlsOpen}
|
||||
playbackRate={videoRef.current?.playbackRate ?? 1}
|
||||
hotKeys={hotKeys}
|
||||
onPlayPause={(play) => {
|
||||
if (!videoRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (play) {
|
||||
videoRef.current.play();
|
||||
} else {
|
||||
videoRef.current.pause();
|
||||
}
|
||||
}}
|
||||
onSeek={(diff) => {
|
||||
const currentTime = videoRef.current?.currentTime;
|
||||
if (play) {
|
||||
videoRef.current.play();
|
||||
} else {
|
||||
videoRef.current.pause();
|
||||
}
|
||||
}}
|
||||
onSeek={(diff) => {
|
||||
const currentTime = videoRef.current?.currentTime;
|
||||
|
||||
if (!videoRef.current || !currentTime) {
|
||||
return;
|
||||
}
|
||||
if (!videoRef.current || !currentTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
videoRef.current.currentTime = Math.max(0, currentTime + diff);
|
||||
}}
|
||||
onSetPlaybackRate={(rate) =>
|
||||
videoRef.current ? (videoRef.current.playbackRate = rate) : null
|
||||
}
|
||||
/>
|
||||
{children}
|
||||
</div>
|
||||
videoRef.current.currentTime = Math.max(0, currentTime + diff);
|
||||
}}
|
||||
onSetPlaybackRate={(rate) =>
|
||||
videoRef.current ? (videoRef.current.playbackRate = rate) : null
|
||||
}
|
||||
/>
|
||||
{children}
|
||||
</div>
|
||||
</TransformWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import PreviewPlayer, { PreviewController } from "../PreviewPlayer";
|
||||
import { DynamicVideoController } from "./DynamicVideoController";
|
||||
import HlsVideoPlayer from "../HlsVideoPlayer";
|
||||
import { TimeRange, Timeline } from "@/types/timeline";
|
||||
import { isDesktop } from "react-device-detect";
|
||||
|
||||
/**
|
||||
* Dynamically switches between video playback and scrubbing preview player.
|
||||
@@ -54,7 +55,7 @@ export default function DynamicVideoPlayer({
|
||||
if (aspectRatio > 2) {
|
||||
return "";
|
||||
} else if (aspectRatio < 16 / 9) {
|
||||
return "aspect-tall";
|
||||
return isDesktop ? "" : "aspect-tall";
|
||||
} else {
|
||||
return "aspect-video";
|
||||
}
|
||||
@@ -168,9 +169,9 @@ export default function DynamicVideoPlayer({
|
||||
}, [controller, recordings]);
|
||||
|
||||
return (
|
||||
<div className={`relative ${className ?? ""}`}>
|
||||
<div className={`w-full relative ${className ?? ""}`}>
|
||||
<HlsVideoPlayer
|
||||
className={`w-full ${grow ?? ""}`}
|
||||
className={isDesktop ? `w-full ${grow}` : "max-h-[50dvh]"}
|
||||
videoRef={playerRef}
|
||||
visible={!(isScrubbing || isLoading)}
|
||||
currentSource={source}
|
||||
@@ -194,7 +195,7 @@ export default function DynamicVideoPlayer({
|
||||
)}
|
||||
</HlsVideoPlayer>
|
||||
<PreviewPlayer
|
||||
className={`${isScrubbing || isLoading ? "visible" : "hidden"} ${grow}`}
|
||||
className={`${isScrubbing || isLoading ? "visible" : "hidden"} ${isDesktop ? `w-full ${grow}` : "max-h-[50dvh]"}`}
|
||||
camera={camera}
|
||||
timeRange={timeRange}
|
||||
cameraPreviews={cameraPreviews}
|
||||
|
||||
Reference in New Issue
Block a user