feat: Add poster prop to VideoControls component
This commit is contained in:
@@ -43,6 +43,7 @@ interface VideoControlsProps {
|
||||
onSubtitlesToggle?: (enabled: boolean) => void;
|
||||
onLoopToggle?: (enabled: boolean) => void;
|
||||
onEnded?: () => void;
|
||||
poster?: string;
|
||||
}
|
||||
|
||||
const VideoControls: React.FC<VideoControlsProps> = ({
|
||||
@@ -56,7 +57,8 @@ const VideoControls: React.FC<VideoControlsProps> = ({
|
||||
subtitlesEnabled: initialSubtitlesEnabled = true,
|
||||
onSubtitlesToggle,
|
||||
onLoopToggle,
|
||||
onEnded
|
||||
onEnded,
|
||||
poster
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const { t } = useLanguage();
|
||||
@@ -131,6 +133,14 @@ const VideoControls: React.FC<VideoControlsProps> = ({
|
||||
videoElement.src = src;
|
||||
|
||||
// For mobile browsers, try to load the video
|
||||
const handleLoadedMetadata = () => {
|
||||
setIsLoading(false);
|
||||
if (loadTimeoutRef.current) {
|
||||
clearTimeout(loadTimeoutRef.current);
|
||||
loadTimeoutRef.current = null;
|
||||
}
|
||||
};
|
||||
|
||||
const handleCanPlay = () => {
|
||||
setIsLoading(false);
|
||||
if (loadTimeoutRef.current) {
|
||||
@@ -156,11 +166,13 @@ const VideoControls: React.FC<VideoControlsProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
videoElement.addEventListener('loadedmetadata', handleLoadedMetadata);
|
||||
videoElement.addEventListener('canplay', handleCanPlay);
|
||||
videoElement.addEventListener('loadeddata', handleLoadedData);
|
||||
videoElement.addEventListener('error', handleError);
|
||||
|
||||
return () => {
|
||||
videoElement.removeEventListener('loadedmetadata', handleLoadedMetadata);
|
||||
videoElement.removeEventListener('canplay', handleCanPlay);
|
||||
videoElement.removeEventListener('loadeddata', handleLoadedData);
|
||||
videoElement.removeEventListener('error', handleError);
|
||||
@@ -726,6 +738,7 @@ const VideoControls: React.FC<VideoControlsProps> = ({
|
||||
}}
|
||||
playsInline
|
||||
crossOrigin="anonymous"
|
||||
poster={poster}
|
||||
>
|
||||
{subtitles && subtitles.map((subtitle) => (
|
||||
<track
|
||||
|
||||
@@ -27,7 +27,6 @@ import { Collection, Video } from '../types';
|
||||
import { getRecommendations } from '../utils/recommendations';
|
||||
import { validateUrlForOpen } from '../utils/urlValidation';
|
||||
const API_URL = import.meta.env.VITE_API_URL;
|
||||
const BACKEND_URL = import.meta.env.VITE_BACKEND_URL;
|
||||
|
||||
const VideoPlayer: React.FC = () => {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
@@ -472,7 +471,7 @@ const VideoPlayer: React.FC = () => {
|
||||
onSuccess: (data, visibility) => {
|
||||
if (data.success) {
|
||||
queryClient.setQueryData(['video', id], (old: Video | undefined) => old ? { ...old, visibility } : old);
|
||||
queryClient.setQueryData(['videos'], (old: Video[] | undefined) =>
|
||||
queryClient.setQueryData(['videos'], (old: Video[] | undefined) =>
|
||||
old ? old.map(v => v.id === id ? { ...v, visibility } : v) : []
|
||||
);
|
||||
showSnackbar(visibility === 1 ? t('showVideo') : t('hideVideo'), 'success');
|
||||
@@ -613,6 +612,9 @@ const VideoPlayer: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
// Get thumbnail URL for poster
|
||||
const posterUrl = useCloudStorageUrl(video?.thumbnailPath, 'thumbnail');
|
||||
|
||||
return (
|
||||
<Container maxWidth={false} disableGutters sx={{ py: { xs: 0, md: 4 }, px: { xs: 0, md: 2 } }}>
|
||||
<Grid container spacing={{ xs: 0, md: 4 }}>
|
||||
@@ -620,6 +622,7 @@ const VideoPlayer: React.FC = () => {
|
||||
<Grid size={{ xs: 12, lg: 8 }}>
|
||||
<VideoControls
|
||||
src={videoUrl || video?.sourceUrl}
|
||||
poster={posterUrl || video?.thumbnailUrl}
|
||||
autoPlay={autoPlay}
|
||||
autoLoop={autoLoop}
|
||||
onTimeUpdate={handleTimeUpdate}
|
||||
|
||||
Reference in New Issue
Block a user