| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When the sidebar was changed to position:fixed (overlay mode), flex:1
was removed from .main-content. Without flex:1 or an explicit height,
.main-content relied on align-items:stretch for its height constraint.
This is unreliable for establishing a definite height that overflow-y:auto
respects — the element can grow with its content instead of constraining
at 100vh and scrolling.
Add height:100% to .main-content so it has a definite height from the
parent chain (body 100vh → #app 100% → .layout 100% → .main-content 100%).
This ensures overflow-y:auto creates a proper scroll container, which is
required for both the scroll-based infinite loading and mark-as-read to work.
https://claude.ai/code/session_01DpWhB9uGGMBnzqS28HxnuV
|
|
|
The IntersectionObserver approach for infinite scroll was unreliable —
items would not load when scrolling to the bottom in v3, while v1's
polling approach worked fine. The issue was that IntersectionObserver
with a custom root element (main-content, whose height comes from flex
align-items:stretch rather than an explicit height) didn't fire
reliably, and renderItems() being called 3 times per fetch cycle
(from both items-updated and loading-state-changed events) kept
destroying and recreating the observer.
Replace with a simple scroll-position check in the existing onscroll
handler, matching v1's proven approach: when the user scrolls within
200px of the bottom of #main-content, trigger loadMore(). This runs
on every scroll event (cheap arithmetic comparison) and only fires
when content actually overflows the container.
Remove the unused itemObserver module-level variable.
Update regression tests to simulate scroll position instead of
IntersectionObserver callbacks, with 4 cases: scroll near bottom
triggers load, scroll far from bottom doesn't, loading=true blocks,
and hasMore=false hides sentinel.
https://claude.ai/code/session_01DpWhB9uGGMBnzqS28HxnuV
|