diff --git a/src/components/IdleMainPagesSlideshow.js b/src/components/IdleMainPagesSlideshow.js index 0515052..70ce1dc 100644 --- a/src/components/IdleMainPagesSlideshow.js +++ b/src/components/IdleMainPagesSlideshow.js @@ -13,6 +13,13 @@ const SLIDESHOW_STEP_MS = 14_000; /** Ignore duplicate events (mousemove etc.) within this window. */ const ACTIVITY_THROTTLE_MS = 400; +/** + * After auto-navigation, ignore user-activity handlers briefly — route changes + * often emit scroll / mousemove / focus events that would call resetIdle() and + * clear the slideshow interval (only one slide before stopping). + */ +const POST_NAV_GRACE_MS = 3_000; + /** * After idle on /, /aktionen, or /filiale, cycles those routes slowly. * Lives outside MainPageLayout so it is not reset when the route changes. @@ -25,6 +32,10 @@ export default function IdleMainPagesSlideshow() { const pathRef = useRef(location.pathname); const wasOnMainPageRef = useRef(false); const lastActivityRef = useRef(0); + const ignoreActivityUntilRef = useRef(0); + + const resetIdleRef = useRef(() => {}); + const clearTimersRef = useRef(() => {}); pathRef.current = location.pathname; @@ -39,11 +50,14 @@ export default function IdleMainPagesSlideshow() { } }, []); + clearTimersRef.current = clearTimers; + const startSlideshow = useCallback(() => { let idx = MAIN_PAGE_PATHS.indexOf(pathRef.current); if (idx < 0) idx = 0; const advance = () => { idx = (idx + 1) % MAIN_PAGE_PATHS.length; + ignoreActivityUntilRef.current = Date.now() + POST_NAV_GRACE_MS; navigate(MAIN_PAGE_PATHS[idx], { replace: true }); }; slideTimerRef.current = setInterval(advance, SLIDESHOW_STEP_MS); @@ -58,6 +72,8 @@ export default function IdleMainPagesSlideshow() { }, IDLE_MS); }, [clearTimers, startSlideshow]); + resetIdleRef.current = resetIdle; + useEffect(() => { const nowMain = MAIN_PAGE_PATHS.includes(location.pathname); if (!nowMain) { @@ -73,10 +89,11 @@ export default function IdleMainPagesSlideshow() { useEffect(() => { const onActivity = () => { - const t = Date.now(); - if (t - lastActivityRef.current < ACTIVITY_THROTTLE_MS) return; - lastActivityRef.current = t; - resetIdle(); + const now = Date.now(); + if (now < ignoreActivityUntilRef.current) return; + if (now - lastActivityRef.current < ACTIVITY_THROTTLE_MS) return; + lastActivityRef.current = now; + resetIdleRef.current(); }; const events = [ @@ -96,9 +113,9 @@ export default function IdleMainPagesSlideshow() { return () => { events.forEach((ev) => window.removeEventListener(ev, onActivity)); window.removeEventListener("mousemove", onActivity); - clearTimers(); + clearTimersRef.current(); }; - }, [resetIdle, clearTimers]); + }, []); return null; }