diff --git a/frontend/components/SlideControls.js b/frontend/components/SlideControls.js index 60a6380eb0..0b096d6996 100644 --- a/frontend/components/SlideControls.js +++ b/frontend/components/SlideControls.js @@ -1,6 +1,35 @@ -import { html } from "../imports/Preact.js" +import { html, useRef, useState, useLayoutEffect, useEffect } from "../imports/Preact.js" +import { open_pluto_popup } from "./Popup.js" export const SlideControls = () => { + const button_prev_ref = useRef(/** @type {HTMLButtonElement?} */ (null)) + const button_next_ref = useRef(/** @type {HTMLButtonElement?} */ (null)) + + const [presenting, set_presenting] = useState(false) + + const move_slides_with_keyboard = (/** @type {KeyboardEvent} */ e) => { + const activeElement = document.activeElement + if ( + activeElement != null && + activeElement !== document.body && + activeElement !== button_prev_ref.current && + activeElement !== button_next_ref.current + ) { + // We do not move slides with arrow if we have an active element + return + } + if (e.key === "ArrowLeft" || e.key === "PageUp") { + button_prev_ref.current?.click() + } else if (e.key === "ArrowRight" || e.key === " " || e.key === "PageDown") { + button_next_ref.current?.click() + } else if (e.key === "Escape") { + set_presenting(false) + } else { + return + } + e.preventDefault() + } + const calculate_slide_positions = (/** @type {Event} */ e) => { const notebook_node = /** @type {HTMLElement?} */ (e.target)?.closest("pluto-editor")?.querySelector("pluto-notebook") if (!notebook_node) return [] @@ -40,15 +69,29 @@ export const SlideControls = () => { if (pos) window.scrollTo(window.pageXOffset, pos) } + const presenting_ref = useRef(false) + presenting_ref.current = presenting // @ts-ignore window.present = () => { - document.body.classList.toggle("presentation") + set_presenting(!presenting_ref.current) } + useLayoutEffect(() => { + document.body.classList.toggle("presentation", presenting) + + if (!presenting) return // We do not add listeners if not presenting + + window.addEventListener("keydown", move_slides_with_keyboard) + + return () => { + window.removeEventListener("keydown", move_slides_with_keyboard) + } + }, [presenting]) + return html` ` }