From 89cb70392adb6001bc704c6ab18a55665c3ceb74 Mon Sep 17 00:00:00 2001 From: marwin Date: Sun, 5 Apr 2026 18:32:32 +0200 Subject: [PATCH] j/k scroll continuously while held, stop on keyup Uses a 16ms interval (~60fps) instead of per-event smooth scroll, so holding j/k scrolls fluidly. d/u/f/b remain one-shot with smooth. Co-Authored-By: Claude Sonnet 4.6 --- static/js/app.js | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/static/js/app.js b/static/js/app.js index e7255b2..83c238e 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -2117,10 +2117,17 @@ document.addEventListener('keydown', e => { if (tag !== 'INPUT' && tag !== 'TEXTAREA') { const contentEl = $('reader-content'); if (contentEl) { - const small = Math.round(contentEl.clientHeight * 0.08); const large = Math.round(contentEl.clientHeight * 0.85); - if (e.key === 'j') { e.preventDefault(); contentEl.scrollBy({top: small, behavior: 'smooth'}); } - if (e.key === 'k') { e.preventDefault(); contentEl.scrollBy({top: -small, behavior: 'smooth'}); } + const continuousKeys = {'j': 8, 'k': -8}; + if (continuousKeys[e.key] !== undefined && !e.repeat) { + e.preventDefault(); + _readerScrollStep = continuousKeys[e.key]; + if (!_readerScrollInterval) { + _readerScrollInterval = setInterval(() => { + $('reader-content')?.scrollBy({top: _readerScrollStep}); + }, 16); + } + } if (e.key === 'd') { e.preventDefault(); contentEl.scrollBy({top: large / 2, behavior: 'smooth'}); } if (e.key === 'u') { e.preventDefault(); contentEl.scrollBy({top: -large / 2, behavior: 'smooth'}); } if (e.key === 'f') { e.preventDefault(); contentEl.scrollBy({top: large, behavior: 'smooth'}); } @@ -2136,6 +2143,13 @@ document.addEventListener('keydown', e => { } }); +document.addEventListener('keyup', e => { + if (e.key === 'j' || e.key === 'k') { + clearInterval(_readerScrollInterval); + _readerScrollInterval = null; + } +}); + function sanitizeSidebarHtml(html) { if (!html) return '

No show notes available.

'; const div = document.createElement('div'); @@ -2748,6 +2762,8 @@ let pdfTotalPages = 0; let _pdfPageTextBoxCache = {}; let _pdfRenderGen = 0; let _touchStartX = 0; +let _readerScrollInterval = null; +let _readerScrollStep = 0; let _pinchStartDist = 0; let _pinchStartZoom = 100; let _isPinching = false;