Sync URL and prev/next nav with the chapter being viewed
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>
This commit is contained in:
parent
cad59143a3
commit
1c74348fae
@ -50,16 +50,6 @@ export default async function ChapterReaderPage({ params }: Props) {
|
|||||||
const currentChapter = manga.chapters.find((c) => c.number === chapterNum);
|
const currentChapter = manga.chapters.find((c) => c.number === chapterNum);
|
||||||
if (!currentChapter) notFound();
|
if (!currentChapter) notFound();
|
||||||
|
|
||||||
const chapterIndex = manga.chapters.findIndex(
|
|
||||||
(c) => c.number === chapterNum
|
|
||||||
);
|
|
||||||
const prevChapter =
|
|
||||||
chapterIndex > 0 ? manga.chapters[chapterIndex - 1].number : null;
|
|
||||||
const nextChapter =
|
|
||||||
chapterIndex < manga.chapters.length - 1
|
|
||||||
? manga.chapters[chapterIndex + 1].number
|
|
||||||
: null;
|
|
||||||
|
|
||||||
const allChapters = manga.chapters.map((c) => ({
|
const allChapters = manga.chapters.map((c) => ({
|
||||||
id: c.id,
|
id: c.id,
|
||||||
number: c.number,
|
number: c.number,
|
||||||
@ -72,8 +62,6 @@ export default async function ChapterReaderPage({ params }: Props) {
|
|||||||
mangaSlug={manga.slug}
|
mangaSlug={manga.slug}
|
||||||
mangaTitle={manga.title}
|
mangaTitle={manga.title}
|
||||||
startChapterNumber={currentChapter.number}
|
startChapterNumber={currentChapter.number}
|
||||||
prevChapter={prevChapter}
|
|
||||||
nextChapter={nextChapter}
|
|
||||||
chapters={allChapters}
|
chapters={allChapters}
|
||||||
initialChapterMeta={initialChapterMeta}
|
initialChapterMeta={initialChapterMeta}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -29,8 +29,6 @@ type PageReaderProps = {
|
|||||||
mangaSlug: string;
|
mangaSlug: string;
|
||||||
mangaTitle: string;
|
mangaTitle: string;
|
||||||
startChapterNumber: number;
|
startChapterNumber: number;
|
||||||
prevChapter: number | null;
|
|
||||||
nextChapter: number | null;
|
|
||||||
chapters: ChapterMeta[];
|
chapters: ChapterMeta[];
|
||||||
initialChapterMeta: PageMeta[];
|
initialChapterMeta: PageMeta[];
|
||||||
};
|
};
|
||||||
@ -51,8 +49,6 @@ export function PageReader({
|
|||||||
mangaSlug,
|
mangaSlug,
|
||||||
mangaTitle,
|
mangaTitle,
|
||||||
startChapterNumber,
|
startChapterNumber,
|
||||||
prevChapter,
|
|
||||||
nextChapter,
|
|
||||||
chapters,
|
chapters,
|
||||||
initialChapterMeta,
|
initialChapterMeta,
|
||||||
}: PageReaderProps) {
|
}: PageReaderProps) {
|
||||||
@ -272,6 +268,25 @@ export function PageReader({
|
|||||||
});
|
});
|
||||||
}, [mangaSlug, currentChapterNum, currentPageNum]);
|
}, [mangaSlug, currentChapterNum, currentPageNum]);
|
||||||
|
|
||||||
|
// Keep URL in sync with the chapter currently in the viewport so browser
|
||||||
|
// back / reload returns to the latest chapter, not the one first opened.
|
||||||
|
useEffect(() => {
|
||||||
|
const url = `/manga/${mangaSlug}/${currentChapterNum}`;
|
||||||
|
if (window.location.pathname === url) return;
|
||||||
|
window.history.replaceState(window.history.state, "", url);
|
||||||
|
}, [mangaSlug, currentChapterNum]);
|
||||||
|
|
||||||
|
const { prevChapter, nextChapter } = useMemo(() => {
|
||||||
|
const idx = chapters.findIndex((c) => c.number === currentChapterNum);
|
||||||
|
return {
|
||||||
|
prevChapter: idx > 0 ? chapters[idx - 1].number : null,
|
||||||
|
nextChapter:
|
||||||
|
idx >= 0 && idx < chapters.length - 1
|
||||||
|
? chapters[idx + 1].number
|
||||||
|
: null,
|
||||||
|
};
|
||||||
|
}, [chapters, currentChapterNum]);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const touchMovedRef = useRef(false);
|
const touchMovedRef = useRef(false);
|
||||||
const singleTapTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
const singleTapTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user