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;