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:
2026-09-07 23:03:26 +08:00
parent 7e63c21902
commit 065fde5b56
9 changed files with 330 additions and 102 deletions
+7
View File
@@ -47,3 +47,10 @@ export function splitChapters(text: string): TxtChapter[] {
export function chapterText(text: string, chapters: TxtChapter[], i: number): string {
return text.slice(chapters[i].start, chapters[i + 1]?.start ?? text.length);
}
/** 全书进度分数(0..1)→ 章序号 + 章内分数。进度滑条用。 */
export function seekChapter(n: number, frac: number): { idx: number; intra: number } {
const p = Math.min(0.9999, Math.max(0, frac)) * n;
const idx = Math.min(n - 1, Math.floor(p));
return { idx, intra: p - idx };
}
+1 -2
View File
@@ -28,8 +28,7 @@ export function useReaderPrefs() {
return {
prefs,
fontSize: FONT_SIZES[prefs.sizeIdx],
cycleTheme: () =>
setPrefs((p) => ({ ...p, theme: RD_THEMES[(RD_THEMES.indexOf(p.theme) + 1) % RD_THEMES.length] })),
setTheme: (theme: RdTheme) => setPrefs((p) => ({ ...p, theme })),
bump: (d: number) =>
setPrefs((p) => ({ ...p, sizeIdx: Math.min(FONT_SIZES.length - 1, Math.max(0, p.sizeIdx + d)) })),
};
+7
View File
@@ -4,9 +4,16 @@ import { api } from "../api/client";
import type { Book } from "../api/types";
import { createProgressSaver, type ProgressSaver } from "./progress";
export interface Chrome {
on: boolean;
toggle(): void;
show(): void;
}
export interface ReaderProps {
book: Book;
initialLocator?: Record<string, unknown>;
chrome: Chrome;
}
export function useProgressSaver(bookId: number): ProgressSaver {