diff --git a/static/js/app.js b/static/js/app.js index 799e3c0..b04629b 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -2960,65 +2960,27 @@ async function renderPdf(arrayBuffer, contentEl, scaleOverride) { } // --------------------------------------------------------------------------- -// Immersive reader mode — bars slide out after 5 s, return on edge hover/tap +// Immersive reader mode — tap centre of screen to toggle bars // --------------------------------------------------------------------------- -let _immTimer = null; -let _immTopShowing = false; -let _immBottomShowing = false; -const _IMM_DELAY = 5000; -const _IMM_EDGE = 60; // px from top/bottom edge +let _immBarsVisible = true; -function _immMouseMove(e) { - // When bars are already showing, extend threshold to cover their actual height - const topThreshold = _immTopShowing - ? (document.querySelector('.navbar')?.offsetHeight ?? 0) + - (document.querySelector('.reader-header')?.offsetHeight ?? 0) + 12 - : _IMM_EDGE; - const bottomThreshold = _immBottomShowing - ? (document.querySelector('.now-playing-bar')?.offsetHeight ?? 0) + 12 - : _IMM_EDGE; - - const atTop = e.clientY < topThreshold; - const atBottom = e.clientY > window.innerHeight - bottomThreshold; - if (atTop !== _immTopShowing) { - _immTopShowing = atTop; - document.body.classList.toggle('reader-show-top', atTop); - } - if (atBottom !== _immBottomShowing) { - _immBottomShowing = atBottom; - document.body.classList.toggle('reader-show-bottom', atBottom); - } -} - -function _immTouch(e) { - const y = (e.touches[0] ?? e.changedTouches[0])?.clientY; - if (y == null) return; - if (y < _IMM_EDGE) { - document.body.classList.add('reader-show-top'); - clearTimeout(_immTimer); - _immTimer = setTimeout(() => document.body.classList.remove('reader-show-top'), 3000); - } else if (y > window.innerHeight - _IMM_EDGE) { - document.body.classList.add('reader-show-bottom'); - clearTimeout(_immTimer); - _immTimer = setTimeout(() => document.body.classList.remove('reader-show-bottom'), 3000); - } +function _immHandleTap(e) { + // Ignore taps on interactive elements (buttons, links, inputs, settings panel) + if (e.target.closest('button, a, input, select, label, #reader-settings-panel, .reader-header')) return; + _immBarsVisible = !_immBarsVisible; + document.body.classList.toggle('reader-immersive', !_immBarsVisible); } function enterReaderImmersiveMode() { - clearTimeout(_immTimer); - _immTimer = setTimeout(() => document.body.classList.add('reader-immersive'), _IMM_DELAY); - window.addEventListener('mousemove', _immMouseMove); - window.addEventListener('touchstart', _immTouch, { passive: true }); + _immBarsVisible = true; + document.body.classList.remove('reader-immersive'); + document.addEventListener('click', _immHandleTap); } function exitReaderImmersiveMode() { - clearTimeout(_immTimer); - _immTimer = null; - document.body.classList.remove('reader-immersive', 'reader-show-top', 'reader-show-bottom'); - _immTopShowing = false; - _immBottomShowing = false; - window.removeEventListener('mousemove', _immMouseMove); - window.removeEventListener('touchstart', _immTouch); + _immBarsVisible = true; + document.body.classList.remove('reader-immersive'); + document.removeEventListener('click', _immHandleTap); } async function openBook(bookId) {