mirror of
https://github.com/Qortal/q-tube.git
synced 2025-02-11 17:55:51 +00:00
Merge pull request #64 from QortalSeth/main
Bugfixes on PlaylistContent.tsx
This commit is contained in:
commit
d9f04030d5
@ -1,29 +1,38 @@
|
|||||||
import React from "react";
|
|
||||||
import { smallScreenSizeString } from "../../constants/Misc.ts";
|
|
||||||
import { CardContentContainerComment } from "../common/Comments/Comments-styles";
|
|
||||||
import {
|
import {
|
||||||
CrowdfundSubTitle,
|
Box,
|
||||||
CrowdfundSubTitleRow,
|
SxProps,
|
||||||
} from "../Publish/PublishVideo/PublishVideo-styles.tsx";
|
Theme,
|
||||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
Typography,
|
||||||
import { useNavigate } from "react-router-dom";
|
useMediaQuery,
|
||||||
|
useTheme,
|
||||||
|
} from "@mui/material";
|
||||||
|
import React from "react";
|
||||||
|
import { CardContentContainerComment } from "../common/Comments/Comments-styles";
|
||||||
|
|
||||||
|
interface PlaylistsProps {
|
||||||
|
playlistData;
|
||||||
|
currentVideoIdentifier;
|
||||||
|
onClick;
|
||||||
|
sx?: SxProps<Theme>;
|
||||||
|
}
|
||||||
export const Playlists = ({
|
export const Playlists = ({
|
||||||
playlistData,
|
playlistData,
|
||||||
currentVideoIdentifier,
|
currentVideoIdentifier,
|
||||||
onClick,
|
onClick,
|
||||||
}) => {
|
sx,
|
||||||
|
}: PlaylistsProps) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isScreenSmall = !useMediaQuery(`(min-width:700px)`);
|
const isScreenSmall = !useMediaQuery(`(min-width:700px)`);
|
||||||
const videoPlayerHeight = "33.75vw"; // This is videoplayer width * 9/16 (inverse of aspect ratio)
|
const PlaylistsHeight = "36vw"; // This is videoplayer width * 9/16 (inverse of aspect ratio)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
height: isScreenSmall ? "200px" : PlaylistsHeight,
|
||||||
|
...sx,
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
width: "100%",
|
|
||||||
height: isScreenSmall ? "200px" : videoPlayerHeight,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CardContentContainerComment
|
<CardContentContainerComment
|
||||||
|
@ -28,7 +28,7 @@ const ResponsiveImage: React.FC<ResponsiveImageProps> = ({
|
|||||||
}, endTimeMilliSeconds);
|
}, endTimeMilliSeconds);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => endLoading(30), [endLoading]);
|
useEffect(() => endLoading(60), [endLoading]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
|
@ -30,6 +30,7 @@ export const useVideoControlsState = (
|
|||||||
videoObjectFit,
|
videoObjectFit,
|
||||||
canPlay,
|
canPlay,
|
||||||
containerRef,
|
containerRef,
|
||||||
|
alwaysShowControls,
|
||||||
} = videoPlayerState;
|
} = videoPlayerState;
|
||||||
const { identifier, autoPlay } = props;
|
const { identifier, autoPlay } = props;
|
||||||
|
|
||||||
@ -218,6 +219,9 @@ export const useVideoControlsState = (
|
|||||||
videoObjectFit.value === "contain" ? "fill" : "contain";
|
videoObjectFit.value === "contain" ? "fill" : "contain";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const toggleAlwaysShowControls = () => {
|
||||||
|
alwaysShowControls.value = !alwaysShowControls.value;
|
||||||
|
};
|
||||||
const keyboardShortcuts = (
|
const keyboardShortcuts = (
|
||||||
e: KeyboardEvent | React.KeyboardEvent<HTMLDivElement>
|
e: KeyboardEvent | React.KeyboardEvent<HTMLDivElement>
|
||||||
) => {
|
) => {
|
||||||
@ -228,7 +232,9 @@ export const useVideoControlsState = (
|
|||||||
case "o":
|
case "o":
|
||||||
toggleObjectFit();
|
toggleObjectFit();
|
||||||
break;
|
break;
|
||||||
|
case "c":
|
||||||
|
toggleAlwaysShowControls();
|
||||||
|
break;
|
||||||
case Key.Add:
|
case Key.Add:
|
||||||
increaseSpeed(false);
|
increaseSpeed(false);
|
||||||
break;
|
break;
|
||||||
|
@ -16,6 +16,7 @@ import { useDispatch, useSelector } from "react-redux";
|
|||||||
import { smallVideoSize } from "../../../constants/Misc.ts";
|
import { smallVideoSize } from "../../../constants/Misc.ts";
|
||||||
import { setVideoPlaying } from "../../../state/features/globalSlice.ts";
|
import { setVideoPlaying } from "../../../state/features/globalSlice.ts";
|
||||||
import {
|
import {
|
||||||
|
setAlwaysShowControls,
|
||||||
setIsMuted,
|
setIsMuted,
|
||||||
setMutedVolumeSetting,
|
setMutedVolumeSetting,
|
||||||
setReduxPlaybackRate,
|
setReduxPlaybackRate,
|
||||||
@ -44,6 +45,9 @@ export const useVideoPlayerState = (props: VideoPlayerProps, ref: any) => {
|
|||||||
const videoObjectFit = useSignal<StretchVideoType>(
|
const videoObjectFit = useSignal<StretchVideoType>(
|
||||||
persistSelector.stretchVideoSetting
|
persistSelector.stretchVideoSetting
|
||||||
);
|
);
|
||||||
|
const alwaysShowControls = useSignal<boolean>(
|
||||||
|
persistSelector.alwaysShowControls
|
||||||
|
);
|
||||||
|
|
||||||
useSignalEffect(() => {
|
useSignalEffect(() => {
|
||||||
dispatch(setIsMuted(isMuted.value));
|
dispatch(setIsMuted(isMuted.value));
|
||||||
@ -63,6 +67,9 @@ export const useVideoPlayerState = (props: VideoPlayerProps, ref: any) => {
|
|||||||
useSignalEffect(() => {
|
useSignalEffect(() => {
|
||||||
dispatch(setStretchVideoSetting(videoObjectFit.value));
|
dispatch(setStretchVideoSetting(videoObjectFit.value));
|
||||||
});
|
});
|
||||||
|
useSignalEffect(() => {
|
||||||
|
dispatch(setAlwaysShowControls(alwaysShowControls.value));
|
||||||
|
});
|
||||||
|
|
||||||
const anchorEl = useSignal(null);
|
const anchorEl = useSignal(null);
|
||||||
|
|
||||||
@ -312,5 +319,6 @@ export const useVideoPlayerState = (props: VideoPlayerProps, ref: any) => {
|
|||||||
anchorEl,
|
anchorEl,
|
||||||
videoObjectFit,
|
videoObjectFit,
|
||||||
isScreenSmall,
|
isScreenSmall,
|
||||||
|
alwaysShowControls,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -56,11 +56,13 @@ export const VideoPlayer = forwardRef<videoRefType, VideoPlayerProps>(
|
|||||||
videoObjectFit,
|
videoObjectFit,
|
||||||
showControlsFullScreen,
|
showControlsFullScreen,
|
||||||
isFullscreen,
|
isFullscreen,
|
||||||
|
alwaysShowControls,
|
||||||
} = contextData;
|
} = contextData;
|
||||||
|
|
||||||
const showControls =
|
const showControls =
|
||||||
!isFullscreen.value ||
|
!isFullscreen.value ||
|
||||||
(isFullscreen.value && showControlsFullScreen.value);
|
(isFullscreen.value && showControlsFullScreen.value) ||
|
||||||
|
alwaysShowControls.value;
|
||||||
|
|
||||||
const idleTime = 5000; // Time in milliseconds
|
const idleTime = 5000; // Time in milliseconds
|
||||||
useIdleTimeout({
|
useIdleTimeout({
|
||||||
@ -76,6 +78,10 @@ export const VideoPlayer = forwardRef<videoRefType, VideoPlayerProps>(
|
|||||||
onKeyDown={keyboardShortcuts}
|
onKeyDown={keyboardShortcuts}
|
||||||
style={{
|
style={{
|
||||||
padding: from === "create" ? "8px" : 0,
|
padding: from === "create" ? "8px" : 0,
|
||||||
|
cursor:
|
||||||
|
!showControlsFullScreen.value && isFullscreen.value
|
||||||
|
? "none"
|
||||||
|
: "auto",
|
||||||
...videoStyles?.videoContainer,
|
...videoStyles?.videoContainer,
|
||||||
}}
|
}}
|
||||||
onMouseEnter={e => {
|
onMouseEnter={e => {
|
||||||
@ -105,7 +111,7 @@ export const VideoPlayer = forwardRef<videoRefType, VideoPlayerProps>(
|
|||||||
...videoStyles?.video,
|
...videoStyles?.video,
|
||||||
objectFit: videoObjectFit.value,
|
objectFit: videoObjectFit.value,
|
||||||
height:
|
height:
|
||||||
isFullscreen.value && showControlsFullScreen.value
|
isFullscreen.value && showControls
|
||||||
? "calc(100vh - 40px)"
|
? "calc(100vh - 40px)"
|
||||||
: "100%",
|
: "100%",
|
||||||
}}
|
}}
|
||||||
|
@ -34,11 +34,13 @@ export const categories = [
|
|||||||
{ id: 19, name: "Nature & Environment" },
|
{ id: 19, name: "Nature & Environment" },
|
||||||
{ id: 20, name: "Business & Finance" },
|
{ id: 20, name: "Business & Finance" },
|
||||||
{ id: 21, name: "Personal Development" },
|
{ id: 21, name: "Personal Development" },
|
||||||
{ id: 22, name: "Other" },
|
{ id: 22, name: "Religion" },
|
||||||
{ id: 23, name: "History" },
|
{ id: 23, name: "History" },
|
||||||
{ id: 24, name: "Anime" },
|
{ id: 24, name: "Anime" },
|
||||||
{ id: 25, name: "Cartoons" },
|
{ id: 25, name: "Cartoons" },
|
||||||
{ id: 26, name: "Qortal" },
|
{ id: 26, name: "Qortal" },
|
||||||
|
{ id: 27, name: "Paranormal" },
|
||||||
|
{ id: 28, name: "Spirituality" },
|
||||||
{ id: 99, name: "Other" },
|
{ id: 99, name: "Other" },
|
||||||
].sort(sortCategory);
|
].sort(sortCategory);
|
||||||
|
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
import { Box, Grid, Typography, useMediaQuery } from "@mui/material";
|
import { Box, SxProps, Theme, Typography, useMediaQuery } from "@mui/material";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { CommentSection } from "../../../components/common/Comments/CommentSection.tsx";
|
import { CommentSection } from "../../../components/common/Comments/CommentSection.tsx";
|
||||||
import { SuperLikesSection } from "../../../components/common/SuperLikesList/SuperLikesSection.tsx";
|
import { SuperLikesSection } from "../../../components/common/SuperLikesList/SuperLikesSection.tsx";
|
||||||
import { DisplayHtml } from "../../../components/common/TextEditor/DisplayHtml.tsx";
|
import { DisplayHtml } from "../../../components/common/TextEditor/DisplayHtml.tsx";
|
||||||
import { VideoPlayer } from "../../../components/common/VideoPlayer/VideoPlayer.tsx";
|
import { VideoPlayer } from "../../../components/common/VideoPlayer/VideoPlayer.tsx";
|
||||||
import { Playlists } from "../../../components/Playlists/Playlists.tsx";
|
import { Playlists } from "../../../components/Playlists/Playlists.tsx";
|
||||||
import {
|
import { fontSizeSmall, minFileSize } from "../../../constants/Misc.ts";
|
||||||
fontSizeSmall,
|
|
||||||
minFileSize,
|
|
||||||
smallScreenSizeString,
|
|
||||||
} from "../../../constants/Misc.ts";
|
|
||||||
import { formatBytes } from "../../../utils/numberFunctions.ts";
|
import { formatBytes } from "../../../utils/numberFunctions.ts";
|
||||||
import { formatDate } from "../../../utils/time.ts";
|
import { formatDate } from "../../../utils/time.ts";
|
||||||
import { VideoActionsBar } from "../VideoContent/VideoActionsBar.tsx";
|
import { VideoActionsBar } from "../VideoContent/VideoActionsBar.tsx";
|
||||||
@ -46,7 +42,11 @@ export const PlaylistContent = () => {
|
|||||||
loadingSuperLikes,
|
loadingSuperLikes,
|
||||||
} = usePlaylistContentState();
|
} = usePlaylistContentState();
|
||||||
|
|
||||||
const isScreenSmall = !useMediaQuery(`(min-width:700px)`);
|
const isScreenSmall = !useMediaQuery(`(min-width:950px)`);
|
||||||
|
|
||||||
|
const playlistsSX: SxProps<Theme> = isScreenSmall
|
||||||
|
? { width: "100%", marginTop: "10px" }
|
||||||
|
: { width: "35%", position: "absolute", right: "20px" };
|
||||||
|
|
||||||
return videoData && videoData?.videos?.length === 0 ? (
|
return videoData && videoData?.videos?.length === 0 ? (
|
||||||
<Box
|
<Box
|
||||||
@ -70,41 +70,36 @@ export const PlaylistContent = () => {
|
|||||||
>
|
>
|
||||||
<VideoPlayerContainer
|
<VideoPlayerContainer
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: isScreenSmall ? "100%" : "60%",
|
||||||
display: "grid",
|
alignSelf: "start",
|
||||||
gridTemplateColumns: isScreenSmall ? "1fr" : "60vw auto",
|
paddingRight: isScreenSmall ? "10px" : "0px",
|
||||||
gap: "20px",
|
marginBottom: "20px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{videoReference && (
|
{videoReference && (
|
||||||
<Box
|
<VideoPlayer
|
||||||
sx={{
|
name={videoReference?.name}
|
||||||
aspectRatio: "16/9",
|
service={videoReference?.service}
|
||||||
|
identifier={videoReference?.identifier}
|
||||||
|
user={channelName}
|
||||||
|
jsonId={id}
|
||||||
|
poster={videoCover || ""}
|
||||||
|
nextVideo={nextVideo}
|
||||||
|
onEnd={onEndVideo}
|
||||||
|
autoPlay={doAutoPlay}
|
||||||
|
ref={containerRef}
|
||||||
|
videoStyles={{
|
||||||
|
video: { aspectRatio: "16 / 9" },
|
||||||
}}
|
}}
|
||||||
>
|
duration={videoData?.duration}
|
||||||
<VideoPlayer
|
/>
|
||||||
name={videoReference?.name}
|
|
||||||
service={videoReference?.service}
|
|
||||||
identifier={videoReference?.identifier}
|
|
||||||
user={channelName}
|
|
||||||
jsonId={id}
|
|
||||||
poster={videoCover || ""}
|
|
||||||
nextVideo={nextVideo}
|
|
||||||
onEnd={onEndVideo}
|
|
||||||
autoPlay={doAutoPlay}
|
|
||||||
ref={containerRef}
|
|
||||||
videoStyles={{
|
|
||||||
videoContainer: { aspectRatio: "16 / 9" },
|
|
||||||
video: { aspectRatio: "16 / 9" },
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
)}
|
||||||
{playlistData && (
|
{playlistData && (
|
||||||
<Playlists
|
<Playlists
|
||||||
playlistData={playlistData}
|
playlistData={playlistData}
|
||||||
currentVideoIdentifier={videoData?.id}
|
currentVideoIdentifier={videoData?.id}
|
||||||
onClick={getVideoData}
|
onClick={getVideoData}
|
||||||
|
sx={playlistsSX}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</VideoPlayerContainer>
|
</VideoPlayerContainer>
|
||||||
@ -179,8 +174,8 @@ export const PlaylistContent = () => {
|
|||||||
cursor: !descriptionHeight
|
cursor: !descriptionHeight
|
||||||
? "default"
|
? "default"
|
||||||
: isExpandedDescription
|
: isExpandedDescription
|
||||||
? "default"
|
? "default"
|
||||||
: "pointer",
|
: "pointer",
|
||||||
}}
|
}}
|
||||||
className={
|
className={
|
||||||
!descriptionHeight ? "" : isExpandedDescription ? "" : "hover-click"
|
!descriptionHeight ? "" : isExpandedDescription ? "" : "hover-click"
|
||||||
@ -208,8 +203,8 @@ export const PlaylistContent = () => {
|
|||||||
height: !descriptionHeight
|
height: !descriptionHeight
|
||||||
? "auto"
|
? "auto"
|
||||||
: isExpandedDescription
|
: isExpandedDescription
|
||||||
? "auto"
|
? "auto"
|
||||||
: `${descriptionHeight}px`,
|
: `${descriptionHeight}px`,
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -8,12 +8,9 @@ import { DisplayHtml } from "../../../components/common/TextEditor/DisplayHtml.t
|
|||||||
import { VideoPlayer } from "../../../components/common/VideoPlayer/VideoPlayer.tsx";
|
import { VideoPlayer } from "../../../components/common/VideoPlayer/VideoPlayer.tsx";
|
||||||
import {
|
import {
|
||||||
fontSizeSmall,
|
fontSizeSmall,
|
||||||
largeScreenSizeString,
|
|
||||||
minFileSize,
|
minFileSize,
|
||||||
smallScreenSizeString,
|
|
||||||
smallVideoSize,
|
smallVideoSize,
|
||||||
} from "../../../constants/Misc.ts";
|
} from "../../../constants/Misc.ts";
|
||||||
import { useIsMobile } from "../../../hooks/useIsMobile.ts";
|
|
||||||
import { formatBytes } from "../../../utils/numberFunctions.ts";
|
import { formatBytes } from "../../../utils/numberFunctions.ts";
|
||||||
import { formatDate } from "../../../utils/time.ts";
|
import { formatDate } from "../../../utils/time.ts";
|
||||||
import { VideoActionsBar } from "./VideoActionsBar.tsx";
|
import { VideoActionsBar } from "./VideoActionsBar.tsx";
|
||||||
@ -25,7 +22,6 @@ import {
|
|||||||
VideoPlayerContainer,
|
VideoPlayerContainer,
|
||||||
VideoTitle,
|
VideoTitle,
|
||||||
} from "./VideoContent-styles.tsx";
|
} from "./VideoContent-styles.tsx";
|
||||||
import { useSignal } from "@preact/signals-react";
|
|
||||||
|
|
||||||
export const VideoContent = () => {
|
export const VideoContent = () => {
|
||||||
const {
|
const {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import BlockIcon from "@mui/icons-material/Block";
|
import BlockIcon from "@mui/icons-material/Block";
|
||||||
import EditIcon from "@mui/icons-material/Edit";
|
import EditIcon from "@mui/icons-material/Edit";
|
||||||
import { Avatar, Box, Tooltip, Typography, useTheme } from "@mui/material";
|
import { Avatar, Box, Tooltip, Typography, useTheme } from "@mui/material";
|
||||||
import React, { useMemo, useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { PlaylistSVG } from "../../../assets/svgs/PlaylistSVG.tsx";
|
import { PlaylistSVG } from "../../../assets/svgs/PlaylistSVG.tsx";
|
||||||
|
@ -21,6 +21,7 @@ interface settingsState {
|
|||||||
volume: number;
|
volume: number;
|
||||||
mutedVolume: number;
|
mutedVolume: number;
|
||||||
isMuted: boolean;
|
isMuted: boolean;
|
||||||
|
alwaysShowControls: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: settingsState = {
|
const initialState: settingsState = {
|
||||||
@ -34,6 +35,7 @@ const initialState: settingsState = {
|
|||||||
volume: 0.5,
|
volume: 0.5,
|
||||||
mutedVolume: 0,
|
mutedVolume: 0,
|
||||||
isMuted: false,
|
isMuted: false,
|
||||||
|
alwaysShowControls: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const persistSlice = createSlice({
|
export const persistSlice = createSlice({
|
||||||
@ -87,6 +89,9 @@ export const persistSlice = createSlice({
|
|||||||
setIsMuted: (state, action: PayloadAction<boolean>) => {
|
setIsMuted: (state, action: PayloadAction<boolean>) => {
|
||||||
state.isMuted = action.payload;
|
state.isMuted = action.payload;
|
||||||
},
|
},
|
||||||
|
setAlwaysShowControls: (state, action: PayloadAction<boolean>) => {
|
||||||
|
state.alwaysShowControls = action.payload;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -101,6 +106,7 @@ export const {
|
|||||||
setVolumeSetting,
|
setVolumeSetting,
|
||||||
setMutedVolumeSetting,
|
setMutedVolumeSetting,
|
||||||
setIsMuted,
|
setIsMuted,
|
||||||
|
setAlwaysShowControls,
|
||||||
} = persistSlice.actions;
|
} = persistSlice.actions;
|
||||||
|
|
||||||
export default persistSlice.reducer;
|
export default persistSlice.reducer;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user