- Resume scroll position only when arriving via 继续阅读 (?resume=1).
Plain chapter-list / drawer clicks now actively scroll to top on mount.
- Progress format extended to {chapter, page, ratio} for within-page
precision; legacy bare-number and {chapter, page} still read correctly.
- Tappable skeleton logo (sunflower outline, spins) while a page loads;
tap force-fetches a fresh signed URL.
- Viewport-priority image loading: second IntersectionObserver at margin 0
marks truly-visible pages, drives <img fetchpriority="high"> and fires
immediate single-page fetches that cut the batch queue.
- Bounded image cache: unmount previous chapter's <img> elements when
currentPage > 5 into the new chapter; placeholders stay for layout.
One AbortController per live chapter; unmount aborts in-flight batches.
- Hashed chapter IDs on the wire via hashids; DB PKs unchanged.
- Origin/Referer allowlist + rate limiting on all /api/* routes via a
withGuards(opts, handler) wrapper (eliminates 6-line boilerplate x5).
- robots.txt allows Googlebot/Bingbot/Slurp/DuckDuckBot/Baiduspider/
YandexBot only; disallows /api/ for all UAs.
- Extract pure helpers for future TDD: lib/scroll-ratio.ts (calcScrollRatio,
scrollOffsetFromRatio), lib/progress.ts (parseProgress + injectable
StorageLike), lib/rate-limit.ts (optional { now, store, ipOf } deps),
lib/api-guards.ts.
- New env keys: HASHIDS_SALT, ALLOWED_ORIGINS (wired into docker-compose).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Once continuous scroll crosses a chapter boundary, the URL was stuck at
the originally-opened chapter so browser back / reload would jump the
user back there. Double-tap left/right also walked off the wrong chapter
since prevChapter/nextChapter were frozen at mount time.
- replaceState the URL as currentChapterNum changes (no server refetch).
- Derive prevChapter/nextChapter dynamically via useMemo on
currentChapterNum, dropping the now-redundant server-computed props.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces the prepend/flushSync/scrollBy gymnastics with placeholder divs
sized by each page's width/height. Document height is correct from the
first paint, so resume + backward scroll just work — no scroll
compensation, no gesture fights, no forced aspect ratio distorting images.
- New /api/chapters/[id]/meta returns the dim skeleton for any chapter.
- Chapter page pre-fetches the starting chapter's meta server-side and
parallelizes the two Prisma queries via Promise.all.
- Reader renders placeholders with aspectRatio: w/h, lazy-loads image
URLs in batches via IntersectionObserver, and prefetches the next
chapter's meta ~3 pages from the end.
- Scroll tracker walks only the intersecting-pages set (~3–5 elements)
instead of every loaded page per rAF.
- scroll={false} on all Links into the reader + { scroll: false } on
double-tap router.push, plus a belt-and-suspenders rAF re-scroll, so
resume survives soft navigation and browser scroll-restoration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces the fixed-position reader with a sticky layout that works
correctly on iPhone Safari and Edge, while also auto-appending the
next chapter's pages when the current one finishes.
Layout
- Swap all position:fixed for sticky (Header, BottomNav, reader top nav)
— fixed-positioning quirks broke the bottom nav in Edge and
prevented Safari's URL bar from collapsing on scroll
- Viewport: viewport-fit=cover + interactiveWidget=overlays-content
so manga extends edge-to-edge and the URL bar overlays content
without resizing the viewport
- Add pt-safe / pb-safe utilities; apply on nav bars so chrome
respects the notch and home-indicator
- Drop fixed-positioning bottom padding now that BottomNav is in flow
Continuous reading
- PageReader now receives the full chapter manifest (id + totalPages)
and auto-fetches the next chapter when the current one is done
- Subtle chapter divider strip appears between chapters in the scroll
- Top nav chapter title updates as the user scrolls into a new chapter
(rAF-throttled scroll listener, cached offsetTop)
- Double-tap on left/right viewport half navigates prev/next chapter
- End-of-manga footer fills the viewport with a Back-to-Manga action
Theme polish
- Light theme: white body/background, blue accent preserved for
chapter numbers, badges, active states
- Modern chapter drawer: white sheet, rounded-t-3xl, two-column
rows with chapter-number badge, blue highlight for current chapter
- Suppress hydration warnings for extension-injected attributes on
<html> and the search input
- Manga detail CTA localized to 开始阅读
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Sign all image URLs server-side with 60s expiry presigned URLs
- Add /api/pages endpoint for batched page fetching (7 per batch)
- PageReader prefetches next batch when user scrolls to 3rd page
- Move chapter count badge outside overflow-hidden for 3D effect
- Fix missing URL signing on search and genre pages
- Extract signCoverUrls helper to reduce duplication
- Clamp API limit param to prevent abuse
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Nav bars hide when scrolling down and reappear on scroll up.
Replace static page count with a chapter picker that opens as a
bottom sheet drawer for quick chapter navigation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>