3
0
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:
Qortal Dev 2025-01-02 16:11:45 -07:00
parent 1cfdb7a7bf
commit d4f5c7a8ee
9 changed files with 98 additions and 69 deletions

View File

@ -3,6 +3,7 @@ import { Box, IconButton, Menu, MenuItem } from "@mui/material";
import { useVideoContext } from "./VideoContext.ts";
import {
FullscreenButton,
ObjectFitButton,
PictureInPictureButton,
PlaybackRate,
PlayButton,
@ -55,7 +56,10 @@ export const MobileControlsBar = () => {
>
<MenuItem>
<VolumeButton />
<VolumeSlider />
<VolumeSlider width={"100%"} />
</MenuItem>
<MenuItem>
<ObjectFitButton />
</MenuItem>
<MenuItem>
<PictureInPictureButton />

View File

@ -209,11 +209,11 @@ export const useVideoControlsState = (
}
};
const setStretchVideoSetting = (value: "contain" | "fill") => {
const setObjectFit = (value: "contain" | "fill") => {
videoObjectFit.value = value;
};
const toggleStretchVideoSetting = () => {
const toggleObjectFit = () => {
videoObjectFit.value =
videoObjectFit.value === "contain" ? "fill" : "contain";
};
@ -226,7 +226,7 @@ export const useVideoControlsState = (
switch (e.key) {
case "o":
toggleStretchVideoSetting();
toggleObjectFit();
break;
case Key.Add:
@ -364,6 +364,7 @@ export const useVideoControlsState = (
showControlsFullScreen,
setPlaying,
isFullscreen,
setStretchVideoSetting,
toggleObjectFit,
setObjectFit,
};
};

View File

@ -3,6 +3,7 @@ import { fontSizeExSmall, fontSizeSmall } from "../../../../constants/Misc.ts";
import { CustomFontTooltip } from "../../../../utils/CustomFontTooltip.tsx";
import { formatTime } from "../../../../utils/numberFunctions.ts";
import { useVideoContext } from "./VideoContext.ts";
import AspectRatioIcon from "@mui/icons-material/AspectRatio";
import {
Fullscreen,
Pause,
@ -48,7 +49,6 @@ export const ReloadButton = () => {
export const ProgressSlider = () => {
const { progress, onProgressChange, videoRef } = useVideoContext();
const sliderThumbSize = "16px";
return (
<Slider
value={progress.value}
@ -65,9 +65,10 @@ export const ProgressSlider = () => {
"& .MuiSlider-thumb": {
backgroundColor: "#fff",
width: sliderThumbSize,
height: sliderThumbSize,
width: "16px",
height: "16px",
},
"& .MuiSlider-thumb::after": { width: "20px", height: "20px" },
"& .MuiSlider-rail": { opacity: 0.5 },
}}
/>
@ -112,6 +113,7 @@ export const VolumeButton = () => {
<IconButton
sx={{
color: "white",
marginRight: "10px",
}}
onClick={toggleMute}
>
@ -121,7 +123,7 @@ export const VolumeButton = () => {
);
};
export const VolumeSlider = () => {
export const VolumeSlider = ({ width }: { width: string }) => {
const { volume, onVolumeChange } = useVideoContext();
return (
<Slider
@ -131,7 +133,9 @@ export const VolumeSlider = () => {
max={1}
step={0.01}
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 = () => {
const { toggleFullscreen } = useVideoContext();
return (

View File

@ -4,6 +4,7 @@ import { MobileControlsBar } from "./MobileControlsBar.tsx";
import { useVideoContext } from "./VideoContext.ts";
import {
FullscreenButton,
ObjectFitButton,
PictureInPictureButton,
PlaybackRate,
PlayButton,
@ -46,12 +47,13 @@ export const VideoControlsBar = () => {
<ProgressSlider />
<VolumeButton />
<VolumeSlider />
<VolumeSlider width={"100px"} />
<VideoTime />
</Box>
<Box sx={controlGroupSX}>
<PlaybackRate />
<ObjectFitButton />
<PictureInPictureButton />
<FullscreenButton />
</Box>

View File

@ -103,7 +103,7 @@ export const VideoPlayer = forwardRef<videoRefType, VideoPlayerProps>(
preload="metadata"
style={{
...videoStyles?.video,
objectFit: isFullscreen ? "fill" : videoObjectFit.value,
objectFit: videoObjectFit.value,
height:
isFullscreen.value && showControlsFullScreen.value
? "calc(100vh - 40px)"

View File

@ -67,7 +67,7 @@
height: 100%;
}
a:link { color: #8AB4F8}
.test-grid {
display: grid;

View File

@ -174,18 +174,17 @@ export const VideoContent = () => {
cursor: !descriptionHeight
? "default"
: isExpandedDescription
? "default"
: "pointer",
? "default"
: "pointer",
position: "relative",
marginBottom: "30px",
}}
className={
!descriptionHeight
? ""
: isExpandedDescription
? ""
: "hover-click"
? ""
: "hover-click"
}
>
{descriptionHeight && !isExpandedDescription && (
@ -210,8 +209,8 @@ export const VideoContent = () => {
height: !descriptionHeight
? "auto"
: isExpandedDescription
? "auto"
: "200px",
? "auto"
: "200px",
overflow: "hidden",
}}
>

View File

@ -110,6 +110,7 @@ export const NameContainer = styled(Box)(({ theme }) => ({
alignItems: "center",
gap: "10px",
marginBottom: "2px",
width: "100%",
}));
export const VideoManagerRow = styled(Box)(({ theme }) => ({

View File

@ -11,38 +11,38 @@ const commonThemeOptions = {
"Oxygen",
"Catamaran",
"Cairo",
"Arial"
"Arial",
].join(","),
h1: {
fontSize: "2rem",
fontWeight: 600
fontWeight: 600,
},
h2: {
fontSize: "1.75rem",
fontWeight: 500
fontWeight: 500,
},
h3: {
fontSize: "1.5rem",
fontWeight: 500
fontWeight: 500,
},
h4: {
fontSize: "1.25rem",
fontWeight: 500
fontWeight: 500,
},
h5: {
fontSize: "1rem",
fontWeight: 500
fontWeight: 500,
},
h6: {
fontSize: "0.875rem",
fontWeight: 500
fontWeight: 500,
},
body1: {
fontSize: "23px",
fontFamily: "Raleway",
fontWeight: 400,
lineHeight: 1.5,
letterSpacing: "0.5px"
letterSpacing: "0.5px",
},
body2: {
@ -50,12 +50,12 @@ const commonThemeOptions = {
fontFamily: "Raleway, Arial",
fontWeight: 400,
lineHeight: 1.4,
letterSpacing: "0.2px"
}
letterSpacing: "0.2px",
},
},
spacing: 8,
shape: {
borderRadius: 4
borderRadius: 4,
},
breakpoints: {
values: {
@ -63,8 +63,8 @@ const commonThemeOptions = {
sm: 600,
md: 900,
lg: 1200,
xl: 1536
}
xl: 1536,
},
},
components: {
MuiButton: {
@ -73,16 +73,16 @@ const commonThemeOptions = {
backgroundColor: "inherit",
transition: "filter 0.3s ease-in-out",
"&:hover": {
filter: "brightness(1.1)"
}
}
filter: "brightness(1.1)",
},
},
},
defaultProps: {
disableElevation: true,
disableRipple: true
}
}
}
disableRipple: true,
},
},
},
};
const lightTheme = createTheme({
@ -92,21 +92,22 @@ const lightTheme = createTheme({
primary: {
main: "#ffffff",
dark: "#F5F5F5",
light: "#FCFCFC"
light: "#FCFCFC",
},
secondary: {
main: "#417Ed4",
dark: "#3e74c1"
dark: "#3e74c1",
},
background: {
default: "#fcfcfc",
paper: "#F5F5F5"
paper: "#F5F5F5",
},
text: {
primary: "#000000",
secondary: "#525252"
}
secondary: "#525252",
},
},
components: {
MuiCard: {
styleOverrides: {
@ -118,19 +119,19 @@ const lightTheme = createTheme({
"&:hover": {
cursor: "pointer",
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: {
defaultProps: {
style: {
color: "#000000"
}
}
}
}
color: "#000000",
},
},
},
},
});
const darkTheme = createTheme({
@ -140,22 +141,22 @@ const darkTheme = createTheme({
primary: {
main: "#2e3d60",
dark: "#1a2744",
light: "#353535"
light: "#353535",
},
secondary: {
main: "#417Ed4",
dark: "#3e74c1"
dark: "#3e74c1",
},
background: {
default: "#111111",
paper: "#1A1C1E"
paper: "#1A1C1E",
},
text: {
primary: "#ffffff",
secondary: "#b3b3b3"
}
secondary: "#b3b3b3",
},
},
components: {
MuiCard: {
styleOverrides: {
@ -166,19 +167,19 @@ const darkTheme = createTheme({
"&:hover": {
cursor: "pointer",
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: {
defaultProps: {
style: {
color: "#ffffff"
}
}
}
}
color: "#ffffff",
},
},
},
},
});
export { lightTheme, darkTheme };