From fef2bf4a49d4ceb6a8e4799f855c67dd3e22e73c Mon Sep 17 00:00:00 2001 From: WhiredPlanck Date: Fri, 3 Jun 2022 11:36:29 +0800 Subject: [PATCH 1/8] refactor(res): polish Chinese Simplified translations - Use full-width symbols for all text - Use correct case for proper nouns and avoid jargons - Place a space before and after English words or numbers - Polish translations appropriately - Add missing translations. Reference: 1. https://github.com/sparanoid/chinese-copywriting-guidelines 2. https://www.w3.org/TR/clreq/ --- app/src/main/res/values-zh/strings.xml | 404 ++++++++++++------------- 1 file changed, 202 insertions(+), 202 deletions(-) diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index a4727df79..345a0513c 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -2,20 +2,20 @@ 阅读 阅读·搜索 - 阅读需要访问存储卡权限,请前往“设置”—“应用权限”—打开所需权限 + 阅读需要访问存储卡权限,请前往“设置”—“应用权限”,打开所需权限 Home 恢复 导入阅读数据 离线缓存书籍备份 - 导出本地同时备份到legado文件夹下exports目录 + 导出本地同时备份到 legado 文件夹下的 exports 目录 备份路径 请选择备份路径 导入旧版数据 - 导入Github数据 + 导入 Github 数据 净化替换 - Send + 发送 提示 取消 @@ -59,7 +59,7 @@ 添加本地 书源 书源管理 - 新建/导入/编辑/管理书源 + 新建、导入、编辑或管理书源 设置 主题设置 与界面/颜色相关的一些设置 @@ -68,33 +68,33 @@ 关于 捐赠 退出 - 尚未保存,是否继续编辑 + 尚未保存,是否继续编辑 阅读样式设置 版本 本地 搜索 - 来源: %s - 最近: %s + 来源:%s + 最近:%s 书名 - 最新: %s + 最新:%s 是否将《%s》放入书架? - 共%s个Text文件 + 共 %s 个文本文件 加载中… 重试 Web 服务 - 浏览器写源,看书 - web编辑书源 + 用浏览器写源或看书 + Web 编辑书源 离线缓存 离线缓存 缓存选择的章节到本地 换源 - \u3000\u3000这是一款使用Kotlin全新开发的开源的阅读软件,欢迎您的加入。关注公众号[开源阅读]! + \u3000\u3000这是一款使用 Kotlin 全新开发的开源的阅读软件,欢迎您的加入。关注公众号【开源阅读】! - 阅读3.0下载地址:\nhttps://www.coolapk.com/apk/256030 + 阅读 3.0 下载地址:\nhttps://www.coolapk.com/apk/256030 - Version %s + 版本 %s 后台校验书源 打开后可以在校验书源时自由操作 自动刷新 @@ -102,16 +102,16 @@ 自动下载最新章节 更新书籍时自动下载最新章节 备份与恢复 - WebDav设置 - WebDav设置/导入旧版本数据 + WebDav 设置 + WebDav 设置/导入旧版本数据 备份 恢复 - 备份请给与存储权限 - 恢复请给与存储权限 + 备份请给予存储权限 + 恢复请给予存储权限 确认 取消 确认备份吗? - 新备份会替换原有备份。\n备份文件夹YueDu + 新备份会替换原有备份。\n备份文件夹 YueDu 确认恢复吗? 恢复书架会覆盖现有书架。 备份成功 @@ -125,7 +125,7 @@ 竖向 跟随系统 免责声明 - 共%d章 + 共 %d 章 界面 亮度 目录 @@ -148,8 +148,8 @@ 继续 定时 朗读暂停 - 正在朗读(还剩%d分钟) - 正在播放(还剩%d分钟) + 正在朗读(还剩 %d 分钟) + 正在播放(还剩 %d 分钟) 阅读界面隐藏虚拟按键 隐藏导航栏 导航栏颜色 @@ -162,7 +162,7 @@ 添加书籍网址 背景 作者 - 作者: %s + 作者:%s 朗读停止 清理缓存 成功清理缓存 @@ -197,20 +197,20 @@ 音量键翻页 点击翻页 翻页动画 - 翻页动画(本书) + 翻页动画(本书) 屏幕超时 返回 菜单 调节 滚动条 - 清除缓存会删除所有已保存章节,是否确认删除? + 清除缓存会删除所有已保存章节,是否确认删除? 书源共享 替换规则名称 替换规则为空或者不满足正则表达式要求 选择操作 全选 - 全选(%1$d/%2$d) - 取消全选(%1$d/%2$d) + 全选(%1$d/%2$d) + 取消全选(%1$d/%2$d) 深色模式 启动页 开始下载 @@ -218,17 +218,17 @@ 暂无任务 已下载 %1$d/%2$d 导入选择书籍 - 更新和搜索线程数,太多会卡顿 + 更新和搜索线程数(太多会卡顿) 切换图标 删除书籍 开始阅读 加载数据中… - 加载失败,点击重试 + 加载失败,点击重试 内容简介 - 简介:%s - 简介: 暂无简介 + 简介:%s + 简介:暂无简介 打开外部书籍 - 来源: %s + 来源:%s 导入替换规则 导入在线规则 检查更新间隔 @@ -239,11 +239,11 @@ 阅读方式 排版 删除所选 - 是否确认删除? + 是否确认删除? 默认字体 发现 发现管理 - 没有内容,去书源里自定义吧! + 还没有内容,去书源里自定义吧! 删除所有 搜索历史 清除 @@ -257,9 +257,9 @@ 拷贝内容 一键缓存 这是一段测试文字\n\u3000\u3000只是让你看看效果的 - 文字颜色和背景(长按自定义) + 文字颜色和背景(长按自定义) 沉浸式状态栏 - 还剩%d章未下载 + 还剩 %d 章未下载 长按输入颜色值 加载中… 追更区 @@ -268,14 +268,14 @@ 添加书签 删除 加载超时 - 关注:%s + 关注:%s 已拷贝 书架管理 这将会删除所有书籍,请谨慎操作。 搜索书源 搜索订阅源 - 搜索(共%d个书源) - 目录(%d) + 搜索(共 %d 个书源) + 目录(%d) 加粗 字体 文字 @@ -292,19 +292,19 @@ 校验书源 校验所选 %1$s 进度 %2$d/%3$d - 请安装并选择中文TTS! - TTS初始化失败! + 请安装并选择中文 TTS! + TTS 初始化失败! 简繁转换 关闭 简转繁 繁转简 翻页模式 %1$d 项 - 存储卡: + 存储卡: 加入书架 - 加入书架(%1$d) - 成功添加%1$d本书 - 请将字体文件放到SD根目录Fonts文件夹下重新选择 + 加入书架(%1$d) + 成功添加 %1$d 本书 + 请将字体文件放到存储根目录 Fonts 文件夹下后重新选择 默认字体 选择字体 字号 @@ -325,14 +325,14 @@ 书籍信息编辑 默认打开书架 自动跳转最近阅读 - 替换范围,选填书名或者书源url + 替换范围,选填书名或者书源 URL 分组 内容缓存路径 系统文件选择器 新版本 下载更新 朗读时音量键翻页 - Tip边距跟随边距调整 + 提示边距跟随页边距调整 允许更新 禁止更新 拆分超长章节 @@ -344,7 +344,7 @@ 显示所有发现 关闭则只显示勾选源的发现 更新目录 - Txt目录正则 + TXT 目录正则 设置编码 倒序-顺序 排序 @@ -375,74 +375,74 @@ 无动画 此书源使用了高级功能,请到捐赠里点击支付宝红包搜索码领取红包开启。 后台更新换源最新章节 - 开启则会在软件打开1分钟后开始更新 - 书架ToolBar自动隐藏 - 滚动书架时ToolBar自动隐藏与显示 + 开启则会在软件打开 1 分钟后开始更新 + 书架工具栏自动隐藏 + 滚动书架时工具栏自动隐藏与显示 登录 - 登录%s + 登录 %s 成功 当前源没有配置登陆地址 没有上一页 没有下一页 - 源名称(sourceName) - 源URL(sourceUrl) - 源分组(sourceGroup) + 源名称(sourceName) + 源 URL(sourceUrl) + 源分组(sourceGroup) 自定义源分组 输入自定义源分组名称 - 并发率(concurrentRate) - 分类Url(sortUrl) - 登录URL(loginUrl) - 登录UI(loginUi) - 登录检查JS(loginCheckJs) - 源注释(sourceComment) - 搜索地址(url) - 发现地址规则(url) - 书籍列表规则(bookList) - 书名规则(name) - 详情页url规则(bookUrl) - 作者规则(author) - 分类规则(kind) - 简介规则(intro) - 封面规则(coverUrl) - 最新章节规则(lastChapter) - 字数规则(wordCount) - 书籍URL正则(bookUrlPattern) - 预处理规则(bookInfoInit) - 目录URL规则(tocUrl) - 允许修改书名作者(canReName) - 目录下一页规则(nextTocUrl) - 目录列表规则(chapterList) - 章节名称规则(ChapterName) - 章节URL规则(chapterUrl) - Volume标识(isVolume) - VIP标识(isVip) - 更新时间(ChapterInfo) - 更新之前Js(preUpdateJs) - 正文规则(content) - 正文下一页URL规则(nextContentUrl) - WebViewJs(webJs) - 图片样式(imageStyle) - 替换规则(replaceRegex) - 资源正则(sourceRegex) - 购买操作(payAction) + 并发率(concurrentRate) + 分类 URL(sortUrl) + 登录 URL(loginUrl) + 登录 UI(loginUi) + 登录检查 JS(loginCheckJs) + 源注释(sourceComment) + 搜索地址(url) + 发现地址规则(url) + 书籍列表规则(bookList) + 书名规则(name) + 详情页 URL 规则(bookUrl) + 作者规则(author) + 分类规则(kind) + 简介规则(intro) + 封面规则(coverUrl) + 最新章节规则(lastChapter) + 字数规则(wordCount) + 书籍 URL 正则(bookUrlPattern) + 预处理规则(bookInfoInit) + 目录 URL 规则(tocUrl) + 允许修改书名作者(canReName) + 目录下一页规则(nextTocUrl) + 目录列表规则(chapterList) + 章节名称规则(ChapterName) + 章节 URL 规则(chapterUrl) + Volume 标识(isVolume) + VIP 标识(isVip) + 更新时间(ChapterInfo) + 更新之前 JS(preUpdateJs) + 正文规则(content) + 正文下一页 URL 规则(nextContentUrl) + WebView JS(webJs) + 图片样式(imageStyle) + 替换规则(replaceRegex) + 资源正则(sourceRegex) + 购买操作(payAction) - 图标(sourceIcon) - 列表规则(ruleArticles) - 列表下一页规则(ruleArticles) - 标题规则(ruleTitle) - guid规则(ruleGuid) - 时间规则(rulePubDate) - 类别规则(ruleCategories) - 描述规则(ruleDescription) - 图片url规则(ruleImage) - 内容规则(ruleContent) - 样式(style) - 链接规则(ruleLink) - 校验关键字(checkKeyWord) - 操作(actions) - 购买标识(isPay) + 图标(sourceIcon) + 列表规则(ruleArticles) + 列表下一页规则(ruleArticles) + 标题规则(ruleTitle) + GUID 规则(ruleGuid) + 时间规则(rulePubDate) + 类别规则(ruleCategories) + 描述规则(ruleDescription) + 图片 URL 规则(ruleImage) + 内容规则(ruleContent) + 样式(style) + 链接规则(ruleLink) + 校验关键字(checkKeyWord) + 操作(actions) + 购买标识(isPay) @@ -450,7 +450,7 @@ 书籍信息获取失败 内容获取失败 目录获取失败 - 访问网站失败:%s + 访问网站失败:%s 文件读取失败 加载目录失败 获取数据失败! @@ -460,7 +460,7 @@ 数据解析失败 - 请求头(header) + 请求头(header) 调试源 二维码导入 分享选中源 @@ -469,23 +469,23 @@ 主题 主题模式 选择主题模式 - 加入QQ群 + 加入 QQ 群 获取背景图片需存储权限 输入书源网址 删除文件 删除文件成功 - 确定删除文件吗? + 确定删除文件吗? 手机目录 智能导入 发现 切换显示样式 - 导入本地书籍需存储权限 + 导入本地书籍需要存储权限 夜间模式 E-Ink 模式 电子墨水屏模式 需要存储权限 再按一次退出程序 - 导入本地书籍需存储权限 + 导入本地书籍需要存储权限 网络连接不可用 @@ -495,14 +495,14 @@ 是否删除全部书籍? 是否同时删除已下载的书籍目录? 扫描二维码需相机权限 - 朗读正在运行,不能自动翻页 + 朗读正在运行,不能自动翻页 输入编码 - TXT目录规则 - 打开外部书籍需获取存储权限 + TXT 目录规则 + 打开外部书籍需要存储权限 未获取到书名 输入替换规则网址 - 搜索列表获取成功%d - 名称和URL不能为空 + 搜索列表获取成功 %d + 名称和 URL 不能为空 图库 领支付宝红包 没有获取到更新地址 @@ -536,14 +536,14 @@ 正文 E-Ink 模式 - 去除动画,优化电纸书使用体验 - Web服务 - web端口 + 去除动画,优化电纸书使用体验 + Web 服务 + Web 端口 当前端口 %s 二维码分享 字符串分享 - wifi分享 - 请给于存储权限 + WiFi 分享 + 请给予存储权限 减速 加速 上一个 @@ -551,8 +551,8 @@ 音乐 音频 启用 - 启用JS - 加载BaseUrl + 启用 JavaScript + 加载 BaseUrl 全部书源 输入不能为空 清空发现缓存 @@ -562,8 +562,8 @@ 我的 阅读 %d%% - %d分钟 - 自动亮度%s + %d 分钟 + 自动亮度 %s 按页朗读 朗读引擎 背景图片 @@ -578,8 +578,8 @@ 移除分组 新建替换 分组 - 分组: %s - 目录: %s + 分组:%s + 目录:%s 启用发现 禁用发现 启用所选 @@ -590,11 +590,11 @@ 加载详情页 TTS WebDav 密码 - 输入你的WebDav授权密码 + 输入你的 WebDav 授权密码 输入你的服务器地址 WebDav 服务器地址 WebDav 账号 - 输入你的WebDav账号 + 输入你的 WebDav 账号 订阅源 编辑订阅源 筛选 @@ -606,11 +606,11 @@ 文件选择 文件夹选择 我是有底线的 - Uri转Path失败 + URI 转 Path 失败 刷新封面 封面换源 选择本地图片 - 类型: + 类型: 后台 正在导入 正在导出 @@ -622,28 +622,28 @@ 上一句 下一句 其它目录 - 文字太多,生成二维码失败 - 分享RSS源 + 文字太多,生成二维码失败 + 分享 RSS 源 分享书源 自动切换夜间模式 夜间模式跟随系统 上级 在线朗读音色 - (%1$d/%2$d) + (%1$d/%2$d) 显示订阅 服务已停止 - 正在启动服务\n具体信息查看通知栏 + 正在启动服务\n具体信息请查看通知栏 默认路径 系统文件夹选择器 自带文件夹选择器 自带文件选择器 - Android10以上因权限限制可能无法读写文件 + Android 10 以上因系统权限限制可能无法读写文件 长按文字在操作菜单中显示阅读·搜索 文字操作显示搜索 记录日志 日志 中文简繁体转换 - 图标为矢量图标,Android8.0以前不支持 + 图标为矢量图标,Android 8.0 以前不支持 朗读设置 主界面 长按选择文本 @@ -675,11 +675,11 @@ 设置分组 查看目录 导航栏阴影 - 当前阴影大小(elevation): %s + 当前阴影大小(elevation):%s 默认 主菜单 点击授予权限 - 阅读需要访问存储卡权限,请点击下方的"授予权限"按钮,或前往“设置”—“应用权限”—打开所需权限。如果授予权限后仍然不正常,请点击右上角的“选择文件夹”,使用系统文件夹选择器。 + 阅读需要访问存储卡权限,请点击下方的“授予权限”按钮,或前往“设置”—“应用权限”,打开所需权限。如果授予权限后仍然不正常,请点击右上角的“选择文件夹”,使用系统文件夹选择器。 全文朗读中不能朗读选中文字 扩展到刘海 更新目录中 @@ -693,7 +693,7 @@ 关注公众号 微信 您的支持是我更新的动力 - 公众号[开源阅读] + 公众号【开源阅读】 正在自动换源 点击加入 @@ -723,27 +723,27 @@ 文字底部对齐 自动翻页速度 地址排序 - 本地和WebDav一起备份 - 优先从WebDav恢复,长按从本地恢复 + 本地和 WebDav 一起备份 + 优先从 WebDav 恢复,长按从本地恢复 选择旧版备份文件夹 已启用 已禁用 正在启动下载 该书已在下载列表 点击打开 - 关注[开源阅读]点击广告支持我 + 关注【开源阅读】点击广告支持我 微信赞赏码 支付宝 支付宝红包搜索码 537954522 点击复制 支付宝红包二维码 支付宝收款二维码 - QQ收款二维码 - gedoor,Invinciblelee,Xwite等,详情请在github中查看 + QQ 收款二维码 + gedoor、Invinciblelee 和 Xwite 等,详情请在 GitHub 中查看 清除已下载书籍和字体缓存 默认封面 恢复忽略列表 - 恢复时忽略一些内容不恢复,方便不同手机配置不同 + 恢复时忽略一些内容不恢复,方便不同手机配置不同 阅读界面设置 分组名称 备注内容 @@ -762,10 +762,10 @@ 语言 导入订阅源 您的支持是我更新的动力 - 公众号[开源阅读软件] + 公众号【开源阅读软件】 阅读记录 阅读时间记录 - 本地TTS + 本地 TTS 线程数 总阅读时间 全不选 @@ -775,25 +775,25 @@ 保存白天主题配置以供调用和分享 保存夜间主题配置以供调用和分享 主题列表 - 使用保存主题,导入,分享主题 + 使用、保存、导入或分享主题 切换默认主题 更新时间排序 全文搜索 搜索结果 - 搜索内容为空,检查净化/简繁设置 - Empty now! - 当前没有发现源! - 将焦点放到输入框按下物理按键会自动录入键值,多个按键会自动用英文逗号隔开. + 搜索内容为空,请检查净化或简繁设置 + RSS 源目前为空! + 当前没有发现源! + 将焦点放到输入框按下物理按键会自动录入键值,多个按键会自动用英文逗号隔开。 主题名称 自动清除过期搜索数据 超过一天的搜索数据 重新分段 - 样式名称: - 点击右上角文件夹图标,选择文件夹 + 样式名称: + 点击右上角文件夹图标,选择文件夹 智能扫描 导入文件名 - 拷贝书籍URL - 拷贝目录URL + 拷贝书籍 URL + 拷贝目录 URL 没有书籍 保留原名 点击区域设置 @@ -807,30 +807,30 @@ 规则订阅 添加大佬们提供的规则导入地址\n添加后点击可导入规则 拉取云端进度 - 当前进度超过云端进度,是否同步? + 当前进度超过云端进度,是否同步? 同步阅读进度 进入退出阅读界面时同步阅读进度 创建书签失败 - 单URL + 单 URL 导出书单 导入书单 预下载 - 预先下载%s章正文 + 预先下载 %s 章正文 是否启用 背景图片 背景图片虚化 虚化半径 - 0为停用,启用范围1~25\n半径数值越大,虚化效果越高 + 0 为停用,启用范围 1~25\n半径数值越大,虚化效果越高 导出文件夹 导出编码 - TXT不导出章节名 - 导出到WebDav + TXT 不导出章节名 + 导出到 WebDav 反转内容 调试 崩溃日志 使用自定义中文分行 图片样式 - 系统TTS + 系统 TTS 导出格式 校验作者 搜索源码 @@ -838,14 +838,14 @@ 目录源码 正文源码 列表源码 - 此url已订阅 - 高刷 + 此 URL 已订阅 + 高刷新率 使用屏幕最高刷新率 导出所有 完成 显示未读标志 总是使用默认封面 - 总是显示默认封面,不显示网络封面 + 总是显示默认封面(不显示网络封面) 字号 上边距 下边距 @@ -858,7 +858,7 @@ 分组样式 导出文件名 重置 - url为空 + URL 为空 字典 未知错误 自动备份失败\n%s @@ -866,22 +866,22 @@ 关闭替换分组/开启添加分组 媒体按钮•上一首|下一首 上一段|下一段/上一章|下一章 - 及时翻页,翻页时会停顿一下 + 及时翻页,翻页时会停顿一下 校验显示详细信息 书源校验时显示网络请求步骤和时间 - 需登录 - 使用Cronet网络组件 + 需要登录 + 使用 Cronet 网络组件 抗锯齿 绘制图片时抗锯齿 - 上传URL - 下载URL规则 + 上传 URL + 下载 URL 规则 响应时间排序 导出成功 路径 直链上传规则 - 用于导出书源书单时生成直链url + 用于导出书源书单时生成直链 URL 直链上传配置 - 拷贝播放Url + 拷贝播放 URL 设置源变量 设置书籍变量 注释 @@ -903,20 +903,20 @@ 购买 平板/横屏双页 浏览器打开 - 拷贝url + 拷贝 URL 打开方式 - 是否使用外部浏览器打开? + 是否使用外部浏览器打开? 查看 打开 删除登录头 查看登录头 登录头 字体大小 - 当前字体大小:%.1f + 当前字体大小:%.1f 语速减 语速加 - 打开系统文件夹选择器出错,自动打开应用文件夹选择器 - 打开系统文件选择器出错,自动打开应用文件选择器 + 打开系统文件夹选择器出错,将自动打开应用文件夹选择器 + 打开系统文件选择器出错,将自动打开应用文件选择器 展开文本选择菜单 书籍保存位置 从其它应用打开的书籍保存位置 @@ -927,19 +927,19 @@ 校验设置 校验项目 - 单个书源校验超时(秒) + 单个书源校验超时(秒) 超时 小于 - 校验超时: %1$s秒\n校验项目:%2$s + 校验超时:%1$s秒\n校验项目:%2$s 记录调试日志 子文件夹 全局 使用替换 作用于标题 作用于正文 - 加入QQ频道 - 点击加入阅读QQ频道 + 加入 QQ 频道 + 点击加入阅读 QQ 频道 刷新当前章节 刷新之后章节 刷新全部章节 @@ -961,14 +961,14 @@ 显示默认书籍图标 缓存/导出 辅助按键配置 - Url参数 - 仅WIFI - 仅在wifi下加载网络封面 + URL 参数 + 仅 WiFi + 仅在 WiFi 下加载网络封面 封面规则 进入详情页时使用封面规则重新获取封面 定位到当前书源 - 系统tts设置 - 打开系统tts设置界面 + 系统 TTS 设置 + 打开系统 TTS 设置界面 非播放状态无法定时 所有书签 批量换源 @@ -977,23 +977,23 @@ 输入验证码 验证码 超时毫秒数 - 文件%1$s 不受支持,是否继续打开? - 导入TTS + 文件 %1$s 不受支持,是否继续打开? + 导入 TTS 导入主题 - 导入txt目录规则 + 导入 TXT 目录规则 CookieJar 点击阅读加载目录 - 清除cookie + 清除 Cookie 导入在线书籍文件 - Upload Success - Upload Fail - Download Success - Download Fail - 上传WebDav - WebDav书籍 + 上传成功 + 上传失败 + 下载成功 + 下载失败 + 上传 WebDav + WebDav 书籍 当前最大缓存 %1$s MB 图片绘制缓存 - TXT导出图片 + TXT 导出图片 图片解码失败 图片链接为空,检查替换净化规则 From a15ce01ef62fa9018ce38dcf04f346e7415f73ec Mon Sep 17 00:00:00 2001 From: kunfei Date: Fri, 3 Jun 2022 23:06:00 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/ui/book/cache/CacheViewModel.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt b/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt index 4655c07c1..d08e0c956 100644 --- a/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt @@ -49,7 +49,11 @@ class CacheViewModel(application: Application) : BaseViewModel(application) { val bindings = SimpleBindings() bindings["name"] = book.name bindings["author"] = book.getRealAuthor() - return AppConst.SCRIPT_ENGINE.eval(jsStr, bindings).toString() + return kotlin.runCatching { + AppConst.SCRIPT_ENGINE.eval(jsStr, bindings).toString() + }.onFailure { + context.toastOnUi("书名规则错误\n${it.localizedMessage}") + }.getOrDefault("${book.name} 作者:${book.getRealAuthor()}") } fun export(path: String, book: Book) { From 9785c5ea09a73038443acdc97e52a8a2209a90c2 Mon Sep 17 00:00:00 2001 From: WhiredPlanck Date: Sat, 4 Jun 2022 02:01:21 +0800 Subject: [PATCH 3/8] refactor(res): polish appHelp.md --- app/src/main/assets/help/appHelp.md | 261 +++++++++++++++------------- 1 file changed, 143 insertions(+), 118 deletions(-) diff --git a/app/src/main/assets/help/appHelp.md b/app/src/main/assets/help/appHelp.md index 63c170809..a62396b21 100644 --- a/app/src/main/assets/help/appHelp.md +++ b/app/src/main/assets/help/appHelp.md @@ -1,190 +1,215 @@ # 帮助文档 -## **新人必读** +【温馨提醒】 *本帮助可以在“**我的**”——右上角帮助按钮再次打开,更新前一定要做好备份,以免数据丢失!* -【温馨提醒】 *本帮助可以在我的-右上角帮助按钮再次打开,更新前一定要做好备份,以免数据丢失!* +## 新人必读 -1. 为什么第一次安装好之后什么东西都没有? -* 阅读只是一个转码工具,不提供内容,第一次安装app,需要自己手动导入书源,可以从公众号 **[开源阅读]**、QQ群、酷安评论里获取由书友制作分享的书源。 +### 1. 为什么第一次安装好之后什么东西都没有? +阅读只是一个转码工具,不提供内容,第一次安装 APP,需要自己手动导入书源,可以从公众号 **【开源阅读】**、QQ 群或酷安评论里获取由书友制作分享的书源。 -2. 正文出现缺字漏字、内容缺失、排版错乱等情况,如何处理? -* 有可能是净化规则出现问题,先关闭替换净化并刷新,再观察是否正常。如果正常说明净化规则存在误杀,如果关闭后仍然出现相关问题,请点击源链接查看原文与正文是否相同,如果不同,再进行反馈。 +### 2. 正文出现缺字漏字、内容缺失或排版错乱等情况,如何处理? +有可能是净化规则出现问题,先关闭替换净化并刷新,再观察是否正常。如果正常说明净化规则存在误杀,如果关闭后仍然出现相关问题,请点击源链接查看原文与正文是否相同,如果不同,再进行反馈。 -3. 漫画源看书显示乱码,如何解决? -* 异次元和阅读是两个不同的软件,**两个软件的源并不通用**,请导入阅读的支持的漫画源! +### 3. 漫画源看书显示乱码,如何解决? +【异次元】和【阅读】是两个不同的软件,**两个软件的源并不通用**,请导入【阅读】的支持的漫画源! ## 书源相关 -1. 如何导入本地书源文件? -* 下载群文件里的书源文件(书源格式后缀有txt、json,其中json文件某些情况下无法导入,需要修改后缀为txt格式才可导入); -* 打开阅读软件; -* 我的 - 点击“书源管理”; -* 点击右上角选择“本地导入”; +### 1. 如何导入本地书源文件? +以导入 QQ 接收到的书源文件为例: +* 下载群文件里的书源文件; +* 打开【阅读】软件; +* 点击“**我的**”——“**书源管理**”; +* 点击右上角选择“**本地导入**”; * 左下角选择书源文件所在的路径; * 点击书源文件导入; * 导入后返回书源管理界面; -* 新版qq下载路径:Android/data/com.tencent.mobileqq/Tencent/QQfile_recv/ -![QQ导入书源](https://cdn.jsdelivr.net/gh/gedoor/gedoor.github.io@master/images/importSource.jpg) +**【注】** +1. *新版 QQ 文件下载路径:`Android/data/com.tencent.mobileqq/Tencent/QQfile_recv/`。* +2. *书源格式后缀有 .txt 和 .json,其中 .json 文件在某些情况下可能无法导入,需要修改后缀为 .txt 才可导入。* + +![QQ 导入书源](https://cdn.jsdelivr.net/gh/gedoor/gedoor.github.io@master/images/importSource.jpg) -2. 如何新建大佬发的单独书源? +### 2. 如何新建大佬发的单独书源? * 复制书源代码; * 打开阅读软件; -* 我的 - 点击“书源管理”; -* 右上角选择“新建书源”; -* 进入新建书源后点击右上角“粘贴源”; -* 粘贴书源完成后点击上方保存; +* 点击“**我的**”——“**书源管理**”; +* 右上角“**⁝**”——“**+ 新建书源**”; +* 进入后点击右上角“**⁝**”——“**粘贴源**”; +* 粘贴完成后点击上方保存“**🖫**”按钮; * 本次新建单独书源操作完成。 -* 注:如果书源有错误或者复制不全会显示格式错误,请重新复制。 -3. 为什么导入2.0书源后无法阅读? -* 部分2.0书源并不适用于3.0版本的阅读,建议导入后进行筛选。 +**【注】** *如果书源有错误或者复制不全会显示格式错误,请重新复制。* -4. 阅读2.0数据如何导入阅读3.0? -* 先对阅读2.0的数据进行备份,然后进入阅读3.0,点击“我的”,选择“备份与恢复”,再点击“导入旧版本数据”。 +### 3. 为什么导入 2.0 书源后无法阅读? +部分 2.0 书源并不适用于 3.0 版本的阅读,建议导入后进行筛选。 -5. 如何给朋友分享我的书源? -* 打开阅读软件; +### 4. 【阅读】2.0 数据如何导入【阅读】3.0? +先对【阅读】2.0 的数据进行备份,然后进入【阅读】3.0,点击“**我的**”,选择“**备份与恢复**”,再点击“**导入旧版本数据**”。 + +### 5. 如何给朋友分享我的书源? +* 打开【阅读】软件; * 点击备份; -* 打开手机自带的文件管理; -* 手机自带内存根目录找到YueDu3.0文件夹; -* 找到myBookSource.json长按选择分享; -* 选择微信分享或者QQ分享; +* 打开手机系统自带的文件管理; +* 在手机内置存储根目录找到 `YueDu3.0` 文件夹; +* 找到 `myBookSource.json`,长按选择分享; +* 选择微信分享或者 QQ 分享; * 选择你要分享的好友点击发送; -* 好友接收后在手机自带内存根目录找到myBookSource.json文件(最新版QQ 安卓10及以下版本在Android/data/com.tencent.mobileqq/Tencent/QQfile_recv/,安卓11版本用户由于系统限制无法访问data目录,微信在Tencent/MicroMsg/Download); -* 复制该文件到手机自带内存根目录找到YueDu3.0文件夹(如已有该文件请先删除该文件或者备份到其他地方再复制到文件夹); -* 打开阅读软件点击恢复。 -* 注:备份路径如已修改过请在修改后的路径下查找书源文件。 +* 好友接收后在手机内置存储根目录找到 `myBookSource.json` 文件; +* 复制该文件到手机内置存储根目录找到 `YueDu3.0` 文件夹(如已有该文件请先删除该文件或者备份到其他地方再复制到文件夹); +* 打开【阅读】软件点击恢复。 -6. 效验书源显示失效就说明书源不能用了吗? -* 效验书源只是测试书源,可以做个参考,失效了不代表书源不能用了。 +**【注】** +1. *备份路径如已修改过请在修改后的路径下查找书源文件。* +2. *Android 10 及以下版本系统,新版 QQ 文件接收路径在 `Android/data/com.tencent.mobileqq/Tencent/QQfile_recv/`,旧版 QQ 文件接收路径则在 `Tencent/QQfile_recv/`;新版微信文件接收路径在 `Android/data/com.tencent.mobileqq/Tencent/MicroMsg/Download`,旧版微信文件接收路径则在 `Tencent/MicroMsg/Download`。* +3. *Android 11 及以上系统版本用户,由于系统限制,无法访问 `Android/data` 目录。* -7. 发现和正版书源能不能使用? -* 发现和正版书源只能用来找书,看排行榜,不能用来看书,如需看书请切换书源。 +### 6. 效验书源显示失效就说明书源不能用了吗? +效验书源只是测试书源,可以做为参考,但失效了不代表书源不能用了。 -8. 为什么书源这么多,发现里却只有一点点? -* 书源想要在发现界面里显示需要在书源里添加发现规则,并不是所有书源都有发现规则。 +### 7. “发现”和正版书源能不能使用? +发现和正版书源只能用来找书或看排行榜,不能用来看书,如需看书请切换书源。 + +### 8. 为什么书源这么多,“发现”里却只有一点点? +书源想要在发现界面里显示需要在书源里添加发现规则,并不是所有书源都有发现规则。 ## 本地书籍相关 -1. 目前阅读支持哪些格式的本地书籍? -* 目前支持TXT、EPUB格式 -2. 如何导入本地书籍? -* 在书架页面点击右上角,选择“添加本地”,授予相关权限后即可导入本地书籍。也可在文件管理器中使用 **阅读** 打开相关书籍。 +### 1. 目前阅读支持哪些格式的本地书籍? +目前支持 TXT 和 EPUB 格式。 + +### 2. 如何导入本地书籍? +在书架页面点击右上角“**⁝**”,选择“**添加本地**”,授予相关权限后即可导入本地书籍。也可在文件管理器中使用【阅读】打开相关书籍。 -3. 导入TXT文件提示“LoadTocError”或“List is empty”是怎么回事? -* 请先去应用详情中确认是否授予了阅读“读写手机存储”的权限。 +### 3. 导入 TXT 文件提示“LoadTocError”或“List is empty”是怎么回事? +* 请先去应用详情中确认是否授予了【阅读】“读写手机存储”的权限。 * 自动识别目录失败,可能是相关目录规则未开启,请点击右上角的换源按钮手动更换目录规则。 -* 如果尝试所有规则均无法识别,请在github上提交issue并附件相关txt文件,也可以发送邮件至i@qnmlgb.trade(标题:legado本地文件章节无法识别,内容对其具体情况进行简要说明,附件上传相关txt文件)。 -4. 如何下载书籍到本地? -* 把在线书籍加入到书架后,在书架页面点击右上角,选择“离线缓存”即可。 +如果尝试所有规则均无法识别,请在 GitHub 上提交 Issue 并附上相关 TXT 文件,也可以发送邮件至 i@qnmlgb.trade(标题:legado 本地文件章节无法识别;内容对其具体情况进行简要说明,附件上传相关 TXT 文件)。 + +### 4. 如何下载书籍到本地? +把在线书籍加入到书架后,在书架页面点击右上角,选择“**离线缓存**”即可。 -5. 如何自定义导出的txt/epub文件名称? -* 点击 **离线缓存** - **导出文件名**. +### 5. 如何自定义导出的 TXT 或 EPUB 文件名称? +* 点击“**离线缓存**“——”**导出文件名**“ * 使用方法: - - 导出文件名支持js语法 - - 可用变量: name - 书名 author-作者 + - 导出文件名支持 JSON 语法 + - 可用变量: name(书名)和 author(作者) - 示例: > {name+"作者:"+author} - 导出文件名: - > Legado是最好的在线阅读软件 作者: kunfei. + > Legado 是最好的在线阅读软件 作者: kunfei -**注意:** name、author等变量与字符串的拼接都需要在js环境中进行,即必须使用{ } 将变量与字符串包裹起来. +**【注】** *name、author 等变量与字符串的拼接都需要在 JSON 上下文环境中进行,即必须使用 `{}` 将变量与字符串包裹起来。* -6. 为什么我打开本地的TXT文件,显示内容却是乱码? -* 部分编码在阅读上会识别错误,建议先用文本编辑器转换为常用的UTF-8格式。 +### 6. 为什么我打开本地的 TXT 文件,显示内容却是乱码? +部分编码在阅读上会识别错误,建议先用文本编辑器转换为常用的 UTF-8 格式。 -7. 阅读对部分把正文(如所有含引号的句子)识别成标题,如何解决? -* 点击右上角更换目录规则即可。 +### 7. 阅读对部分把正文(如所有含引号的句子)识别成标题,如何解决? +点击右上角更换目录规则即可。 ## 书籍界面相关 -1. 如何刷新书架? -* 在书架界面下拉即可刷新。 +### 1. 如何刷新书架? +在书架界面下拉即可刷新。 -2. 书架界面书籍右上角的红色或者灰色背景小数字代表什么? -* 红色代表书籍有更新,灰色代表无更新,数字代表未读章节。 +### 2. 书架界面书籍右上角的红色或者灰色背景小数字代表什么? +红色代表书籍有更新,灰色代表无更新,数字代表未读章节。 -3. 如何查看书籍详情? -* 长按书籍。 +### 3. 如何查看书籍详情? +长按书籍即可查看。 -4. 如何对书架上的书进行删除、切换书架的操作? -* 书籍详情页操作即可。 +### 4. 如何对书架上的书进行删除、切换书架的操作? +书籍详情页操作即可。 -5. 如何禁止或允许某本书更新? -* 书籍详情页,点击右上角 - “允许更新”。 +### 5. 如何禁止或允许某本书更新? +书籍详情页,点击右上角——“**允许更新**”。 -6. 如何更换小说封面、名字、作者或简介? -* 书籍详情页,点击右上角修改按钮。 +### 6. 如何更换小说封面、名字、作者或简介? +书籍详情页,点击右上角修改按钮。 -7. 怎么使用自定义字体? -* 阅读界面 - 字体-点击右上角选择字体文件路径。 +### 7. 怎么使用自定义字体? +阅读界面——“**字体**”——点击右上角选择字体文件路径。 -8. 目前支持哪些格式的字体文件? -* 目前支持ttf、otf格式。 +### 8. 目前支持哪些格式的字体文件? +目前支持 TTF 和 OTF 格式。 -9. 书籍经常“正在加载中”怎么办? -* 在线书籍出现这个问题通常是由于源质量不好或不兼容引起的,可以换其它源多试试;本地书籍出现这个问题大概率是目录规则问题,手动切换规则可以解决。 +### 9. 书籍经常“正在加载中”怎么办? +在线书籍出现这个问题通常是由于源质量不好或不兼容引起的,可以换其它源多试试;本地书籍出现这个问题大概率是目录规则问题,手动切换规则可以解决。 -10. 书籍内容只有标题,正文内容是路径怎么办? -* 通常是缓存路径引起的,更换缓存路径即可。 +### 10. 书籍内容只有标题,正文内容是路径怎么办? +通常是缓存路径引起的,更换缓存路径即可。 -11. 看书时如遇到“目录为空”、“加载失败”和长串英文等情况怎么办? -* 在线书籍一般是书源问题,切换或更新书源即可。本地书籍请尝试手动更换目录规则。 +### 11. 看书时如遇到“目录为空”、“加载失败”或长串英文等情况怎么办? +在线书籍一般是书源问题,切换或更新书源即可。本地书籍请尝试手动更换目录规则。 -12. 为什么每一章的最后一页,阅读的文字和横线背景总是对不齐? -* 请在 设置-文字底部对齐 选项中关闭底部对齐,再调整排版。 +### 12. 为什么每一章的最后一页,阅读的文字和横线背景总是对不齐? +请在“**设置**”——“**文字底部对齐**”选项中关闭底部对齐,再调整排版。 -13. 漫画源或图片章节只能看到第一页,如何解决? -* 请先查看原网页是否正常,若正常,请在书籍阅读界面点击右上角的 **⁝** 按钮,在弹出的菜单中,选择 **翻页动画(本书)**,将翻页动画更改为 **滚动**。 +### 13. 漫画源或图片章节只能看到第一页,如何解决? +请先查看原网页是否正常,若正常,请在书籍阅读界面点击右上角的“**⁝**”按钮,在弹出的菜单中,选择“**翻页动画(本书)**”,将翻页动画更改为“**滚动**”。 -14. 阅读图片章节、漫画或epub插图时,图片被缩放到一页中,以至无法看清,如何处理? -* 临时处理方案:长按图片可以进行双指缩放。图片章节请先参考Q13中的方案将翻页动画更改为**滚动** -* 3.0旧版可以点击书籍界面的章节标题进入 **编辑书源** 界面,在 正文-图片样式 中填入 *full*,保存更改,刷新当前章节即可。 -* 3.0新版可以直接在书籍阅读界面点击右上角的 **⁝** 按钮,选择 图片样式- *full*. +### 14. 阅读图片章节、漫画或 EPUB 插图时,图片被缩放到一页中,以至无法看清,如何处理? +* 临时处理方案:长按图片可以进行双指缩放。图片章节请先参考 Q13 中的方案将翻页动画更改为“**滚动**”。 +* 3.0 旧版可以点击书籍界面的章节标题进入“**编辑书源**”界面,在“**正文**”——“**图片样式**”中填入 *`full`*,保存更改,刷新当前章节即可。 +* 3.0 新版可以直接在书籍阅读界面点击右上角的“**⁝**”按钮,选择“**图片样式**”——***`full`***。 ## 替换净化相关 -1. 替换净化是什么? -* 替换净化可以去除书籍内容里的广告、错别字、屏蔽词等。 -2. 如何自己填写净化替换规则? -* 第一行:替换规则名称 - 根据自己需求对替换净化规则进行命名; -* 第二行:分组 - 净化规则的分组组别; -* 第三行:替换规则 - 填写需要被替换的内容; -* 第四行:替换为 - 填写想替换成的内容(如不填则默认表示删除第三行里填写的内容); -* 第五行:替换范围,选填书名或者源名 - 填写此替换净化规则需要对哪本书籍或者哪个书源生效(如不填则对所有书籍和书源生效)。 -* 注:如常规去除方法去除不掉,则需要勾选“使用正则表达式”,同时第三行里的替换规则也需要按照正则表达式来填写(正则表达式填写方法可自行百度学习)。 +### 1. 替换净化是什么? +替换净化可以去除书籍内容里的广告、错别字、屏蔽词等。 + +### 2. 如何自己填写净化替换规则? +* 第一行:替换规则名称。请根据自己需求对替换净化规则进行命名; +* 第二行:分组。净化规则的分组组别; +* 第三行:替换规则。填写需要被替换的内容; +* 第四行:替换为。填写想替换成的内容(如不填则默认表示删除第三行里填写的内容); +* 第五行:替换范围,选填书名或者源名。填写此替换净化规则需要对哪本书籍或者哪个书源生效(如不填则对所有书籍和书源生效)。 + +**【注】** *如常规去除方法去除不掉,则需要勾选“使用正则表达式”,同时第三行里的替换规则也需要按照正则表达式来填写(正则表达式填写方法可自行网上搜索学习)。* ## 备份相关 -1. 云备份在哪? -* 我的 - 备份与恢复 - WebDav设置。 +### 1. 云备份在哪? +“**我的**”——“**备份与恢复**”——“**WebDav 设置**”。 + +### 2. 如何操作进行云备份? +* 侧栏设置,WebDav 设置; +* 正确填写 WebDAV 服务器地址、账号和密码; +* 无需操作,APP 默认每天自动云备份一次。 + +作者在此诚挚推荐使用【坚果云】进行 WebDav 备份。 -2. 如何操作进行云备份? -* 侧栏设置,WebDav设置; -* 正确填写WebDAV 服务器地址、WebDAV 账号、WebDAV 密码;(要获得这三项的信息,需要注册一个坚果云账号,如果直接在手机上注册,坚果云会让你下载app,过程比较麻烦,为了一步到位,最好是在电脑上打开这个注册链接:https://www.jianguoyun.com/d/signup ;注册后,进入坚果云;点击右上角账户名处选择 “账户信息”,然后选择“安全选项”;在“安全选项” 中找到“第三方应用管理”,并选择“添加应用”,输入名称如“阅读”后,会生成密码,选择完成;其中 https://dav.jianguoyun.com/dav/ 就是填入“WebDAV 服务器地址”的内容,“使用情况”后面的邮箱地址就是你的“WebDAV 账号”,点击显示密码后得到的密码就是你的“WebDAV 密码”。) -* 无需操作,APP默认每天自动云备份一次。 +如果直接在手机上注册,须下载【坚果云】APP,步骤较为繁琐。推荐在电脑上进行操作: +1. 打开注册链接:https://www.jianguoyun.com/d/signup ; +2. 注册后,进入坚果云; +3. 点击右上角账户名处选择“**账户信息**”,然后选择“**安全选项**”; +4. 在“**安全选项**”中找到“**第三方应用管理**”,并选择“**添加应用**”,输入名称(如“阅读”)后,会生成密码,选择完成; +5. 其中 `https://dav.jianguoyun.com/dav/` 就是填入“**WebDAV 服务器地址**”的内容,“**使用情况**”后面的邮箱地址就是你的“**WebDAV 账号**”,点击“**显示密码**“后得到的密码就是你的“**WebDAV 密码**”。 -3. 关于云备份的相关说明 -* 在正确设置好云备份的情况下,APP默认每天自动云备份一次,当日多次手动云备份会对当日的旧云备份文件进行覆盖,并不会覆盖之前及之后不同日期的备份文件,每天所自动云备份的文件会按照日期进行命名。 +### 3. 关于云备份的相关说明 -4. 本地备份和云备份都能备份哪些东西? -* 书架、看书进度、搜索记录、书源、替换、APP设置等都会备份,基本涵盖所有内容。 +在正确设置好云备份的情况下,APP 默认每天自动云备份一次,当日多次手动云备份会对当日的旧云备份文件进行覆盖,并不会覆盖之前及之后不同日期的备份文件,每天所自动云备份的文件会按照日期进行命名。 -5. 出现某些未知bug怎么办? -* 清除软件数据试试看,不行再进行反馈。 +### 4. 本地备份和云备份都能备份哪些东西? +书架、看书进度、搜索记录、书源、替换和 APP 设置等都会备份,基本涵盖所有内容。 + +### 5. 出现某些未知 Bug 怎么办? +清除软件数据试试看,不行再进行反馈。 ## 其他 -1. 如何听书? -* 可以使用手机自带的朗读引擎,也可使用第三方如谷歌、小米等朗读引擎。 -* 【具体操作:安装-系统设置-其他高级设置-辅助功能-TTS输出-选择安装的朗读引擎(不同品牌手机的操作方法及步骤也不同,视情况而定)。】 -2. 如何设置屏幕方向、屏幕显示时长、显示/隐藏状态栏、显示/隐藏导航栏、音量键翻页、长按选择文本、点击总是翻下一页、自定义翻页案件? -* 阅读界面,设置(可上划,下面还有其他设置)。 +### 1. 如何听书? +可以使用手机自带的朗读引擎,也可使用第三方如 Google(谷歌)或小米等朗读引擎。 + +【具体操作】*安装——系统设置——其他高级设置——辅助功能——TTS 输出——选择安装的朗读引擎(不同品牌手机的操作方法及步骤也不同,视情况而定)。* + +### 2. 如何设置屏幕方向、屏幕显示时长、显示/隐藏状态栏、显示/隐藏导航栏、音量键翻页、长按选择文本、点击总是翻下一页或自定义翻页按键? +阅读界面——“**设置**”(可上划,下面还有其他设置)。 -3. 搜索的时候感觉手机卡顿,如何解决? -* 我的 - 其他设置 - “更新和搜索线程数”调低。 +### 3. 搜索的时候感觉手机卡顿,如何解决? +“**我的**”——“**其他设置**”——调低“**更新和搜索线程数**”。 From c71099a379d9962c246038ec29c1fca21ddbabf5 Mon Sep 17 00:00:00 2001 From: Xwite <1797350009@qq.com> Date: Sat, 4 Jun 2022 15:36:21 +0800 Subject: [PATCH 4/8] fix(epub): titlepage.xhtml --- .../main/java/io/legado/app/model/localBook/EpubFile.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt b/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt index b12e0726e..428cccb82 100644 --- a/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt +++ b/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt @@ -122,11 +122,10 @@ class EpubFile(var book: Book) { private fun getContent(chapter: BookChapter): String? { /** - * - * - * titlepage.xhtml + * + * ...titlepage.xhtml */ - if (chapter.url == "titlepage.xhtml") { + if (chapter.url.contains("titlepage.xhtml")) { return "" } /*获取当前章节文本*/ From 05581c30c3f13a88c4e39884a6fdfd37c2645b34 Mon Sep 17 00:00:00 2001 From: Xwite <1797350009@qq.com> Date: Sat, 4 Jun 2022 15:45:57 +0800 Subject: [PATCH 5/8] fix(LocalBook): remove duplicated chapter --- app/src/main/java/io/legado/app/model/localBook/LocalBook.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt b/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt index 4819cf85c..b53d1cb32 100644 --- a/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt +++ b/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt @@ -76,7 +76,8 @@ object LocalBook { if (chapters.isEmpty()) { throw TocEmptyException(appCtx.getString(R.string.chapter_list_empty)) } - return chapters + val lh = LinkedHashSet(chapters) + return ArrayList(lh) } fun getContent(book: Book, chapter: BookChapter): String? { From e5447581da8d6c4a3fdfd52ad40fb965f45331ba Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 4 Jun 2022 18:33:06 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/help/appHelp.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/assets/help/appHelp.md b/app/src/main/assets/help/appHelp.md index a62396b21..193dbd591 100644 --- a/app/src/main/assets/help/appHelp.md +++ b/app/src/main/assets/help/appHelp.md @@ -94,10 +94,10 @@ ### 5. 如何自定义导出的 TXT 或 EPUB 文件名称? * 点击“**离线缓存**“——”**导出文件名**“ * 使用方法: - - 导出文件名支持 JSON 语法 + - 导出文件名支持 js 语法 - 可用变量: name(书名)和 author(作者) - - 示例: - > {name+"作者:"+author} + - 示例: + > name + "作者:" + author - 导出文件名: > Legado 是最好的在线阅读软件 作者: kunfei From 65136bca5012f7b6d86244c19c2ce70d40ff7494 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 5 Jun 2022 21:57:11 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io.legado.app.data.AppDatabase/50.json | 1666 +++++++++++++++++ app/src/main/assets/updateLog.md | 4 + .../java/io/legado/app/data/AppDatabase.kt | 5 +- .../io/legado/app/data/entities/BookSource.kt | 10 + .../io/legado/app/data/entities/RssSource.kt | 33 +- .../app/ui/book/info/BookInfoActivity.kt | 22 +- .../app/ui/rss/article/RssSortActivity.kt | 14 +- .../legado/app/ui/rss/read/ReadRssActivity.kt | 2 +- 8 files changed, 1737 insertions(+), 19 deletions(-) create mode 100644 app/schemas/io.legado.app.data.AppDatabase/50.json diff --git a/app/schemas/io.legado.app.data.AppDatabase/50.json b/app/schemas/io.legado.app.data.AppDatabase/50.json new file mode 100644 index 000000000..05ebf3e6f --- /dev/null +++ b/app/schemas/io.legado.app.data.AppDatabase/50.json @@ -0,0 +1,1666 @@ +{ + "formatVersion": 1, + "database": { + "version": 50, + "identityHash": "524cf3564400bd897a49355afd984ac1", + "entities": [ + { + "tableName": "books", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookUrl` TEXT NOT NULL DEFAULT '', `tocUrl` TEXT NOT NULL DEFAULT '', `origin` TEXT NOT NULL DEFAULT '', `originName` TEXT NOT NULL DEFAULT '', `name` TEXT NOT NULL DEFAULT '', `author` TEXT NOT NULL DEFAULT '', `kind` TEXT, `customTag` TEXT, `coverUrl` TEXT, `customCoverUrl` TEXT, `intro` TEXT, `customIntro` TEXT, `charset` TEXT, `type` INTEGER NOT NULL DEFAULT 0, `group` INTEGER NOT NULL DEFAULT 0, `latestChapterTitle` TEXT, `latestChapterTime` INTEGER NOT NULL DEFAULT 0, `lastCheckTime` INTEGER NOT NULL DEFAULT 0, `lastCheckCount` INTEGER NOT NULL DEFAULT 0, `totalChapterNum` INTEGER NOT NULL DEFAULT 0, `durChapterTitle` TEXT, `durChapterIndex` INTEGER NOT NULL DEFAULT 0, `durChapterPos` INTEGER NOT NULL DEFAULT 0, `durChapterTime` INTEGER NOT NULL DEFAULT 0, `wordCount` TEXT, `canUpdate` INTEGER NOT NULL DEFAULT 1, `order` INTEGER NOT NULL DEFAULT 0, `originOrder` INTEGER NOT NULL DEFAULT 0, `variable` TEXT, `readConfig` TEXT, PRIMARY KEY(`bookUrl`))", + "fields": [ + { + "fieldPath": "bookUrl", + "columnName": "bookUrl", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "tocUrl", + "columnName": "tocUrl", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "origin", + "columnName": "origin", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "originName", + "columnName": "originName", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "author", + "columnName": "author", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "kind", + "columnName": "kind", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "customTag", + "columnName": "customTag", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "coverUrl", + "columnName": "coverUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "customCoverUrl", + "columnName": "customCoverUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "intro", + "columnName": "intro", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "customIntro", + "columnName": "customIntro", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "charset", + "columnName": "charset", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "group", + "columnName": "group", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "latestChapterTitle", + "columnName": "latestChapterTitle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "latestChapterTime", + "columnName": "latestChapterTime", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "lastCheckTime", + "columnName": "lastCheckTime", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "lastCheckCount", + "columnName": "lastCheckCount", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "totalChapterNum", + "columnName": "totalChapterNum", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "durChapterTitle", + "columnName": "durChapterTitle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "durChapterIndex", + "columnName": "durChapterIndex", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "durChapterPos", + "columnName": "durChapterPos", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "durChapterTime", + "columnName": "durChapterTime", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "wordCount", + "columnName": "wordCount", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "canUpdate", + "columnName": "canUpdate", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "order", + "columnName": "order", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "originOrder", + "columnName": "originOrder", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "variable", + "columnName": "variable", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "readConfig", + "columnName": "readConfig", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "bookUrl" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_books_name_author", + "unique": true, + "columnNames": [ + "name", + "author" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_books_name_author` ON `${TABLE_NAME}` (`name`, `author`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "book_groups", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`groupId` INTEGER NOT NULL, `groupName` TEXT NOT NULL, `cover` TEXT, `order` INTEGER NOT NULL, `show` INTEGER NOT NULL, PRIMARY KEY(`groupId`))", + "fields": [ + { + "fieldPath": "groupId", + "columnName": "groupId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "groupName", + "columnName": "groupName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "cover", + "columnName": "cover", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "order", + "columnName": "order", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "show", + "columnName": "show", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "groupId" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "book_sources", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookSourceUrl` TEXT NOT NULL, `bookSourceName` TEXT NOT NULL, `bookSourceGroup` TEXT, `bookSourceType` INTEGER NOT NULL, `bookUrlPattern` TEXT, `customOrder` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `enabledExplore` INTEGER NOT NULL, `enabledCookieJar` INTEGER DEFAULT 0, `concurrentRate` TEXT, `header` TEXT, `loginUrl` TEXT, `loginUi` TEXT, `loginCheckJs` TEXT, `bookSourceComment` TEXT, `variableComment` TEXT, `lastUpdateTime` INTEGER NOT NULL, `respondTime` INTEGER NOT NULL, `weight` INTEGER NOT NULL, `exploreUrl` TEXT, `ruleExplore` TEXT, `searchUrl` TEXT, `ruleSearch` TEXT, `ruleBookInfo` TEXT, `ruleToc` TEXT, `ruleContent` TEXT, PRIMARY KEY(`bookSourceUrl`))", + "fields": [ + { + "fieldPath": "bookSourceUrl", + "columnName": "bookSourceUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "bookSourceName", + "columnName": "bookSourceName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "bookSourceGroup", + "columnName": "bookSourceGroup", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "bookSourceType", + "columnName": "bookSourceType", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "bookUrlPattern", + "columnName": "bookUrlPattern", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "customOrder", + "columnName": "customOrder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "enabled", + "columnName": "enabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "enabledExplore", + "columnName": "enabledExplore", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "enabledCookieJar", + "columnName": "enabledCookieJar", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "0" + }, + { + "fieldPath": "concurrentRate", + "columnName": "concurrentRate", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "header", + "columnName": "header", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "loginUrl", + "columnName": "loginUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "loginUi", + "columnName": "loginUi", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "loginCheckJs", + "columnName": "loginCheckJs", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "bookSourceComment", + "columnName": "bookSourceComment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "variableComment", + "columnName": "variableComment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastUpdateTime", + "columnName": "lastUpdateTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "respondTime", + "columnName": "respondTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "weight", + "columnName": "weight", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "exploreUrl", + "columnName": "exploreUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleExplore", + "columnName": "ruleExplore", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "searchUrl", + "columnName": "searchUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleSearch", + "columnName": "ruleSearch", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleBookInfo", + "columnName": "ruleBookInfo", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleToc", + "columnName": "ruleToc", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleContent", + "columnName": "ruleContent", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "bookSourceUrl" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_book_sources_bookSourceUrl", + "unique": false, + "columnNames": [ + "bookSourceUrl" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_book_sources_bookSourceUrl` ON `${TABLE_NAME}` (`bookSourceUrl`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "chapters", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `title` TEXT NOT NULL, `isVolume` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `bookUrl` TEXT NOT NULL, `index` INTEGER NOT NULL, `isVip` INTEGER NOT NULL, `isPay` INTEGER NOT NULL, `resourceUrl` TEXT, `tag` TEXT, `start` INTEGER, `end` INTEGER, `startFragmentId` TEXT, `endFragmentId` TEXT, `variable` TEXT, PRIMARY KEY(`url`, `bookUrl`), FOREIGN KEY(`bookUrl`) REFERENCES `books`(`bookUrl`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isVolume", + "columnName": "isVolume", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "baseUrl", + "columnName": "baseUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "bookUrl", + "columnName": "bookUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index", + "columnName": "index", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isVip", + "columnName": "isVip", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isPay", + "columnName": "isPay", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "resourceUrl", + "columnName": "resourceUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "tag", + "columnName": "tag", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "start", + "columnName": "start", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "end", + "columnName": "end", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "startFragmentId", + "columnName": "startFragmentId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "endFragmentId", + "columnName": "endFragmentId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "variable", + "columnName": "variable", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "url", + "bookUrl" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_chapters_bookUrl", + "unique": false, + "columnNames": [ + "bookUrl" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_chapters_bookUrl` ON `${TABLE_NAME}` (`bookUrl`)" + }, + { + "name": "index_chapters_bookUrl_index", + "unique": true, + "columnNames": [ + "bookUrl", + "index" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_chapters_bookUrl_index` ON `${TABLE_NAME}` (`bookUrl`, `index`)" + } + ], + "foreignKeys": [ + { + "table": "books", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "bookUrl" + ], + "referencedColumns": [ + "bookUrl" + ] + } + ] + }, + { + "tableName": "replace_rules", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL DEFAULT '', `group` TEXT, `pattern` TEXT NOT NULL DEFAULT '', `replacement` TEXT NOT NULL DEFAULT '', `scope` TEXT, `scopeTitle` INTEGER NOT NULL DEFAULT 0, `scopeContent` INTEGER NOT NULL DEFAULT 1, `isEnabled` INTEGER NOT NULL DEFAULT 1, `isRegex` INTEGER NOT NULL DEFAULT 1, `timeoutMillisecond` INTEGER NOT NULL DEFAULT 3000, `sortOrder` INTEGER NOT NULL DEFAULT 0)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "group", + "columnName": "group", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "pattern", + "columnName": "pattern", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "replacement", + "columnName": "replacement", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "scope", + "columnName": "scope", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "scopeTitle", + "columnName": "scopeTitle", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "scopeContent", + "columnName": "scopeContent", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "isEnabled", + "columnName": "isEnabled", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "isRegex", + "columnName": "isRegex", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "timeoutMillisecond", + "columnName": "timeoutMillisecond", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "3000" + }, + { + "fieldPath": "order", + "columnName": "sortOrder", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_replace_rules_id", + "unique": false, + "columnNames": [ + "id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_replace_rules_id` ON `${TABLE_NAME}` (`id`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "searchBooks", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookUrl` TEXT NOT NULL, `origin` TEXT NOT NULL, `originName` TEXT NOT NULL, `type` INTEGER NOT NULL, `name` TEXT NOT NULL, `author` TEXT NOT NULL, `kind` TEXT, `coverUrl` TEXT, `intro` TEXT, `wordCount` TEXT, `latestChapterTitle` TEXT, `tocUrl` TEXT NOT NULL, `time` INTEGER NOT NULL, `variable` TEXT, `originOrder` INTEGER NOT NULL, PRIMARY KEY(`bookUrl`), FOREIGN KEY(`origin`) REFERENCES `book_sources`(`bookSourceUrl`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "bookUrl", + "columnName": "bookUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "origin", + "columnName": "origin", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "originName", + "columnName": "originName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "author", + "columnName": "author", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "kind", + "columnName": "kind", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "coverUrl", + "columnName": "coverUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "intro", + "columnName": "intro", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "wordCount", + "columnName": "wordCount", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "latestChapterTitle", + "columnName": "latestChapterTitle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "tocUrl", + "columnName": "tocUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "time", + "columnName": "time", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "variable", + "columnName": "variable", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "originOrder", + "columnName": "originOrder", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "bookUrl" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_searchBooks_bookUrl", + "unique": true, + "columnNames": [ + "bookUrl" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_searchBooks_bookUrl` ON `${TABLE_NAME}` (`bookUrl`)" + }, + { + "name": "index_searchBooks_origin", + "unique": false, + "columnNames": [ + "origin" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_searchBooks_origin` ON `${TABLE_NAME}` (`origin`)" + } + ], + "foreignKeys": [ + { + "table": "book_sources", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "origin" + ], + "referencedColumns": [ + "bookSourceUrl" + ] + } + ] + }, + { + "tableName": "search_keywords", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`word` TEXT NOT NULL, `usage` INTEGER NOT NULL, `lastUseTime` INTEGER NOT NULL, PRIMARY KEY(`word`))", + "fields": [ + { + "fieldPath": "word", + "columnName": "word", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "usage", + "columnName": "usage", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastUseTime", + "columnName": "lastUseTime", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "word" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_search_keywords_word", + "unique": true, + "columnNames": [ + "word" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_search_keywords_word` ON `${TABLE_NAME}` (`word`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "cookies", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `cookie` TEXT NOT NULL, PRIMARY KEY(`url`))", + "fields": [ + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "cookie", + "columnName": "cookie", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "url" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_cookies_url", + "unique": true, + "columnNames": [ + "url" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_cookies_url` ON `${TABLE_NAME}` (`url`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "rssSources", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`sourceUrl` TEXT NOT NULL, `sourceName` TEXT NOT NULL, `sourceIcon` TEXT NOT NULL, `sourceGroup` TEXT, `sourceComment` TEXT, `enabled` INTEGER NOT NULL, `variableComment` TEXT, `enabledCookieJar` INTEGER DEFAULT 0, `concurrentRate` TEXT, `header` TEXT, `loginUrl` TEXT, `loginUi` TEXT, `loginCheckJs` TEXT, `sortUrl` TEXT, `singleUrl` INTEGER NOT NULL, `articleStyle` INTEGER NOT NULL, `ruleArticles` TEXT, `ruleNextPage` TEXT, `ruleTitle` TEXT, `rulePubDate` TEXT, `ruleDescription` TEXT, `ruleImage` TEXT, `ruleLink` TEXT, `ruleContent` TEXT, `style` TEXT, `enableJs` INTEGER NOT NULL, `loadWithBaseUrl` INTEGER NOT NULL, `customOrder` INTEGER NOT NULL, PRIMARY KEY(`sourceUrl`))", + "fields": [ + { + "fieldPath": "sourceUrl", + "columnName": "sourceUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sourceName", + "columnName": "sourceName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sourceIcon", + "columnName": "sourceIcon", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sourceGroup", + "columnName": "sourceGroup", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "sourceComment", + "columnName": "sourceComment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "enabled", + "columnName": "enabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "variableComment", + "columnName": "variableComment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "enabledCookieJar", + "columnName": "enabledCookieJar", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "0" + }, + { + "fieldPath": "concurrentRate", + "columnName": "concurrentRate", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "header", + "columnName": "header", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "loginUrl", + "columnName": "loginUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "loginUi", + "columnName": "loginUi", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "loginCheckJs", + "columnName": "loginCheckJs", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "sortUrl", + "columnName": "sortUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "singleUrl", + "columnName": "singleUrl", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "articleStyle", + "columnName": "articleStyle", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "ruleArticles", + "columnName": "ruleArticles", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleNextPage", + "columnName": "ruleNextPage", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleTitle", + "columnName": "ruleTitle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "rulePubDate", + "columnName": "rulePubDate", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleDescription", + "columnName": "ruleDescription", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleImage", + "columnName": "ruleImage", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleLink", + "columnName": "ruleLink", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleContent", + "columnName": "ruleContent", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "style", + "columnName": "style", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "enableJs", + "columnName": "enableJs", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "loadWithBaseUrl", + "columnName": "loadWithBaseUrl", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "customOrder", + "columnName": "customOrder", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "sourceUrl" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_rssSources_sourceUrl", + "unique": false, + "columnNames": [ + "sourceUrl" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_rssSources_sourceUrl` ON `${TABLE_NAME}` (`sourceUrl`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "bookmarks", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`time` INTEGER NOT NULL, `bookName` TEXT NOT NULL, `bookAuthor` TEXT NOT NULL, `chapterIndex` INTEGER NOT NULL, `chapterPos` INTEGER NOT NULL, `chapterName` TEXT NOT NULL, `bookText` TEXT NOT NULL, `content` TEXT NOT NULL, PRIMARY KEY(`time`))", + "fields": [ + { + "fieldPath": "time", + "columnName": "time", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "bookName", + "columnName": "bookName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "bookAuthor", + "columnName": "bookAuthor", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "chapterIndex", + "columnName": "chapterIndex", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "chapterPos", + "columnName": "chapterPos", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "chapterName", + "columnName": "chapterName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "bookText", + "columnName": "bookText", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "time" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_bookmarks_bookName_bookAuthor", + "unique": false, + "columnNames": [ + "bookName", + "bookAuthor" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_bookmarks_bookName_bookAuthor` ON `${TABLE_NAME}` (`bookName`, `bookAuthor`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "rssArticles", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`origin` TEXT NOT NULL, `sort` TEXT NOT NULL, `title` TEXT NOT NULL, `order` INTEGER NOT NULL, `link` TEXT NOT NULL, `pubDate` TEXT, `description` TEXT, `content` TEXT, `image` TEXT, `read` INTEGER NOT NULL, `variable` TEXT, PRIMARY KEY(`origin`, `link`))", + "fields": [ + { + "fieldPath": "origin", + "columnName": "origin", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sort", + "columnName": "sort", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "order", + "columnName": "order", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "link", + "columnName": "link", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "pubDate", + "columnName": "pubDate", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "image", + "columnName": "image", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "read", + "columnName": "read", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "variable", + "columnName": "variable", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "origin", + "link" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "rssReadRecords", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`record` TEXT NOT NULL, `read` INTEGER NOT NULL, PRIMARY KEY(`record`))", + "fields": [ + { + "fieldPath": "record", + "columnName": "record", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "read", + "columnName": "read", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "record" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "rssStars", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`origin` TEXT NOT NULL, `sort` TEXT NOT NULL, `title` TEXT NOT NULL, `starTime` INTEGER NOT NULL, `link` TEXT NOT NULL, `pubDate` TEXT, `description` TEXT, `content` TEXT, `image` TEXT, `variable` TEXT, PRIMARY KEY(`origin`, `link`))", + "fields": [ + { + "fieldPath": "origin", + "columnName": "origin", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sort", + "columnName": "sort", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "starTime", + "columnName": "starTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "link", + "columnName": "link", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "pubDate", + "columnName": "pubDate", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "image", + "columnName": "image", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "variable", + "columnName": "variable", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "origin", + "link" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "txtTocRules", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `rule` TEXT NOT NULL, `serialNumber` INTEGER NOT NULL, `enable` INTEGER NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "rule", + "columnName": "rule", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "serialNumber", + "columnName": "serialNumber", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "enable", + "columnName": "enable", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "readRecord", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`deviceId` TEXT NOT NULL, `bookName` TEXT NOT NULL, `readTime` INTEGER NOT NULL, PRIMARY KEY(`deviceId`, `bookName`))", + "fields": [ + { + "fieldPath": "deviceId", + "columnName": "deviceId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "bookName", + "columnName": "bookName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "readTime", + "columnName": "readTime", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "deviceId", + "bookName" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "httpTTS", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `url` TEXT NOT NULL, `contentType` TEXT, `concurrentRate` TEXT DEFAULT '0', `loginUrl` TEXT, `loginUi` TEXT, `header` TEXT, `enabledCookieJar` INTEGER DEFAULT 0, `loginCheckJs` TEXT, `lastUpdateTime` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "contentType", + "columnName": "contentType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "concurrentRate", + "columnName": "concurrentRate", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'0'" + }, + { + "fieldPath": "loginUrl", + "columnName": "loginUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "loginUi", + "columnName": "loginUi", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "header", + "columnName": "header", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "enabledCookieJar", + "columnName": "enabledCookieJar", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "0" + }, + { + "fieldPath": "loginCheckJs", + "columnName": "loginCheckJs", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastUpdateTime", + "columnName": "lastUpdateTime", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "caches", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`key` TEXT NOT NULL, `value` TEXT, `deadline` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "key", + "columnName": "key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "deadline", + "columnName": "deadline", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_caches_key", + "unique": true, + "columnNames": [ + "key" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_caches_key` ON `${TABLE_NAME}` (`key`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "ruleSubs", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `url` TEXT NOT NULL, `type` INTEGER NOT NULL, `customOrder` INTEGER NOT NULL, `autoUpdate` INTEGER NOT NULL, `update` INTEGER NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "customOrder", + "columnName": "customOrder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "autoUpdate", + "columnName": "autoUpdate", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "update", + "columnName": "update", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "keyboardAssists", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`type` INTEGER NOT NULL DEFAULT 0, `key` TEXT NOT NULL DEFAULT '', `value` TEXT NOT NULL DEFAULT '', `serialNo` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`type`, `key`))", + "fields": [ + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "serialNo", + "columnName": "serialNo", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "columnNames": [ + "type", + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '524cf3564400bd897a49355afd984ac1')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index c113b2031..c9d308efb 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -11,6 +11,10 @@ * 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则或简繁转换出现问题。 * 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源! +**2022/06/05** + +* 添加源变量说明,输入源变量界面显示说明 + **2022/06/01** * 更新cronet: 102.0.5005.78 diff --git a/app/src/main/java/io/legado/app/data/AppDatabase.kt b/app/src/main/java/io/legado/app/data/AppDatabase.kt index 1cb68c80d..c03e049e9 100644 --- a/app/src/main/java/io/legado/app/data/AppDatabase.kt +++ b/app/src/main/java/io/legado/app/data/AppDatabase.kt @@ -20,7 +20,7 @@ val appDb by lazy { } @Database( - version = 49, + version = 50, exportSchema = true, entities = [Book::class, BookGroup::class, BookSource::class, BookChapter::class, ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class, @@ -33,7 +33,8 @@ val appDb by lazy { AutoMigration(from = 45, to = 46), AutoMigration(from = 46, to = 47), AutoMigration(from = 47, to = 48), - AutoMigration(from = 48, to = 49) + AutoMigration(from = 48, to = 49), + AutoMigration(from = 49, to = 50) ] ) abstract class AppDatabase : RoomDatabase() { diff --git a/app/src/main/java/io/legado/app/data/entities/BookSource.kt b/app/src/main/java/io/legado/app/data/entities/BookSource.kt index 4d76d1713..72d2b7589 100644 --- a/app/src/main/java/io/legado/app/data/entities/BookSource.kt +++ b/app/src/main/java/io/legado/app/data/entities/BookSource.kt @@ -54,6 +54,8 @@ data class BookSource( var loginCheckJs: String? = null, // 注释 var bookSourceComment: String? = null, + // 自定义变量说明 + var variableComment: String? = null, // 最后更新时间,用于排序 var lastUpdateTime: Long = 0, // 响应时间,用于排序 @@ -211,6 +213,14 @@ data class BookSource( }?.joinToString() ?: "" } + fun getDisplayVariableComment(otherComment: String): String { + return if (variableComment.isNullOrBlank()) { + otherComment + } else { + "${variableComment}\n$otherComment" + } + } + fun equal(source: BookSource) = equal(bookSourceName, source.bookSourceName) && equal(bookSourceUrl, source.bookSourceUrl) diff --git a/app/src/main/java/io/legado/app/data/entities/RssSource.kt b/app/src/main/java/io/legado/app/data/entities/RssSource.kt index 90a17273a..dd4eaa9b5 100644 --- a/app/src/main/java/io/legado/app/data/entities/RssSource.kt +++ b/app/src/main/java/io/legado/app/data/entities/RssSource.kt @@ -15,22 +15,35 @@ import splitties.init.appCtx data class RssSource( @PrimaryKey var sourceUrl: String = "", + // 名称 var sourceName: String = "", + // 图标 var sourceIcon: String = "", + // 分组 var sourceGroup: String? = null, + // 注释 var sourceComment: String? = null, + // 是否启用 var enabled: Boolean = true, + // 自定义变量说明 + var variableComment: String? = null, @ColumnInfo(defaultValue = "0") override var enabledCookieJar: Boolean? = false, - override var concurrentRate: String? = null, //并发率 - override var header: String? = null, // 请求头 - override var loginUrl: String? = null, // 登录地址 - override var loginUi: String? = null, //登录UI - var loginCheckJs: String? = null, //登录检测js + //并发率 + override var concurrentRate: String? = null, + // 请求头 + override var header: String? = null, + // 登录地址 + override var loginUrl: String? = null, + //登录UI + override var loginUi: String? = null, + //登录检测js + var loginCheckJs: String? = null, var sortUrl: String? = null, var singleUrl: Boolean = false, /*列表规则*/ - var articleStyle: Int = 0, //列表样式,0,1,2 + //列表样式,0,1,2 + var articleStyle: Int = 0, var ruleArticles: String? = null, var ruleNextPage: String? = null, var ruleTitle: String? = null, @@ -131,6 +144,14 @@ data class RssSource( } } + fun getDisplayVariableComment(otherComment: String): String { + return if (variableComment.isNullOrBlank()) { + otherComment + } else { + "${variableComment}\n$otherComment" + } + } + @Suppress("MemberVisibilityCanBePrivate") companion object { diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt index 176c08f76..0f93ba53b 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt @@ -247,7 +247,11 @@ class BookInfoActivity : binding.tvToc.text = getString(R.string.toc_s, getString(R.string.loading)) } chapterList.isNullOrEmpty() -> { - binding.tvToc.text = if (viewModel.isImportBookOnLine) getString(R.string.click_read_button_load) else getString(R.string.toc_s, getString(R.string.error_load_toc)) + binding.tvToc.text = + if (viewModel.isImportBookOnLine) getString(R.string.click_read_button_load) else getString( + R.string.toc_s, + getString(R.string.error_load_toc) + ) } else -> { viewModel.bookData.value?.let { @@ -358,9 +362,14 @@ class BookInfoActivity : private fun setSourceVariable() { launch { - val variable = withContext(IO) { viewModel.bookSource?.getVariable() } + val source = viewModel.bookSource + if (source == null) { + toastOnUi("书源不存在") + return@launch + } + val variable = withContext(IO) { source.getVariable() } alert(R.string.set_source_variable) { - setMessage("源变量可在js中通过source.getVariable()获取") + setMessage(source.getDisplayVariableComment("源变量可在js中通过source.getVariable()获取")) val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { editView.hint = "source variable" editView.setText(variable) @@ -379,9 +388,14 @@ class BookInfoActivity : private fun setBookVariable() { launch { + val source = viewModel.bookSource + if (source == null) { + toastOnUi("书源不存在") + return@launch + } val variable = withContext(IO) { viewModel.bookData.value?.getVariable("custom") } alert(R.string.set_source_variable) { - setMessage("""书籍变量可在js中通过book.getVariable("custom")获取""") + setMessage(source.getDisplayVariableComment("""书籍变量可在js中通过book.getVariable("custom")获取""")) val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { editView.hint = "book variable" editView.setText(variable) diff --git a/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt b/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt index cf769b459..a2d8cc935 100644 --- a/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt @@ -17,11 +17,8 @@ import io.legado.app.lib.dialogs.alert import io.legado.app.lib.theme.accentColor import io.legado.app.ui.login.SourceLoginActivity import io.legado.app.ui.rss.source.edit.RssSourceEditActivity -import io.legado.app.utils.StartActivityContract -import io.legado.app.utils.gone -import io.legado.app.utils.startActivity +import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding -import io.legado.app.utils.visible import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -106,9 +103,14 @@ class RssSortActivity : VMBaseActivity return true } - @Suppress("DEPRECATION") + @Suppress("DEPRECATION", "OVERRIDE_DEPRECATION") override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { url?.let { return shouldOverrideUrlLoading(Uri.parse(it)) From e04e1432aee7fb80afb0dbc82b3428a9fd3ff848 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 5 Jun 2022 22:08:01 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/book/source/edit/BookSourceEditActivity.kt | 10 +++------- .../app/ui/rss/source/edit/RssSourceEditActivity.kt | 8 +++----- app/src/main/res/values-es-rES/strings.xml | 3 ++- app/src/main/res/values-ja-rJP/strings.xml | 3 ++- app/src/main/res/values-pt-rBR/strings.xml | 3 ++- app/src/main/res/values-zh-rHK/strings.xml | 3 ++- app/src/main/res/values-zh-rTW/strings.xml | 3 ++- app/src/main/res/values-zh/strings.xml | 3 ++- app/src/main/res/values/strings.xml | 3 ++- 9 files changed, 20 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt index fdf694bb3..acc770fff 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt @@ -215,13 +215,8 @@ class BookSourceEditActivity : add(EditEntity("loginCheckJs", source?.loginCheckJs, R.string.login_check_js)) add(EditEntity("bookUrlPattern", source?.bookUrlPattern, R.string.book_url_pattern)) add(EditEntity("header", source?.header, R.string.source_http_header)) - add( - EditEntity( - "concurrentRate", - source?.concurrentRate, - R.string.source_concurrent_rate - ) - ) + add(EditEntity("variableComment", source?.variableComment, R.string.variable_comment)) + add(EditEntity("concurrentRate", source?.concurrentRate, R.string.concurrent_rate)) } //搜索 val sr = source?.getSearchRule() @@ -328,6 +323,7 @@ class BookSourceEditActivity : "header" -> source.header = it.value "bookSourceComment" -> source.bookSourceComment = it.value ?: "" "concurrentRate" -> source.concurrentRate = it.value + "variableComment" -> source.variableComment = it.value } } searchEntities.forEach { diff --git a/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt b/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt index 01bd4bbe6..45cea1484 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt @@ -170,11 +170,8 @@ class RssSourceEditActivity : add(EditEntity("loginUi", source?.loginUi, R.string.login_ui)) add(EditEntity("loginCheckJs", source?.loginCheckJs, R.string.login_check_js)) add(EditEntity("header", source?.header, R.string.source_http_header)) - add( - EditEntity( - "concurrentRate", source?.concurrentRate, R.string.source_concurrent_rate - ) - ) + add(EditEntity("variableComment", source?.variableComment, R.string.variable_comment)) + add(EditEntity("concurrentRate", source?.concurrentRate, R.string.concurrent_rate)) add(EditEntity("sortUrl", source?.sortUrl, R.string.sort_url)) add(EditEntity("ruleArticles", source?.ruleArticles, R.string.r_articles)) add(EditEntity("ruleNextPage", source?.ruleNextPage, R.string.r_next)) @@ -207,6 +204,7 @@ class RssSourceEditActivity : "loginUi" -> source.loginUi = it.value "loginCheckJs" -> source.loginCheckJs = it.value "header" -> source.header = it.value + "variableComment" -> source.variableComment = it.value "concurrentRate" -> source.concurrentRate = it.value "sortUrl" -> source.sortUrl = it.value "ruleArticles" -> source.ruleArticles = it.value diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index 5827eba82..49bd444fd 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -388,7 +388,7 @@ 源分组(sourceGroup) 自定义源分组 输入自定义源分组名称 - 并发率(concurrentRate) + 并发率(concurrentRate) 分类Url(sortUrl) 登录URL(loginUrl) 登录UI(loginUi) @@ -995,4 +995,5 @@ Fail to decode bitmap Image url is empty, check replacement rules + 变量说明(variableComment) diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index 88570cfdc..324995eb8 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -392,7 +392,7 @@ 源分组(sourceGroup) 自定义源分组 输入自定义源分组名称 - 并发率(concurrentRate) + 并发率(concurrentRate) 分类Url(sortUrl) 登录URL(loginUrl) 登录UI(loginUi) @@ -998,4 +998,5 @@ Fail to decode bitmap Image url is empty, check replacement rules + 变量说明(variableComment) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index ee55c893a..6fae8a053 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -390,7 +390,7 @@ 源分组(fonteGrupo) 自定义源分组 输入自定义源分组名称 - 并发率(taxaSimultânea) + 并发率(taxaSimultânea) 分类Url(ordenarUrl) 登录URL(loginUrl) 登UI(loginIU) @@ -998,4 +998,5 @@ Fail to decode bitmap Image url is empty, check replacement rules + 变量说明(variableComment) diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 22c20f729..8afa0fb70 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -388,7 +388,7 @@ 源URL (sourceUrl) 源分組 (sourceGroup) 分類 Url(sortUrl) - 並發率(concurrentRate) + 並發率(concurrentRate) 登錄 URL(loginUrl) 登錄UI(loginUi) 登錄檢查JS(loginCheckJs) @@ -995,4 +995,5 @@ 图片解码失败 图片链接为空,检查替换净化规则 + 变量说明(variableComment) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 963cff29e..2958a2c5a 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -391,7 +391,7 @@ 源分組(sourceGroup) 自訂源分組 輸入自訂源分組名稱 - 並發率(concurrentRate) + 並發率(concurrentRate) 分類Url(sortUrl) 登入URL(loginUrl) 登入UI(loginUi) @@ -997,4 +997,5 @@ 图片解码失败 图片链接为空,检查替换净化规则 + 变量说明(variableComment) diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 345a0513c..c9bb20512 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -391,7 +391,7 @@ 源分组(sourceGroup) 自定义源分组 输入自定义源分组名称 - 并发率(concurrentRate) + 并发率(concurrentRate) 分类 URL(sortUrl) 登录 URL(loginUrl) 登录 UI(loginUi) @@ -997,4 +997,5 @@ 图片解码失败 图片链接为空,检查替换净化规则 + 变量说明(variableComment) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d6905d954..c81e399db 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -392,7 +392,7 @@ 源分组(sourceGroup) 自定义源分组 输入自定义源分组名称 - 并发率(concurrentRate) + 并发率(concurrentRate) 分类Url(sortUrl) 登录URL(loginUrl) Login UI(loginUi) @@ -998,4 +998,5 @@ Fail to decode bitmap Image url is empty, check replacement rules + 变量说明(variableComment)