Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions plugins/hushreader/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,41 @@
# Changelog

All notable changes to this project will be documented in this file.
## [1.2.0](https://github.com/ZToolsCenter/ZTools-plugins) - 2026-06-16

## [1.3.1](https://github.com/me1dlinger/hushreader/releases/tag/v1.3.1) - 2026-06-17

### Added
- **窗口大小锁定开关**:功能设置中新增"窗口大小锁定"开关,开启后窗口不允许拉伸调整大小

### Fixed
- **窗口可拖动开关生效**:修复关闭"窗口可拖动"后窗口仍可拖动的问题,关闭后拖动区域 cursor 变为 default
- **ThemeToggle 主题未随配置加载更新**:改用 `watch` + `immediate: true` 替代直接调用 `applyTheme()`,确保配置异步加载后主题也能正确应用
- **纯色封面时误清章节缓存**:开启"显示纯色封面"时仅清除封面和自定义封面缓存,不再误删章节缓存
- **MOBI 导入 coverUrl 未赋值**:MOBI 解析成功后将 coverUrl 赋值给 coverImage
- **MOBI recordOffsets 边界检查**:增加 `firstRecordOffset + 16 > data.length` 检查,防止格式损坏文件导致越界
- **MOBI firstImageIndex 为 0xffffffff 时封面索引错误**:在 extractCoverUrl 中判断 firstImageIndex 无效值,避免错误计算封面记录索引
- **HTML 实体解码 fromCharCode → fromCodePoint**:`&#xxx;` 和 `&#xHH;` 解码改用 `String.fromCodePoint`,parseInt 增加 radix 参数,支持 BMP 外字符
- **纯色封面关闭后 MOBI 封面未恢复**:新增 `resolveMobiCovers()` 函数,关闭纯色封面时同步恢复 MOBI 书籍封面(此前仅恢复 EPUB 封面)

### Removed
- **固定行数分页模式**:移除分页模式中的"固定行数"选项,统一使用自适应模式


## [1.3.0](https://github.com/me1dlinger/hushreader/releases/tag/v1.3.0) - 2026-06-17

### Added
- **MOBI 格式支持**:新增 MOBI 电子书格式的解析和阅读功能
- **主题模式切换**:新增"主题模式"切换

### Changed
- **封面和章节内容缓存迁移至 ztools.db 数据库**:封面和章节内容不再每次实时解析,改为存到 ztools.db 数据库,提升书架加载和打开书籍的速度
- 封面图(coverImage/customCoverImage)存入数据库文档 `cover_{bookId}` / `custom_cover_{bookId}`,书架加载时从数据库恢复
- 章节内容存入数据库文档 `chapters_{bookId}`,打开书籍时优先从数据库加载,文件修改后自动重新解析并更新缓存
- 删除书籍时同步清理数据库中对应的封面和章节文档
- 开启"显示纯色封面"时清除数据库中的封面数据
- dbStorage 中仅保留轻量数据:书籍列表(不含封面)、阅读进度、配置

## [1.2.0](https://github.com/me1dlinger/hushreader/releases/tag/v1.2.0) - 2026-06-16

### Fixed
- **移除大体积缓存,改为实时解析**:EPUB 封面和章节内容不再持久化到 dbStorage,改为每次需要时从文件实时解析,彻底解决存储空间溢出导致书籍丢失的问题
Expand All @@ -13,12 +47,12 @@ All notable changes to this project will be documented in this file.
### Added
- **显示纯色封面选项**:其他设置中新增"显示纯色封面"开关,开启后 EPUB 不再解析封面图片,所有书籍使用纯色背景封面,节省性能消耗

## [1.1.1](https://github.com/ZToolsCenter/ZTools-plugins) - 2026-06-16
## [1.1.1](https://github.com/me1dlinger/hushreader/releases/tag/v1.1.1) - 2026-06-16

### Fixed
- **窗口拖动/拉伸卡顿**:修复移动和拉伸阅读窗口时严重卡顿的问题——移动预览未做帧节流、预览期间重复调用 `setAlwaysOnTop`/`moveTop` 等重操作、提交时重复推送状态

## [1.1.0](https://github.com/ZToolsCenter/ZTools-plugins) - 2026-06-16
## [1.1.0](https://github.com/me1dlinger/hushreader/releases/tag/v1.1.0) - 2026-06-16

### Fixed
- **设置编辑触发主窗口隐藏**:修复在设置界面编辑背景颜色输入框或快捷键时,每次输入/删除字符都会触发沉浸式阅读窗口 `show()`,导致主窗口被推到后面的问题
Expand All @@ -42,7 +76,7 @@ All notable changes to this project will be documented in this file.
- **百分比进度编辑跳转**:百分比进度模式下,左键点击进度组件进入编辑模式,输入 0-100 数字后按 Enter 或点击外部区域跳转到对应进度,支持 ArrowUp/Down 微调(Shift 步进 10),Escape 取消
- **书架"最近阅读"排序**:书架排序栏新增"最近阅读"选项,按最后阅读时间降序排列,未读过的书排在最后

## [1.0.0](https://github.com/ZToolsCenter/ZTools-plugins) - 2026-06-16
## [1.0.0](https://github.com/me1dlinger/hushreader/releases/tag/v1.0.0) - 2026-06-16

### Added
- **隐阅盒阅读器插件**:隐阅盒阅读器插件初版实现
Expand Down
66 changes: 63 additions & 3 deletions plugins/hushreader/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# 隐阅盒 · HushReader

适配 [ZTools](https://github.com/ZToolsCenter/ZTools) 的阅读插件,支持 TXT / EPUB 格式
适配 [ZTools](https://github.com/ZToolsCenter/ZTools) 的阅读插件,支持 TXT / EPUB / MOBI 格式

</div>

Expand Down Expand Up @@ -94,7 +94,7 @@ npm run build # 构建生产版本
<details>
<summary><b>文本预处理</b></summary>

解析 TXT / EPUB 时自动预处理:
解析 TXT / EPUB / MOBI 时自动预处理:

- `\r\n` / `\r` → 统一为 `\n`
- Tab / 全角空格 → 普通空格
Expand All @@ -104,6 +104,62 @@ npm run build # 构建生产版本

</details>

<details>
<summary><b>MOBI 格式解析</b></summary>

### 加密检测(DRM)

本应用**不支持**解密 DRM 加密的书籍,但会正确识别加密类型并返回用户友好的提示:

| 加密类型 | 说明 | 提示信息 |
| -------- | ---- | -------- |
| `0` | 未加密 | 正常解析正文 |
| `1` | 旧版 Mobipocket(单 PID) | 提示使用旧版加密方案,正文受保护 |
| `2` | Mobipocket/Kindle DRM(多 PID) | 提示使用现代加密方案,正文受保护 |

**即使书籍加密,仍可读取**:标题、作者、封面等元数据(这些存储在未加密的记录区域)。

### 压缩格式支持

| 压缩类型 | 值 | 支持情况 |
| -------- | --- | -------- |
| `COMPRESSION_NONE` | `1` | ✅ 支持,直接读取原始内容 |
| `COMPRESSION_PALMDOC` | `2` | ✅ 支持,实现了 PalmDOC 解压缩算法 |
| `COMPRESSION_HUFFCDIC` | `17480` | ❌ 暂不支持,返回明确提示 |

### 封面提取

封面图片存储在独立的资源记录中(不受正文加密影响):

1. 从 EXTH 记录 201 获取封面索引偏移
2. 将偏移值与 MOBI 头的 `firstImageIndex` 相加得到实际记录索引
3. 从对应 PDB 记录中提取图片数据
4. 自动检测图片格式(JPEG / PNG / GIF),转换为 Base64 URL

### 解析流程

```
PDB 文件头 (78字节) → 读取总记录数
记录偏移表 → 获取每条记录的起始位置
Record 0 → PalmDOC 头 + MOBI 头 + EXTH 记录
元数据提取:标题(FullName)、作者(EXTH 100)、封面(EXTH 201)
加密检测 → 若加密,返回元数据 + 提示信息
正文记录 → 按 firstNonBookIndex 或 recordCount 读取文本记录
解压缩 → PalmDOC 压缩格式解码
编码检测 → UTF-8 或 Windows-1252 解码
HTML/纯文本判断 → 分章解析或按 TXT 逻辑处理
```

</details>

## 项目结构

```
Expand All @@ -117,13 +173,17 @@ npm run build # 构建生产版本
├── src/
│ ├── App.vue # 根组件
│ ├── main.ts # 应用入口
│ ├── main.css # 应用样式
│ ├── env.d.ts #环境变量类型定义
│ ├── stores/
│ │ ├── books.ts # 书籍数据 + 持久化
│ │ ├── config.ts # 配置数据 + 持久化
│ │ └── reader.ts # 阅读器状态 + 分页
│ ├── utils/
│ │ ├── db.ts # 数据库操作工具
│ │ ├── txtParser.ts # TXT 解析 + 分页 + 预处理
│ │ └── epubParser.ts # EPUB 解析
│ │ ├── epubParser.ts # EPUB 解析
│ │ └── mobiParser.ts # MOBI 解析 + 加密检测 + 封面提取
│ └── components/
│ ├── Bookshelf/ # 书架组件
│ │ ├── index.vue
Expand Down
55 changes: 29 additions & 26 deletions plugins/hushreader/public/hushreader.html
Original file line number Diff line number Diff line change
Expand Up @@ -215,14 +215,25 @@
grid-template-rows: minmax(0, 1fr);
min-width: 0;
overflow: hidden;
cursor: grab;
touch-action: none;
}

body.is-moving .hushreader-content {
cursor: grabbing;
}

body.no-move .hushreader-content {
cursor: default;
}

body.no-move.is-moving .hushreader-content {
cursor: default;
}

body.no-resize .hushreader-resize-zone {
cursor: default;
}

.hushreader-lines {
display: grid;
align-content: center;
Expand Down Expand Up @@ -274,22 +285,21 @@
}

.show-meta .hushreader-reader {
grid-template-rows: 18px minmax(0, 1fr);
grid-template-rows: minmax(0, 1fr);
}

.show-meta .hushreader-content {
grid-row: 2;
grid-row: 1;
}

.show-meta .hushreader-meta {
position: relative;
position: absolute;
bottom: 1px;
right: 32px;
top: auto;
right: auto;
grid-row: 1;
grid-column: 1;
align-self: start;
justify-self: end;
margin: 2px 32px 0 10px;
left: auto;
z-index: 4;
margin: 0;
opacity: 0.66;
pointer-events: auto;
cursor: default;
Expand Down Expand Up @@ -359,20 +369,6 @@
background: rgba(255, 255, 255, 0.15);
}

@media (max-height: 42px) {
.show-meta .hushreader-reader {
grid-template-rows: minmax(0, 1fr);
}

.show-meta .hushreader-content {
grid-row: 1;
}

.show-meta .hushreader-meta {
display: none;
}
}

.hushreader-reader {
border: 0;
background: var(--hushreader-bg-color);
Expand All @@ -385,7 +381,7 @@
}

.hushreader-meta {
background: rgba(0, 0, 0, 0.3);
background: transparent;
color: var(--hushreader-text-color);
}
</style>
Expand Down Expand Up @@ -489,7 +485,7 @@
function normalizeResizeSize(width, height) {
return {
width: clamp(snap(width, 10), getResizeLimit("minWidth", 280), getResizeLimit("maxWidth", 1180)),
height: clamp(snap(height, 2), getResizeLimit("minHeight", 22), getResizeLimit("maxHeight", 160))
height: clamp(snap(height, 2), getResizeLimit("minHeight", 22), getResizeLimit("maxHeight", 500))
}
}

Expand Down Expand Up @@ -728,6 +724,8 @@
settings.showHushreaderMeta ? "show-meta" : "",
isAutoHidden && visible && hideMode === 'hide-all' ? "is-auto-hidden" : "",
isAutoHidden && visible && hideMode === 'show-progress' ? "is-auto-hidden-show-progress" : "",
!settings.windowMovable ? "no-move" : "",
settings.windowSizeLocked ? "no-resize" : "",
visible ? "" : "is-hidden"
]
.filter(Boolean)
Expand Down Expand Up @@ -886,6 +884,10 @@
document.addEventListener("pointerdown", (event) => {
const handle = event.target.closest("[data-resize]")
if (handle) {
const isSizeLocked = Boolean(latestSettings.windowSizeLocked)

if (isSizeLocked) return

event.preventDefault()
event.stopPropagation()

Expand All @@ -908,6 +910,7 @@

const moveHandle = event.target.closest("[data-move]")
if (!moveHandle || resizeState || event.button !== 0) return
if (!latestSettings.windowMovable) return

event.preventDefault()
event.stopPropagation()
Expand Down
4 changes: 2 additions & 2 deletions plugins/hushreader/public/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
"$schema": "node_modules/@ztools-center/ztools-api-types/resource/ztools.schema.json",
"name": "hushreader",
"title": "隐阅盒",
"description": "沉浸式阅读,注意身后",
"description": "隐阅盒,ZTools自己的摸鱼阅读,支持TXT/EPUB/MOBI格式,沉浸式阅读",
"author": "meidlinger",
"version": "1.2.0",
"version": "1.3.1",
"main": "index.html",
"preload": "preload/services.js",
"logo": "logo.png",
Expand Down
Loading
Loading