"use client"; import Image from "next/image"; import { useEffect, useRef, useState } from "react"; import { useReducedMotion } from "@/app/hooks/useReducedMotion"; import type { ShowcaseAssets } from "@/lib/project-showcase"; /** * Vídeo de rolagem na capa do card. Quem decide se ele toca é a vitrine (`active`: só um card por vez, o que * está sob o mouse ou o mais perto do centro da tela). Nada do vídeo é baixado antes da primeira vez que o * card fica ativo; fora de cena ele pausa. Com prefers-reduced-motion só o poster aparece. * O poster também fica por baixo (fundo da tela da moldura): o vídeo aparece em fade quando começa a tocar. */ export function ProjectVideo({ video, title, active, }: { video: ShowcaseAssets; title: string; active: boolean; }) { const reducedMotion = useReducedMotion(); const ref = useRef(null); const [attached, setAttached] = useState(false); const [ready, setReady] = useState(false); const playing = active && !reducedMotion; useEffect(() => { if (playing) setAttached(true); }, [playing]); useEffect(() => { // as fontes entram depois do primeiro render: o elemento precisa ler a lista nova if (attached) ref.current?.load(); }, [attached]); useEffect(() => { const element = ref.current; if (!element || !attached) return; if (playing) { element.muted = true; // o React não reflete `muted` no DOM e o autoplay exige o valor real element.play().catch(() => {}); } else { element.pause(); // também cancela um autoplay que ainda esperava o arquivo chegar } }, [attached, playing]); if (reducedMotion) { return ( {`Captura ); } return ( ); }