Files
platform/ios
Yusuf Suleman 532a071715
All checks were successful
Security Checks / dependency-audit (push) Successful in 13s
Security Checks / secret-scanning (push) Successful in 4s
Security Checks / dockerfile-lint (push) Successful in 4s
feat: scroll-based mark-as-read with geometry tracking + navigation protection
Uses GeometryReader + coordinate space to track entry positions —
NOT onAppear/onDisappear.

How it works:
1. ScrollView has a named coordinate space ("readerScroll")
2. Invisible anchor at top measures scroll offset via PreferenceKey
3. Each entry row has a background GeometryReader that tracks its
   frame in the scroll coordinate space
4. onChange(of: maxY) detects when an entry's bottom edge crosses
   above the viewport top (oldMaxY >= 0 → newMaxY < 0)
5. Entry is marked read only when ALL conditions are true:
   - trackingActive (user scrolled down >100pt)
   - isScrollingDown (current direction is down)
   - entry is unread
   - entry hasn't been marked by scroll already
   - entry's bottom edge just crossed above viewport

Navigation protection:
- onAppear resets trackingActive = false and cumulativeDown = 0
- When returning from an article, tracking is suspended
- User must scroll down 100pt before tracking reactivates
- This prevents all visible entries from being marked read on
  navigation back (they were already below viewport, not crossing)
- Scrolling up never marks anything (isScrollingDown = false)

State updates are local-first (immediate) with background API sync.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 23:04:32 -05:00
..