Simplify immersive reader: tap centre to toggle bars
All checks were successful
Build and push Docker image / build (push) Successful in 12s
Test / test (push) Successful in 15s

Replace timer/edge-hover system with a simple click-to-toggle.
Tapping interactive elements (buttons, links, settings) is ignored.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
marwin 2026-04-01 15:50:31 +02:00
parent 2448586050
commit dbe3b46f3e

View file

@ -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) {