mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-17 10:15:27 -04:00
Cookbook auto-fold: capture-phase scroll listener catches hwfit-list
IntersectionObserver missed the case because scrolling inside the nested .hwfit-list (max-height:52vh own scroller) doesn't move the header out of view at all. The user wants any downward scroll in the scan/download area to fold Direct Download. Switched to a capture-phase scroll listener on #cookbook-modal that catches every scroll event from any nested scroller (.hwfit-list, .cookbook-body, .modal-content). Folds only on downward scrolls so scrolling back up doesn't keep re-folding.
This commit is contained in:
+19
-21
@@ -1415,29 +1415,27 @@ function _wireTabEvents(body) {
|
|||||||
const folded = dlFoldBody.style.display === 'none';
|
const folded = dlFoldBody.style.display === 'none';
|
||||||
_setFolded(!folded);
|
_setFolded(!folded);
|
||||||
});
|
});
|
||||||
// Auto-fold when the user scrolls past the Direct Download header.
|
// Auto-fold when the user scrolls inside any scroll container —
|
||||||
// Use IntersectionObserver — fires whenever the header element
|
// the outer cookbook-body / modal-content (which moves the header
|
||||||
// crosses the viewport edge, regardless of which scroll container
|
// out of view) OR the nested hwfit results list (which doesn't
|
||||||
// moved (cookbook-body, modal-content, hwfit-list, viewport, etc).
|
// move the header but signals the user is now focused on results).
|
||||||
// Doesn't auto-unfold; the chevron ▸ still expands manually.
|
// Doesn't auto-unfold; chevron ▸ still expands manually.
|
||||||
let _ioPrimed = false;
|
const _maybeFold = () => {
|
||||||
const _io = new IntersectionObserver((entries) => {
|
|
||||||
const entry = entries[0];
|
|
||||||
if (!entry) return;
|
|
||||||
// Skip the initial firing where the header is already in view.
|
|
||||||
if (!_ioPrimed) {
|
|
||||||
_ioPrimed = true;
|
|
||||||
if (entry.isIntersecting) return;
|
|
||||||
}
|
|
||||||
if (entry.isIntersecting) return;
|
|
||||||
// Only fold when scrolled ABOVE the viewport (not when the modal
|
|
||||||
// closes / detaches under it). boundingClientRect.top < 0 means
|
|
||||||
// the header was pushed off the top.
|
|
||||||
if (entry.boundingClientRect.top >= 0) return;
|
|
||||||
if (dlFoldBody.style.display === 'none') return;
|
if (dlFoldBody.style.display === 'none') return;
|
||||||
_setFolded(true, /* persist */ false);
|
_setFolded(true, /* persist */ false);
|
||||||
}, { threshold: 0 });
|
};
|
||||||
_io.observe(dlFold);
|
// Catch every scroll event anywhere inside the cookbook modal
|
||||||
|
// (capture phase so even non-bubbling scrolls on nested scrollers
|
||||||
|
// like .hwfit-list hit us).
|
||||||
|
const _modal = dlFold.closest('#cookbook-modal') || document;
|
||||||
|
let _lastY = 0;
|
||||||
|
_modal.addEventListener('scroll', (e) => {
|
||||||
|
// Only fold on scroll DOWN — ignore upward / horizontal scrolls.
|
||||||
|
const tgt = e.target;
|
||||||
|
const y = (tgt && typeof tgt.scrollTop === 'number') ? tgt.scrollTop : 0;
|
||||||
|
if (y > _lastY) _maybeFold();
|
||||||
|
_lastY = y;
|
||||||
|
}, true);
|
||||||
}
|
}
|
||||||
const hfToggle = document.getElementById('cookbook-hf-latest-toggle');
|
const hfToggle = document.getElementById('cookbook-hf-latest-toggle');
|
||||||
const hfArrow = document.getElementById('cookbook-hf-latest-arrow');
|
const hfArrow = document.getElementById('cookbook-hf-latest-arrow');
|
||||||
|
|||||||
Reference in New Issue
Block a user