Improve video player experience with better controls and fallback images
Fixes issues with missing thumbnails by adding a fallback image and ensures video controls are properly displayed and hidden. Replit-Commit-Author: Agent Replit-Commit-Session-Id: d7424866-83d1-4486-a212-ac12b4c7becf Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/d7424866-83d1-4486-a212-ac12b4c7becf/AbkXVNx
This commit is contained in:
parent
0adbf9900b
commit
1f6bd20a13
@ -192,8 +192,24 @@ export default function HLSPreviewThumbnail({ video, onClick, className = "" }:
|
|||||||
alt={video.title}
|
alt={video.title}
|
||||||
className="w-full h-full object-cover transition-all duration-300 group-hover:scale-105"
|
className="w-full h-full object-cover transition-all duration-300 group-hover:scale-105"
|
||||||
data-testid={`img-hls-preview-${video.id}`}
|
data-testid={`img-hls-preview-${video.id}`}
|
||||||
|
onError={(e) => {
|
||||||
|
const target = e.target as HTMLImageElement;
|
||||||
|
target.style.display = 'none';
|
||||||
|
// Show fallback background
|
||||||
|
if (target.parentElement) {
|
||||||
|
target.parentElement.style.background = 'linear-gradient(45deg, #374151, #4b5563)';
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Fallback for missing thumbnails */}
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-br from-gray-600 to-gray-700 flex items-center justify-center opacity-0">
|
||||||
|
<div className="text-white text-center">
|
||||||
|
<Play className="w-12 h-12 mx-auto mb-2 opacity-50" />
|
||||||
|
<p className="text-sm opacity-75">Video Preview</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Overlay with play button */}
|
{/* Overlay with play button */}
|
||||||
<div className={`absolute inset-0 bg-black/20 group-hover:bg-black/40 transition-all duration-300 flex items-center justify-center ${
|
<div className={`absolute inset-0 bg-black/20 group-hover:bg-black/40 transition-all duration-300 flex items-center justify-center ${
|
||||||
isHovering ? 'bg-black/50' : ''
|
isHovering ? 'bg-black/50' : ''
|
||||||
|
|||||||
@ -443,6 +443,7 @@ export default function VideoModal({ video, isOpen, onClose }: VideoModalProps)
|
|||||||
ref={videoRef}
|
ref={videoRef}
|
||||||
className="w-full h-auto max-h-[80vh] cursor-pointer"
|
className="w-full h-auto max-h-[80vh] cursor-pointer"
|
||||||
preload="metadata"
|
preload="metadata"
|
||||||
|
controls={false}
|
||||||
onPlay={handleVideoPlay}
|
onPlay={handleVideoPlay}
|
||||||
data-testid="video-player"
|
data-testid="video-player"
|
||||||
crossOrigin="anonymous"
|
crossOrigin="anonymous"
|
||||||
@ -452,16 +453,18 @@ export default function VideoModal({ video, isOpen, onClose }: VideoModalProps)
|
|||||||
</video>
|
</video>
|
||||||
|
|
||||||
{/* Central Play/Pause Button */}
|
{/* Central Play/Pause Button */}
|
||||||
{!isPlaying && showControls && (
|
{showControls && (
|
||||||
<div className="absolute inset-0 flex items-center justify-center">
|
<div className="absolute inset-0 flex items-center justify-center">
|
||||||
<Button
|
<Button
|
||||||
onClick={togglePlay}
|
onClick={togglePlay}
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
className="w-20 h-20 rounded-full bg-black/50 hover:bg-black/70 text-white border-2 border-white/20 hover:border-white/40 transition-all duration-200"
|
className={`rounded-full bg-black/50 hover:bg-black/70 text-white border-2 border-white/20 hover:border-white/40 transition-all duration-200 ${
|
||||||
|
isPlaying ? 'w-16 h-16 opacity-0 hover:opacity-100' : 'w-20 h-20 opacity-100'
|
||||||
|
}`}
|
||||||
data-testid="button-play-center"
|
data-testid="button-play-center"
|
||||||
>
|
>
|
||||||
<Play className="w-8 h-8 ml-1" />
|
{isPlaying ? <Pause className="w-6 h-6" /> : <Play className="w-8 h-8 ml-1" />}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -645,30 +648,33 @@ export default function VideoModal({ video, isOpen, onClose }: VideoModalProps)
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="absolute bottom-16 left-0 right-0 bg-gradient-to-t from-black/80 to-transparent p-6 pointer-events-none">
|
{/* Video info - only show when not playing or when controls are visible */}
|
||||||
<h3
|
{(!isPlaying || showControls) && (
|
||||||
className="text-xl font-semibold mb-2 text-white"
|
<div className="absolute bottom-16 left-0 right-0 bg-gradient-to-t from-black/80 to-transparent p-6 pointer-events-none transition-opacity duration-300">
|
||||||
data-testid="text-modal-title"
|
<h3
|
||||||
>
|
className="text-xl font-semibold mb-2 text-white"
|
||||||
{video.title}
|
data-testid="text-modal-title"
|
||||||
</h3>
|
>
|
||||||
<div className="flex items-center space-x-4 text-sm text-gray-300">
|
{video.title}
|
||||||
<span data-testid="text-modal-views">
|
</h3>
|
||||||
{formatViews(video.views)}
|
<div className="flex items-center space-x-4 text-sm text-gray-300">
|
||||||
</span>
|
<span data-testid="text-modal-views">
|
||||||
<span data-testid="text-modal-date">
|
{formatViews(video.views)}
|
||||||
{formatDate(video.createdAt)}
|
</span>
|
||||||
</span>
|
<span data-testid="text-modal-date">
|
||||||
<span data-testid="text-modal-duration">
|
{formatDate(video.createdAt)}
|
||||||
{formatDuration(video.duration)}
|
</span>
|
||||||
</span>
|
<span data-testid="text-modal-duration">
|
||||||
|
{formatDuration(video.duration)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{video.description && (
|
||||||
|
<p className="mt-3 text-gray-300 text-sm" data-testid="text-modal-description">
|
||||||
|
{video.description}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{video.description && (
|
)}
|
||||||
<p className="mt-3 text-gray-300 text-sm" data-testid="text-modal-description">
|
|
||||||
{video.description}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Video Edit Modal */}
|
{/* Video Edit Modal */}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user