Skip to content

Commit

Permalink
add keyboard shortcuts (LeftArrow and RightArrow) to move slides in p…
Browse files Browse the repository at this point in the history
…resentation mode (#2611)
  • Loading branch information
disberd authored Sep 16, 2023
1 parent a86709b commit ea89479
Showing 1 changed file with 47 additions and 4 deletions.
51 changes: 47 additions & 4 deletions frontend/components/SlideControls.js
Original file line number Diff line number Diff line change
@@ -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 []
Expand Down Expand Up @@ -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`
<nav id="slide_controls">
<button class="changeslide prev" title="Previous slide" onClick=${go_previous_slide}><span></span></button>
<button class="changeslide next" title="Next slide" onClick=${go_next_slide}><span></span></button>
<button ref=${button_prev_ref} class="changeslide prev" title="Previous slide" onClick=${go_previous_slide}><span></span></button>
<button ref=${button_next_ref} class="changeslide next" title="Next slide" onClick=${go_next_slide}><span></span></button>
</nav>
`
}

0 comments on commit ea89479

Please sign in to comment.