"use client"; import { BookReaderProps } from "./types"; import { useOrientation } from "./hooks/useOrientation"; import { usePageNavigation } from "./hooks/usePageNavigation"; import { usePageCache } from "./hooks/usePageCache"; import { useState, useEffect, useCallback } from "react"; import { NavigationBar } from "./components/NavigationBar"; import { ControlButtons } from "./components/ControlButtons"; import { ImageLoader } from "@/components/ui/image-loader"; import { cn } from "@/lib/utils"; export function BookReader({ book, pages, onClose }: BookReaderProps) { const [isDoublePage, setIsDoublePage] = useState(false); const [showControls, setShowControls] = useState(false); const isLandscape = useOrientation(); const { currentPage, navigateToPage, isLoading, setIsLoading, secondPageLoading, setSecondPageLoading, imageError, setImageError, handlePreviousPage, handleNextPage, shouldShowDoublePage, syncReadProgress, } = usePageNavigation({ book, pages, isDoublePage, }); const { preloadPage, getPageUrl, cleanCache } = usePageCache({ book, pages, }); // État pour stocker les URLs des images const [currentPageUrl, setCurrentPageUrl] = useState(""); const [nextPageUrl, setNextPageUrl] = useState(""); // Effet pour charger les URLs des images useEffect(() => { let isMounted = true; const loadPageUrls = async () => { try { const url = await getPageUrl(currentPage); if (isMounted) { setCurrentPageUrl(url); setIsLoading(false); } if (isDoublePage && shouldShowDoublePage(currentPage)) { const nextUrl = await getPageUrl(currentPage + 1); if (isMounted) { setNextPageUrl(nextUrl); setSecondPageLoading(false); } } } catch (error) { console.error("Erreur lors du chargement des URLs:", error); setImageError(true); } finally { // On s'assure que le chargement est terminé même en cas d'erreur if (isMounted) { setIsLoading(false); setSecondPageLoading(false); } } }; setIsLoading(true); setSecondPageLoading(true); loadPageUrls(); return () => { isMounted = false; }; }, [currentPage, isDoublePage, shouldShowDoublePage, getPageUrl]); // Effet pour précharger la page courante et les pages adjacentes useEffect(() => { let isMounted = true; const preloadCurrentPages = async () => { if (!isMounted) return; await preloadPage(currentPage); if (!isMounted) return; if (isDoublePage && shouldShowDoublePage(currentPage)) { await preloadPage(currentPage + 1); } if (!isMounted) return; const pagesToPreload = []; for (let i = 1; i <= 4 && currentPage + i <= pages.length; i++) { pagesToPreload.push(currentPage + i); } for (let i = 1; i <= 2 && currentPage - i >= 1; i++) { pagesToPreload.push(currentPage - i); } for (const page of pagesToPreload) { if (!isMounted) break; await preloadPage(page); } }; preloadCurrentPages(); cleanCache(currentPage); return () => { isMounted = false; }; }, [currentPage, isDoublePage, shouldShowDoublePage, preloadPage, cleanCache, pages.length]); // Effet pour gérer le mode double page automatiquement en paysage useEffect(() => { setIsDoublePage(isLandscape); }, [isLandscape]); const handleThumbnailLoad = useCallback( (pageNumber: number) => { if (pageNumber === currentPage) { setIsLoading(false); } else if (pageNumber === currentPage + 1) { setSecondPageLoading(false); } }, [currentPage] ); return (
setShowControls(!showControls)} > {/* Contenu principal */}
setShowControls(!showControls)} onPreviousPage={handlePreviousPage} onNextPage={handleNextPage} onClose={onClose} currentPage={currentPage} totalPages={pages.length} isDoublePage={isDoublePage} onToggleDoublePage={() => setIsDoublePage(!isDoublePage)} /> {/* Pages */}
{/* Page courante */}
{currentPageUrl && ( {`Page handleThumbnailLoad(currentPage)} /> )}
{/* Deuxième page en mode double page */} {isDoublePage && shouldShowDoublePage(currentPage) && (
{nextPageUrl && ( {`Page handleThumbnailLoad(currentPage + 1)} /> )}
)}
); }