3
0
mirror of https://github.com/Qortal/q-tube.git synced 2025-02-11 17:55:51 +00:00

Merge pull request #68 from QortalSeth/main

M4V videos are explicitly stated to be supported on the Publish Form
This commit is contained in:
Qortal Dev 2025-02-10 20:12:30 -07:00 committed by GitHub
commit 3b770069d9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 72 additions and 60 deletions

View File

@ -741,8 +741,8 @@ export const PublishVideo = ({
<Box> <Box>
<CodecTypography> <CodecTypography>
Supported File Containers:{" "} Supported File Containers:{" "}
<span style={{ fontWeight: "bold" }}>MP4</span>, Ogg, WebM, <span style={{ fontWeight: "bold" }}>MP4</span>, M4V, OGG,
WAV WEBM, WAV
</CodecTypography> </CodecTypography>
<CodecTypography> <CodecTypography>
Audio Codecs: <span style={{ fontWeight: "bold" }}>Opus</span> Audio Codecs: <span style={{ fontWeight: "bold" }}>Opus</span>

View File

@ -1,52 +1,52 @@
import { useDispatch, useSelector } from 'react-redux' import { useDispatch, useSelector } from "react-redux";
import { toast, ToastContainer, Zoom, Slide } from 'react-toastify' import { toast, ToastContainer, Zoom, Slide } from "react-toastify";
import { removeNotification } from '../../../state/features/notificationsSlice' import { removeNotification } from "../../../state/features/notificationsSlice";
import 'react-toastify/dist/ReactToastify.css' import "react-toastify/dist/ReactToastify.css";
import { RootState } from '../../../state/store' import { RootState } from "../../../state/store";
const Notification = () => { const Notification = () => {
const dispatch = useDispatch() const dispatch = useDispatch();
const { alertTypes } = useSelector((state: RootState) => state.notifications) const { alertTypes } = useSelector((state: RootState) => state.notifications);
if (alertTypes.alertError) { if (alertTypes.alertError) {
toast.error(`${alertTypes?.alertError}`, { toast.error(`${alertTypes?.alertError}`, {
position: 'bottom-right', position: "bottom-right",
autoClose: 4000, autoClose: 4000,
hideProgressBar: false, hideProgressBar: false,
closeOnClick: true, closeOnClick: true,
pauseOnHover: true, pauseOnHover: true,
draggable: true, draggable: true,
progress: undefined, progress: undefined,
icon: false icon: false,
}) });
dispatch(removeNotification()) dispatch(removeNotification());
} }
if (alertTypes.alertSuccess) { if (alertTypes.alertSuccess) {
toast.success(`✔️ ${alertTypes?.alertSuccess}`, { toast.success(`✔️ ${alertTypes?.alertSuccess}`, {
position: 'bottom-right', position: "bottom-right",
autoClose: 4000, autoClose: 4000,
hideProgressBar: false, hideProgressBar: false,
closeOnClick: true, closeOnClick: true,
pauseOnHover: true, pauseOnHover: true,
draggable: true, draggable: true,
progress: undefined, progress: undefined,
icon: false icon: false,
}) });
dispatch(removeNotification()) dispatch(removeNotification());
} }
if (alertTypes.alertInfo) { if (alertTypes.alertInfo) {
toast.info(`${alertTypes?.alertInfo}`, { toast.info(`${alertTypes?.alertInfo}`, {
position: 'top-right', position: "top-right",
autoClose: 1300, autoClose: 1300,
hideProgressBar: false, hideProgressBar: false,
closeOnClick: true, closeOnClick: true,
pauseOnHover: true, pauseOnHover: true,
draggable: true, draggable: true,
progress: undefined, progress: undefined,
theme: 'light' theme: "light",
}) });
dispatch(removeNotification()) dispatch(removeNotification());
} }
if (alertTypes.alertInfo) { if (alertTypes.alertInfo) {
@ -62,10 +62,10 @@ const Notification = () => {
draggable draggable
pauseOnHover pauseOnHover
theme="light" theme="light"
toastStyle={{ fontSize: '16px' }} toastStyle={{ fontSize: "16px" }}
transition={Slide} transition={Slide}
/> />
) );
} }
return ( return (
@ -80,7 +80,7 @@ const Notification = () => {
draggable draggable
pauseOnHover pauseOnHover
/> />
) );
} };
export default Notification export default Notification;

View File

@ -14,9 +14,15 @@ import {
} from "./VideoControls.tsx"; } from "./VideoControls.tsx";
export const MobileControlsBar = () => { export const MobileControlsBar = () => {
const { handleMenuOpen, handleMenuClose, anchorEl } = useVideoContext(); const { handleMenuOpen, handleMenuClose, anchorEl, controlsHeight } =
useVideoContext();
const controlGroupSX = { display: "flex", gap: "5px", alignItems: "center" }; const controlGroupSX = {
display: "flex",
gap: "5px",
alignItems: "center",
height: controlsHeight,
};
return ( return (
<> <>
@ -36,7 +42,7 @@ export const MobileControlsBar = () => {
color="inherit" color="inherit"
aria-label="menu" aria-label="menu"
onClick={handleMenuOpen} onClick={handleMenuOpen}
sx={{ minWidth: "30px", paddingLeft: "0px" }} sx={{ paddingLeft: "0px", marginRight: "0px" }}
> >
<MoreIcon /> <MoreIcon />
</IconButton> </IconButton>

View File

@ -42,6 +42,7 @@ export const useVideoControlsState = (
(state: RootState) => state.global.videoPlaying (state: RootState) => state.global.videoPlaying
); );
const controlsHeight = "42px";
const minSpeed = 0.25; const minSpeed = 0.25;
const maxSpeed = 4.0; const maxSpeed = 4.0;
const speedChange = 0.25; const speedChange = 0.25;
@ -372,5 +373,6 @@ export const useVideoControlsState = (
isFullscreen, isFullscreen,
toggleObjectFit, toggleObjectFit,
setObjectFit, setObjectFit,
controlsHeight,
}; };
}; };

View File

@ -15,13 +15,17 @@ import {
} from "@mui/icons-material"; } from "@mui/icons-material";
import { useSignalEffect } from "@preact/signals-react"; import { useSignalEffect } from "@preact/signals-react";
const buttonPaddingBig = "6px";
const buttonPaddingSmall = "4px";
export const PlayButton = () => { export const PlayButton = () => {
const { togglePlay, playing } = useVideoContext(); const { togglePlay, playing, isScreenSmall } = useVideoContext();
return ( return (
<CustomFontTooltip title="Pause/Play (Spacebar)" placement="bottom" arrow> <CustomFontTooltip title="Pause/Play (Spacebar)" placement="bottom" arrow>
<IconButton <IconButton
sx={{ sx={{
color: "white", color: "white",
padding: isScreenSmall ? buttonPaddingSmall : buttonPaddingBig,
}} }}
onClick={() => togglePlay()} onClick={() => togglePlay()}
> >
@ -32,12 +36,13 @@ export const PlayButton = () => {
}; };
export const ReloadButton = () => { export const ReloadButton = () => {
const { reloadVideo } = useVideoContext(); const { reloadVideo, isScreenSmall } = useVideoContext();
return ( return (
<CustomFontTooltip title="Reload Video (R)" placement="bottom" arrow> <CustomFontTooltip title="Reload Video (R)" placement="bottom" arrow>
<IconButton <IconButton
sx={{ sx={{
color: "white", color: "white",
padding: isScreenSmall ? buttonPaddingSmall : buttonPaddingBig,
}} }}
onClick={reloadVideo} onClick={reloadVideo}
> >
@ -164,6 +169,7 @@ export const VolumeControl = ({ sliderWidth }: { sliderWidth: string }) => {
</Box> </Box>
); );
}; };
export const PlaybackRate = () => { export const PlaybackRate = () => {
const { playbackRate, increaseSpeed, isScreenSmall } = useVideoContext(); const { playbackRate, increaseSpeed, isScreenSmall } = useVideoContext();
return ( return (
@ -175,22 +181,37 @@ export const PlaybackRate = () => {
<IconButton <IconButton
sx={{ sx={{
color: "white", color: "white",
fontSize: isScreenSmall ? fontSizeExSmall : fontSizeSmall, fontSize: fontSizeSmall,
paddingTop: "0px", padding: isScreenSmall ? buttonPaddingSmall : buttonPaddingBig,
paddingBottom: "0px",
}} }}
onClick={() => increaseSpeed()} onClick={() => increaseSpeed()}
> >
<span style={{ display: "flex", alignItems: "center", height: "40px" }}> {playbackRate}x
{playbackRate}x </IconButton>
</span> </CustomFontTooltip>
);
};
export const ObjectFitButton = () => {
const { toggleObjectFit, isScreenSmall } = useVideoContext();
return (
<CustomFontTooltip title="Toggle Aspect Ratio (O)" placement="bottom" arrow>
<IconButton
sx={{
color: "white",
padding: isScreenSmall ? buttonPaddingSmall : buttonPaddingBig,
}}
onClick={() => toggleObjectFit()}
>
<AspectRatioIcon />
</IconButton> </IconButton>
</CustomFontTooltip> </CustomFontTooltip>
); );
}; };
export const PictureInPictureButton = () => { export const PictureInPictureButton = () => {
const { isFullscreen, toggleRef, togglePictureInPicture } = useVideoContext(); const { isFullscreen, toggleRef, togglePictureInPicture, isScreenSmall } =
useVideoContext();
return ( return (
<> <>
{!isFullscreen.value && ( {!isFullscreen.value && (
@ -202,6 +223,7 @@ export const PictureInPictureButton = () => {
<IconButton <IconButton
sx={{ sx={{
color: "white", color: "white",
padding: isScreenSmall ? buttonPaddingSmall : buttonPaddingBig,
}} }}
ref={toggleRef} ref={toggleRef}
onClick={togglePictureInPicture} onClick={togglePictureInPicture}
@ -214,31 +236,14 @@ export const PictureInPictureButton = () => {
); );
}; };
export const ObjectFitButton = () => {
const { toggleObjectFit } = useVideoContext();
return (
<CustomFontTooltip title="Toggle Aspect Ratio (O)" placement="bottom" arrow>
<IconButton
sx={{
color: "white",
paddingRight: "0px",
}}
onClick={() => toggleObjectFit()}
>
<AspectRatioIcon />
</IconButton>
</CustomFontTooltip>
);
};
export const FullscreenButton = () => { export const FullscreenButton = () => {
const { toggleFullscreen } = useVideoContext(); const { toggleFullscreen, isScreenSmall } = useVideoContext();
return ( return (
<CustomFontTooltip title="Toggle Fullscreen (F)" placement="bottom" arrow> <CustomFontTooltip title="Toggle Fullscreen (F)" placement="bottom" arrow>
<IconButton <IconButton
sx={{ sx={{
color: "white", color: "white",
paddingRight: "0px", padding: isScreenSmall ? buttonPaddingSmall : buttonPaddingBig,
}} }}
onClick={() => toggleFullscreen()} onClick={() => toggleFullscreen()}
> >

View File

@ -15,11 +15,10 @@ import {
} from "./VideoControls.tsx"; } from "./VideoControls.tsx";
export const VideoControlsBar = () => { export const VideoControlsBar = () => {
const { from, canPlay, showControlsFullScreen, isScreenSmall, progress } = const { canPlay, isScreenSmall, controlsHeight } = useVideoContext();
useVideoContext();
const showMobileControls = isScreenSmall && canPlay.value; const showMobileControls = isScreenSmall && canPlay.value;
const controlsHeight = "42px";
const controlGroupSX = { const controlGroupSX = {
display: "flex", display: "flex",
gap: "5px", gap: "5px",