import { useEffect, RefObject } from 'react'; interface UsePlayerKeyboardNavigationOptions { containerRef: RefObject; isVertical: boolean; currentPostType: string; handleClose: () => void; handleNextPost: () => void; handlePreviousPost: () => void; togglePlay: () => void; toggleMute: () => void; } /** * Adds keyboard navigation to a player dialog. * * - Escape → close * - ArrowRight/Left → next/previous post (horizontal mode) * - ArrowDown/Up → next/previous post (vertical mode) * - k → toggle play (video only) * - m → toggle mute (video only) * * Space and Enter are left to their native behaviour when a button, link or * other interactive element inside the dialog has focus. */ export function usePlayerKeyboardNavigation({ containerRef, isVertical, currentPostType, handleClose, handleNextPost, handlePreviousPost, togglePlay, toggleMute, }: UsePlayerKeyboardNavigationOptions): void { useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') { handleClose(); return; } const active = document.activeElement as HTMLElement | null; const activeIsInteractive = active && active !== document.body && active !== containerRef.current && active.matches?.('button, a, input, select, textarea, [role="button"]'); if (activeIsInteractive && (e.key === ' ' || e.key === 'Enter')) return; switch (e.key) { case 'ArrowRight': if (!isVertical) { e.preventDefault(); handleNextPost(); } break; case 'ArrowLeft': if (!isVertical) { e.preventDefault(); handlePreviousPost(); } break; case 'ArrowDown': if (isVertical) { e.preventDefault(); handleNextPost(); } break; case 'ArrowUp': if (isVertical) { e.preventDefault(); handlePreviousPost(); } break; case ' ': case 'k': if (currentPostType === 'video') { e.preventDefault(); togglePlay(); } break; case 'm': if (currentPostType === 'video') toggleMute(); break; } }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [ containerRef, isVertical, currentPostType, handleClose, handleNextPost, handlePreviousPost, togglePlay, toggleMute, ]); }