diff --git a/plugins/slides/frontend/views/TVDashboard.vue b/plugins/slides/frontend/views/TVDashboard.vue index 6a2ad27..dd503d0 100644 --- a/plugins/slides/frontend/views/TVDashboard.vue +++ b/plugins/slides/frontend/views/TVDashboard.vue @@ -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() + } +}