diff --git a/app/components/tvone-promo-strip.tsx b/app/components/tvone-promo-strip.tsx index 9decd94..98ba49e 100644 --- a/app/components/tvone-promo-strip.tsx +++ b/app/components/tvone-promo-strip.tsx @@ -1,7 +1,8 @@ "use client"; import Image from "next/image"; -import { useCallback, useEffect, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import type { CSSProperties } from "react"; import type { SliderPhoto } from "@/lib/slider-photos"; @@ -14,10 +15,47 @@ function PromoStripSingleSlide({ photos: SliderPhoto[]; activeIndex: number; }) { + const [ratioBySrc, setRatioBySrc] = useState>({}); + const lastKnownRatioRef = useRef(16 / 9); + + const active = photos[activeIndex]; + const activeRatio = active ? ratioBySrc[active.src] : undefined; + + const displayRatio = + activeRatio != null && activeRatio > 0 ? activeRatio : photos.length > 0 ? lastKnownRatioRef.current : undefined; + + useEffect(() => { + if (activeRatio != null && activeRatio > 0) { + lastKnownRatioRef.current = activeRatio; + } + }, [activeRatio]); + + const containerStyle = useMemo((): CSSProperties => { + if (photos.length === 0) { + return { minHeight: "10rem" }; + } + if (displayRatio != null) { + return { aspectRatio: displayRatio }; + } + return { minHeight: "10rem" }; + }, [photos.length, displayRatio]); + + const handleImageLoad = useCallback((src: string, naturalWidth: number, naturalHeight: number) => { + if (naturalHeight <= 0) return; + setRatioBySrc((prev) => { + const next = naturalWidth / naturalHeight; + if (prev[src] === next) return prev; + return { ...prev, [src]: next }; + }); + }, []); + const n = photos.length; return ( -
+
{n > 0 ? ( photos.map((photo, i) => ( {photo.alt} handleImageLoad(photo.src, e.currentTarget.naturalWidth, e.currentTarget.naturalHeight)} /> )) ) : ( @@ -79,7 +119,7 @@ function useSliderPhotos(): { photos: SliderPhoto[]; loading: boolean } { return { photos, loading }; } -/** Slider: one image at a time from `public/slider` (see `lib/slider-photos.ts`). */ +/** Slider: one image at a time; container height follows each image aspect ratio (no fixed empty band). */ export function TvonePromoStrip() { const { photos, loading } = useSliderPhotos(); const [index, setIndex] = useState(0); @@ -122,7 +162,7 @@ export function TvonePromoStrip() { {current ? current.alt : loading ? "A carregar" : "Sem imagens"} -
+