import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { Suspense, lazy, type ComponentType, type LazyExoticComponent } from "react"; import { Link, useNavigate, useParams } from "react-router-dom"; import { api } from "../api/client"; import type { Format } from "../api/types"; import { useAuth } from "../auth/AuthContext"; import { toast } from "../components/Toaster"; import { btn } from "../components/ui"; import type { ReaderProps } from "../lib/useProgress"; const READERS: Partial>>> = { cbz: lazy(() => import("../readers/CbzReader")), txt: lazy(() => import("../readers/TextReader")), md: lazy(() => import("../readers/TextReader")), pdf: lazy(() => import("../readers/PdfReader")), epub: lazy(() => import("../readers/EpubReader")), }; export default function Reader() { const { id: idStr } = useParams(); const id = Number(idStr); const qc = useQueryClient(); const nav = useNavigate(); const { isAdmin } = useAuth(); const bookQ = useQuery({ queryKey: ["book", id], queryFn: () => api.getBook(id), enabled: Number.isFinite(id) }); const progQ = useQuery({ queryKey: ["progress"], queryFn: api.listProgress }); const del = useMutation({ mutationFn: () => api.deleteBook(id), onSuccess: () => { toast("ok", "已删除"); qc.invalidateQueries({ queryKey: ["books"] }); nav("/"); }, onError: (e) => toast("err", e instanceof Error ? e.message : "删除失败"), }); const book = bookQ.data; const body = (() => { if (!Number.isFinite(id)) return ; if (bookQ.isPending) return ; if (bookQ.isError) return ( bookQ.refetch()} /> ); if (!book) return ; if (book.state === "error") return ; if (progQ.isPending) return ; const R = READERS[book.format]; if (!R) return ; const row = (progQ.data ?? []).find((r) => r.library_id === book.library_id && r.path === book.path); return ; })(); return (
← 书架 {book?.title ?? "…"} {book?.library ? book.library + " · " : ""} {book?.format} {book ? ` · ${Math.round(book.percent * 100)}%` : ""} {isAdmin && book && ( )}
}>{body}
); } function Msg({ text, retry }: { text: string; retry?: () => void }) { return (

{text}

{retry && ( )}
); }