Reader: treat browser refresh as implicit resume
Refreshing the chapter page was landing the user back at the top, because only ?resume=1 triggered the saved-position restore. Added isPageReload() helper (checks performance navigation entry type === 'reload') and OR'd it with the resume flag. Refresh now restores to the last scroll position; drawer/list clicks still go to top as intended. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fb2b032d73
commit
95135942a2
@ -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;
|
||||
}
|
||||
|
||||
@ -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"
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user