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
+10 -1
View File
@@ -1,5 +1,5 @@
import { expect, it } from "vitest";
import { chapterText, splitChapters } from "../src/lib/chapters";
import { chapterText, seekChapter, splitChapters } from "../src/lib/chapters";
const pad = (n: number) => "字".repeat(n);
@@ -50,6 +50,15 @@ it("卷不感知:只按章切,卷题行留在正文里", () => {
expect(chapterText(t, chs, 1)).toContain("第二卷 仙界"); // 卷题在第二章结尾,不进第三章开头
});
it("seekChapter:全局进度分数 → (章序号, 章内分数),端点与越界安全", () => {
expect(seekChapter(69, 0)).toEqual({ idx: 0, intra: 0 });
expect(seekChapter(69, 0.5)).toEqual({ idx: 34, intra: 0.5 }); // 69*0.5=34.5
expect(seekChapter(69, 1).idx).toBe(68); // 顶到 0.9999 防越界
expect(seekChapter(69, 1).intra).toBeGreaterThan(0.99);
expect(seekChapter(69, -0.2)).toEqual({ idx: 0, intra: 0 });
expect(seekChapter(1, 0.3)).toEqual({ idx: 0, intra: 0.3 });
});
it("只有卷没有章的书:按伪章节切", () => {
const t = "第一卷 起\n" + pad(600) + "\n第二卷 承\n" + pad(600) + "\n第三卷 转\n" + pad(600);
const chs = splitChapters(t);