Merge branch 'gedoor:master' into master

pull/1119/head
ag2s20150909 3 years ago committed by GitHub
commit 2f16520593
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      app/src/main/assets/updateLog.md
  2. 0
      app/src/main/assets/web/bookSource/index.css
  3. 398
      app/src/main/assets/web/bookSource/index.html
  4. 0
      app/src/main/assets/web/bookSource/index.js
  5. 176
      app/src/main/assets/web/bookshelf.css
  6. 39
      app/src/main/assets/web/bookshelf.html
  7. 203
      app/src/main/assets/web/bookshelf.js
  8. 0
      app/src/main/assets/web/bookshelf/css/about.dbe575e1.css
  9. 0
      app/src/main/assets/web/bookshelf/css/app.e4c919b7.css
  10. 0
      app/src/main/assets/web/bookshelf/css/chunk-vendors.8a465a1d.css
  11. 0
      app/src/main/assets/web/bookshelf/css/detail.e03dc50b.css
  12. 0
      app/src/main/assets/web/bookshelf/fonts/element-icons.535877f5.woff
  13. 0
      app/src/main/assets/web/bookshelf/fonts/element-icons.732389de.ttf
  14. 0
      app/src/main/assets/web/bookshelf/fonts/iconfont.f9a3fb0e.woff
  15. 0
      app/src/main/assets/web/bookshelf/fonts/popfont.f39ecc1a.ttf
  16. 0
      app/src/main/assets/web/bookshelf/fonts/shelffont.6c094b6d.ttf
  17. 0
      app/src/main/assets/web/bookshelf/img/icons/android-chrome-192x192.png
  18. 0
      app/src/main/assets/web/bookshelf/img/icons/android-chrome-512x512.png
  19. 0
      app/src/main/assets/web/bookshelf/img/icons/apple-touch-icon-120x120.png
  20. 0
      app/src/main/assets/web/bookshelf/img/icons/apple-touch-icon-152x152.png
  21. 0
      app/src/main/assets/web/bookshelf/img/icons/apple-touch-icon-180x180.png
  22. 0
      app/src/main/assets/web/bookshelf/img/icons/apple-touch-icon-60x60.png
  23. 0
      app/src/main/assets/web/bookshelf/img/icons/apple-touch-icon-76x76.png
  24. 0
      app/src/main/assets/web/bookshelf/img/icons/apple-touch-icon.png
  25. 0
      app/src/main/assets/web/bookshelf/img/icons/msapplication-icon-144x144.png
  26. 0
      app/src/main/assets/web/bookshelf/img/icons/mstile-150x150.png
  27. 0
      app/src/main/assets/web/bookshelf/img/icons/safari-pinned-tab.svg
  28. 0
      app/src/main/assets/web/bookshelf/img/noCover.b5c48bc1.jpeg
  29. 0
      app/src/main/assets/web/bookshelf/index.html
  30. 0
      app/src/main/assets/web/bookshelf/js/about.517e59ea.js
  31. 0
      app/src/main/assets/web/bookshelf/js/about~detail.d5f6fddf.js
  32. 0
      app/src/main/assets/web/bookshelf/js/app.b53a207e.js
  33. 0
      app/src/main/assets/web/bookshelf/js/chunk-vendors.3ef7796f.js
  34. 0
      app/src/main/assets/web/bookshelf/js/detail.133910b4.js
  35. 0
      app/src/main/assets/web/bookshelf/manifest.json
  36. 0
      app/src/main/assets/web/bookshelf/precache-manifest.04173d48a716bddd6fb159c907ea23ec.js
  37. 0
      app/src/main/assets/web/bookshelf/robots.txt
  38. 0
      app/src/main/assets/web/bookshelf/service-worker.js
  39. 442
      app/src/main/assets/web/index.html
  40. 2
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSoup.kt
  41. 5
      app/src/main/java/io/legado/app/service/TTSReadAloudService.kt
  42. 13
      app/src/main/java/io/legado/app/ui/book/read/TextActionMenu.kt

@ -14,6 +14,7 @@
* 禁止在js里通过geClass反射 * 禁止在js里通过geClass反射
* 禁止在js里创建File对象 * 禁止在js里创建File对象
* 禁止在js里获取Packages scope * 禁止在js里获取Packages scope
2. 优化并修复bug
**2021/07/10** **2021/07/10**
1. 阅读界面长按菜单改回原来样式 1. 阅读界面长按菜单改回原来样式

@ -0,0 +1,398 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>阅读3.0书源编辑器_V4.0</title>
<link rel="icon" href="favicon.ico">
<link rel="stylesheet" type="text/css" href="index.css"/>
</head>
<body>
<div class="editor">
<div class="setbox">
<div class="rules">
<div><b>基本</b></div>
<div>
<div>源域名 :</div>
<textarea rows="1" id="bookSourceUrl" class="base" title="bookSourceUrl"
placeholder="<必填>通常填写网站主页,例: https://www.qidian.com"></textarea>
</div>
<div>
<div>源类型 :</div>
<textarea rows="1" id="bookSourceType" class="base" title="bookSourceType"
placeholder="&lt;必填&gt;0:文本 1:音频"></textarea>
</div>
<div>
<div>源名称 :</div>
<textarea rows="1" id="bookSourceName" class="base" title="bookSourceName"
placeholder="&lt;必填&gt;会显示在书源列表"></textarea>
</div>
<div>
<div>源分组 :</div>
<textarea rows="1" id="bookSourceGroup" class="base" title="bookSourceGroup"
placeholder="&lt;选填&gt;描述书源的特征信息"></textarea>
</div>
<div>
<div>源注释 :</div>
<textarea rows="1" id="bookSourceComment" class="base" title="bookSourceComment"
placeholder="&lt;选填&gt;描述书源作者和状态"></textarea>
</div>
<div>
<div>登录地址:</div>
<textarea rows="1" id="loginUrl" class="base" title="loginUrl"
placeholder="&lt;选填&gt;填写网站登录网址,仅在需要登录的书源有用"></textarea>
</div>
<div>
<div>链接验证:</div>
<textarea rows="1" id="bookUrlPattern" class="base" title="bookUrlPattern"
placeholder="&lt;选填&gt;当详情页URL与源URL的域名不一致时有效,用于添加网址"></textarea>
</div>
<div>
<div>请求头 :</div>
<textarea rows="3" id="header" class="base" title="header"
placeholder="&lt;选填&gt;客户端标识"></textarea>
</div>
<p></p>
<div><b>搜索</b></div>
<div>
<div>搜索地址:</div>
<textarea rows="3" id="searchUrl" class="base" title="searchUrl"
placeholder="[域名可省略]/search.php@kw={{key}}"></textarea>
</div>
<div>
<div>列表规则:</div>
<textarea rows="3" id="ruleSearch_bookList" class="ruleSearch" title="bookList"
placeholder="选择书籍节点 (规则结果为List&lt;Element&gt;)"></textarea>
</div>
<div>
<div>书名规则:</div>
<textarea rows="1" id="ruleSearch_name" class="ruleSearch" title="name"
placeholder="选择节点书名 (规则结果为String)"></textarea>
</div>
<div>
<div>作者规则:</div>
<textarea rows="1" id="ruleSearch_author" class="ruleSearch" title="author"
placeholder="选择节点作者 (规则结果为String)"></textarea>
</div>
<div>
<div>分类规则:</div>
<textarea rows="1" id="ruleSearch_kind" class="ruleSearch" title="kind"
placeholder="选择节点分类信息 (规则结果为String)"></textarea>
</div>
<div>
<div>字数规则:</div>
<textarea rows="1" id="ruleSearch_wordCount" class="ruleSearch" title="wordCount"
placeholder="选择节点字数信息 (规则结果为String)"></textarea>
</div>
<div>
<div>最新章节:</div>
<textarea rows="1" id="ruleSearch_lastChapter" class="ruleSearch"
title="lastChapter"
placeholder="选择节点最新章节 (规则结果为String)"></textarea>
</div>
<div>
<div>简介规则:</div>
<textarea rows="1" id="ruleSearch_intro" class="ruleSearch" title="intro"
placeholder="选择节点书籍简介 (规则结果为String)"></textarea>
</div>
<div>
<div>封面规则:</div>
<textarea rows="1" id="ruleSearch_coverUrl" class="ruleSearch" title="coverUrl"
placeholder="选择节点书籍封面 (规则结果为String类型的url)"></textarea>
</div>
<div>
<div>详情地址:</div>
<textarea rows="1" id="ruleSearch_bookUrl" class="ruleSearch" title="bookUrl"
placeholder="选择书籍详情页网址 (规则结果为String类型的url)"></textarea>
</div>
<p></p>
<div><b>发现</b></div>
<div>
<div>发现地址:</div>
<textarea rows="6" id="exploreUrl" class="base" title="exploreUrl"
placeholder="内容能显示在发现菜单&#10;每行一条发现分类(网址域名可省略),例:&#10;名称1::网址(Url)1&#10;名称2::网址(Url)2&#10;..."></textarea>
</div>
<div>
<div>列表规则:</div>
<textarea rows="1" id="ruleExplore_bookList" class="ruleExplore" title="bookList"
placeholder="选择书籍节点 (规则结果为List&lt;Element&gt;)"></textarea>
</div>
<div>
<div>书名规则:</div>
<textarea rows="1" id="ruleExplore_name" class="ruleExplore" title="name"
placeholder="选择节点书名 (规则结果为String)"></textarea>
</div>
<div>
<div>作者规则:</div>
<textarea rows="1" id="ruleExplore_author" class="ruleExplore" title="author"
placeholder="选择节点作者 (规则结果为String)"></textarea>
</div>
<div>
<div>分类规则:</div>
<textarea rows="1" id="ruleExplore_kind" class="ruleExplore" title="kind"
placeholder="选择节点分类信息 (规则结果为String)"></textarea>
</div>
<div>
<div>字数规则:</div>
<textarea rows="1" id="ruleExplore_wordCount" class="ruleExplore" title="wordCount"
placeholder="选择节点字数信息 (规则结果为String)"></textarea>
</div>
<div>
<div>最新章节:</div>
<textarea rows="1" id="ruleExplore_lastChapter" class="ruleExplore"
title="lastChapter"
placeholder="选择节点最新章节 (规则结果为String)"></textarea>
</div>
<div>
<div>简介规则:</div>
<textarea rows="1" id="ruleExplore_intro" class="ruleExplore" title="intro"
placeholder="选择节点书籍简介 (规则结果为String)"></textarea>
</div>
<div>
<div>封面规则:</div>
<textarea rows="1" id="ruleExplore_coverUrl" class="ruleExplore" title="coverUrl"
placeholder="选择节点书籍封面 (规则结果为String类型的url)"></textarea>
</div>
<div>
<div>详情地址:</div>
<textarea rows="1" id="ruleExplore_bookUrl" class="ruleExplore" title="bookUrl"
placeholder="选择书籍详情页网址 (规则结果为String类型的url)"></textarea>
</div>
<p></p>
<div><b>详情</b></div>
<div>
<div>预处理 :</div>
<textarea rows="3" id="ruleBookInfo_init" class="ruleBookInfo" title="init"
placeholder="用于加速详情信息检索,只支持AllInOne规则"></textarea>
</div>
<div>
<div>书名规则:</div>
<textarea rows="1" id="ruleBookInfo_name" class="ruleBookInfo" title="name"
placeholder="选择节点书名 (规则结果为String)"></textarea>
</div>
<div>
<div>作者规则:</div>
<textarea rows="1" id="ruleBookInfo_author" class="ruleBookInfo" title="author"
placeholder="选择节点作者 (规则结果为String)"></textarea>
</div>
<div>
<div>分类规则:</div>
<textarea rows="1" id="ruleBookInfo_kind" class="ruleBookInfo" title="kind"
placeholder="选择节点分类信息 (规则结果为String)"></textarea>
</div>
<div>
<div>字数规则:</div>
<textarea rows="1" id="ruleBookInfo_wordCount" class="ruleBookInfo"
title="wordCount"
placeholder="选择节点字数信息 (规则结果为String)"></textarea>
</div>
<div>
<div>最新章节:</div>
<textarea rows="1" id="ruleBookInfo_lastChapter" class="ruleBookInfo"
title="lastChapter"
placeholder="选择节点最新章节 (规则结果为String)"></textarea>
</div>
<div>
<div>简介规则:</div>
<textarea rows="1" id="ruleBookInfo_intro" class="ruleBookInfo" title="intro"
placeholder="选择节点书籍简介 (规则结果为String)"></textarea>
</div>
<div>
<div>封面规则:</div>
<textarea rows="1" id="ruleBookInfo_coverUrl" class="ruleBookInfo" title="coverUrl"
placeholder="选择节点书籍封面 (规则结果为String类型的url)"></textarea>
</div>
<div>
<div>目录地址:</div>
<textarea rows="1" id="ruleBookInfo_tocUrl" class="ruleBookInfo" title="tocUrl"
placeholder="选择书籍详情页网址 (规则结果为String类型的url, 与详情页相同时可省略)"></textarea>
</div>
<p></p>
<div><b>目录</b></div>
<div>
<div>列表规则:</div>
<textarea rows="3" id="ruleToc_chapterList" class="ruleToc" title="chapterList"
placeholder="选择目录列表的章节节点 (规则结果为List&lt;Element&gt;)"></textarea>
</div>
<div>
<div>章节名称:</div>
<textarea rows="1" id="ruleToc_chapterName" class="ruleToc" title="chapterName"
placeholder="选择章节名称 (规则结果为String)"></textarea>
</div>
<div>
<div>章节地址:</div>
<textarea rows="1" id="ruleToc_chapterUrl" class="ruleToc" title="chapterUrl"
placeholder="选择章节链接 (规则结果为String类型的Url)"></textarea>
</div>
<div>
<div>收费标识:</div>
<textarea rows="1" id="ruleToc_isVip" class="ruleToc" title="isVip"
placeholder="章节是否为VIP章节 (规则结果为Bool)"></textarea>
</div>
<div>
<div>章节信息:</div>
<textarea rows="1" id="ruleToc_updateTime" class="ruleToc" title="updateTime"
placeholder="选择章节信息 (规则结果为String)"></textarea>
</div>
<div>
<div>翻页规则:</div>
<textarea rows="1" id="ruleToc_nextTocUrl" class="ruleToc" title="nextTocUrl"
placeholder="选择目录下一页链接 (规则结果为List&lt;String&gt;或String)"></textarea>
</div>
<p></p>
<div><b>正文</b></div>
<div>
<div>脚本注入:</div>
<textarea rows="3" id="ruleContent_webJs" class="ruleContent" title="webJs"
placeholder="注入javascript,用于模拟鼠标点击等,必须有返回值,一般为String类型"></textarea>
</div>
<div>
<div>正文规则:</div>
<textarea rows="1" id="ruleContent_content" class="ruleContent" title="content"
placeholder="选择正文内容 (规则结果为String)"></textarea>
</div>
<div>
<div>翻页规则:</div>
<textarea rows="1" id="ruleContent_nextContentUrl" class="ruleContent"
title="nextContentUrl"
placeholder="选择下一分页(不是下一章)链接 (规则结果为String类型的Url)"></textarea>
</div>
<div>
<div>资源正则:</div>
<textarea rows="1" id="ruleContent_sourceRegex" class="ruleContent"
title="sourceRegex"
placeholder="匹配资源的url特征,用于嗅探"></textarea>
</div>
<div>
<div>替换规则:</div>
<textarea rows="1" id="ruleContent_replaceRegex" class="ruleContent"
title="replaceRegex"
placeholder="多页内容合并后替换,用于正文净化"></textarea>
</div>
<div>
<div>图片样式:</div>
<textarea rows="1" id="ruleContent_imageStyle" class="ruleContent"
title="imageStyle"
placeholder="FULL:铺满 不填:默认样式"></textarea>
</div>
<p></p>
<div><b>其它规则</b></div>
<div>
<div>启用搜索:</div>
<textarea rows="1" id="enabled" class="base" title="enabled"
placeholder="启用: true 关闭: false (可选,默认true)"></textarea>
</div>
<div>
<div>启用发现:</div>
<textarea rows="1" id="enabledExplore" class="base" title="enabledExplore"
placeholder="启用: true 关闭: false (可选,默认true)"></textarea>
</div>
<div>
<div>搜索权重:</div>
<textarea rows="1" id="weight" class="base" title="weight"
placeholder="整数: 0~N (可选,默认0) | 数字越大越靠前"></textarea>
</div>
<div>
<div>排序编号:</div>
<textarea rows="1" id="customOrder" class="base" title="customOrder"
placeholder="整数: 0~N (可选,默认0) | 数字越小越靠前"></textarea>
</div>
<div style="display:none;">
<div>更新时间:</div>
<textarea rows="1" id="lastUpdateTime" class="base" title="lastUpdateTime"
placeholder="毫秒级时间戳 (自动生成) | 请勿手动填写"></textarea>
</div>
</div>
</div>
<div class="menu">
<svg class="button">
<text x="50%" y="55%">⇈推送书源</text>
<rect id="push"></rect>
</svg>
<svg class="button">
<text x="50%" y="55%">⇊拉取书源</text>
<rect id="pull"></rect>
</svg>
<svg class="button">
<text x="50%" y="55%">⋘编辑书源</text>
<rect id="editor"></rect>
</svg>
<svg class="button">
<text x="50%" y="55%">⋙生成书源</text>
<rect id="conver"></rect>
</svg>
<svg class="button">
<text x="50%" y="55%">✗清空表单</text>
<rect id="initial"></rect>
</svg>
<svg class="button">
<text x="50%" y="55%">↶撤销操作</text>
<rect id="undo"></rect>
</svg>
<svg class="button">
<text x="50%" y="55%">↷重做操作</text>
<rect id="redo"></rect>
</svg>
<svg class="button">
<text x="50%" y="55%">⇏调试书源</text>
<rect id="debug"></rect>
</svg>
<svg class="button">
<text x="50%" y="55%">✓保存书源</text>
<rect id="accept"></rect>
</svg>
</div>
<div class="outbox">
<div class="tabbox">
<div class="tabtitle">
<div name="编辑书源" class="tab1 this">编辑书源</div>
<div name="调试书源" class="tab2">调试书源</div>
<div name="书源列表" class="tab3">书源列表</div>
<div name="帮助信息" class="tab4">帮助信息</div>
</div>
<div class="tabbody">
<div class="tab1 this">
<textarea class="context" id="RuleJsonString"
placeholder="这里输出序列化的JSON数据,可直接导入'阅读'APP"></textarea>
</div>
<div class="tab2">
<input type="text" class="inputbox" id="DebugKey" placeholder="输入搜索关键字,默认搜「我的」">
<textarea class="context" id="DebugConsole" placeholder="这里用于输出调试信息"></textarea>
</div>
<div class="tab3">
<input type="text" class="inputbox" id="Filter"
placeholder="输入筛选关键词(源名称、源URL或源分组)后按回车筛选源">
<div class="titlebar">
<button id="Import">导入书源文件</button>
<button id="Export">导出书源文件</button>
<button id="Delete">删除选中书源</button>
<button id="ClrAll">清空当前列表</button>
</div>
<div class="context" id="RuleList"></div>
</div>
<div class="tab4">
<div class="context link">
<a target="_blank" href="https://alanskycn.gitee.io/teachme">源制作教程</a>
<a target="_blank"
href="https://zhuanlan.zhihu.com/p/29436838">Xpath基础教程</a>
<a target="_blank"
href="https://zhuanlan.zhihu.com/p/32187820">Xpath高级教程</a>
<a target="_blank" href="https://www.w3cschool.cn/regex_rmjc">正则表达式教程</a>
<a target="_blank" href="https://regexr.com">正则表达式在线验证工具</a>
<div>^$()[]{}.?+*| 这些是Java正则特殊符号,匹配需转义
<br>(?s) 前缀表示跨行解析
<br>(?m) 前缀表示逐行匹配
<br>(?i) 前缀表示忽略大小写
</div>
<a target="_blank" href="https://www.beta.browxy.com">代码在线运行工具</a>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="index.js"></script>
</body>
</html>

@ -1,176 +0,0 @@
html, body {
height: 100%;
margin: 0;
}
.hide {
display: none;
}
.top, .showchapter, .hidebooks {
width: 60px;
height: 50px;
position: absolute;
right: 30px;
bottom: 30px;
color: black;
font-size: 28px;
background-color: #ddd;
opacity: 0.85;
}
.top {
bottom: 150px;
}
.showchapter {
bottom: 90px;
bottom: 90px;
}
.address {
width: 270px;
}
.nav {
border-bottom: solid 1px #ccc;
}
input, button {
width: 110px;
line-height: 34px;
background-color: #eee;
color: #555;
border: none;
margin: 10px 5px;
font-weight: 500;
border-radius: 2px;
outline: none;
cursor: pointer;
}
input {
padding: 0 10px;
cursor: text;
}
input:hover, button:hover {
border-color: #aaa;
background-color: #efefef;
color: #222;
outline: solid 1px #ccc;
}
.allcontent {
height: calc(100% - 60px);
}
.allscreen {
height: 100%
}
.books > div {
display: inline-block;
margin: 10px;
vertical-align: top;
border: solid 1px #ddd;
}
.read > .books {
width: 420px;
float: left;
height: 100%;
overflow: auto;
border-right: solid 1px #ccc;
}
.read > .books > div {
margin-right: 0;
border-right: none;
}
.more {
overflow-y: auto;
height: 100%;
display: none;
}
.read .more {
display: block;
}
.books > div > img {
width: 120px;
height: 180px;
float: left;
margin-right: 10px;
cursor: pointer;
}
.info {
padding: 10px 20px 0 20px;
width: 600px;
margin: 0 auto;
}
.info > img {
width: 600px;
height: 900px;
}
.info p {
line-height: 1.5;
text-align: justify;
margin: 0;
}
.books tr:nth-child(n+2) td {
border-top: solid 1px #999;
}
.books td:nth-child(1) {
vertical-align: top;
width: 50px;
}
.books td:nth-child(2) {
vertical-align: top;
width: 200px;
}
.clear {
clear: both;
}
.chapter {
margin: 10px;
max-height: 500px;
overflow-y: auto;
border-top: solid 1px #333;
border-bottom: solid 1px #333;
}
.chapter button {
width: 230px;
text-align: left;
text-indent: 14px;
margin: 10px 4px;
}
.content {
padding: 20px;
text-align: justify;
min-height: 1000px;
padding-bottom: 200px;
}
.content h2 {
font-family: "Microsoft YaHei",微软雅黑,"MicrosoftJhengHei",华文细黑,STHeiti,MingLiu;
font-weight: 500;
text-align: center;
line-height: 100px;
font-size: 40px;
margin: 0;
}

@ -1,39 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>阅读3.0书架</title>
<link rel="icon" href="favicon.ico">
<link href="bookshelf.css" rel="stylesheet" />
</head>
<body>
<button id="top" class="top"></button>
<button id="showchapter" class="showchapter"></button>
<button id="hidebooks" class="hidebooks"></button>
<div class="nav">
<button id="back">返回</button>
<button id="type">所有书籍 ▼</button>
<button id="sort">手动排序 ▼</button>
<button id="setting">阅读设置</button>
<input type="text" class="address" id="address" title="阅读APP地址或IP" value="" />
<button id="refresh">重新加载</button>
</div>
<div class="allcontent" id="allcontent">
<div id="books" class="books"></div>
<div id="more" class="more">
<div id="info" class="info"></div>
<div class="clear"></div>
<div id="chapter" class="chapter"></div>
<div id="content" class="content"></div>
<div id="page" class="button">
<center><button id='up'>上一章</button><button id='down'>下一章</button></center>
</div>
</div>
</div>
<script src="bookshelf.js"></script>
</body>
</html>

@ -1,203 +0,0 @@
var $ = document.querySelector.bind(document)
, $$ = document.querySelectorAll.bind(document)
, $c = document.createElement.bind(document)
, randomImg = "http://api.mtyqx.cn/api/random.php"
, randomImg2 = "http://img.xjh.me/random_img.php"
, books
;
var now_chapter = -1;
var sum_chapter = 0;
var formatTime = value => {
return new Date(value).toLocaleString('zh-CN', {
hour12: false, year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"
}).replace(/\//g, "-");
};
var apiMap = {
"getBookshelf": "/getBookshelf",
"getChapterList": "/getChapterList",
"getBookContent": "/getBookContent",
"saveBook": "/saveBook"
};
var apiAddress = (apiName, url, index) => {
let address = $('#address').value || window.location.host;
if (!(/^http|^\/\//).test(address)) {
address = "//" + address;
}
if (!(/:\d{4,}/).test(address.split("//")[1].split("/")[0])) {
address += ":1122";
}
localStorage.setItem('address', address);
if (apiName == "getBookContent") {
return address + apiMap[apiName] + (url ? "?url=" + encodeURIComponent(url) : "") + "&index=" + index;
}
return address + apiMap[apiName] + (url ? "?url=" + encodeURIComponent(url) : "");
};
var init = () => {
$('#allcontent').classList.remove("read");
$('#books').innerHTML = "";
fetch(apiAddress("getBookshelf"), { mode: "cors" })
.then(res => res.json())
.then(data => {
if (!data.isSuccess) {
alert(getBookshelf.errorMsg);
return;
}
books = data.data;
books.forEach((book, i) => {
let bookDiv = $c("div");
let img = $c("img");
img.src = book.coverUrl || randomImg;
img.setAttribute("data-series-num", i);
bookDiv.appendChild(img);
bookDiv.innerHTML += `<table><tbody>
<tr><td>书名</td><td>${book.name}</td></tr>
<tr><td>作者</td><td>${book.author}</td></tr>
<tr><td>阅读</td><td>${book.durChapterTitle}<br>${formatTime(book.durChapterTime)}</td></tr>
<tr><td>更新</td><td>${book.latestChapterTitle}<br>${formatTime(book.latestChapterTime)}</td></tr>
<tr><td>来源</td><td>${book.origin}</td></tr>
</tbody></table>`;
$('#books').appendChild(bookDiv);
});
$$('#books img').forEach(bookImg =>
bookImg.addEventListener("click", () => {
now_chapter = -1;
sum_chapter = 0;
$('#allcontent').classList.add("read");
var book = books[bookImg.getAttribute("data-series-num")];
$("#info").innerHTML = `<img src="${bookImg.src}">
<p>  来源${book.origin}</p>
<p>  书名${book.name}</p>
<p>  作者${book.author}</p>
<p>阅读章节${book.durChapterName}</p>
<p>阅读时间${formatTime(book.durChapterTime)}</p>
<p>最新章节${book.latestChapterTitle}</p>
<p>检查时间${formatTime(book.lastCheckTime)}</p>
<p>  简介${book.intro.trim().replace(/\n/g, "<br>")}</p>`;
window.location.hash = "";
window.location.hash = "#info";
$("#content").innerHTML = "章节列表加载中...";
$("#chapter").innerHTML = "";
fetch(apiAddress("getChapterList", book.bookUrl), { mode: "cors" })
.then(res => res.json())
.then(data => {
if (!data.isSuccess) {
alert(data.errorMsg);
$("#content").innerHTML = "章节列表加载失败!";
return;
}
data.data.forEach(chapter => {
let ch = $c("button");
ch.setAttribute("data-url", chapter.bookUrl);
ch.setAttribute("data-index", chapter.index);
ch.setAttribute("title", chapter.title);
ch.innerHTML = chapter.title.length > 15 ? chapter.title.substring(0, 14) + "..." : chapter.title;
$("#chapter").appendChild(ch);
});
sum_chapter = data.data.length;
$('#chapter').scrollTop = 0;
$("#content").innerHTML = "章节列表加载完成!";
});
}));
});
};
$("#back").addEventListener("click", () => {
if (window.location.hash === "#content") {
window.location.hash = "#chapter";
} else if (window.location.hash === "#chapter") {
window.location.hash = "#info";
} else {
$('#allcontent').classList.remove("read");
}
});
$("#refresh").addEventListener("click", init);
$('#hidebooks').addEventListener("click", () => {
$("#books").classList.toggle("hide");
$(".nav").classList.toggle("hide");
$("#allcontent").classList.toggle("allscreen");
});
$('#top').addEventListener("click", () => {
window.location.hash = "";
window.location.hash = "#info";
});
$('#showchapter').addEventListener("click", () => {
window.location.hash = "";
window.location.hash = "#chapter";
});
$('#up').addEventListener('click', e => {
if (now_chapter > 0) {
now_chapter--;
let clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent("click", true, false);
$('[data-index="' + now_chapter + '"]').dispatchEvent(clickEvent);
} else if (now_chapter == 0) {
alert("已经是第一章了^_^!")
} else {
}
});
$('#down').addEventListener('click', e => {
if (now_chapter > -1) {
if (now_chapter < sum_chapter - 1) {
now_chapter++;
let clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent("click", true, false);
$('[data-index="' + now_chapter + '"]').dispatchEvent(clickEvent);
} else {
alert("已经是最后一章了^_^!")
}
}
});
$('#chapter').addEventListener("click", (e) => {
if (e.target.tagName === "BUTTON") {
var url = e.target.getAttribute("data-url");
var index = e.target.getAttribute("data-index");
var name = e.target.getAttribute("title");
if (!url) {
alert("未取得书籍地址");
}
if (!index && (0 != index)) {
alert("未取得章节索引");
}
now_chapter = parseInt(index);
$("#content").innerHTML = "<p>" + name + " 加载中...</p>";
fetch(apiAddress("getBookContent", url, index), { mode: "cors" })
.then(res => res.json())
.then(data => {
if (!data.isSuccess) {
alert(data.errorMsg);
$("#content").innerHTML = "<p>" + name + " 加载失败!</p>";
return;
}
var content = data.data.trim().split("\n\n");
if (content.length === 2) {
$("#content").innerHTML = `<h2>${content[0]}</h2>  (全文 ${content[1].length} 字)<br><br>  ` + content[1].trim().replace(/\n/g, "<br><br>");
} else {
$("#content").innerHTML = `<h2>${name || e.target.innerHTML}</h2>  (全文 ${data.data.length} 字)<br><br>  ` + data.data.trim().replace(/\n/g, "<br><br>");
}
window.location.hash = "";
window.location.hash = "#content";
});
}
});
$('#address').setAttribute("placeholder", "阅读APP地址或IP:" + window.location.host);
if (!$('#address').value && typeof localStorage && localStorage.getItem('address')) {
$('#address').value = localStorage.getItem('address');
}
init();

@ -3,387 +3,73 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>阅读3.0书源编辑器_V4.0</title> <title>legado web导航</title>
<link rel="icon" href="favicon.ico"> <link rel="icon" href="favicon.ico">
<link rel="stylesheet" type="text/css" href="index.css" /> <style type="text/css">
.header {
width: 100%;
height: 100px;
text-align: center;
padding: 5px;
}
.main {
display: flex;
justify-content: center;
width: 100%;
height: 100%;
padding: 10px;
top: 120px;
bottom: 80px;
}
.content {
display: flex;
justify-content: center;
width: 700px;
height: 300px;
}
.button {
border-radius: 20px;
background-color: #4CAF50;
/* Green */
border: none;
color: white;
width: 300px;
height: 300px;
line-height: 300px;
margin: 10px;
/* 设置垂直居中 */
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 60px;
}
.footer {
width: 100%;
height: 60px;
clear: both;
text-align: center;
padding: 5px;
position: absolute;
bottom: 0;
}
</style>
</head> </head>
<body> <body>
<div class="editor"> <div class="header">
<div class="setbox"> <h1>Legado</h1>
<div class="rules"> </div>
<div><b>基本</b></div> <div class="main">
<div> <div class="content">
<div>源域名 :</div> <a href="bookshelf/index.html" class="button">书架</a>
<textarea rows="1" id="bookSourceUrl" class="base" title="bookSourceUrl" <a href="bookSource/index.html" class="button">书源</a>
placeholder="<必填>通常填写网站主页,例: https://www.qidian.com"></textarea>
</div>
<div>
<div>源类型 :</div>
<textarea rows="1" id="bookSourceType" class="base" title="bookSourceType"
placeholder="&lt;必填&gt;0:文本 1:音频"></textarea>
</div>
<div>
<div>源名称 :</div>
<textarea rows="1" id="bookSourceName" class="base" title="bookSourceName"
placeholder="&lt;必填&gt;会显示在书源列表"></textarea>
</div>
<div>
<div>源分组 :</div>
<textarea rows="1" id="bookSourceGroup" class="base" title="bookSourceGroup"
placeholder="&lt;选填&gt;描述书源的特征信息"></textarea>
</div>
<div>
<div>源注释 :</div>
<textarea rows="1" id="bookSourceComment" class="base" title="bookSourceComment"
placeholder="&lt;选填&gt;描述书源作者和状态"></textarea>
</div>
<div>
<div>登录地址:</div>
<textarea rows="1" id="loginUrl" class="base" title="loginUrl"
placeholder="&lt;选填&gt;填写网站登录网址,仅在需要登录的书源有用"></textarea>
</div>
<div>
<div>链接验证:</div>
<textarea rows="1" id="bookUrlPattern" class="base" title="bookUrlPattern"
placeholder="&lt;选填&gt;当详情页URL与源URL的域名不一致时有效,用于添加网址"></textarea>
</div>
<div>
<div>请求头 :</div>
<textarea rows="3" id="header" class="base" title="header" placeholder="&lt;选填&gt;客户端标识"></textarea>
</div>
<p></p>
<div><b>搜索</b></div>
<div>
<div>搜索地址:</div>
<textarea rows="3" id="searchUrl" class="base" title="searchUrl"
placeholder="[域名可省略]/search.php@kw={{key}}"></textarea>
</div>
<div>
<div>列表规则:</div>
<textarea rows="3" id="ruleSearch_bookList" class="ruleSearch" title="bookList"
placeholder="选择书籍节点 (规则结果为List&lt;Element&gt;)"></textarea>
</div>
<div>
<div>书名规则:</div>
<textarea rows="1" id="ruleSearch_name" class="ruleSearch" title="name"
placeholder="选择节点书名 (规则结果为String)"></textarea>
</div>
<div>
<div>作者规则:</div>
<textarea rows="1" id="ruleSearch_author" class="ruleSearch" title="author"
placeholder="选择节点作者 (规则结果为String)"></textarea>
</div>
<div>
<div>分类规则:</div>
<textarea rows="1" id="ruleSearch_kind" class="ruleSearch" title="kind"
placeholder="选择节点分类信息 (规则结果为String)"></textarea>
</div>
<div>
<div>字数规则:</div>
<textarea rows="1" id="ruleSearch_wordCount" class="ruleSearch" title="wordCount"
placeholder="选择节点字数信息 (规则结果为String)"></textarea>
</div>
<div>
<div>最新章节:</div>
<textarea rows="1" id="ruleSearch_lastChapter" class="ruleSearch" title="lastChapter"
placeholder="选择节点最新章节 (规则结果为String)"></textarea>
</div>
<div>
<div>简介规则:</div>
<textarea rows="1" id="ruleSearch_intro" class="ruleSearch" title="intro"
placeholder="选择节点书籍简介 (规则结果为String)"></textarea>
</div>
<div>
<div>封面规则:</div>
<textarea rows="1" id="ruleSearch_coverUrl" class="ruleSearch" title="coverUrl"
placeholder="选择节点书籍封面 (规则结果为String类型的url)"></textarea>
</div>
<div>
<div>详情地址:</div>
<textarea rows="1" id="ruleSearch_bookUrl" class="ruleSearch" title="bookUrl"
placeholder="选择书籍详情页网址 (规则结果为String类型的url)"></textarea>
</div>
<p></p>
<div><b>发现</b></div>
<div>
<div>发现地址:</div>
<textarea rows="6" id="exploreUrl" class="base" title="exploreUrl"
placeholder="内容能显示在发现菜单&#10;每行一条发现分类(网址域名可省略),例:&#10;名称1::网址(Url)1&#10;名称2::网址(Url)2&#10;..."></textarea>
</div>
<div>
<div>列表规则:</div>
<textarea rows="1" id="ruleExplore_bookList" class="ruleExplore" title="bookList"
placeholder="选择书籍节点 (规则结果为List&lt;Element&gt;)"></textarea>
</div>
<div>
<div>书名规则:</div>
<textarea rows="1" id="ruleExplore_name" class="ruleExplore" title="name"
placeholder="选择节点书名 (规则结果为String)"></textarea>
</div>
<div>
<div>作者规则:</div>
<textarea rows="1" id="ruleExplore_author" class="ruleExplore" title="author"
placeholder="选择节点作者 (规则结果为String)"></textarea>
</div>
<div>
<div>分类规则:</div>
<textarea rows="1" id="ruleExplore_kind" class="ruleExplore" title="kind"
placeholder="选择节点分类信息 (规则结果为String)"></textarea>
</div>
<div>
<div>字数规则:</div>
<textarea rows="1" id="ruleExplore_wordCount" class="ruleExplore" title="wordCount"
placeholder="选择节点字数信息 (规则结果为String)"></textarea>
</div>
<div>
<div>最新章节:</div>
<textarea rows="1" id="ruleExplore_lastChapter" class="ruleExplore" title="lastChapter"
placeholder="选择节点最新章节 (规则结果为String)"></textarea>
</div>
<div>
<div>简介规则:</div>
<textarea rows="1" id="ruleExplore_intro" class="ruleExplore" title="intro"
placeholder="选择节点书籍简介 (规则结果为String)"></textarea>
</div>
<div>
<div>封面规则:</div>
<textarea rows="1" id="ruleExplore_coverUrl" class="ruleExplore" title="coverUrl"
placeholder="选择节点书籍封面 (规则结果为String类型的url)"></textarea>
</div>
<div>
<div>详情地址:</div>
<textarea rows="1" id="ruleExplore_bookUrl" class="ruleExplore" title="bookUrl"
placeholder="选择书籍详情页网址 (规则结果为String类型的url)"></textarea>
</div>
<p></p>
<div><b>详情</b></div>
<div>
<div>预处理 :</div>
<textarea rows="3" id="ruleBookInfo_init" class="ruleBookInfo" title="init"
placeholder="用于加速详情信息检索,只支持AllInOne规则"></textarea>
</div>
<div>
<div>书名规则:</div>
<textarea rows="1" id="ruleBookInfo_name" class="ruleBookInfo" title="name"
placeholder="选择节点书名 (规则结果为String)"></textarea>
</div>
<div>
<div>作者规则:</div>
<textarea rows="1" id="ruleBookInfo_author" class="ruleBookInfo" title="author"
placeholder="选择节点作者 (规则结果为String)"></textarea>
</div>
<div>
<div>分类规则:</div>
<textarea rows="1" id="ruleBookInfo_kind" class="ruleBookInfo" title="kind"
placeholder="选择节点分类信息 (规则结果为String)"></textarea>
</div>
<div>
<div>字数规则:</div>
<textarea rows="1" id="ruleBookInfo_wordCount" class="ruleBookInfo" title="wordCount"
placeholder="选择节点字数信息 (规则结果为String)"></textarea>
</div>
<div>
<div>最新章节:</div>
<textarea rows="1" id="ruleBookInfo_lastChapter" class="ruleBookInfo" title="lastChapter"
placeholder="选择节点最新章节 (规则结果为String)"></textarea>
</div>
<div>
<div>简介规则:</div>
<textarea rows="1" id="ruleBookInfo_intro" class="ruleBookInfo" title="intro"
placeholder="选择节点书籍简介 (规则结果为String)"></textarea>
</div>
<div>
<div>封面规则:</div>
<textarea rows="1" id="ruleBookInfo_coverUrl" class="ruleBookInfo" title="coverUrl"
placeholder="选择节点书籍封面 (规则结果为String类型的url)"></textarea>
</div>
<div>
<div>目录地址:</div>
<textarea rows="1" id="ruleBookInfo_tocUrl" class="ruleBookInfo" title="tocUrl"
placeholder="选择书籍详情页网址 (规则结果为String类型的url, 与详情页相同时可省略)"></textarea>
</div>
<p></p>
<div><b>目录</b></div>
<div>
<div>列表规则:</div>
<textarea rows="3" id="ruleToc_chapterList" class="ruleToc" title="chapterList"
placeholder="选择目录列表的章节节点 (规则结果为List&lt;Element&gt;)"></textarea>
</div>
<div>
<div>章节名称:</div>
<textarea rows="1" id="ruleToc_chapterName" class="ruleToc" title="chapterName"
placeholder="选择章节名称 (规则结果为String)"></textarea>
</div>
<div>
<div>章节地址:</div>
<textarea rows="1" id="ruleToc_chapterUrl" class="ruleToc" title="chapterUrl"
placeholder="选择章节链接 (规则结果为String类型的Url)"></textarea>
</div>
<div>
<div>收费标识:</div>
<textarea rows="1" id="ruleToc_isVip" class="ruleToc" title="isVip"
placeholder="章节是否为VIP章节 (规则结果为Bool)"></textarea>
</div>
<div>
<div>章节信息:</div>
<textarea rows="1" id="ruleToc_updateTime" class="ruleToc" title="updateTime"
placeholder="选择章节信息 (规则结果为String)"></textarea>
</div>
<div>
<div>翻页规则:</div>
<textarea rows="1" id="ruleToc_nextTocUrl" class="ruleToc" title="nextTocUrl"
placeholder="选择目录下一页链接 (规则结果为List&lt;String&gt;或String)"></textarea>
</div>
<p></p>
<div><b>正文</b></div>
<div>
<div>脚本注入:</div>
<textarea rows="3" id="ruleContent_webJs" class="ruleContent" title="webJs"
placeholder="注入javascript,用于模拟鼠标点击等,必须有返回值,一般为String类型"></textarea>
</div>
<div>
<div>正文规则:</div>
<textarea rows="1" id="ruleContent_content" class="ruleContent" title="content"
placeholder="选择正文内容 (规则结果为String)"></textarea>
</div>
<div>
<div>翻页规则:</div>
<textarea rows="1" id="ruleContent_nextContentUrl" class="ruleContent"
title="nextContentUrl"
placeholder="选择下一分页(不是下一章)链接 (规则结果为String类型的Url)"></textarea>
</div>
<div>
<div>资源正则:</div>
<textarea rows="1" id="ruleContent_sourceRegex" class="ruleContent" title="sourceRegex"
placeholder="匹配资源的url特征,用于嗅探"></textarea>
</div>
<div>
<div>替换规则:</div>
<textarea rows="1" id="ruleContent_replaceRegex" class="ruleContent" title="replaceRegex"
placeholder="多页内容合并后替换,用于正文净化"></textarea>
</div>
<div>
<div>图片样式:</div>
<textarea rows="1" id="ruleContent_imageStyle" class="ruleContent" title="imageStyle"
placeholder="FULL:铺满 不填:默认样式"></textarea>
</div>
<p></p>
<div><b>其它规则</b></div>
<div>
<div>启用搜索:</div>
<textarea rows="1" id="enabled" class="base" title="enabled"
placeholder="启用: true 关闭: false (可选,默认true)"></textarea>
</div>
<div>
<div>启用发现:</div>
<textarea rows="1" id="enabledExplore" class="base" title="enabledExplore"
placeholder="启用: true 关闭: false (可选,默认true)"></textarea>
</div>
<div>
<div>搜索权重:</div>
<textarea rows="1" id="weight" class="base" title="weight"
placeholder="整数: 0~N (可选,默认0) | 数字越大越靠前"></textarea>
</div>
<div>
<div>排序编号:</div>
<textarea rows="1" id="customOrder" class="base" title="customOrder"
placeholder="整数: 0~N (可选,默认0) | 数字越小越靠前"></textarea>
</div>
<div style="display:none;">
<div>更新时间:</div>
<textarea rows="1" id="lastUpdateTime" class="base" title="lastUpdateTime"
placeholder="毫秒级时间戳 (自动生成) | 请勿手动填写"></textarea>
</div>
</div>
</div>
<div class="menu">
<svg class="button">
<text x="50%" y="55%">⇈推送书源</text>
<rect id="push"></rect>
</svg>
<svg class="button">
<text x="50%" y="55%">⇊拉取书源</text>
<rect id="pull"></rect>
</svg>
<svg class="button">
<text x="50%" y="55%">⋘编辑书源</text>
<rect id="editor"></rect>
</svg>
<svg class="button">
<text x="50%" y="55%">⋙生成书源</text>
<rect id="conver"></rect>
</svg>
<svg class="button">
<text x="50%" y="55%">✗清空表单</text>
<rect id="initial"></rect>
</svg>
<svg class="button">
<text x="50%" y="55%">↶撤销操作</text>
<rect id="undo"></rect>
</svg>
<svg class="button">
<text x="50%" y="55%">↷重做操作</text>
<rect id="redo"></rect>
</svg>
<svg class="button">
<text x="50%" y="55%">⇏调试书源</text>
<rect id="debug"></rect>
</svg>
<svg class="button">
<text x="50%" y="55%">✓保存书源</text>
<rect id="accept"></rect>
</svg>
</div>
<div class="outbox">
<div class="tabbox">
<div class="tabtitle">
<div name="编辑书源" class="tab1 this">编辑书源</div>
<div name="调试书源" class="tab2">调试书源</div>
<div name="书源列表" class="tab3">书源列表</div>
<div name="帮助信息" class="tab4">帮助信息</div>
</div>
<div class="tabbody">
<div class="tab1 this">
<textarea class="context" id="RuleJsonString"
placeholder="这里输出序列化的JSON数据,可直接导入'阅读'APP"></textarea>
</div>
<div class="tab2">
<input type="text" class="inputbox" id="DebugKey" placeholder="输入搜索关键字,默认搜「我的」">
<textarea class="context" id="DebugConsole" placeholder="这里用于输出调试信息"></textarea>
</div>
<div class="tab3">
<input type="text" class="inputbox" id="Filter" placeholder="输入筛选关键词(源名称、源URL或源分组)后按回车筛选源">
<div class="titlebar">
<button id="Import">导入书源文件</button>
<button id="Export">导出书源文件</button>
<button id="Delete">删除选中书源</button>
<button id="ClrAll">清空当前列表</button>
</div>
<div class="context" id="RuleList"></div>
</div>
<div class="tab4">
<div class="context link">
<a target="_blank" href="https://alanskycn.gitee.io/teachme">源制作教程</a>
<a target="_blank" href="https://zhuanlan.zhihu.com/p/29436838">Xpath基础教程</a>
<a target="_blank" href="https://zhuanlan.zhihu.com/p/32187820">Xpath高级教程</a>
<a target="_blank" href="https://www.w3cschool.cn/regex_rmjc">正则表达式教程</a>
<a target="_blank" href="https://regexr.com">正则表达式在线验证工具</a>
<div>^$()[]{}.?+*| 这些是Java正则特殊符号,匹配需转义
<br>(?s) 前缀表示跨行解析
<br>(?m) 前缀表示逐行匹配
<br>(?i) 前缀表示忽略大小写
</div>
<a target="_blank" href="https://www.beta.browxy.com">代码在线运行工具</a>
<a target="_blank" href="bookshelf.html">阅读书架(经典)</a>
<a target="_blank" href="new/index.html">阅读书架(新潮)</a>
</div>
</div>
</div>
</div>
</div>
</div> </div>
<script type="text/javascript" src="index.js"></script> </div>
<div class="footer">
<a href="https://github.com/gedoor/legado">https://github.com/gedoor/legado</a>
</div>
</body> </body>
</html>

@ -245,7 +245,7 @@ class AnalyzeByJSoup(doc: Any) {
val url = element.attr(lastRule) val url = element.attr(lastRule)
if(url.isEmpty() || textS.contains(url)) break if (url.isBlank() || textS.contains(url)) continue
textS.add(url) textS.add(url)
} }

@ -13,7 +13,6 @@ import io.legado.app.service.help.ReadBook
import io.legado.app.utils.getPrefBoolean import io.legado.app.utils.getPrefBoolean
import io.legado.app.utils.postEvent import io.legado.app.utils.postEvent
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.launch
import java.util.* import java.util.*
class TTSReadAloudService : BaseReadAloudService(), TextToSpeech.OnInitListener { class TTSReadAloudService : BaseReadAloudService(), TextToSpeech.OnInitListener {
@ -56,9 +55,7 @@ class TTSReadAloudService : BaseReadAloudService(), TextToSpeech.OnInitListener
play() play()
} }
} else { } else {
launch { toastOnUi(R.string.tts_init_failed)
toastOnUi(R.string.tts_init_failed)
}
} }
} }

@ -167,17 +167,22 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac
} }
if (!ttsInitFinish) return if (!ttsInitFinish) return
if (text == "") return if (text == "") return
if (textToSpeech?.isSpeaking == true) if (textToSpeech?.isSpeaking == true) {
textToSpeech?.stop() textToSpeech?.stop()
}
textToSpeech?.speak(text, TextToSpeech.QUEUE_ADD, null, "select_text") textToSpeech?.speak(text, TextToSpeech.QUEUE_ADD, null, "select_text")
lastText = "" lastText = ""
} }
@Synchronized @Synchronized
override fun onInit(status: Int) { override fun onInit(status: Int) {
textToSpeech?.language = Locale.CHINA if (status == TextToSpeech.SUCCESS) {
ttsInitFinish = true textToSpeech?.language = Locale.CHINA
readAloud(lastText) ttsInitFinish = true
readAloud(lastText)
} else {
context.toastOnUi(R.string.tts_init_failed)
}
} }
@RequiresApi(Build.VERSION_CODES.M) @RequiresApi(Build.VERSION_CODES.M)

Loading…
Cancel
Save