diff --git a/components/PageReader.tsx b/components/PageReader.tsx index a510875..58ef609 100644 --- a/components/PageReader.tsx +++ b/components/PageReader.tsx @@ -15,6 +15,7 @@ import { readProgress, writeProgress, } from "@/components/ReadingProgressButton"; +import { isPageReload } from "@/lib/progress"; import { LoadingLogo } from "@/components/LoadingLogo"; import { calcScrollRatio, @@ -70,7 +71,8 @@ export function PageReader({ const [currentChapterNum, setCurrentChapterNum] = useState(startChapterNumber); const [currentPageNum, setCurrentPageNum] = useState(() => { - if (typeof window === "undefined" || !resume) return 1; + if (typeof window === "undefined") return 1; + if (!resume && !isPageReload()) return 1; const p = readProgress(mangaSlug); if (p && p.chapter === startChapterNumber && p.page > 1) return p.page; return 1; @@ -322,15 +324,17 @@ export function PageReader({ // All reader Links use scroll={false} to preserve scroll during in-reader // nav (natural scroll between chapters updates URL without remount). On - // a fresh mount we must actively position the scroll: resume-to-saved - // if ?resume=1 AND the saved chapter matches; otherwise top. + // a fresh mount we position scroll: resume-to-saved if ?resume=1 (from + // 继续阅读) OR a page reload (so browser refresh preserves position). + // Plain chapter-link clicks from drawer / list go to top. const resumeDoneRef = useRef(false); useLayoutEffect(() => { if (resumeDoneRef.current) return; resumeDoneRef.current = true; const instantTop = (top: number) => window.scrollTo({ top, behavior: "instant" as ScrollBehavior }); - if (!resume) { + const shouldResume = resume || isPageReload(); + if (!shouldResume) { instantTop(0); return; } diff --git a/lib/progress.ts b/lib/progress.ts index 63ad6d4..eae80d0 100644 --- a/lib/progress.ts +++ b/lib/progress.ts @@ -66,3 +66,13 @@ export function writeProgress( function defaultStorage(): StorageLike | null { return typeof window === "undefined" ? null : window.localStorage; } + +export function isPageReload(): boolean { + if (typeof window === "undefined") return false; + if (typeof performance === "undefined") return false; + const entries = performance.getEntriesByType("navigation"); + if (entries.length === 0) return false; + return ( + (entries[0] as PerformanceNavigationTiming).type === "reload" + ); +}