54 lines
1.5 KiB
TypeScript
54 lines
1.5 KiB
TypeScript
'use client';
|
|
|
|
import { useState, useEffect } from 'react';
|
|
|
|
interface DeferredVideoProps {
|
|
videoUrl: string;
|
|
pathname: string;
|
|
}
|
|
|
|
export function DeferredVideo({ videoUrl, pathname }: DeferredVideoProps) {
|
|
const [videoSrcLoaded, setVideoSrcLoaded] = useState(false);
|
|
|
|
useEffect(() => {
|
|
let interactionTriggered = false;
|
|
|
|
const handleInteraction = () => {
|
|
if (interactionTriggered) return;
|
|
interactionTriggered = true;
|
|
setVideoSrcLoaded(true);
|
|
|
|
// Cleanup listeners
|
|
['scroll', 'mousemove', 'touchstart', 'keydown'].forEach((event) =>
|
|
window.removeEventListener(event, handleInteraction)
|
|
);
|
|
};
|
|
|
|
// Listen for any user interaction
|
|
['scroll', 'mousemove', 'touchstart', 'keydown'].forEach((event) =>
|
|
window.addEventListener(event, handleInteraction, { passive: true, once: true })
|
|
);
|
|
|
|
return () => {
|
|
['scroll', 'mousemove', 'touchstart', 'keydown'].forEach((event) =>
|
|
window.removeEventListener(event, handleInteraction)
|
|
);
|
|
};
|
|
}, []);
|
|
|
|
if (!videoUrl) return null;
|
|
|
|
return (
|
|
<video
|
|
key={`${pathname}-${videoUrl}`}
|
|
className={`absolute inset-0 w-full h-full object-cover z-[2] pointer-events-none filter contrast-125 saturate-110 brightness-90 transition-opacity duration-1000 ${videoSrcLoaded ? 'opacity-100' : 'opacity-0'}`}
|
|
src={videoSrcLoaded ? videoUrl : undefined}
|
|
autoPlay
|
|
muted
|
|
loop
|
|
playsInline
|
|
preload="none"
|
|
/>
|
|
);
|
|
}
|