import { useEffect, useMemo, useState } from "react"; import type { EnvironmentBackground, EnvironmentMediaItem, } from "../core/environment/environmentSettings"; type ReadyEnvironmentMediaItem = EnvironmentMediaItem & { url: string; mediaKind: "image" | "video"; }; function isReadyMediaItem( item: EnvironmentMediaItem, ): item is ReadyEnvironmentMediaItem { return Boolean(item.url && item.mediaKind); } export function EnvironmentBackgroundMedia({ background, }: { background: EnvironmentBackground; }) { const items = useMemo( () => background.items.filter(isReadyMediaItem), [background.items], ); const playlistIdentity = items.map((item) => `${item.id}:${item.url}`).join("|"); const [activeIndex, setActiveIndex] = useState(0); const [failedIds, setFailedIds] = useState>(new Set()); const playableItems = items.filter((item) => !failedIds.has(item.id)); const activeItem = playableItems[activeIndex] ?? playableItems[0] ?? null; useEffect(() => { setActiveIndex(0); setFailedIds(new Set()); }, [playlistIdentity]); useEffect(() => { if ( !background.enabled || !activeItem || activeItem.mediaKind !== "image" || playableItems.length < 2 ) { return; } const timer = window.setTimeout(() => { setActiveIndex((current) => (current + 1) % playableItems.length); }, background.imageDurationSeconds * 1_000); return () => window.clearTimeout(timer); }, [ activeItem, background.enabled, background.imageDurationSeconds, playableItems.length, ]); if (!background.enabled || !activeItem) return null; return ( ); }