mirror of
https://github.com/Qortal/q-tube.git
synced 2025-02-11 17:55:51 +00:00
Merge pull request #46 from QortalSeth/main
Videoplayer data is stored in a context.
This commit is contained in:
commit
4b0953666d
@ -2,23 +2,12 @@ import { Box, CircularProgress, Typography } from "@mui/material";
|
||||
import { setVideoPlaying } from "../../../../state/features/globalSlice.ts";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { PlayArrow } from "@mui/icons-material";
|
||||
import { useVideoContext } from "./VideoContext.ts";
|
||||
|
||||
export const LoadingVideo = () => {
|
||||
const { isLoading, resourceStatus, src, startPlay, from, togglePlay } =
|
||||
useVideoContext();
|
||||
|
||||
export interface LoadingVideoProps {
|
||||
isLoading: boolean;
|
||||
resourceStatus: any;
|
||||
src: any;
|
||||
startPlay: boolean;
|
||||
from: any;
|
||||
togglePlay: () => void;
|
||||
}
|
||||
export const LoadingVideo = ({
|
||||
isLoading,
|
||||
resourceStatus,
|
||||
src,
|
||||
startPlay,
|
||||
from,
|
||||
togglePlay,
|
||||
}: LoadingVideoProps) => {
|
||||
const getDownloadProgress = (current: number, total: number) => {
|
||||
const progress = (current / total) * 100;
|
||||
return Number.isNaN(progress) ? "" : progress.toFixed(0) + "%";
|
||||
@ -27,7 +16,7 @@ export const LoadingVideo = ({
|
||||
const dispatch = useDispatch();
|
||||
return (
|
||||
<>
|
||||
{isLoading && (
|
||||
{isLoading.value && (
|
||||
<Box
|
||||
position="absolute"
|
||||
top={0}
|
||||
@ -87,7 +76,7 @@ export const LoadingVideo = ({
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
{((!src && !isLoading) || !startPlay) && (
|
||||
{((!src && !isLoading.value) || !startPlay.value) && (
|
||||
<Box
|
||||
position="absolute"
|
||||
top={0}
|
||||
|
107
src/components/common/VideoPlayer/Components/MobileControls.tsx
Normal file
107
src/components/common/VideoPlayer/Components/MobileControls.tsx
Normal file
@ -0,0 +1,107 @@
|
||||
import {
|
||||
Fullscreen,
|
||||
MoreVert as MoreIcon,
|
||||
Pause,
|
||||
PictureInPicture,
|
||||
PlayArrow,
|
||||
Refresh,
|
||||
VolumeUp,
|
||||
} from "@mui/icons-material";
|
||||
import { IconButton, Menu, MenuItem, Slider, Typography } from "@mui/material";
|
||||
import { useVideoContext } from "./VideoContext.ts";
|
||||
|
||||
export const MobileControls = () => {
|
||||
const {
|
||||
togglePlay,
|
||||
reloadVideo,
|
||||
onProgressChange,
|
||||
videoRef,
|
||||
handleMenuOpen,
|
||||
handleMenuClose,
|
||||
onVolumeChange,
|
||||
increaseSpeed,
|
||||
togglePictureInPicture,
|
||||
toggleFullscreen,
|
||||
playing,
|
||||
progress,
|
||||
anchorEl,
|
||||
volume,
|
||||
playbackRate,
|
||||
} = useVideoContext();
|
||||
|
||||
return (
|
||||
<>
|
||||
<IconButton
|
||||
sx={{
|
||||
color: "rgba(255, 255, 255, 0.7)",
|
||||
}}
|
||||
onClick={() => togglePlay()}
|
||||
>
|
||||
{playing.value ? <Pause /> : <PlayArrow />}
|
||||
</IconButton>
|
||||
<IconButton
|
||||
sx={{
|
||||
color: "rgba(255, 255, 255, 0.7)",
|
||||
marginLeft: "15px",
|
||||
}}
|
||||
onClick={reloadVideo}
|
||||
>
|
||||
<Refresh />
|
||||
</IconButton>
|
||||
<Slider
|
||||
value={progress.value}
|
||||
onChange={onProgressChange}
|
||||
min={0}
|
||||
max={videoRef.current?.duration || 100}
|
||||
sx={{ flexGrow: 1, mx: 2 }}
|
||||
/>
|
||||
<IconButton
|
||||
edge="end"
|
||||
color="inherit"
|
||||
aria-label="menu"
|
||||
onClick={handleMenuOpen}
|
||||
>
|
||||
<MoreIcon />
|
||||
</IconButton>
|
||||
<Menu
|
||||
id="simple-menu"
|
||||
anchorEl={anchorEl.value}
|
||||
keepMounted
|
||||
open={Boolean(anchorEl.value)}
|
||||
onClose={handleMenuClose}
|
||||
PaperProps={{
|
||||
style: {
|
||||
width: "250px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<MenuItem>
|
||||
<VolumeUp />
|
||||
<Slider
|
||||
value={volume.value}
|
||||
onChange={onVolumeChange}
|
||||
min={0}
|
||||
max={1}
|
||||
step={0.01}
|
||||
/>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => increaseSpeed()}>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "rgba(255, 255, 255, 0.7)",
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
Speed: {playbackRate}x
|
||||
</Typography>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={togglePictureInPicture}>
|
||||
<PictureInPicture />
|
||||
</MenuItem>
|
||||
<MenuItem onClick={toggleFullscreen}>
|
||||
<Fullscreen />
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</>
|
||||
);
|
||||
};
|
28
src/components/common/VideoPlayer/Components/VideoContext.ts
Normal file
28
src/components/common/VideoPlayer/Components/VideoContext.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { createContext, useContext } from "react";
|
||||
import { useVideoPlayerState } from "../VideoPlayer-State.ts";
|
||||
import { VideoPlayerProps } from "../VideoPlayer.tsx";
|
||||
import { useVideoControlsState } from "./VideoControls-State.ts";
|
||||
|
||||
export type VideoContextType = VideoPlayerProps &
|
||||
ReturnType<typeof useVideoPlayerState> &
|
||||
ReturnType<typeof useVideoControlsState>;
|
||||
|
||||
export const VideoContext = createContext<VideoContextType | undefined>(
|
||||
undefined
|
||||
);
|
||||
export const useContextData = (props, ref) => {
|
||||
const videoState = useVideoPlayerState(props, ref);
|
||||
const controlState = useVideoControlsState(props, videoState);
|
||||
|
||||
return {
|
||||
...props,
|
||||
...videoState,
|
||||
...controlState,
|
||||
};
|
||||
};
|
||||
|
||||
export const useVideoContext = () => {
|
||||
const context = useContext<VideoContextType>(VideoContext);
|
||||
if (!context) throw new Error("VideoContext is NULL");
|
||||
return context;
|
||||
};
|
@ -1,3 +1,9 @@
|
||||
import { useSignal } from "@preact/signals-react";
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { useSelector } from "react-redux";
|
||||
import { Key } from "ts-key-enum";
|
||||
import { setVideoPlaying } from "../../../../state/features/globalSlice.ts";
|
||||
import {
|
||||
@ -6,36 +12,33 @@ import {
|
||||
setVolumeSetting,
|
||||
} from "../../../../state/features/persistSlice.ts";
|
||||
import { RootState, store } from "../../../../state/store.ts";
|
||||
import {
|
||||
canPlay,
|
||||
isLoading,
|
||||
isMuted,
|
||||
mutedVolume,
|
||||
playbackRate,
|
||||
playing,
|
||||
progress,
|
||||
startPlay,
|
||||
useVideoPlayerState,
|
||||
videoObjectFit,
|
||||
volume,
|
||||
} from "../VideoPlayer-State.ts";
|
||||
import { useEffect } from "react";
|
||||
import { signal, useSignal } from "@preact/signals-react";
|
||||
import { useSignalEffect, useSignals } from "@preact/signals-react/runtime";
|
||||
import { useVideoPlayerState } from "../VideoPlayer-State.ts";
|
||||
import { VideoPlayerProps } from "../VideoPlayer.tsx";
|
||||
import ReactDOM from "react-dom";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
export const showControlsFullScreen = signal(true);
|
||||
|
||||
export const useVideoControlsState = (
|
||||
props: VideoPlayerProps,
|
||||
videoRef: React.MutableRefObject<HTMLVideoElement>,
|
||||
videoPlayerState: ReturnType<typeof useVideoPlayerState>
|
||||
) => {
|
||||
useSignals();
|
||||
const { src, getSrc, resourceStatus } = videoPlayerState;
|
||||
const {
|
||||
src,
|
||||
getSrc,
|
||||
resourceStatus,
|
||||
videoRef,
|
||||
playbackRate,
|
||||
playing,
|
||||
isLoading,
|
||||
startPlay,
|
||||
volume,
|
||||
isMuted,
|
||||
mutedVolume,
|
||||
progress,
|
||||
videoObjectFit,
|
||||
canPlay,
|
||||
} = videoPlayerState;
|
||||
const { identifier, autoPlay } = props;
|
||||
|
||||
const showControlsFullScreen = useSignal(true);
|
||||
const persistSelector = store.getState().persist;
|
||||
|
||||
const videoPlaying = useSelector(
|
||||
@ -146,8 +149,19 @@ export const useVideoControlsState = (
|
||||
togglePlay();
|
||||
};
|
||||
|
||||
const handleCanPlay = () => {
|
||||
isLoading.value = false;
|
||||
canPlay.value = true;
|
||||
updatePlaybackRate(playbackRate.value);
|
||||
setPlaying(true); // makes the video play when fully loaded
|
||||
};
|
||||
|
||||
const setPlaying = async (setPlay: boolean) => {
|
||||
setPlay ? await videoRef.current.play() : videoRef.current.pause();
|
||||
playing.value = setPlay;
|
||||
};
|
||||
|
||||
const togglePlay = async () => {
|
||||
// console.log("in toggleplay playing is: ", playing.value);
|
||||
if (!videoRef.current) return;
|
||||
if (!src || resourceStatus?.status !== "READY") {
|
||||
const el = document.getElementById("videoWrapper");
|
||||
@ -159,13 +173,9 @@ export const useVideoControlsState = (
|
||||
});
|
||||
getSrc();
|
||||
}
|
||||
|
||||
startPlay.value = true;
|
||||
|
||||
const pause = playing.value;
|
||||
playing.value = !playing.value;
|
||||
|
||||
if (pause) videoRef.current.pause();
|
||||
else await videoRef.current.play();
|
||||
setPlaying(!playing.value);
|
||||
};
|
||||
|
||||
const onVolumeChange = (_: any, value: number | number[]) => {
|
||||
@ -178,9 +188,7 @@ export const useVideoControlsState = (
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (autoPlay && identifier) {
|
||||
togglePlay();
|
||||
}
|
||||
if (autoPlay && identifier) togglePlay();
|
||||
}, [autoPlay, identifier]);
|
||||
|
||||
const mute = () => {
|
||||
@ -353,12 +361,6 @@ export const useVideoControlsState = (
|
||||
}
|
||||
};
|
||||
|
||||
const handleCanPlay = () => {
|
||||
isLoading.value = false;
|
||||
canPlay.value = true;
|
||||
updatePlaybackRate(playbackRate.value);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
videoRef.current.volume = volume.value;
|
||||
if (
|
||||
@ -390,5 +392,6 @@ export const useVideoControlsState = (
|
||||
keyboardShortcutsDown,
|
||||
handleCanPlay,
|
||||
toggleMute,
|
||||
showControlsFullScreen,
|
||||
};
|
||||
};
|
||||
|
@ -1,6 +1,5 @@
|
||||
import {
|
||||
Fullscreen,
|
||||
MoreVert as MoreIcon,
|
||||
Pause,
|
||||
PictureInPicture,
|
||||
PlayArrow,
|
||||
@ -8,39 +7,15 @@ import {
|
||||
VolumeOff,
|
||||
VolumeUp,
|
||||
} from "@mui/icons-material";
|
||||
import { IconButton, Menu, MenuItem, Slider, Typography } from "@mui/material";
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
import { IconButton, Slider, Typography } from "@mui/material";
|
||||
import { useSignalEffect, useSignals } from "@preact/signals-react/runtime";
|
||||
import { useEffect } from "react";
|
||||
import {
|
||||
anchorEl,
|
||||
canPlay,
|
||||
isMobileView,
|
||||
isMuted,
|
||||
playbackRate,
|
||||
playing,
|
||||
progress,
|
||||
useVideoPlayerState,
|
||||
volume,
|
||||
} from "../VideoPlayer-State.ts";
|
||||
import { ControlsContainer } from "../VideoPlayer-styles.ts";
|
||||
import { VideoPlayerProps } from "../VideoPlayer.tsx";
|
||||
import {
|
||||
showControlsFullScreen,
|
||||
useVideoControlsState,
|
||||
} from "./VideoControls-State.ts";
|
||||
|
||||
export interface VideoControlProps {
|
||||
controlState: ReturnType<typeof useVideoControlsState>;
|
||||
videoState: ReturnType<typeof useVideoPlayerState>;
|
||||
props: VideoPlayerProps;
|
||||
videoRef: any;
|
||||
}
|
||||
export const VideoControls = ({
|
||||
controlState,
|
||||
videoState,
|
||||
props,
|
||||
videoRef,
|
||||
}: VideoControlProps) => {
|
||||
import { ControlsContainer } from "../VideoPlayer-styles.ts";
|
||||
import { MobileControls } from "./MobileControls.tsx";
|
||||
import { useVideoContext } from "./VideoContext.ts";
|
||||
|
||||
export const VideoControls = () => {
|
||||
useSignals();
|
||||
const {
|
||||
reloadVideo,
|
||||
@ -51,97 +26,38 @@ export const VideoControls = ({
|
||||
toggleFullscreen,
|
||||
formatTime,
|
||||
toggleMute,
|
||||
} = controlState;
|
||||
const { onProgressChange, handleMenuOpen, handleMenuClose, toggleRef } =
|
||||
videoState;
|
||||
const { from = null } = props;
|
||||
onProgressChange,
|
||||
toggleRef,
|
||||
from,
|
||||
videoRef,
|
||||
canPlay,
|
||||
isMobileView,
|
||||
isMuted,
|
||||
playbackRate,
|
||||
playing,
|
||||
progress,
|
||||
volume,
|
||||
showControlsFullScreen,
|
||||
} = useVideoContext();
|
||||
|
||||
useEffect(() => {
|
||||
useSignalEffect(() => {
|
||||
console.log("canPlay is: ", canPlay.value); // makes the function execute when canPlay changes
|
||||
const videoWidth = videoRef?.current?.offsetWidth;
|
||||
if (videoWidth && videoWidth <= 600) {
|
||||
isMobileView.value = true;
|
||||
}
|
||||
}, [canPlay.value]);
|
||||
});
|
||||
|
||||
const showMobileControls =
|
||||
isMobileView.value && canPlay.value && showControlsFullScreen.value;
|
||||
|
||||
return (
|
||||
<ControlsContainer
|
||||
style={{ bottom: from === "create" ? "15px" : 0, padding: "0px" }}
|
||||
display={showControlsFullScreen.value ? "flex" : "none"}
|
||||
>
|
||||
{isMobileView.value && canPlay.value && showControlsFullScreen.value ? (
|
||||
<>
|
||||
<IconButton
|
||||
sx={{
|
||||
color: "rgba(255, 255, 255, 0.7)",
|
||||
}}
|
||||
onClick={() => togglePlay()}
|
||||
>
|
||||
{playing.value ? <Pause /> : <PlayArrow />}
|
||||
</IconButton>
|
||||
<IconButton
|
||||
sx={{
|
||||
color: "rgba(255, 255, 255, 0.7)",
|
||||
marginLeft: "15px",
|
||||
}}
|
||||
onClick={reloadVideo}
|
||||
>
|
||||
<Refresh />
|
||||
</IconButton>
|
||||
<Slider
|
||||
value={progress.value}
|
||||
onChange={onProgressChange}
|
||||
min={0}
|
||||
max={videoRef.current?.duration || 100}
|
||||
sx={{ flexGrow: 1, mx: 2 }}
|
||||
/>
|
||||
<IconButton
|
||||
edge="end"
|
||||
color="inherit"
|
||||
aria-label="menu"
|
||||
onClick={handleMenuOpen}
|
||||
>
|
||||
<MoreIcon />
|
||||
</IconButton>
|
||||
<Menu
|
||||
id="simple-menu"
|
||||
anchorEl={anchorEl.value}
|
||||
keepMounted
|
||||
open={Boolean(anchorEl)}
|
||||
onClose={handleMenuClose}
|
||||
PaperProps={{
|
||||
style: {
|
||||
width: "250px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<MenuItem>
|
||||
<VolumeUp />
|
||||
<Slider
|
||||
value={volume.value}
|
||||
onChange={onVolumeChange}
|
||||
min={0}
|
||||
max={1}
|
||||
step={0.01}
|
||||
/>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => increaseSpeed()}>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "rgba(255, 255, 255, 0.7)",
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
Speed: {playbackRate.value}x
|
||||
</Typography>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={togglePictureInPicture}>
|
||||
<PictureInPicture />
|
||||
</MenuItem>
|
||||
<MenuItem onClick={toggleFullscreen}>
|
||||
<Fullscreen />
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</>
|
||||
{showMobileControls ? (
|
||||
<MobileControls />
|
||||
) : canPlay.value ? (
|
||||
<>
|
||||
<IconButton
|
||||
@ -174,14 +90,16 @@ export const VideoControls = ({
|
||||
marginRight: "5px",
|
||||
color: "rgba(255, 255, 255, 0.7)",
|
||||
visibility:
|
||||
!videoRef.current?.duration || !progress ? "hidden" : "visible",
|
||||
!videoRef.current?.duration || !progress.value
|
||||
? "hidden"
|
||||
: "visible",
|
||||
}}
|
||||
>
|
||||
{progress &&
|
||||
{progress.value &&
|
||||
videoRef.current?.duration &&
|
||||
formatTime(progress.value)}
|
||||
/
|
||||
{progress &&
|
||||
{progress.value &&
|
||||
videoRef.current?.duration &&
|
||||
formatTime(videoRef.current?.duration)}
|
||||
</Typography>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { signal } from "@preact/signals-react";
|
||||
import { useSignal, useSignals } from "@preact/signals-react/runtime";
|
||||
import React, {
|
||||
useContext,
|
||||
useEffect,
|
||||
@ -10,33 +10,28 @@ import React, {
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { setVideoPlaying } from "../../../state/features/globalSlice.ts";
|
||||
import { StretchVideoType } from "../../../state/features/persistSlice.ts";
|
||||
import { RootState, store } from "../../../state/store.ts";
|
||||
import { RootState } from "../../../state/store.ts";
|
||||
import { MyContext } from "../../../wrappers/DownloadWrapper.tsx";
|
||||
import { VideoPlayerProps } from "./VideoPlayer.tsx";
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
|
||||
export const playing = signal(false);
|
||||
|
||||
export const isMuted = signal(false);
|
||||
export const progress = signal(0);
|
||||
export const isLoading = signal(false);
|
||||
export const canPlay = signal(false);
|
||||
export const startPlay = signal(false);
|
||||
export const isMobileView = signal(false);
|
||||
|
||||
export const volume = signal(0.5);
|
||||
export const mutedVolume = signal(0.5);
|
||||
export const playbackRate = signal(1);
|
||||
export const anchorEl = signal(null);
|
||||
export const videoObjectFit = signal<StretchVideoType>("contain");
|
||||
|
||||
export const useVideoPlayerState = (props: VideoPlayerProps, ref: any) => {
|
||||
useSignals();
|
||||
const persistSelector = useSelector((state: RootState) => state.persist);
|
||||
volume.value = persistSelector.volume;
|
||||
mutedVolume.value = persistSelector.volume;
|
||||
playbackRate.value = persistSelector.playbackRate;
|
||||
videoObjectFit.value = persistSelector.stretchVideoSetting;
|
||||
|
||||
const playing = useSignal(false);
|
||||
const isMuted = useSignal(false);
|
||||
const progress = useSignal(0);
|
||||
const isLoading = useSignal(false);
|
||||
const canPlay = useSignal(false);
|
||||
const startPlay = useSignal(false);
|
||||
const isMobileView = useSignal(false);
|
||||
const volume = useSignal(persistSelector.volume);
|
||||
const mutedVolume = useSignal(persistSelector.volume);
|
||||
const playbackRate = useSignal(persistSelector.playbackRate);
|
||||
const anchorEl = useSignal(null);
|
||||
const videoObjectFit = useSignal<StretchVideoType>(
|
||||
persistSelector.stretchVideoSetting
|
||||
);
|
||||
|
||||
const {
|
||||
name,
|
||||
@ -119,7 +114,8 @@ export const useVideoPlayerState = (props: VideoPlayerProps, ref: any) => {
|
||||
if (!videoRef.current) return;
|
||||
videoRef.current.currentTime = value as number;
|
||||
progress.value = value as number;
|
||||
if (!playing) {
|
||||
|
||||
if (!playing.value) {
|
||||
await videoRef.current.play();
|
||||
playing.value = true;
|
||||
}
|
||||
@ -269,5 +265,17 @@ export const useVideoPlayerState = (props: VideoPlayerProps, ref: any) => {
|
||||
handleMenuOpen,
|
||||
handleMenuClose,
|
||||
toggleRef,
|
||||
playing,
|
||||
isMuted,
|
||||
progress,
|
||||
isLoading,
|
||||
canPlay,
|
||||
startPlay,
|
||||
isMobileView,
|
||||
volume,
|
||||
mutedVolume,
|
||||
playbackRate,
|
||||
anchorEl,
|
||||
videoObjectFit,
|
||||
};
|
||||
};
|
||||
|
@ -2,17 +2,8 @@ import { useSignals } from "@preact/signals-react/runtime";
|
||||
import CSS from "csstype";
|
||||
import { forwardRef } from "react";
|
||||
import { LoadingVideo } from "./Components/LoadingVideo.tsx";
|
||||
import {
|
||||
showControlsFullScreen,
|
||||
useVideoControlsState,
|
||||
} from "./Components/VideoControls-State.ts";
|
||||
import { useContextData, VideoContext } from "./Components/VideoContext.ts";
|
||||
import { VideoControls } from "./Components/VideoControls.tsx";
|
||||
import {
|
||||
isLoading,
|
||||
startPlay,
|
||||
useVideoPlayerState,
|
||||
videoObjectFit,
|
||||
} from "./VideoPlayer-State.ts";
|
||||
import { VideoContainer, VideoElement } from "./VideoPlayer-styles.ts";
|
||||
|
||||
export interface VideoStyles {
|
||||
@ -37,95 +28,85 @@ export interface VideoPlayerProps {
|
||||
style?: CSS.Properties;
|
||||
}
|
||||
|
||||
export type refType = {
|
||||
export type videoRefType = {
|
||||
getContainerRef: () => React.MutableRefObject<HTMLDivElement>;
|
||||
getVideoRef: () => React.MutableRefObject<HTMLVideoElement>;
|
||||
};
|
||||
export const VideoPlayer = forwardRef<refType, VideoPlayerProps>(
|
||||
export const VideoPlayer = forwardRef<videoRefType, VideoPlayerProps>(
|
||||
(props: VideoPlayerProps, ref) => {
|
||||
useSignals();
|
||||
const contextData = useContextData(props, ref);
|
||||
|
||||
const {
|
||||
poster,
|
||||
identifier,
|
||||
autoplay = true,
|
||||
from = null,
|
||||
videoStyles = {},
|
||||
} = props;
|
||||
const videoState = useVideoPlayerState(props, ref);
|
||||
const {
|
||||
keyboardShortcutsUp,
|
||||
keyboardShortcutsDown,
|
||||
from,
|
||||
videoStyles,
|
||||
containerRef,
|
||||
resourceStatus,
|
||||
videoRef,
|
||||
src,
|
||||
togglePlay,
|
||||
identifier,
|
||||
videoRef,
|
||||
poster,
|
||||
updateProgress,
|
||||
autoplay,
|
||||
handleEnded,
|
||||
getSrc,
|
||||
toggleRef,
|
||||
} = videoState;
|
||||
|
||||
const controlState = useVideoControlsState(props, videoRef, videoState);
|
||||
const { keyboardShortcutsUp, keyboardShortcutsDown, togglePlay } =
|
||||
controlState;
|
||||
handleCanPlay,
|
||||
startPlay,
|
||||
videoObjectFit,
|
||||
showControlsFullScreen,
|
||||
} = contextData;
|
||||
|
||||
return (
|
||||
<VideoContainer
|
||||
tabIndex={0}
|
||||
onKeyUp={keyboardShortcutsUp}
|
||||
onKeyDown={keyboardShortcutsDown}
|
||||
style={{
|
||||
padding: from === "create" ? "8px" : 0,
|
||||
...videoStyles?.videoContainer,
|
||||
}}
|
||||
ref={containerRef}
|
||||
>
|
||||
<LoadingVideo
|
||||
isLoading={isLoading.value}
|
||||
resourceStatus={resourceStatus}
|
||||
src={src}
|
||||
startPlay={startPlay.value}
|
||||
from={from}
|
||||
togglePlay={togglePlay}
|
||||
/>
|
||||
<VideoElement
|
||||
id={identifier}
|
||||
ref={videoRef}
|
||||
src={
|
||||
!startPlay.value
|
||||
? ""
|
||||
: resourceStatus?.status === "READY"
|
||||
? src
|
||||
: ""
|
||||
}
|
||||
poster={!startPlay.value ? poster : ""}
|
||||
onTimeUpdate={updateProgress}
|
||||
autoPlay={autoplay}
|
||||
onClick={() => togglePlay()}
|
||||
onEnded={handleEnded}
|
||||
// onLoadedMetadata={handleLoadedMetadata}
|
||||
onCanPlay={controlState.handleCanPlay}
|
||||
onMouseEnter={e => {
|
||||
showControlsFullScreen.value = true;
|
||||
<VideoContext.Provider value={contextData}>
|
||||
<VideoContainer
|
||||
tabIndex={0}
|
||||
onKeyUp={keyboardShortcutsUp}
|
||||
onKeyDown={keyboardShortcutsDown}
|
||||
style={{
|
||||
padding: from === "create" ? "8px" : 0,
|
||||
...videoStyles?.videoContainer,
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
showControlsFullScreen.value = false;
|
||||
}}
|
||||
preload="metadata"
|
||||
style={
|
||||
startPlay.value
|
||||
? {
|
||||
...videoStyles?.video,
|
||||
objectFit: videoObjectFit.value,
|
||||
}
|
||||
: { height: "100%", ...videoStyles }
|
||||
}
|
||||
/>
|
||||
<VideoControls
|
||||
controlState={controlState}
|
||||
videoState={videoState}
|
||||
props={props}
|
||||
videoRef={videoRef}
|
||||
/>
|
||||
</VideoContainer>
|
||||
ref={containerRef}
|
||||
>
|
||||
<LoadingVideo />
|
||||
<VideoElement
|
||||
id={identifier}
|
||||
ref={videoRef}
|
||||
src={
|
||||
!startPlay.value
|
||||
? ""
|
||||
: resourceStatus?.status === "READY"
|
||||
? src
|
||||
: ""
|
||||
}
|
||||
poster={!startPlay.value ? poster : ""}
|
||||
onTimeUpdate={updateProgress}
|
||||
autoPlay={autoplay}
|
||||
onClick={() => togglePlay()}
|
||||
onEnded={handleEnded}
|
||||
// onLoadedMetadata={handleLoadedMetadata}
|
||||
onCanPlay={handleCanPlay}
|
||||
onMouseEnter={e => {
|
||||
showControlsFullScreen.value = true;
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
showControlsFullScreen.value = false;
|
||||
}}
|
||||
preload="metadata"
|
||||
style={
|
||||
startPlay.value
|
||||
? {
|
||||
...videoStyles?.video,
|
||||
objectFit: videoObjectFit.value,
|
||||
}
|
||||
: { height: "100%", ...videoStyles }
|
||||
}
|
||||
/>
|
||||
<VideoControls />
|
||||
</VideoContainer>
|
||||
</VideoContext.Provider>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -4,7 +4,7 @@ import { LikeAndDislike } from "../../../components/common/ContentButtons/LikeAn
|
||||
import { SubscribeButton } from "../../../components/common/ContentButtons/SubscribeButton.tsx";
|
||||
import { SuperLike } from "../../../components/common/ContentButtons/SuperLike.tsx";
|
||||
import FileElement from "../../../components/common/FileElement.tsx";
|
||||
import { refType } from "../../../components/common/VideoPlayer/VideoPlayer.tsx";
|
||||
import { videoRefType } from "../../../components/common/VideoPlayer/VideoPlayer.tsx";
|
||||
import { titleFormatterOnSave } from "../../../constants/Misc.ts";
|
||||
import { useFetchSuperLikes } from "../../../hooks/useFetchSuperLikes.tsx";
|
||||
import DownloadIcon from "@mui/icons-material/Download";
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { refType } from "../../../components/common/VideoPlayer/VideoPlayer.tsx";
|
||||
import { videoRefType } from "../../../components/common/VideoPlayer/VideoPlayer.tsx";
|
||||
import {
|
||||
QTUBE_VIDEO_BASE,
|
||||
SUPER_LIKE_BASE,
|
||||
@ -27,7 +27,7 @@ export const useVideoContentState = () => {
|
||||
|
||||
const [isExpandedDescription, setIsExpandedDescription] =
|
||||
useState<boolean>(false);
|
||||
const containerRef = useRef<refType>(null);
|
||||
const containerRef = useRef<videoRefType>(null);
|
||||
|
||||
const [nameAddress, setNameAddress] = useState<string>("");
|
||||
const [descriptionHeight, setDescriptionHeight] = useState<null | number>(
|
||||
|
@ -6,7 +6,7 @@ import { CommentSection } from "../../../components/common/Comments/CommentSecti
|
||||
import { SuperLikesSection } from "../../../components/common/SuperLikesList/SuperLikesSection.tsx";
|
||||
import { DisplayHtml } from "../../../components/common/TextEditor/DisplayHtml.tsx";
|
||||
import {
|
||||
refType,
|
||||
videoRefType,
|
||||
VideoPlayer,
|
||||
} from "../../../components/common/VideoPlayer/VideoPlayer.tsx";
|
||||
import {
|
||||
|
Loading…
x
Reference in New Issue
Block a user