feat: refactor PhotoswipeReader to enhance modularity with new components and hooks for improved navigation, image loading, and touch handling
This commit is contained in:
117
src/components/reader/hooks/usePageNavigation.ts
Normal file
117
src/components/reader/hooks/usePageNavigation.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import { useState, useCallback, useRef, useEffect } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { ClientOfflineBookService } from "@/lib/services/client-offlinebook.service";
|
||||
import type { KomgaBook } from "@/types/komga";
|
||||
|
||||
interface UsePageNavigationProps {
|
||||
book: KomgaBook;
|
||||
pages: number[];
|
||||
isDoublePage: boolean;
|
||||
shouldShowDoublePage: (page: number) => boolean;
|
||||
onClose?: (currentPage: number) => void;
|
||||
nextBook?: KomgaBook | null;
|
||||
}
|
||||
|
||||
export function usePageNavigation({
|
||||
book,
|
||||
pages,
|
||||
isDoublePage,
|
||||
shouldShowDoublePage,
|
||||
onClose: _onClose,
|
||||
nextBook,
|
||||
}: UsePageNavigationProps) {
|
||||
const router = useRouter();
|
||||
const [currentPage, setCurrentPage] = useState(() => {
|
||||
const saved = ClientOfflineBookService.getCurrentPage(book);
|
||||
return saved < 1 ? 1 : saved;
|
||||
});
|
||||
const [showEndMessage, setShowEndMessage] = useState(false);
|
||||
const syncTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||
const currentPageRef = useRef(currentPage);
|
||||
|
||||
// Garder currentPage à jour dans la ref pour le cleanup
|
||||
useEffect(() => {
|
||||
currentPageRef.current = currentPage;
|
||||
}, [currentPage]);
|
||||
|
||||
// Sync progress
|
||||
const syncReadProgress = useCallback(
|
||||
async (page: number) => {
|
||||
try {
|
||||
ClientOfflineBookService.setCurrentPage(book, page);
|
||||
const completed = page === pages.length;
|
||||
await fetch(`/api/komga/books/${book.id}/read-progress`, {
|
||||
method: "PATCH",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ page, completed }),
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Sync error:", error);
|
||||
}
|
||||
},
|
||||
[book, pages.length]
|
||||
);
|
||||
|
||||
const debouncedSync = useCallback(
|
||||
(page: number) => {
|
||||
if (syncTimeoutRef.current) {
|
||||
clearTimeout(syncTimeoutRef.current);
|
||||
}
|
||||
syncTimeoutRef.current = setTimeout(() => syncReadProgress(page), 500);
|
||||
},
|
||||
[syncReadProgress]
|
||||
);
|
||||
|
||||
const navigateToPage = useCallback(
|
||||
(page: number) => {
|
||||
if (page >= 1 && page <= pages.length) {
|
||||
setCurrentPage(page);
|
||||
// Mettre à jour le localStorage immédiatement
|
||||
ClientOfflineBookService.setCurrentPage(book, page);
|
||||
// Débouncer seulement l'API Komga
|
||||
debouncedSync(page);
|
||||
}
|
||||
},
|
||||
[pages.length, debouncedSync, book]
|
||||
);
|
||||
|
||||
const handlePreviousPage = useCallback(() => {
|
||||
if (currentPage === 1) return;
|
||||
const step = isDoublePage && shouldShowDoublePage(currentPage - 2) ? 2 : 1;
|
||||
navigateToPage(Math.max(1, currentPage - step));
|
||||
}, [currentPage, isDoublePage, navigateToPage, shouldShowDoublePage]);
|
||||
|
||||
const handleNextPage = useCallback(() => {
|
||||
if (currentPage === pages.length) {
|
||||
if (nextBook) {
|
||||
router.push(`/books/${nextBook.id}`);
|
||||
return;
|
||||
}
|
||||
setShowEndMessage(true);
|
||||
return;
|
||||
}
|
||||
const step = isDoublePage && shouldShowDoublePage(currentPage) ? 2 : 1;
|
||||
navigateToPage(Math.min(pages.length, currentPage + step));
|
||||
}, [currentPage, pages.length, isDoublePage, shouldShowDoublePage, navigateToPage, nextBook, router]);
|
||||
|
||||
// Cleanup - Sync final sans debounce
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (syncTimeoutRef.current) {
|
||||
clearTimeout(syncTimeoutRef.current);
|
||||
}
|
||||
// Sync immédiatement au cleanup avec la VRAIE valeur actuelle
|
||||
syncReadProgress(currentPageRef.current);
|
||||
};
|
||||
}, [syncReadProgress]);
|
||||
|
||||
return {
|
||||
currentPage,
|
||||
setCurrentPage,
|
||||
showEndMessage,
|
||||
setShowEndMessage,
|
||||
navigateToPage,
|
||||
handlePreviousPage,
|
||||
handleNextPage,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user