feat(reader): immersive chrome + WeChat-Read/Mihon-style bottom sheets — tap-center toggles header/toolbar, progress & page sliders seek anywhere, WYSIWYG theme swatches, A± font size; CBZ gains 连读/整页/适高 modes, edge-tap & arrow-key paging, persisted mode (seekChapter helper + test)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { Suspense, lazy, type ComponentType, type LazyExoticComponent } from "react";
|
||||
import { Suspense, lazy, useCallback, useMemo, useState, 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";
|
||||
@@ -22,6 +22,11 @@ export default function Reader() {
|
||||
const qc = useQueryClient();
|
||||
const nav = useNavigate();
|
||||
const { isAdmin } = useAuth();
|
||||
const [chromeOn, setChromeOn] = useState(true);
|
||||
|
||||
const toggle = useCallback(() => setChromeOn((v) => !v), []);
|
||||
const show = useCallback(() => setChromeOn(true), []);
|
||||
const chrome = useMemo(() => ({ on: chromeOn, toggle, show }), [chromeOn, toggle, show]);
|
||||
|
||||
const bookQ = useQuery({ queryKey: ["book", id], queryFn: () => api.getBook(id), enabled: Number.isFinite(id) });
|
||||
const progQ = useQuery({ queryKey: ["progress"], queryFn: api.listProgress });
|
||||
@@ -52,12 +57,17 @@ export default function Reader() {
|
||||
const R = READERS[book.format];
|
||||
if (!R) return <Msg text={`暂不支持的格式:${book.format}`} />;
|
||||
const row = (progQ.data ?? []).find((r) => r.library_id === book.library_id && r.path === book.path);
|
||||
return <R book={book} initialLocator={row?.locator} />;
|
||||
return <R book={book} initialLocator={row?.locator} chrome={chrome} />;
|
||||
})();
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-col">
|
||||
<header className="flex shrink-0 items-center gap-3 border-b border-stone-800/80 bg-stone-950/80 px-4 py-2 text-sm backdrop-blur">
|
||||
<header
|
||||
className={
|
||||
"flex shrink-0 items-center gap-3 overflow-hidden border-b border-stone-800/80 bg-stone-950/80 px-4 text-sm backdrop-blur transition-all duration-300 " +
|
||||
(chromeOn ? "h-11 py-2 opacity-100" : "h-0 border-b-0 py-0 opacity-0")
|
||||
}
|
||||
>
|
||||
<Link
|
||||
to="/"
|
||||
className="shrink-0 rounded-md px-2 py-1 text-stone-400 transition-colors hover:bg-stone-800 hover:text-stone-100"
|
||||
|
||||
Reference in New Issue
Block a user