Compare commits

...

2 Commits

3 changed files with 117 additions and 6 deletions

View File

@ -6,6 +6,7 @@ import { useMarkContentAsRead } from "@/api/generated/user-interaction/user-inte
import { ThemeToggle } from "@/components/ThemeToggle.tsx"; import { ThemeToggle } from "@/components/ThemeToggle.tsx";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { useReadingTracker } from "@/features/chapter/hooks/useReadingTracker.ts"; import { useReadingTracker } from "@/features/chapter/hooks/useReadingTracker.ts";
import { MangaLoadingState } from "@/components/MangaLoadingState.tsx";
const Chapter = () => { const Chapter = () => {
const { setCurrentChapterPage, getCurrentChapterPage } = useReadingTracker(); const { setCurrentChapterPage, getCurrentChapterPage } = useReadingTracker();
@ -109,6 +110,14 @@ const Chapter = () => {
} }
}, [infiniteScroll]); }, [infiniteScroll]);
if (isLoading) {
return (
<div className="flex min-h-screen items-center justify-center bg-background">
<MangaLoadingState />
</div>
);
}
if (!data?.data) { if (!data?.data) {
return ( return (
<div className="flex min-h-screen items-center justify-center bg-background"> <div className="flex min-h-screen items-center justify-center bg-background">
@ -125,6 +134,25 @@ const Chapter = () => {
} }
const images = data.data.contentImageKeys; const images = data.data.contentImageKeys;
const previousContentId = data.data.previousContentId;
const nextContentId = data.data.nextContentId;
const goToNextChapter = () => {
if (nextContentId) {
setCurrentPage(1);
setVisibleCount(1);
window.scrollTo({ top: 0 });
navigate(`/manga/${mangaId}/chapter/${nextContentId}`);
}
};
const goToPreviousChapter = () => {
if (previousContentId) {
setCurrentPage(1);
setVisibleCount(1);
window.scrollTo({ top: 0 });
navigate(`/manga/${mangaId}/chapter/${previousContentId}`);
}
};
/** Standard navigation (non-infinite mode) */ /** Standard navigation (non-infinite mode) */
const goToNextPage = () => { const goToNextPage = () => {
@ -171,10 +199,33 @@ const Chapter = () => {
<h1 className="text-sm font-semibold text-foreground"> <h1 className="text-sm font-semibold text-foreground">
{data.data.mangaTitle} {data.data.mangaTitle}
</h1> </h1>
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground text-center">
Chapter {chapterNumber} {chapterNumber}
</p> </p>
</div> </div>
{previousContentId && (
<Button
variant="ghost"
size="sm"
onClick={goToPreviousChapter}
className="gap-1"
>
<ChevronLeft className="h-4 w-4" />
<span className="hidden sm:inline">Prev</span>
</Button>
)}
{nextContentId && (
<Button
variant="ghost"
size="sm"
onClick={goToNextChapter}
className="gap-1"
>
<span className="hidden sm:inline">Next</span>
<ChevronRight className="h-4 w-4" />
</Button>
)}
</div> </div>
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
@ -202,7 +253,7 @@ const Chapter = () => {
{data.data.mangaTitle} {data.data.mangaTitle}
</h1> </h1>
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
Chapter {chapterNumber} {chapterNumber}
</p> </p>
</div> </div>
@ -224,6 +275,36 @@ const Chapter = () => {
{/* LOAD MORE SENTINEL */} {/* LOAD MORE SENTINEL */}
<div ref={loadMoreRef} className="h-10" /> <div ref={loadMoreRef} className="h-10" />
{/* CHAPTER NAVIGATION (infinite scroll mode) */}
{(previousContentId || nextContentId) && (
<div className="flex items-center justify-center gap-3 border-t border-border py-6">
{previousContentId ? (
<Button
onClick={goToPreviousChapter}
variant="outline"
className="gap-2 bg-transparent"
>
<ChevronLeft className="h-4 w-4" />
Previous
</Button>
) : (
<div className="flex-1" />
)}
{nextContentId ? (
<Button
onClick={goToNextChapter}
variant="outline"
className="gap-2 bg-transparent"
>
Next
<ChevronRight className="h-4 w-4" />
</Button>
) : (
<div className="flex-1" />
)}
</div>
)}
</div> </div>
) : ( ) : (
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
@ -271,6 +352,36 @@ const Chapter = () => {
<ChevronRight className="h-4 w-4" /> <ChevronRight className="h-4 w-4" />
</Button> </Button>
</div> </div>
{/* CHAPTER NAVIGATION */}
{(previousContentId || nextContentId) && (
<div className="flex items-center justify-center gap-3 border-t border-border pt-4">
{previousContentId ? (
<Button
onClick={goToPreviousChapter}
variant="outline"
className="gap-2 bg-transparent"
>
<ChevronLeft className="h-4 w-4" />
Previous
</Button>
) : (
<div className="flex-1" />
)}
{nextContentId ? (
<Button
onClick={goToNextChapter}
variant="outline"
className="gap-2 bg-transparent"
>
Next
<ChevronRight className="h-4 w-4" />
</Button>
) : (
<div className="flex-1" />
)}
</div>
)}
</div> </div>
</> </>
)} )}

View File

@ -11,7 +11,7 @@ import { Skeleton } from "@/components/ui/skeleton.tsx";
import { useUIState } from "@/contexts/UIStateContext.tsx"; import { useUIState } from "@/contexts/UIStateContext.tsx";
import { FilterSidebar } from "@/features/home/components/FilterSidebar.tsx"; import { FilterSidebar } from "@/features/home/components/FilterSidebar.tsx";
import { MangaGrid } from "@/features/home/components/MangaGrid.tsx"; import { MangaGrid } from "@/features/home/components/MangaGrid.tsx";
import { MangaLoadingState } from "@/features/home/components/MangaLoadingState.tsx"; import { MangaLoadingState } from "@/components/MangaLoadingState.tsx";
import { SortDropdown } from "@/features/home/components/SortDropdown.tsx"; import { SortDropdown } from "@/features/home/components/SortDropdown.tsx";
import { useDynamicPageSize } from "@/hooks/useDynamicPageSize.ts"; import { useDynamicPageSize } from "@/hooks/useDynamicPageSize.ts";