import { useEffect, useRef, useState } from 'react'; const DISMISS_AFTER_INPUT_MS = 5000; const LARGE_FADE_MS = 700; export default function RoverDescriptionOverlay({ description, variant = 'default', mobileHud = false, displayKey = '', controlIntentAt = 0, }) { const [largeVisible, setLargeVisible] = useState(false); const [largeFading, setLargeFading] = useState(false); const baselineIntentRef = useRef(0); const fadeTimerRef = useRef(null); const hideTimerRef = useRef(null); useEffect( () => () => { clearTimeout(fadeTimerRef.current); clearTimeout(hideTimerRef.current); }, [], ); useEffect(() => { if (variant !== 'default' || !description) { setLargeVisible(false); setLargeFading(false); clearTimeout(fadeTimerRef.current); clearTimeout(hideTimerRef.current); return undefined; } clearTimeout(fadeTimerRef.current); clearTimeout(hideTimerRef.current); setLargeVisible(true); setLargeFading(false); baselineIntentRef.current = Number(controlIntentAt) || 0; return undefined; }, [description, displayKey, variant]); useEffect(() => { if (variant !== 'default' || !description || !largeVisible || largeFading) return; const nextIntent = Number(controlIntentAt) || 0; if (nextIntent <= baselineIntentRef.current) return; if (fadeTimerRef.current || hideTimerRef.current) return; fadeTimerRef.current = setTimeout(() => { setLargeFading(true); fadeTimerRef.current = null; }, DISMISS_AFTER_INPUT_MS); hideTimerRef.current = setTimeout(() => { setLargeVisible(false); hideTimerRef.current = null; }, DISMISS_AFTER_INPUT_MS + LARGE_FADE_MS); }, [controlIntentAt, description, largeFading, largeVisible, variant]); if (!description) return null; if (variant === 'spectator') { return (
{description}
); } if (variant !== 'default' || !largeVisible) return null; return (

Just so you know, this rover

{description}

This fades 5 seconds after your first control input.

); }