mirror of
https://github.com/Qortal/q-tube.git
synced 2025-02-11 17:55:51 +00:00
VideoPlayer Bugfixes
Videoplayer doesn't set fill ObjectFit when fullscreen. Added ObjectFit button Volume slider doesn't clip into video time label Volume and Progress sliders have a smaller click range so they don't override other video buttons. Usernames in the videolist component now show ellipses when they overflow Hyperlink color throughout the app changed so they are easier to see
This commit is contained in:
parent
1cfdb7a7bf
commit
d4f5c7a8ee
@ -3,6 +3,7 @@ import { Box, IconButton, Menu, MenuItem } from "@mui/material";
|
|||||||
import { useVideoContext } from "./VideoContext.ts";
|
import { useVideoContext } from "./VideoContext.ts";
|
||||||
import {
|
import {
|
||||||
FullscreenButton,
|
FullscreenButton,
|
||||||
|
ObjectFitButton,
|
||||||
PictureInPictureButton,
|
PictureInPictureButton,
|
||||||
PlaybackRate,
|
PlaybackRate,
|
||||||
PlayButton,
|
PlayButton,
|
||||||
@ -55,7 +56,10 @@ export const MobileControlsBar = () => {
|
|||||||
>
|
>
|
||||||
<MenuItem>
|
<MenuItem>
|
||||||
<VolumeButton />
|
<VolumeButton />
|
||||||
<VolumeSlider />
|
<VolumeSlider width={"100%"} />
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem>
|
||||||
|
<ObjectFitButton />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem>
|
<MenuItem>
|
||||||
<PictureInPictureButton />
|
<PictureInPictureButton />
|
||||||
|
@ -209,11 +209,11 @@ export const useVideoControlsState = (
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const setStretchVideoSetting = (value: "contain" | "fill") => {
|
const setObjectFit = (value: "contain" | "fill") => {
|
||||||
videoObjectFit.value = value;
|
videoObjectFit.value = value;
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleStretchVideoSetting = () => {
|
const toggleObjectFit = () => {
|
||||||
videoObjectFit.value =
|
videoObjectFit.value =
|
||||||
videoObjectFit.value === "contain" ? "fill" : "contain";
|
videoObjectFit.value === "contain" ? "fill" : "contain";
|
||||||
};
|
};
|
||||||
@ -226,7 +226,7 @@ export const useVideoControlsState = (
|
|||||||
|
|
||||||
switch (e.key) {
|
switch (e.key) {
|
||||||
case "o":
|
case "o":
|
||||||
toggleStretchVideoSetting();
|
toggleObjectFit();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Key.Add:
|
case Key.Add:
|
||||||
@ -364,6 +364,7 @@ export const useVideoControlsState = (
|
|||||||
showControlsFullScreen,
|
showControlsFullScreen,
|
||||||
setPlaying,
|
setPlaying,
|
||||||
isFullscreen,
|
isFullscreen,
|
||||||
setStretchVideoSetting,
|
toggleObjectFit,
|
||||||
|
setObjectFit,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,7 @@ 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";
|
||||||
import { useVideoContext } from "./VideoContext.ts";
|
import { useVideoContext } from "./VideoContext.ts";
|
||||||
|
import AspectRatioIcon from "@mui/icons-material/AspectRatio";
|
||||||
import {
|
import {
|
||||||
Fullscreen,
|
Fullscreen,
|
||||||
Pause,
|
Pause,
|
||||||
@ -48,7 +49,6 @@ export const ReloadButton = () => {
|
|||||||
|
|
||||||
export const ProgressSlider = () => {
|
export const ProgressSlider = () => {
|
||||||
const { progress, onProgressChange, videoRef } = useVideoContext();
|
const { progress, onProgressChange, videoRef } = useVideoContext();
|
||||||
const sliderThumbSize = "16px";
|
|
||||||
return (
|
return (
|
||||||
<Slider
|
<Slider
|
||||||
value={progress.value}
|
value={progress.value}
|
||||||
@ -65,9 +65,10 @@ export const ProgressSlider = () => {
|
|||||||
|
|
||||||
"& .MuiSlider-thumb": {
|
"& .MuiSlider-thumb": {
|
||||||
backgroundColor: "#fff",
|
backgroundColor: "#fff",
|
||||||
width: sliderThumbSize,
|
width: "16px",
|
||||||
height: sliderThumbSize,
|
height: "16px",
|
||||||
},
|
},
|
||||||
|
"& .MuiSlider-thumb::after": { width: "20px", height: "20px" },
|
||||||
"& .MuiSlider-rail": { opacity: 0.5 },
|
"& .MuiSlider-rail": { opacity: 0.5 },
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -112,6 +113,7 @@ export const VolumeButton = () => {
|
|||||||
<IconButton
|
<IconButton
|
||||||
sx={{
|
sx={{
|
||||||
color: "white",
|
color: "white",
|
||||||
|
marginRight: "10px",
|
||||||
}}
|
}}
|
||||||
onClick={toggleMute}
|
onClick={toggleMute}
|
||||||
>
|
>
|
||||||
@ -121,7 +123,7 @@ export const VolumeButton = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const VolumeSlider = () => {
|
export const VolumeSlider = ({ width }: { width: string }) => {
|
||||||
const { volume, onVolumeChange } = useVideoContext();
|
const { volume, onVolumeChange } = useVideoContext();
|
||||||
return (
|
return (
|
||||||
<Slider
|
<Slider
|
||||||
@ -131,7 +133,9 @@ export const VolumeSlider = () => {
|
|||||||
max={1}
|
max={1}
|
||||||
step={0.01}
|
step={0.01}
|
||||||
sx={{
|
sx={{
|
||||||
width: "100px",
|
width,
|
||||||
|
marginRight: "10px",
|
||||||
|
"& .MuiSlider-thumb::after": { width: "25px", height: "25px" },
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -183,6 +187,23 @@ export const PictureInPictureButton = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ObjectFitButton = () => {
|
||||||
|
const { toggleObjectFit } = useVideoContext();
|
||||||
|
return (
|
||||||
|
<CustomFontTooltip title="Toggle Aspect Ratio (O)" placement="top" arrow>
|
||||||
|
<IconButton
|
||||||
|
sx={{
|
||||||
|
color: "white",
|
||||||
|
paddingRight: "0px",
|
||||||
|
}}
|
||||||
|
onClick={() => toggleObjectFit()}
|
||||||
|
>
|
||||||
|
<AspectRatioIcon />
|
||||||
|
</IconButton>
|
||||||
|
</CustomFontTooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const FullscreenButton = () => {
|
export const FullscreenButton = () => {
|
||||||
const { toggleFullscreen } = useVideoContext();
|
const { toggleFullscreen } = useVideoContext();
|
||||||
return (
|
return (
|
||||||
|
@ -4,6 +4,7 @@ import { MobileControlsBar } from "./MobileControlsBar.tsx";
|
|||||||
import { useVideoContext } from "./VideoContext.ts";
|
import { useVideoContext } from "./VideoContext.ts";
|
||||||
import {
|
import {
|
||||||
FullscreenButton,
|
FullscreenButton,
|
||||||
|
ObjectFitButton,
|
||||||
PictureInPictureButton,
|
PictureInPictureButton,
|
||||||
PlaybackRate,
|
PlaybackRate,
|
||||||
PlayButton,
|
PlayButton,
|
||||||
@ -46,12 +47,13 @@ export const VideoControlsBar = () => {
|
|||||||
<ProgressSlider />
|
<ProgressSlider />
|
||||||
|
|
||||||
<VolumeButton />
|
<VolumeButton />
|
||||||
<VolumeSlider />
|
<VolumeSlider width={"100px"} />
|
||||||
<VideoTime />
|
<VideoTime />
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box sx={controlGroupSX}>
|
<Box sx={controlGroupSX}>
|
||||||
<PlaybackRate />
|
<PlaybackRate />
|
||||||
|
<ObjectFitButton />
|
||||||
<PictureInPictureButton />
|
<PictureInPictureButton />
|
||||||
<FullscreenButton />
|
<FullscreenButton />
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -103,7 +103,7 @@ export const VideoPlayer = forwardRef<videoRefType, VideoPlayerProps>(
|
|||||||
preload="metadata"
|
preload="metadata"
|
||||||
style={{
|
style={{
|
||||||
...videoStyles?.video,
|
...videoStyles?.video,
|
||||||
objectFit: isFullscreen ? "fill" : videoObjectFit.value,
|
objectFit: videoObjectFit.value,
|
||||||
height:
|
height:
|
||||||
isFullscreen.value && showControlsFullScreen.value
|
isFullscreen.value && showControlsFullScreen.value
|
||||||
? "calc(100vh - 40px)"
|
? "calc(100vh - 40px)"
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a:link { color: #8AB4F8}
|
||||||
|
|
||||||
.test-grid {
|
.test-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
@ -174,18 +174,17 @@ export const VideoContent = () => {
|
|||||||
cursor: !descriptionHeight
|
cursor: !descriptionHeight
|
||||||
? "default"
|
? "default"
|
||||||
: isExpandedDescription
|
: isExpandedDescription
|
||||||
? "default"
|
? "default"
|
||||||
: "pointer",
|
: "pointer",
|
||||||
position: "relative",
|
position: "relative",
|
||||||
|
|
||||||
marginBottom: "30px",
|
marginBottom: "30px",
|
||||||
}}
|
}}
|
||||||
className={
|
className={
|
||||||
!descriptionHeight
|
!descriptionHeight
|
||||||
? ""
|
? ""
|
||||||
: isExpandedDescription
|
: isExpandedDescription
|
||||||
? ""
|
? ""
|
||||||
: "hover-click"
|
: "hover-click"
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{descriptionHeight && !isExpandedDescription && (
|
{descriptionHeight && !isExpandedDescription && (
|
||||||
@ -210,8 +209,8 @@ export const VideoContent = () => {
|
|||||||
height: !descriptionHeight
|
height: !descriptionHeight
|
||||||
? "auto"
|
? "auto"
|
||||||
: isExpandedDescription
|
: isExpandedDescription
|
||||||
? "auto"
|
? "auto"
|
||||||
: "200px",
|
: "200px",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -110,6 +110,7 @@ export const NameContainer = styled(Box)(({ theme }) => ({
|
|||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
gap: "10px",
|
gap: "10px",
|
||||||
marginBottom: "2px",
|
marginBottom: "2px",
|
||||||
|
width: "100%",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const VideoManagerRow = styled(Box)(({ theme }) => ({
|
export const VideoManagerRow = styled(Box)(({ theme }) => ({
|
||||||
|
@ -11,38 +11,38 @@ const commonThemeOptions = {
|
|||||||
"Oxygen",
|
"Oxygen",
|
||||||
"Catamaran",
|
"Catamaran",
|
||||||
"Cairo",
|
"Cairo",
|
||||||
"Arial"
|
"Arial",
|
||||||
].join(","),
|
].join(","),
|
||||||
h1: {
|
h1: {
|
||||||
fontSize: "2rem",
|
fontSize: "2rem",
|
||||||
fontWeight: 600
|
fontWeight: 600,
|
||||||
},
|
},
|
||||||
h2: {
|
h2: {
|
||||||
fontSize: "1.75rem",
|
fontSize: "1.75rem",
|
||||||
fontWeight: 500
|
fontWeight: 500,
|
||||||
},
|
},
|
||||||
h3: {
|
h3: {
|
||||||
fontSize: "1.5rem",
|
fontSize: "1.5rem",
|
||||||
fontWeight: 500
|
fontWeight: 500,
|
||||||
},
|
},
|
||||||
h4: {
|
h4: {
|
||||||
fontSize: "1.25rem",
|
fontSize: "1.25rem",
|
||||||
fontWeight: 500
|
fontWeight: 500,
|
||||||
},
|
},
|
||||||
h5: {
|
h5: {
|
||||||
fontSize: "1rem",
|
fontSize: "1rem",
|
||||||
fontWeight: 500
|
fontWeight: 500,
|
||||||
},
|
},
|
||||||
h6: {
|
h6: {
|
||||||
fontSize: "0.875rem",
|
fontSize: "0.875rem",
|
||||||
fontWeight: 500
|
fontWeight: 500,
|
||||||
},
|
},
|
||||||
body1: {
|
body1: {
|
||||||
fontSize: "23px",
|
fontSize: "23px",
|
||||||
fontFamily: "Raleway",
|
fontFamily: "Raleway",
|
||||||
fontWeight: 400,
|
fontWeight: 400,
|
||||||
lineHeight: 1.5,
|
lineHeight: 1.5,
|
||||||
letterSpacing: "0.5px"
|
letterSpacing: "0.5px",
|
||||||
},
|
},
|
||||||
|
|
||||||
body2: {
|
body2: {
|
||||||
@ -50,12 +50,12 @@ const commonThemeOptions = {
|
|||||||
fontFamily: "Raleway, Arial",
|
fontFamily: "Raleway, Arial",
|
||||||
fontWeight: 400,
|
fontWeight: 400,
|
||||||
lineHeight: 1.4,
|
lineHeight: 1.4,
|
||||||
letterSpacing: "0.2px"
|
letterSpacing: "0.2px",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
shape: {
|
shape: {
|
||||||
borderRadius: 4
|
borderRadius: 4,
|
||||||
},
|
},
|
||||||
breakpoints: {
|
breakpoints: {
|
||||||
values: {
|
values: {
|
||||||
@ -63,8 +63,8 @@ const commonThemeOptions = {
|
|||||||
sm: 600,
|
sm: 600,
|
||||||
md: 900,
|
md: 900,
|
||||||
lg: 1200,
|
lg: 1200,
|
||||||
xl: 1536
|
xl: 1536,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
MuiButton: {
|
MuiButton: {
|
||||||
@ -73,16 +73,16 @@ const commonThemeOptions = {
|
|||||||
backgroundColor: "inherit",
|
backgroundColor: "inherit",
|
||||||
transition: "filter 0.3s ease-in-out",
|
transition: "filter 0.3s ease-in-out",
|
||||||
"&:hover": {
|
"&:hover": {
|
||||||
filter: "brightness(1.1)"
|
filter: "brightness(1.1)",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
defaultProps: {
|
defaultProps: {
|
||||||
disableElevation: true,
|
disableElevation: true,
|
||||||
disableRipple: true
|
disableRipple: true,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const lightTheme = createTheme({
|
const lightTheme = createTheme({
|
||||||
@ -92,21 +92,22 @@ const lightTheme = createTheme({
|
|||||||
primary: {
|
primary: {
|
||||||
main: "#ffffff",
|
main: "#ffffff",
|
||||||
dark: "#F5F5F5",
|
dark: "#F5F5F5",
|
||||||
light: "#FCFCFC"
|
light: "#FCFCFC",
|
||||||
},
|
},
|
||||||
secondary: {
|
secondary: {
|
||||||
main: "#417Ed4",
|
main: "#417Ed4",
|
||||||
dark: "#3e74c1"
|
dark: "#3e74c1",
|
||||||
},
|
},
|
||||||
background: {
|
background: {
|
||||||
default: "#fcfcfc",
|
default: "#fcfcfc",
|
||||||
paper: "#F5F5F5"
|
paper: "#F5F5F5",
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
primary: "#000000",
|
primary: "#000000",
|
||||||
secondary: "#525252"
|
secondary: "#525252",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
MuiCard: {
|
MuiCard: {
|
||||||
styleOverrides: {
|
styleOverrides: {
|
||||||
@ -118,19 +119,19 @@ const lightTheme = createTheme({
|
|||||||
"&:hover": {
|
"&:hover": {
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
boxShadow:
|
boxShadow:
|
||||||
"rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px;"
|
"rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px;",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
MuiIcon: {
|
MuiIcon: {
|
||||||
defaultProps: {
|
defaultProps: {
|
||||||
style: {
|
style: {
|
||||||
color: "#000000"
|
color: "#000000",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const darkTheme = createTheme({
|
const darkTheme = createTheme({
|
||||||
@ -140,22 +141,22 @@ const darkTheme = createTheme({
|
|||||||
primary: {
|
primary: {
|
||||||
main: "#2e3d60",
|
main: "#2e3d60",
|
||||||
dark: "#1a2744",
|
dark: "#1a2744",
|
||||||
light: "#353535"
|
light: "#353535",
|
||||||
},
|
},
|
||||||
secondary: {
|
secondary: {
|
||||||
main: "#417Ed4",
|
main: "#417Ed4",
|
||||||
dark: "#3e74c1"
|
dark: "#3e74c1",
|
||||||
},
|
},
|
||||||
|
|
||||||
background: {
|
background: {
|
||||||
default: "#111111",
|
default: "#111111",
|
||||||
paper: "#1A1C1E"
|
paper: "#1A1C1E",
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
primary: "#ffffff",
|
primary: "#ffffff",
|
||||||
secondary: "#b3b3b3"
|
secondary: "#b3b3b3",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
MuiCard: {
|
MuiCard: {
|
||||||
styleOverrides: {
|
styleOverrides: {
|
||||||
@ -166,19 +167,19 @@ const darkTheme = createTheme({
|
|||||||
"&:hover": {
|
"&:hover": {
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
boxShadow:
|
boxShadow:
|
||||||
" 0px 3px 4px 0px hsla(0,0%,0%,0.14), 0px 3px 3px -2px hsla(0,0%,0%,0.12), 0px 1px 8px 0px hsla(0,0%,0%,0.2);"
|
" 0px 3px 4px 0px hsla(0,0%,0%,0.14), 0px 3px 3px -2px hsla(0,0%,0%,0.12), 0px 1px 8px 0px hsla(0,0%,0%,0.2);",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
MuiIcon: {
|
MuiIcon: {
|
||||||
defaultProps: {
|
defaultProps: {
|
||||||
style: {
|
style: {
|
||||||
color: "#ffffff"
|
color: "#ffffff",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export { lightTheme, darkTheme };
|
export { lightTheme, darkTheme };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user