diff --git a/README.md b/README.md index 1b6d4c4..eceaf86 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,53 @@ # 幽灵阅读器 · Stealth Reader -一款永远浮在屏幕角落、能一键隐身、看起来像系统通知的本地小说阅读器。 +一款安静、本地优先的桌面小说阅读器。轻量、纯本地、无账号、无广告,专注「好好读一本书」。 -核心不是「读小说」,而是「安全地读小说」——解决职场场景下「想摸鱼但怕被发现」的焦虑。 +## 已实现功能 -## 定位 +### 书籍导入与解析 +- **本地 TXT 导入**:通过系统文件选择对话框导入,无需任何在线源 +- **编码自动检测**:基于 `chardetng` 自动识别 GBK / UTF-8 等常见中文编码 +- **自动分章**:正则识别「第 X 章」「Chapter N」「楔子 / 序章 / 前言 / 引子 / 后记 / 尾声 / 番外」等格式;无法识别时整本书作为单章「正文」导入 +- **元数据统计**:自动统计章节数与总字数 -桌面端本地小说阅读器,核心卖点是「职场隐身模式」。 +### 书架管理 +- 封面网格展示(本地封面文件 / 默认封面) +- 按书名模糊搜索 +- 右键菜单编辑(书名 / 作者 / 简介)与删除(二次确认) +- 空状态引导一键导入 -- 目标平台:Windows / macOS / Linux(基于 Tauri 跨平台) -- 核心价值:轻量 + 本地 + 隐蔽 +### 书籍详情 +- 封面 + 作者 / 章节数 / 总字数 / 导入时间 / 上次阅读时间 / 阅读进度 +- 简介悬停浮层(超长简介内可滚动) +- 章节列表分页展示(每页 20 / 50 / 100 可选) -## 特性 +### 分页阅读 +- 点击页面左右半屏翻页,或使用键盘(`↑↓` / `PgUp` / `PgDn` / 空格 / `←→`) +- 上一章 / 下一章快速切换,边界提示 +- 阅读外观实时生效:字体大小、字体颜色、背景颜色与透明度、窗口大小 +- 阅读窗口可拖拽,支持窗口阴影开关 -- **本地导入**:支持 TXT 导入,自动检测 GBK / UTF-8 编码 -- **自动分章**:正则识别「第 X 章」等常见格式,自动拆分章节 -- **分页阅读**:按键翻页(↑↓ / PgUp / PgDn),无滚动条,像读实体书 -- **阅读进度持久化**:自动保存进度,下次打开继续读 -- **老板键**:系统级全局快捷键,一键瞬间隐身,任务栏无图标 -- **幽灵模式**:窗口透明 + 鼠标穿透 + 置顶,真正融入桌面 -- **系统托盘**:支持伪装图标,静默驻留后台 -- **零打扰**:无账号、无广告、无在线同步,纯本地 +### 设置中心 +- **外观**:窗口阴影开关(主题模式选项已预留) +- **阅读设置**:字体大小、字体颜色、背景颜色与透明度、阅读窗口大小、窗口阴影 +- **快捷键**:按键说明参考 +- **关于**:版本信息 -## 四种预设模式 - -| 模式 | 尺寸 | 透明度 | 鼠标穿透 | 交互 | 适用场景 | -|------|------|--------|---------|------|---------| -| 专注模式 | 600×400 | 100% | 关闭 | 完整交互 | 午休 / 独处 | -| 幽灵模式 | 300×150 | 30% | 开启 | 无(纯看) | 边工作边偷看 | -| 隐身模式 | 隐藏 | 0% | - | 无 | 老板来了 | -| 迷你模式 | 200×100 | 50% | 可选 | 仅翻页 | 会议中 | +### 窗口与界面 +- 自定义标题栏(Windows / macOS):仅保留关闭与最小化按钮,标题栏区域可拖拽窗口 +- 窗口支持透明背景、置顶显示、圆角毛玻璃外观 +- 设置通过 Pinia + 持久化插件跨会话保存 ## 技术栈 -- [Tauri 2](https://tauri.app/) — 跨平台桌面壳与窗口级 API -- [Vue 3](https://vuejs.org/) + TypeScript + Vite -- [Naive UI](https://www.naiveui.com/) — 组件库 -- [Pinia](https://pinia.vuejs.org/) — 状态管理(persistedstate 持久化) -- Rust — 后端能力(编码检测、全局快捷键、系统托盘等) +| 层 | 技术 | +|----|------| +| 桌面壳 | [Tauri 2](https://tauri.app/) | +| 前端 | [Vue 3](https://vuejs.org/) + TypeScript + [Vite](https://vite.dev/) | +| 组件库 | [Naive UI](https://www.naiveui.com/) + @vicons 图标 | +| 状态 | [Pinia](https://pinia.vuejs.org/) + `pinia-plugin-persistedstate` | +| 后端 | Rust:`sqlx` + SQLite、`chardetng`(编码检测)、`regex`(分章) | +| 插件 | `tauri-plugin-dialog`(文件选择)、`tauri-plugin-store`、`tauri-plugin-opener` | ## 快速开始 @@ -62,37 +72,34 @@ pnpm dev # 启动 Vite 开发服务器(http://localhost:1420) pnpm build # 类型检查 + 构建前端产物 ``` +## 项目结构 + +``` +src/ +├── api/ # Tauri invoke 封装(书籍 / 章节) +├── components/ # BookCover、GlobalLoading +├── hooks/ # useLoading +├── layout/ # 主布局与自定义标题栏(Windows / macOS) +├── stores/ # Pinia(setting 持久化) +├── types/ # 全局类型定义 +└── views/ # Home / BookDetail / Reader / Setting 等页面 +src-tauri/ +└── src/ + ├── commands/ # Tauri 命令(book_*、chapter_*) + ├── services/ # SQLite 初始化、TXT 解析 + └── models/ # 数据模型 +``` + ## 路线图 -### v0.1.0(MVP) - -- TXT 导入 + 编码自动检测 -- 书架列表 + 删除 -- 分页阅读 + 字体 / 行距设置 -- 老板键(显隐) -- 窗口置顶 + 透明度调节 -- 阅读进度保存 - -### v1.0.0 - -- 幽灵模式(鼠标穿透 + 悬停切换) -- 系统托盘 + 伪装图标 -- 设置面板 -- 窗口尺寸记忆 -- 安装包(Windows .msi / macOS .dmg) - -### v1.1.0 - -- EPUB 导入支持 -- 章节手动跳转 -- 阅读时长统计 -- 主题切换(IDE 伪装主题) - -### v2.0(未来) - +- 老板键(系统级全局快捷键,一键显隐) +- 系统托盘与伪装图标 +- 阅读进度自动保存与续读 +- EPUB 解析支持 +- 主题切换实际应用(浅色 / 深色 / 跟随系统) +- 幽灵模式(鼠标穿透 + 极小悬浮窗) - 多设备进度同步(WebDAV / 局域网) -- 语音朗读(TTS) -- 书摘 / 笔记 +- 语音朗读(TTS)、书摘 / 笔记 ## 免责声明 diff --git a/src/types/components.d.ts b/src/types/components.d.ts index adbd0a7..b67a4d7 100644 --- a/src/types/components.d.ts +++ b/src/types/components.d.ts @@ -13,6 +13,39 @@ declare module 'vue' { export interface GlobalComponents { BookCover: typeof import('./../components/BookCover.vue')['default'] GlobalLoading: typeof import('./../components/GlobalLoading.vue')['default'] + NAnchor: typeof import('naive-ui')['NAnchor'] + NAnchorLink: typeof import('naive-ui')['NAnchorLink'] + NButton: typeof import('naive-ui')['NButton'] + NColorPicker: typeof import('naive-ui')['NColorPicker'] + NConfigProvider: typeof import('naive-ui')['NConfigProvider'] + NDescriptions: typeof import('naive-ui')['NDescriptions'] + NDescriptionsItem: typeof import('naive-ui')['NDescriptionsItem'] + NDialogProvider: typeof import('naive-ui')['NDialogProvider'] + NDivider: typeof import('naive-ui')['NDivider'] + NDropdown: typeof import('naive-ui')['NDropdown'] + NEmpty: typeof import('naive-ui')['NEmpty'] + NForm: typeof import('naive-ui')['NForm'] + NFormItem: typeof import('naive-ui')['NFormItem'] + NGi: typeof import('naive-ui')['NGi'] + NGrid: typeof import('naive-ui')['NGrid'] + NIcon: typeof import('naive-ui')['NIcon'] + NInput: typeof import('naive-ui')['NInput'] + NInputNumber: typeof import('naive-ui')['NInputNumber'] + NLayout: typeof import('naive-ui')['NLayout'] + NLayoutContent: typeof import('naive-ui')['NLayoutContent'] + NLayoutHeader: typeof import('naive-ui')['NLayoutHeader'] + NMessageProvider: typeof import('naive-ui')['NMessageProvider'] + NModal: typeof import('naive-ui')['NModal'] + NNotificationProvider: typeof import('naive-ui')['NNotificationProvider'] + NPagination: typeof import('naive-ui')['NPagination'] + NPopover: typeof import('naive-ui')['NPopover'] + NRadioButton: typeof import('naive-ui')['NRadioButton'] + NRadioGroup: typeof import('naive-ui')['NRadioGroup'] + NScrollbar: typeof import('naive-ui')['NScrollbar'] + NSpace: typeof import('naive-ui')['NSpace'] + NSpin: typeof import('naive-ui')['NSpin'] + NSwitch: typeof import('naive-ui')['NSwitch'] + NText: typeof import('naive-ui')['NText'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] } diff --git a/src/views/Reader.vue b/src/views/Reader.vue index a78905a..665f973 100644 --- a/src/views/Reader.vue +++ b/src/views/Reader.vue @@ -1,7 +1,7 @@