From 64263740832656a312850bc6ceb55b24fe02da8b Mon Sep 17 00:00:00 2001 From: sebastjanartic <45803536-sebastjanartic@users.noreply.replit.com> Date: Tue, 2 Sep 2025 15:46:18 +0000 Subject: [PATCH] Add subtle animations to indicate video preview functionality Introduce visual cues, including a "Hover to preview" message and a pulsating play icon, to guide users towards interactive video card features and improve discoverability of the video preview functionality. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 2cd2c0bc-434c-4bc9-ad3f-b99d3897a0d1 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/2cd2c0bc-434c-4bc9-ad3f-b99d3897a0d1/4DOsXkx --- client/src/components/video-card.tsx | 35 +++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/client/src/components/video-card.tsx b/client/src/components/video-card.tsx index 418b7e1..9d5b924 100644 --- a/client/src/components/video-card.tsx +++ b/client/src/components/video-card.tsx @@ -47,7 +47,9 @@ export default function VideoCard({ video, onClick, className = "", hideOverlay const [isHovered, setIsHovered] = useState(false); const [showPreview, setShowPreview] = useState(false); const [isMuted, setIsMuted] = useState(true); + const [showHint, setShowHint] = useState(false); const hoverTimeoutRef = useRef(); + const hintTimeoutRef = useRef(); const videoRef = useRef(null); const hlsRef = useRef(null); const [currentTime, setCurrentTime] = useState(0); @@ -84,18 +86,27 @@ export default function VideoCard({ video, onClick, className = "", hideOverlay // Enable video preview on hover for desktop devices useEffect(() => { if (isHovered) { - // Enable preview for desktop devices after delay + // Show hint after short delay if (window.innerWidth >= 768) { + hintTimeoutRef.current = setTimeout(() => { + setShowHint(true); + }, 300); + const delay = 800; hoverTimeoutRef.current = setTimeout(() => { setShowPreview(true); + setShowHint(false); // Hide hint when preview starts }, delay); } } else { if (hoverTimeoutRef.current) { clearTimeout(hoverTimeoutRef.current); } + if (hintTimeoutRef.current) { + clearTimeout(hintTimeoutRef.current); + } setShowPreview(false); + setShowHint(false); // Clean up HLS when not hovering if (hlsRef.current) { hlsRef.current.destroy(); @@ -107,6 +118,9 @@ export default function VideoCard({ video, onClick, className = "", hideOverlay if (hoverTimeoutRef.current) { clearTimeout(hoverTimeoutRef.current); } + if (hintTimeoutRef.current) { + clearTimeout(hintTimeoutRef.current); + } if (hlsRef.current) { hlsRef.current.destroy(); } @@ -268,6 +282,18 @@ export default function VideoCard({ video, onClick, className = "", hideOverlay )} + {/* Preview hint animation */} + {showHint && !showPreview && ( +
+
+
+ + Hover to preview +
+
+
+ )} + {/* Modern gradient overlay with title */} {!showPreview && !hideOverlay && (
@@ -279,6 +305,13 @@ export default function VideoCard({ video, onClick, className = "", hideOverlay {video.title.split(' - ')[1] || video.title}

+ + {/* Subtle hover indicator in corner */} +
+
+ +
+
)}