Improve video preview audio muting consistency across the platform

Refactor video card component to synchronize mute state across all video previews using localStorage and custom events, ensuring consistent audio behavior.

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
This commit is contained in:
sebastjanartic 2025-09-02 15:44:25 +00:00
parent a3cc41d477
commit 8c596f8326

View File

@ -46,16 +46,40 @@ function formatDate(date: Date | string): string {
export default function VideoCard({ video, onClick, className = "", hideOverlay = false }: VideoCardProps) {
const [isHovered, setIsHovered] = useState(false);
const [showPreview, setShowPreview] = useState(false);
const [isMuted, setIsMuted] = useState(() => {
// Check localStorage for user's audio preference, default to muted
const savedMuteState = localStorage.getItem('videoPreviewMuted');
return savedMuteState === null ? true : savedMuteState === 'true';
});
const [isMuted, setIsMuted] = useState(true);
const hoverTimeoutRef = useRef<NodeJS.Timeout>();
const videoRef = useRef<HTMLVideoElement>(null);
const hlsRef = useRef<Hls | null>(null);
const [currentTime, setCurrentTime] = useState(0);
const [duration, setDuration] = useState(0);
// Load mute preference on component mount
useEffect(() => {
const savedMuteState = localStorage.getItem('videoPreviewMuted');
const shouldBeMuted = savedMuteState === null ? true : savedMuteState === 'true';
setIsMuted(shouldBeMuted);
}, []);
// Listen for changes in localStorage from other components
useEffect(() => {
const handleStorageChange = (e: StorageEvent) => {
if (e.key === 'videoPreviewMuted' && e.newValue !== null) {
setIsMuted(e.newValue === 'true');
}
};
const handleMuteChange = (e: CustomEvent) => {
setIsMuted(e.detail.isMuted);
};
window.addEventListener('storage', handleStorageChange);
window.addEventListener('videoMuteChanged', handleMuteChange as EventListener);
return () => {
window.removeEventListener('storage', handleStorageChange);
window.removeEventListener('videoMuteChanged', handleMuteChange as EventListener);
};
}, []);
// Enable video preview on hover for desktop devices
useEffect(() => {
@ -208,6 +232,11 @@ export default function VideoCard({ video, onClick, className = "", hideOverlay
// Save preference to localStorage for all future previews
localStorage.setItem('videoPreviewMuted', newMutedState.toString());
// Dispatch custom event to notify other components
window.dispatchEvent(new CustomEvent('videoMuteChanged', {
detail: { isMuted: newMutedState }
}));
if (videoRef.current) {
videoRef.current.muted = newMutedState;
}