mirror of
https://github.com/Qortal/q-tube.git
synced 2025-02-11 17:55:51 +00:00
Videoplayer updates:
VideoPlayer tooltips moved below buttons to avoid interfering with clicking on progress slider. Slider raised 2px and is thicker for the same reason. Clicking on progress slider doesn't force the video to start playing. Changed colors on Volume Slider so it is easier to see on Desktop and especially Mobile Volume slider removed on mobile Buggy feature that did picture in picture when leaving video while playing has been removed If on Mobile, video title has bigger topMargin to prevent video clipping into it on some Mobile devices.
This commit is contained in:
parent
823365998a
commit
c6605060db
@ -10,8 +10,7 @@ import {
|
|||||||
ProgressSlider,
|
ProgressSlider,
|
||||||
ReloadButton,
|
ReloadButton,
|
||||||
VideoTime,
|
VideoTime,
|
||||||
VolumeButton,
|
VolumeControl,
|
||||||
VolumeSlider,
|
|
||||||
} from "./VideoControls.tsx";
|
} from "./VideoControls.tsx";
|
||||||
|
|
||||||
export const MobileControlsBar = () => {
|
export const MobileControlsBar = () => {
|
||||||
@ -54,10 +53,6 @@ export const MobileControlsBar = () => {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<MenuItem>
|
|
||||||
<VolumeButton />
|
|
||||||
<VolumeSlider width={"100%"} />
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem>
|
<MenuItem>
|
||||||
<ObjectFitButton />
|
<ObjectFitButton />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { IconButton, Slider, Typography } from "@mui/material";
|
import { Box, IconButton, Slider, Typography } from "@mui/material";
|
||||||
import { fontSizeExSmall, fontSizeSmall } from "../../../../constants/Misc.ts";
|
import { fontSizeExSmall, fontSizeSmall } from "../../../../constants/Misc.ts";
|
||||||
import { CustomFontTooltip } from "../../../../utils/CustomFontTooltip.tsx";
|
import { CustomFontTooltip } from "../../../../utils/CustomFontTooltip.tsx";
|
||||||
import { formatTime } from "../../../../utils/numberFunctions.ts";
|
import { formatTime } from "../../../../utils/numberFunctions.ts";
|
||||||
@ -18,7 +18,7 @@ import { useSignalEffect } from "@preact/signals-react";
|
|||||||
export const PlayButton = () => {
|
export const PlayButton = () => {
|
||||||
const { togglePlay, playing } = useVideoContext();
|
const { togglePlay, playing } = useVideoContext();
|
||||||
return (
|
return (
|
||||||
<CustomFontTooltip title="Pause/Play (Spacebar)" placement="top" arrow>
|
<CustomFontTooltip title="Pause/Play (Spacebar)" placement="bottom" arrow>
|
||||||
<IconButton
|
<IconButton
|
||||||
sx={{
|
sx={{
|
||||||
color: "white",
|
color: "white",
|
||||||
@ -34,7 +34,7 @@ export const PlayButton = () => {
|
|||||||
export const ReloadButton = () => {
|
export const ReloadButton = () => {
|
||||||
const { reloadVideo } = useVideoContext();
|
const { reloadVideo } = useVideoContext();
|
||||||
return (
|
return (
|
||||||
<CustomFontTooltip title="Reload Video (R)" placement="top" arrow>
|
<CustomFontTooltip title="Reload Video (R)" placement="bottom" arrow>
|
||||||
<IconButton
|
<IconButton
|
||||||
sx={{
|
sx={{
|
||||||
color: "white",
|
color: "white",
|
||||||
@ -57,7 +57,7 @@ export const ProgressSlider = () => {
|
|||||||
max={videoRef.current?.duration || 100}
|
max={videoRef.current?.duration || 100}
|
||||||
sx={{
|
sx={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
bottom: "40px",
|
bottom: "42px",
|
||||||
color: "#00abff",
|
color: "#00abff",
|
||||||
padding: "0px",
|
padding: "0px",
|
||||||
// prevents the slider from jumping up 20px in certain mobile conditions
|
// prevents the slider from jumping up 20px in certain mobile conditions
|
||||||
@ -69,7 +69,8 @@ export const ProgressSlider = () => {
|
|||||||
height: "16px",
|
height: "16px",
|
||||||
},
|
},
|
||||||
"& .MuiSlider-thumb::after": { width: "20px", height: "20px" },
|
"& .MuiSlider-thumb::after": { width: "20px", height: "20px" },
|
||||||
"& .MuiSlider-rail": { opacity: 0.5 },
|
"& .MuiSlider-rail": { opacity: 0.5, height: "6px" },
|
||||||
|
"& .MuiSlider-track": { height: "6px", border: "0px" },
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -81,7 +82,7 @@ export const VideoTime = () => {
|
|||||||
return (
|
return (
|
||||||
<CustomFontTooltip
|
<CustomFontTooltip
|
||||||
title="Seek video in 10% increments (0-9)"
|
title="Seek video in 10% increments (0-9)"
|
||||||
placement="top"
|
placement="bottom"
|
||||||
arrow
|
arrow
|
||||||
>
|
>
|
||||||
<Typography
|
<Typography
|
||||||
@ -102,12 +103,12 @@ export const VideoTime = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const VolumeButton = () => {
|
const VolumeButton = () => {
|
||||||
const { isMuted, toggleMute } = useVideoContext();
|
const { isMuted, toggleMute } = useVideoContext();
|
||||||
return (
|
return (
|
||||||
<CustomFontTooltip
|
<CustomFontTooltip
|
||||||
title="Toggle Mute (M), Raise (UP), Lower (DOWN)"
|
title="Toggle Mute (M), Raise (UP), Lower (DOWN)"
|
||||||
placement="top"
|
placement="bottom"
|
||||||
arrow
|
arrow
|
||||||
>
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
@ -122,8 +123,13 @@ export const VolumeButton = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const VolumeSlider = ({ width }: { width: string }) => {
|
const VolumeSlider = ({ width }: { width: string }) => {
|
||||||
const { volume, onVolumeChange } = useVideoContext();
|
const { volume, onVolumeChange } = useVideoContext();
|
||||||
|
let color = "";
|
||||||
|
if (volume.value <= 0.5) color = "green";
|
||||||
|
else if (volume.value <= 0.75) color = "yellow";
|
||||||
|
else color = "red";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Slider
|
<Slider
|
||||||
value={volume.value}
|
value={volume.value}
|
||||||
@ -134,18 +140,36 @@ export const VolumeSlider = ({ width }: { width: string }) => {
|
|||||||
sx={{
|
sx={{
|
||||||
width,
|
width,
|
||||||
marginRight: "10px",
|
marginRight: "10px",
|
||||||
"& .MuiSlider-thumb::after": { width: "25px", height: "25px" },
|
color,
|
||||||
|
"& .MuiSlider-thumb": {
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
width: "16px",
|
||||||
|
height: "16px",
|
||||||
|
},
|
||||||
|
"& .MuiSlider-thumb::after": { width: "16px", height: "16px" },
|
||||||
|
"& .MuiSlider-rail": { opacity: 0.5, height: "6px" },
|
||||||
|
"& .MuiSlider-track": { height: "6px", border: "0px" },
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const VolumeControl = ({ sliderWidth }: { sliderWidth: string }) => {
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
sx={{ display: "flex", gap: "5px", alignItems: "center", width: "100%" }}
|
||||||
|
>
|
||||||
|
<VolumeButton />
|
||||||
|
<VolumeSlider width={sliderWidth} />
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
export const PlaybackRate = () => {
|
export const PlaybackRate = () => {
|
||||||
const { playbackRate, increaseSpeed, isScreenSmall } = useVideoContext();
|
const { playbackRate, increaseSpeed, isScreenSmall } = useVideoContext();
|
||||||
return (
|
return (
|
||||||
<CustomFontTooltip
|
<CustomFontTooltip
|
||||||
title="Video Speed. Increase (+ or >), Decrease (- or <)"
|
title="Video Speed. Increase (+ or >), Decrease (- or <)"
|
||||||
placement="top"
|
placement="bottom"
|
||||||
arrow
|
arrow
|
||||||
>
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
@ -170,7 +194,11 @@ export const PictureInPictureButton = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{!isFullscreen.value && (
|
{!isFullscreen.value && (
|
||||||
<CustomFontTooltip title="Picture in Picture (P)" placement="top" arrow>
|
<CustomFontTooltip
|
||||||
|
title="Picture in Picture (P)"
|
||||||
|
placement="bottom"
|
||||||
|
arrow
|
||||||
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
sx={{
|
sx={{
|
||||||
color: "white",
|
color: "white",
|
||||||
@ -189,7 +217,7 @@ export const PictureInPictureButton = () => {
|
|||||||
export const ObjectFitButton = () => {
|
export const ObjectFitButton = () => {
|
||||||
const { toggleObjectFit } = useVideoContext();
|
const { toggleObjectFit } = useVideoContext();
|
||||||
return (
|
return (
|
||||||
<CustomFontTooltip title="Toggle Aspect Ratio (O)" placement="top" arrow>
|
<CustomFontTooltip title="Toggle Aspect Ratio (O)" placement="bottom" arrow>
|
||||||
<IconButton
|
<IconButton
|
||||||
sx={{
|
sx={{
|
||||||
color: "white",
|
color: "white",
|
||||||
@ -206,7 +234,7 @@ export const ObjectFitButton = () => {
|
|||||||
export const FullscreenButton = () => {
|
export const FullscreenButton = () => {
|
||||||
const { toggleFullscreen } = useVideoContext();
|
const { toggleFullscreen } = useVideoContext();
|
||||||
return (
|
return (
|
||||||
<CustomFontTooltip title="Toggle Fullscreen (F)" placement="top" arrow>
|
<CustomFontTooltip title="Toggle Fullscreen (F)" placement="bottom" arrow>
|
||||||
<IconButton
|
<IconButton
|
||||||
sx={{
|
sx={{
|
||||||
color: "white",
|
color: "white",
|
||||||
|
@ -11,17 +11,15 @@ import {
|
|||||||
ProgressSlider,
|
ProgressSlider,
|
||||||
ReloadButton,
|
ReloadButton,
|
||||||
VideoTime,
|
VideoTime,
|
||||||
VolumeButton,
|
VolumeControl,
|
||||||
VolumeSlider,
|
|
||||||
} from "./VideoControls.tsx";
|
} from "./VideoControls.tsx";
|
||||||
import { useSignalEffect } from "@preact/signals-react";
|
|
||||||
|
|
||||||
export const VideoControlsBar = () => {
|
export const VideoControlsBar = () => {
|
||||||
const { from, canPlay, showControlsFullScreen, isScreenSmall, progress } =
|
const { from, canPlay, showControlsFullScreen, isScreenSmall, progress } =
|
||||||
useVideoContext();
|
useVideoContext();
|
||||||
|
|
||||||
const showMobileControls = isScreenSmall && canPlay.value;
|
const showMobileControls = isScreenSmall && canPlay.value;
|
||||||
const controlsHeight = "40px";
|
const controlsHeight = "42px";
|
||||||
const controlGroupSX = {
|
const controlGroupSX = {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
gap: "5px",
|
gap: "5px",
|
||||||
@ -46,8 +44,7 @@ export const VideoControlsBar = () => {
|
|||||||
|
|
||||||
<ProgressSlider />
|
<ProgressSlider />
|
||||||
|
|
||||||
<VolumeButton />
|
<VolumeControl sliderWidth={"100px"} />
|
||||||
<VolumeSlider width={"100px"} />
|
|
||||||
<VideoTime />
|
<VideoTime />
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
@ -147,11 +147,6 @@ export const useVideoPlayerState = (props: VideoPlayerProps, ref: any) => {
|
|||||||
if (!videoRef.current) return;
|
if (!videoRef.current) return;
|
||||||
videoRef.current.currentTime = value as number;
|
videoRef.current.currentTime = value as number;
|
||||||
progress.value = value as number;
|
progress.value = value as number;
|
||||||
|
|
||||||
if (!playing.value) {
|
|
||||||
await videoRef.current.play();
|
|
||||||
playing.value = true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEnded = () => {
|
const handleEnded = () => {
|
||||||
@ -198,9 +193,7 @@ export const useVideoPlayerState = (props: VideoPlayerProps, ref: any) => {
|
|||||||
const target = event?.target;
|
const target = event?.target;
|
||||||
if (target) {
|
if (target) {
|
||||||
target.pause();
|
target.pause();
|
||||||
if (playing.value) {
|
if (playing.value) playing.value = false;
|
||||||
playing.value = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -445,21 +445,21 @@ export const VideoPlayerGlobal: React.FC<VideoPlayerProps> = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
if (element) {
|
// if (element) {
|
||||||
const oldElement = document.getElementById("videoPlayer");
|
// const oldElement = document.getElementById("videoPlayer");
|
||||||
if (oldElement && oldElement?.parentNode) {
|
// if (oldElement && oldElement?.parentNode) {
|
||||||
oldElement?.parentNode.replaceChild(element, oldElement);
|
// oldElement?.parentNode.replaceChild(element, oldElement);
|
||||||
videoRef.current = element;
|
// videoRef.current = element;
|
||||||
setPlaying(true);
|
// setPlaying(true);
|
||||||
setCanPlay(true);
|
// setCanPlay(true);
|
||||||
setStartPlay(true);
|
// setStartPlay(true);
|
||||||
//videoRef?.current?.addEventListener("click", () => {});
|
// //videoRef?.current?.addEventListener("click", () => {});
|
||||||
videoRef?.current?.addEventListener("timeupdate", updateProgress);
|
// videoRef?.current?.addEventListener("timeupdate", updateProgress);
|
||||||
videoRef?.current?.addEventListener("ended", handleEnded);
|
// videoRef?.current?.addEventListener("ended", handleEnded);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}, [element]);
|
// }, [element]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VideoContainer
|
<VideoContainer
|
||||||
@ -483,9 +483,9 @@ export const VideoPlayerGlobal: React.FC<VideoPlayerProps> = ({
|
|||||||
}}
|
}}
|
||||||
></CloseIcon>
|
></CloseIcon>
|
||||||
</div>
|
</div>
|
||||||
<div onClick={togglePlay}>
|
{/*<div onClick={togglePlay}>*/}
|
||||||
<VideoElement id="videoPlayer" />
|
{/* <VideoElement id="videoPlayer" />*/}
|
||||||
</div>
|
{/*</div>*/}
|
||||||
<ControlsContainer
|
<ControlsContainer
|
||||||
style={{
|
style={{
|
||||||
bottom: from === "create" ? "15px" : 0,
|
bottom: from === "create" ? "15px" : 0,
|
||||||
|
@ -121,7 +121,7 @@ export const VideoContent = () => {
|
|||||||
color="textPrimary"
|
color="textPrimary"
|
||||||
sx={{
|
sx={{
|
||||||
textAlign: "start",
|
textAlign: "start",
|
||||||
marginTop: "10px",
|
marginTop: isScreenSmall ? "20px" : "10px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{videoData?.title}
|
{videoData?.title}
|
||||||
|
@ -228,30 +228,30 @@ const GlobalWrapper: React.FC<Props> = ({ children, setTheme }) => {
|
|||||||
/>
|
/>
|
||||||
<EditVideo />
|
<EditVideo />
|
||||||
<EditPlaylist />
|
<EditPlaylist />
|
||||||
<Rnd
|
{/*<Rnd*/}
|
||||||
onDragStart={onDragStart}
|
{/* onDragStart={onDragStart}*/}
|
||||||
onDragStop={onDragStop}
|
{/* onDragStop={onDragStop}*/}
|
||||||
style={{
|
{/* style={{*/}
|
||||||
display: videoPlaying ? "block" : "none",
|
{/* display: videoPlaying ? "block" : "none",*/}
|
||||||
position: "fixed",
|
{/* position: "fixed",*/}
|
||||||
height: "auto",
|
{/* height: "auto",*/}
|
||||||
width: 350,
|
{/* width: 350,*/}
|
||||||
zIndex: 1000,
|
{/* zIndex: 1000,*/}
|
||||||
maxWidth: 800,
|
{/* maxWidth: 800,*/}
|
||||||
}}
|
{/* }}*/}
|
||||||
default={{
|
{/* default={{*/}
|
||||||
x: 0,
|
{/* x: 0,*/}
|
||||||
y: 60,
|
{/* y: 60,*/}
|
||||||
width: 350,
|
{/* width: 350,*/}
|
||||||
height: "auto",
|
{/* height: "auto",*/}
|
||||||
}}
|
{/* }}*/}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
{/* // eslint-disable-next-line @typescript-eslint/no-empty-function*/}
|
||||||
onDrag={() => {}}
|
{/* onDrag={() => {}}*/}
|
||||||
>
|
{/*>*/}
|
||||||
{videoPlaying && (
|
{/* {videoPlaying && (*/}
|
||||||
<VideoPlayerGlobal checkIfDrag={checkIfDrag} element={videoPlaying} />
|
{/* <VideoPlayerGlobal checkIfDrag={checkIfDrag} element={videoPlaying} />*/}
|
||||||
)}
|
{/* )}*/}
|
||||||
</Rnd>
|
{/*</Rnd>*/}
|
||||||
|
|
||||||
{children}
|
{children}
|
||||||
</>
|
</>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user