fix(web): lecteur PDF/CBZ — pages blanches, timeouts et modes fullscreen
- Rendu PDF via module dédié pdfRender (worker), correction des pages blanches et gestion des timeouts de rendu - Lecteur comics : crop plein écran, locators de page unifiés (pdf/cbz/cbr) avec ancrage pour le calcul de progression - Sauvegarde de progression mise en file (queueSave) pour éviter les pertes lors des navigations rapides - nginx/vite : en-têtes et proxy alignés pour le streaming des livres Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -3,7 +3,7 @@ import type { BookDto } from "@readabook/shared";
|
||||
import { api, getApiFallback } from "../api/client";
|
||||
import { CbzReader } from "../reader/CbzReader";
|
||||
import { EpubReader } from "../reader/EpubReader";
|
||||
import { parseCbrPageLocator, parseCbzPageLocator, parsePdfPageLocator, pdfPagePercent } from "../reader/locators";
|
||||
import { pageLocator, parseCbrPageLocator, parseCbzPageLocator, parsePdfPageLocator, pdfPagePercent } from "../reader/locators";
|
||||
import { PdfReader } from "../reader/PdfReader";
|
||||
import { ReaderShell, type ReaderControls } from "../reader/ReaderShell";
|
||||
import { useReaderPreferences } from "../reader/useReaderPreferences";
|
||||
@ -24,7 +24,7 @@ export function ReaderPage({ bookId }: { bookId: number }) {
|
||||
const [page, setPage] = useState(1);
|
||||
const [readerControls, setReaderControls] = useState<ReaderControls>(idleControls);
|
||||
const [controlsVisible, setControlsVisible] = useState(true);
|
||||
const { progress, saving, error: progressError, save } = useReaderProgress(bookId);
|
||||
const { progress, saving, error: progressError, save, queueSave } = useReaderProgress(bookId);
|
||||
const { preferences, setMode, error: preferencesError } = useReaderPreferences(bookId);
|
||||
|
||||
async function loadBook() {
|
||||
@ -58,20 +58,26 @@ export function ReaderPage({ bookId }: { bookId: number }) {
|
||||
const fileUrl = useMemo(() => api.bookFileUrl(bookId), [bookId]);
|
||||
const backHref = useMemo(() => (book ? `/book/${book.id}` : "/home"), [book]);
|
||||
const savePdfPage = useCallback(
|
||||
(nextPage: number, pages: number) => {
|
||||
(nextPage: number, pages: number, anchor = 1, strategy: "immediate" | "queued" = "immediate") => {
|
||||
setPage(nextPage);
|
||||
void save(`pdf:page:${nextPage}`, pdfPagePercent(nextPage, pages));
|
||||
const locator = pageLocator("pdf", nextPage, anchor);
|
||||
const percent = pdfPagePercent(nextPage, pages, anchor);
|
||||
if (strategy === "queued") queueSave(locator, percent);
|
||||
else void save(locator, percent);
|
||||
},
|
||||
[save]
|
||||
[queueSave, save]
|
||||
);
|
||||
const saveEpubLocator = useCallback((locator: string, percent: number) => void save(locator, percent), [save]);
|
||||
const saveComicPage = useCallback(
|
||||
(nextPage: number, pages: number) => {
|
||||
(nextPage: number, pages: number, anchor = 1, strategy: "immediate" | "queued" = "immediate") => {
|
||||
setPage(nextPage);
|
||||
const prefix = book?.format === "cbr" ? "cbr" : "cbz";
|
||||
void save(`${prefix}:page:${nextPage}`, pdfPagePercent(nextPage, pages));
|
||||
const locator = pageLocator(prefix, nextPage, anchor);
|
||||
const percent = pdfPagePercent(nextPage, pages, anchor);
|
||||
if (strategy === "queued") queueSave(locator, percent);
|
||||
else void save(locator, percent);
|
||||
},
|
||||
[book?.format, save]
|
||||
[book?.format, queueSave, save]
|
||||
);
|
||||
|
||||
const readerError = error ?? progressError ?? preferencesError;
|
||||
|
||||
Reference in New Issue
Block a user