diff --git a/src/components/Player.tsx b/src/components/Player.tsx index a22e4a5..98f117b 100644 --- a/src/components/Player.tsx +++ b/src/components/Player.tsx @@ -299,8 +299,9 @@ export default function Player({ // Escape backs out, as it does everywhere else in the app. useEffect(() => { const onKey = (e: KeyboardEvent) => { - // In fullscreen the browser already handles Escape; closing the player - // as well would drop you all the way back to the feed. + // In fullscreen, Escape is the transport bar's to handle: it leaves + // fullscreen. Closing the player as well would drop you all the way back + // to the feed in one keypress. if (e.key === "Escape" && !document.fullscreenElement) leave(); // Arrow keys only when the video does not own them for seeking. if (e.key === "ArrowLeft" && e.shiftKey) onPrev?.(); diff --git a/src/components/PlayerControls.tsx b/src/components/PlayerControls.tsx index 45108e4..e1c93f9 100644 --- a/src/components/PlayerControls.tsx +++ b/src/components/PlayerControls.tsx @@ -253,6 +253,38 @@ export default function PlayerControls({ } }, [stageRef, onActivity]); + /** + * The shortcuts the buttons advertise. Their tooltips have promised + * "(space)" and "(f)" all along with nothing listening, and Escape left + * fullscreen nowhere: WebKit does not handle it for an element made + * fullscreen this way, so pressing it did nothing and the only way out was + * to find the button again. + */ + useEffect(() => { + const onKey = (e: KeyboardEvent) => { + // Never while typing, and never over a shortcut of the system's own. + const t = e.target as HTMLElement | null; + if (t && (t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.isContentEditable)) return; + if (e.metaKey || e.ctrlKey || e.altKey) return; + + if (e.key === " " || e.code === "Space") { + // Or the space would also press whichever button has focus. + e.preventDefault(); + const v = videoRef.current; + if (!v) return; + if (v.paused) void v.play().catch(() => {}); + else v.pause(); + onActivity?.(); + } else if (e.key === "f" || e.key === "F") { + void toggleFull(); + } else if (e.key === "Escape" && document.fullscreenElement) { + void document.exitFullscreen(); + } + }; + window.addEventListener("keydown", onKey); + return () => window.removeEventListener("keydown", onKey); + }, [videoRef, toggleFull, onActivity]); + const pct = duration > 0 ? (time / duration) * 100 : 0; return (