chore: initial commit — monorepo ReadaBook (API NestJS, web PWA, Docker)
This commit is contained in:
57
apps/web/src/pages/ReaderPage.tsx
Normal file
57
apps/web/src/pages/ReaderPage.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { ArrowLeft, Save } from "lucide-react";
|
||||
import type { BookDto } from "@readabook/shared";
|
||||
import { api } from "../api/client";
|
||||
import { LoadingState, Meter } from "../components/ui";
|
||||
import { navigate } from "../router";
|
||||
import { EpubReader } from "../reader/EpubReader";
|
||||
import { PdfReader } from "../reader/PdfReader";
|
||||
import { useReaderProgress } from "../reader/useReaderProgress";
|
||||
|
||||
export function ReaderPage({ bookId }: { bookId: number }) {
|
||||
const [book, setBook] = useState<BookDto | null>(null);
|
||||
const [page, setPage] = useState(1);
|
||||
const { progress, saving, save } = useReaderProgress(bookId);
|
||||
|
||||
useEffect(() => {
|
||||
api.book(bookId).then(setBook);
|
||||
}, [bookId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (progress?.locator.startsWith("pdf:page:")) setPage(Number(progress.locator.split(":").at(-1)) || 1);
|
||||
}, [progress]);
|
||||
|
||||
const fileUrl = useMemo(() => api.bookFileUrl(bookId), [bookId]);
|
||||
const savePdfPage = useCallback(
|
||||
(nextPage: number, pages: number) => {
|
||||
setPage(nextPage);
|
||||
void save(`pdf:page:${nextPage}`, Math.round((nextPage / pages) * 100));
|
||||
},
|
||||
[save]
|
||||
);
|
||||
const saveEpubLocator = useCallback((locator: string, percent: number) => void save(locator, percent), [save]);
|
||||
|
||||
if (!book) return <LoadingState label="Ouverture du lecteur" />;
|
||||
|
||||
return (
|
||||
<div className="reader-page">
|
||||
<header className="reader-topbar">
|
||||
<button className="ghost-button" onClick={() => navigate(`/book/${book.id}`)}>
|
||||
<ArrowLeft size={17} />
|
||||
Fiche
|
||||
</button>
|
||||
<div>
|
||||
<strong>{book.title}</strong>
|
||||
<span>{saving ? "Sauvegarde" : "Progression synchronisee"}</span>
|
||||
</div>
|
||||
<Save size={18} />
|
||||
</header>
|
||||
<Meter value={progress?.percent ?? 0} />
|
||||
{book.format === "pdf" ? (
|
||||
<PdfReader url={fileUrl} page={page} onPageChange={savePdfPage} />
|
||||
) : (
|
||||
<EpubReader url={fileUrl} locator={progress?.locator} onLocatorChange={saveEpubLocator} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user