Step through slides with the arrow keys

Somebody standing at a display who wants to hold a slide, or go back to one that
has just passed, had to wait for the whole rotation to come round again.

Left and right arrows step back and forward; PageUp and PageDown do the same, so
a presenter remote works without being told about it. The listener is on window
rather than an element because a display has nothing focused.

Stepping restarts the rotation timer instead of leaving it running. Advancing by
hand and then having it move again a second later, because the existing timer
was nearly up, reads as the display ignoring the keypress.

Ignored entirely when there is less than one slide to move to.
This commit is contained in:
cproudlock
2026-08-06 07:27:59 -04:00
parent 8e6f6ad58b
commit a18335b61c

View File

@@ -67,9 +67,14 @@ onMounted(async () => {
// Refresh slide list every 60 seconds
refreshTimer = setInterval(fetchSlides, 60000)
// On window, not on an element: the display has nothing focused, and a
// presenter remote sends the same keys as a keyboard.
window.addEventListener('keydown', onKeydown)
})
onUnmounted(() => {
window.removeEventListener('keydown', onKeydown)
if (slideTimer) clearTimeout(slideTimer)
if (progressTimer) clearTimeout(progressTimer)
if (refreshTimer) clearInterval(refreshTimer)
@@ -139,6 +144,32 @@ function nextSlide() {
if (slides.value.length === 0) return
currentSlide.value = (currentSlide.value + 1) % slides.value.length
}
function previousSlide() {
if (slides.value.length === 0) return
const count = slides.value.length
currentSlide.value = (currentSlide.value - 1 + count) % count
}
// Left and right arrows step through the slides by hand. Someone standing at
// the display wanting to hold a slide, or go back to one that has just passed,
// otherwise has to wait for the whole rotation to come round again.
//
// Stepping RESTARTS the timer rather than leaving it running: advancing
// manually and then having it move again a second later, because the existing
// timer was most of the way through, reads as the display ignoring you.
function onKeydown(event) {
if (slides.value.length < 2) return
if (event.key === 'ArrowRight' || event.key === 'PageDown') {
event.preventDefault()
nextSlide()
scheduleNextSlide()
} else if (event.key === 'ArrowLeft' || event.key === 'PageUp') {
event.preventDefault()
previousSlide()
scheduleNextSlide()
}
}
</script>
<style scoped>