From 22501e74da10fd4ba1052f443d5e7154a6bcd38e Mon Sep 17 00:00:00 2001 From: SplitGemini <764402868@qq.com> Date: Thu, 24 Dec 2020 23:38:46 +0800 Subject: [PATCH 01/68] =?UTF-8?q?=E5=87=80=E5=8C=96=E6=9B=BF=E6=8D=A2?= =?UTF-8?q?=E5=B8=AE=E5=8A=A9markdown=E6=98=BE=E7=A4=BA=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 3 + app/src/main/assets/help/regexHelp.md | 175 +++--------------- .../legado/app/ui/widget/dialog/TextDialog.kt | 4 + 3 files changed, 33 insertions(+), 149 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 46101a548..7e1977da9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -97,6 +97,7 @@ android { kotlinOptions { jvmTarget = "1.8" } + buildToolsVersion '30.0.3' } resourcePlaceholders { @@ -195,6 +196,8 @@ dependencies { //MarkDown implementation 'io.noties.markwon:core:4.6.0' implementation 'io.noties.markwon:image-glide:4.6.0' + implementation 'io.noties.markwon:ext-tables:4.6.0' + implementation 'io.noties.markwon:html:4.6.0' //转换繁体 implementation 'com.hankcs:hanlp:portable-1.7.8' diff --git a/app/src/main/assets/help/regexHelp.md b/app/src/main/assets/help/regexHelp.md index a2e9b2502..8598c718a 100644 --- a/app/src/main/assets/help/regexHelp.md +++ b/app/src/main/assets/help/regexHelp.md @@ -30,18 +30,10 @@ ## 1. 基本匹配 -正则表达式只是我们用于在文本中检索字母和数字的模式。例如正则表达式 `cat`,表示: 字母 `c` 后面跟着一个字母 `a`,再后面跟着一个字母 `t`。 - -
-"cat" => The cat sat on the mat
-
+正则表达式只是我们用于在文本中检索字母和数字的模式。例如正则表达式 `cat`,表示: 字母 `c` 后面跟着一个字母 `a`,再后面跟着一个字母 `t`。
"cat" => The cat sat on the mat
正则表达式 `123` 会匹配字符串 "123"。通过将正则表达式中的每个字符逐个与要匹配的字符串中的每个字符进行比较,来完成正则匹配。 -正则表达式通常区分大小写,因此正则表达式 `Cat` 与字符串 "cat" 不匹配。 - -
-"Cat" => The cat sat on the Cat
-
+正则表达式通常区分大小写,因此正则表达式 `Cat` 与字符串 "cat" 不匹配。
"Cat" => The cat sat on the Cat
## 2. 元字符 @@ -66,35 +58,19 @@ ## 2.1 英文句号 英文句号 `.` 是元字符的最简单的例子。元字符 `.` 可以匹配任意单个字符。它不会匹配换行符和新行的字符。例如正则表达式 `.ar`,表示: 任意字符后面跟着一个字母 `a`, -再后面跟着一个字母 `r`。 - -
-".ar" => The car parked in the garage.
-
+再后面跟着一个字母 `r`。
".ar" => The car parked in the garage.
## 2.2 字符集 字符集也称为字符类。方括号被用于指定字符集。使用字符集内的连字符来指定字符范围。方括号内的字符范围的顺序并不重要。 -例如正则表达式 `[Tt]he`,表示: 大写 `T` 或小写 `t` ,后跟字母 `h`,再后跟字母 `e`。 - -
-"[Tt]he" => The car parked in the garage.
-
+例如正则表达式 `[Tt]he`,表示: 大写 `T` 或小写 `t` ,后跟字母 `h`,再后跟字母 `e`。
"[Tt]he" => The car parked in the garage.
-然而,字符集中的英文句号表示它字面的含义。正则表达式 `ar[.]`,表示小写字母 `a`,后面跟着一个字母 `r`,再后面跟着一个英文句号 `.` 字符。 - -
-"ar[.]" => A garage is a good place to park a car.
-
+然而,字符集中的英文句号表示它字面的含义。正则表达式 `ar[.]`,表示小写字母 `a`,后面跟着一个字母 `r`,再后面跟着一个英文句号 `.` 字符。
"ar[.]" => A garage is a good place to park a car.
### 2.2.1 否定字符集 一般来说插入字符 `^` 表示一个字符串的开始,但是当它在方括号内出现时,它会取消字符集。例如正则表达式 `[^c]ar`,表示: 除了字母 `c` 以外的任意字符,后面跟着字符 `a`, -再后面跟着一个字母 `r`。 - -
-"[^c]ar" => The car parked in the garage.
-
+再后面跟着一个字母 `r`。
"[^c]ar" => The car parked in the garage.
## 2.3 重复 @@ -103,85 +79,42 @@ ### 2.3.1 星号 该符号 `*` 表示匹配上一个匹配规则的零次或多次。正则表达式 `a*` 表示小写字母 `a` 可以重复零次或者多次。但是它如果出现在字符集或者字符类之后,它表示整个字符集的重复。 -例如正则表达式 `[a-z]*`,表示: 一行中可以包含任意数量的小写字母。 - -
-"[a-z]*" => The car parked in the garage #21.
-
+例如正则表达式 `[a-z]*`,表示: 一行中可以包含任意数量的小写字母。
"[a-z]*" => The car parked in the garage #21.
该 `*` 符号可以与元符号 `.` 用在一起,用来匹配任意字符串 `.*`。该 `*` 符号可以与空格符 `\s` 一起使用,用来匹配一串空格字符。 -例如正则表达式 `\s*cat\s*`,表示: 零个或多个空格,后面跟小写字母 `c`,再后面跟小写字母 `a`,再再后面跟小写字母 `t`,后面再跟零个或多个空格。 - -
-"\s*cat\s*" => The fat cat sat on the cat.
-
+例如正则表达式 `\s*cat\s*`,表示: 零个或多个空格,后面跟小写字母 `c`,再后面跟小写字母 `a`,再再后面跟小写字母 `t`,后面再跟零个或多个空格。
"\s*cat\s*" => The fat cat sat on the cat.
### 2.3.2 加号 -该符号 `+` 匹配上一个字符的一次或多次。例如正则表达式 `c.+t`,表示: 一个小写字母 `c`,后跟任意数量的字符,后跟小写字母 `t`。 - -
-"c.+t" => The fat cat sat on the mat.
-
+该符号 `+` 匹配上一个字符的一次或多次。例如正则表达式 `c.+t`,表示: 一个小写字母 `c`,后跟任意数量的字符,后跟小写字母 `t`。
"c.+t" => The fat cat sat on the mat.
### 2.3.3 问号 在正则表达式中,元字符 `?` 用来表示前一个字符是可选的。该符号匹配前一个字符的零次或一次。 -例如正则表达式 `[T]?he`,表示: 可选的大写字母 `T`,后面跟小写字母 `h`,后跟小写字母 `e`。 - -
-"[T]he" => The car is parked in the garage.
-
-
-"[T]?he" => The car is parked in the garage.
-
+例如正则表达式 `[T]?he`,表示: 可选的大写字母 `T`,后面跟小写字母 `h`,后跟小写字母 `e`。
"[T]he" => The car is parked in the garage.
"[T]?he" => The car is parked in the garage.
## 2.4 花括号 -在正则表达式中花括号(也被称为量词 ?)用于指定字符或一组字符可以重复的次数。例如正则表达式 `[0-9]{2,3}`,表示: 匹配至少2位数字但不超过3位(0到9范围内的字符)。 - -
-"[0-9]{2,3}" => The number was 9.9997 but we rounded it off to 10.0.
-
- -我们可以省略第二个数字。例如正则表达式 `[0-9]{2,}`,表示: 匹配2个或更多个数字。如果我们也删除逗号,则正则表达式 `[0-9]{2}`,表示: 匹配正好为2位数的数字。 +在正则表达式中花括号(也被称为量词 ?)用于指定字符或一组字符可以重复的次数。例如正则表达式 `[0-9]{2,3}`,表示: 匹配至少2位数字但不超过3位(0到9范围内的字符)。
"[0-9]{2,3}" => The number was 9.9997 but we rounded it off to 10.0.
-
-"[0-9]{2,}" => The number was 9.9997 but we rounded it off to 10.0.
-
- -
-"[0-9]{2}" => The number was 9.9997 but we rounded it off to 10.0.
-
+我们可以省略第二个数字。例如正则表达式 `[0-9]{2,}`,表示: 匹配2个或更多个数字。如果我们也删除逗号,则正则表达式 `[0-9]{2}`,表示: 匹配正好为2位数的数字。
"[0-9]{2,}" => The number was 9.9997 but we rounded it off to 10.0.
"[0-9]{2}" => The number was 9.9997 but we rounded it off to 10.0.
## 2.5 字符组 字符组是一组写在圆括号内的子模式 `(...)`。正如我们在正则表达式中讨论的那样,如果我们把一个量词放在一个字符之后,它会重复前一个字符。 但是,如果我们把量词放在一个字符组之后,它会重复整个字符组。 -例如正则表达式 `(ab)*` 表示匹配零个或多个的字符串 "ab"。我们还可以在字符组中使用元字符 `|`。例如正则表达式 `(c|g|p)ar`,表示: 小写字母 `c`、`g` 或 `p` 后面跟字母 `a`,后跟字母 `r`。 - -
-"(c|g|p)ar" => The car is parked in the garage.
-
+例如正则表达式 `(ab)*` 表示匹配零个或多个的字符串 "ab"。我们还可以在字符组中使用元字符 `|`。例如正则表达式 `(c|g|p)ar`,表示: 小写字母 `c`、`g` 或 `p` 后面跟字母 `a`,后跟字母 `r`。
"(c|g|p)ar" => The car is parked in the garage.
## 2.6 分支结构 在正则表达式中垂直条 `|` 用来定义分支结构,分支结构就像多个表达式之间的条件。现在你可能认为这个字符集和分支机构的工作方式一样。 但是字符集和分支结构巨大的区别是字符集只在字符级别上有作用,然而分支结构在表达式级别上依然可以使用。 -例如正则表达式 `(T|t)he|car`,表示: 大写字母 `T` 或小写字母 `t`,后面跟小写字母 `h`,后跟小写字母 `e` 或小写字母 `c`,后跟小写字母 `a`,后跟小写字母 `r`。 - -
-"(T|t)he|car" => The car is parked in the garage.
-
+例如正则表达式 `(T|t)he|car`,表示: 大写字母 `T` 或小写字母 `t`,后面跟小写字母 `h`,后跟小写字母 `e` 或小写字母 `c`,后跟小写字母 `a`,后跟小写字母 `r`。
"(T|t)he|car" => The car is parked in the garage.
## 2.7 转义特殊字符 正则表达式中使用反斜杠 `\` 来转义下一个字符。这将允许你使用保留字符来作为匹配字符 `{ } [ ] / \ + * . $ ^ | ?`。在特殊字符前面加 `\`,就可以使用它来做匹配字符。 -例如正则表达式 `.` 是用来匹配除了换行符以外的任意字符。现在要在输入字符串中匹配 `.` 字符,正则表达式 `(f|c|m)at\.?`,表示: 小写字母 `f`、`c` 或者 `m` 后跟小写字母 `a`,后跟小写字母 `t`,后跟可选的 `.` 字符。 - -
-"(f|c|m)at\.?" => The fat cat sat on the mat.
-
+例如正则表达式 `.` 是用来匹配除了换行符以外的任意字符。现在要在输入字符串中匹配 `.` 字符,正则表达式 `(f|c|m)at\.?`,表示: 小写字母 `f`、`c` 或者 `m` 后跟小写字母 `a`,后跟小写字母 `t`,后跟可选的 `.` 字符。
"(f|c|m)at\.?" => The fat cat sat on the mat.
## 2.8 定位符 @@ -192,27 +125,11 @@ 插入符号 `^` 符号用于检查匹配字符是否是输入字符串的第一个字符。如果我们使用正则表达式 `^a` (如果a是起始符号)匹配字符串 `abc`,它会匹配到 `a`。 但是如果我们使用正则表达式 `^b`,它是匹配不到任何东西的,因为在字符串 `abc` 中 "b" 不是起始字符。 -让我们来看看另一个正则表达式 `^(T|t)he`,这表示: 大写字母 `T` 或小写字母 `t` 是输入字符串的起始符号,后面跟着小写字母 `h`,后跟小写字母 `e`。 - -
-"(T|t)he" => The car is parked in the garage.
-
- -
-"^(T|t)he" => The car is parked in the garage.
-
+让我们来看看另一个正则表达式 `^(T|t)he`,这表示: 大写字母 `T` 或小写字母 `t` 是输入字符串的起始符号,后面跟着小写字母 `h`,后跟小写字母 `e`。
"(T|t)he" => The car is parked in the garage.
"^(T|t)he" => The car is parked in the garage.
### 2.8.2 美元符号 -美元 `$` 符号用于检查匹配字符是否是输入字符串的最后一个字符。例如正则表达式 `(at\.)$`,表示: 小写字母 `a`,后跟小写字母 `t`,后跟一个 `.` 字符,且这个匹配器必须是字符串的结尾。 - -
-"(at\.)" => The fat cat. sat. on the mat.
-
- -
-"(at\.)$" => The fat cat sat on the mat.
-
+美元 `$` 符号用于检查匹配字符是否是输入字符串的最后一个字符。例如正则表达式 `(at\.)$`,表示: 小写字母 `a`,后跟小写字母 `t`,后跟一个 `.` 字符,且这个匹配器必须是字符串的结尾。
"(at\.)" => The fat cat. sat. on the mat.
"(at\.)$" => The fat cat sat on the mat.
## 3. 简写字符集 @@ -246,37 +163,21 @@ 正向先行断言认为第一部分的表达式必须是先行断言表达式。返回的匹配结果仅包含与第一部分表达式匹配的文本。 要在一个括号内定义一个正向先行断言,在括号中问号和等号是这样使用的 `(?=...)`。先行断言表达式写在括号中的等号后面。 例如正则表达式 `(T|t)he(?=\sfat)`,表示: 匹配大写字母 `T` 或小写字母 `t`,后面跟字母 `h`,后跟字母 `e`。 -在括号中,我们定义了正向先行断言,它会引导正则表达式引擎匹配 `The` 或 `the` 后面跟着 `fat`。 - -
-"(T|t)he(?=\sfat)" => The fat cat sat on the mat.
-
+在括号中,我们定义了正向先行断言,它会引导正则表达式引擎匹配 `The` 或 `the` 后面跟着 `fat`。
"(T|t)he(?=\sfat)" => The fat cat sat on the mat.
### 4.2 负向先行断言 当我们需要从输入字符串中获取不匹配表达式的内容时,使用负向先行断言。负向先行断言的定义跟我们定义的正向先行断言一样, 唯一的区别是不是等号 `=`,我们使用否定符号 `!`,例如 `(?!...)`。 -我们来看看下面的正则表达式 `(T|t)he(?!\sfat)`,表示: 从输入字符串中获取全部 `The` 或者 `the` 且不匹配 `fat` 前面加上一个空格字符。 - -
-"(T|t)he(?!\sfat)" => The fat cat sat on the mat.
-
+我们来看看下面的正则表达式 `(T|t)he(?!\sfat)`,表示: 从输入字符串中获取全部 `The` 或者 `the` 且不匹配 `fat` 前面加上一个空格字符。
"(T|t)he(?!\sfat)" => The fat cat sat on the mat.
### 4.3 正向后行断言 -正向后行断言是用于获取在特定模式之前的所有匹配内容。正向后行断言表示为 `(?<=...)`。例如正则表达式 `(?<=(T|t)he\s)(fat|mat)`,表示: 从输入字符串中获取在单词 `The` 或 `the` 之后的所有 `fat` 和 `mat` 单词。 - -
-"(?<=(T|t)he\s)(fat|mat)" => The fat cat sat on the mat.
-
+正向后行断言是用于获取在特定模式之前的所有匹配内容。正向后行断言表示为 `(?<=...)`。例如正则表达式 `(?<=(T|t)he\s)(fat|mat)`,表示: 从输入字符串中获取在单词 `The` 或 `the` 之后的所有 `fat` 和 `mat` 单词。
"(?<=(T|t)he\s)(fat|mat)" => The fat cat sat on the mat.
### 4.4 负向后行断言 -负向后行断言是用于获取不在特定模式之前的所有匹配的内容。负向后行断言表示为 `(? -"(?<!(T|t)he\s)(cat)" => The cat sat on cat. - +负向后行断言是用于获取不在特定模式之前的所有匹配的内容。负向后行断言表示为 `(?"(?<!(T|t)he\s)(cat)" => The cat sat on cat. ## 5. 标记 @@ -291,46 +192,22 @@ ### 5.1 不区分大小写 `i` 修饰符用于执行不区分大小写匹配。例如正则表达式 `/The/gi`,表示: 大写字母 `T`,后跟小写字母 `h`,后跟字母 `e`。 -但是在正则匹配结束时 `i` 标记会告诉正则表达式引擎忽略这种情况。正如你所看到的,我们还使用了 `g` 标记,因为我们要在整个输入字符串中搜索匹配。 - -
-"The" => The fat cat sat on the mat.
-
- -
-"/The/gi" => The fat cat sat on the mat.
-
+但是在正则匹配结束时 `i` 标记会告诉正则表达式引擎忽略这种情况。正如你所看到的,我们还使用了 `g` 标记,因为我们要在整个输入字符串中搜索匹配。
"The" => The fat cat sat on the mat.
"/The/gi" => The fat cat sat on the mat.
### 5.2 全局搜索 `g` 修饰符用于执行全局匹配 (会查找所有匹配,不会在查找到第一个匹配时就停止)。 例如正则表达式 `/.(at)/g`,表示: 除换行符之外的任意字符,后跟小写字母 `a`,后跟小写字母 `t`。 -因为我们在正则表达式的末尾使用了 `g` 标记,它会从整个输入字符串中找到每个匹配项。 - -
-".(at)" => The fat cat sat on the mat.
-
- -
-"/.(at)/g" => The fat cat sat on the mat.
-
+因为我们在正则表达式的末尾使用了 `g` 标记,它会从整个输入字符串中找到每个匹配项。
".(at)" => The fat cat sat on the mat.
"/.(at)/g" => The fat cat sat on the mat.
### 5.3 多行匹配 `m` 修饰符被用来执行多行的匹配。正如我们前面讨论过的 `(^, $)`,使用定位符来检查匹配字符是输入字符串开始或者结束。但是我们希望每一行都使用定位符,所以我们就使用 `m` 修饰符。 -例如正则表达式 `/at(.)?$/gm`,表示: 小写字母 `a`,后跟小写字母 `t`,匹配除了换行符以外任意字符零次或一次。而且因为 `m` 标记,现在正则表达式引擎匹配字符串中每一行的末尾。 - -
-"/.at(.)?$/" => The fat
+例如正则表达式 `/at(.)?$/gm`,表示: 小写字母 `a`,后跟小写字母 `t`,匹配除了换行符以外任意字符零次或一次。而且因为 `m` 标记,现在正则表达式引擎匹配字符串中每一行的末尾。
"/.at(.)?$/" => The fat
                 cat sat
-                on the mat.
-
- -
-"/.at(.)?$/gm" => The fat
+                on the mat.
"/.at(.)?$/gm" => The fat
                   cat sat
-                  on the mat.
-
+ on the mat.
## 常用正则表达式 diff --git a/app/src/main/java/io/legado/app/ui/widget/dialog/TextDialog.kt b/app/src/main/java/io/legado/app/ui/widget/dialog/TextDialog.kt index ea4330039..3c8133c8a 100644 --- a/app/src/main/java/io/legado/app/ui/widget/dialog/TextDialog.kt +++ b/app/src/main/java/io/legado/app/ui/widget/dialog/TextDialog.kt @@ -12,6 +12,8 @@ import io.legado.app.utils.getSize import io.legado.app.utils.viewbindingdelegate.viewBinding import io.noties.markwon.Markwon import io.noties.markwon.image.glide.GlideImagesPlugin +import io.noties.markwon.ext.tables.TablePlugin +import io.noties.markwon.html.HtmlPlugin import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -66,6 +68,8 @@ class TextDialog : BaseDialogFragment() { MD -> binding.textView.post { Markwon.builder(requireContext()) .usePlugin(GlideImagesPlugin.create(requireContext())) + .usePlugin(HtmlPlugin.create()) + .usePlugin(TablePlugin.create(requireContext())) .build() .setMarkdown(binding.textView, content) } From e549030bfc39b9cd6a1cfa4939cc8be9615d4985 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sat, 26 Dec 2020 17:21:00 +0800 Subject: [PATCH 02/68] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=A0=8Fbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/values/styles.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 40ce850fd..2791783b5 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -33,7 +33,6 @@ @style/Style.PopupMenu @color/transparent true - false false From dae57c41356393aeb50a0b82f623fa101a445f65 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sat, 26 Dec 2020 20:52:39 +0800 Subject: [PATCH 03/68] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/help/JsExtensions.kt | 11 ++++++----- .../java/io/legado/app/help/http/parser/TextParser.kt | 2 +- .../io/legado/app/model/analyzeRule/AnalyzeRule.kt | 11 ++++++----- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/JsExtensions.kt b/app/src/main/java/io/legado/app/help/JsExtensions.kt index aa6865aed..971f580e9 100644 --- a/app/src/main/java/io/legado/app/help/JsExtensions.kt +++ b/app/src/main/java/io/legado/app/help/JsExtensions.kt @@ -29,13 +29,14 @@ interface JsExtensions { * 访问网络,返回String */ fun ajax(urlStr: String): String? { - return try { - val analyzeUrl = AnalyzeUrl(urlStr) - runBlocking { + return runBlocking { + try { + val analyzeUrl = AnalyzeUrl(urlStr) analyzeUrl.getStrResponse(urlStr).body + } catch (e: Exception) { + e.printStackTrace() + e.msg } - } catch (e: Exception) { - e.msg } } diff --git a/app/src/main/java/io/legado/app/help/http/parser/TextParser.kt b/app/src/main/java/io/legado/app/help/http/parser/TextParser.kt index 09891944d..031ad9d33 100644 --- a/app/src/main/java/io/legado/app/help/http/parser/TextParser.kt +++ b/app/src/main/java/io/legado/app/help/http/parser/TextParser.kt @@ -8,7 +8,7 @@ import rxhttp.wrapper.exception.HttpStatusCodeException import java.nio.charset.Charset @Parser(name = "Text") -class TextParser(val encode: String? = null) : rxhttp.wrapper.parse.Parser { +class TextParser(private val encode: String? = null) : rxhttp.wrapper.parse.Parser { override fun onParse(response: Response): String { diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt index 7a778472e..6fc8e2146 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt @@ -653,13 +653,14 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions { * js实现跨域访问,不能删 */ override fun ajax(urlStr: String): String? { - return try { - val analyzeUrl = AnalyzeUrl(urlStr, book = book) - runBlocking { + return runBlocking { + try { + val analyzeUrl = AnalyzeUrl(urlStr, book = book) analyzeUrl.getStrResponse(urlStr).body + } catch (e: Exception) { + e.printStackTrace() + e.msg } - } catch (e: Exception) { - e.localizedMessage } } From 0d42bec7e184b40c56b18bc8ba5f54f249b272ea Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 27 Dec 2020 14:45:18 +0800 Subject: [PATCH 04/68] update updateLog.md --- app/src/main/assets/updateLog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index f89732b07..61af073cf 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -3,6 +3,10 @@ * 关注合作公众号 **[小说拾遗]** 获取好看的小说。 * 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 +**2020/12/27** +* 订阅添加搜索和分组 +* 修复部分手机状态栏bug + **2020/12/19** * 书签转移到文本菜单里,会记录选择的文本和位置 * 订阅源添加单url选项,直接打开url From b6ee1cc503da6d770fb2ae1381e187115bb27f90 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 27 Dec 2020 14:53:52 +0800 Subject: [PATCH 05/68] update updateLog.md --- app/src/main/assets/updateLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 61af073cf..75bf8b4ea 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -6,6 +6,7 @@ **2020/12/27** * 订阅添加搜索和分组 * 修复部分手机状态栏bug +* 单url订阅支持内容规则和样式 **2020/12/19** * 书签转移到文本菜单里,会记录选择的文本和位置 From f259380aaffbde6113fe90c3df75681c8d6d0978 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 27 Dec 2020 15:19:30 +0800 Subject: [PATCH 06/68] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/base/adapter/DiffRecyclerAdapter.kt | 24 ++++-- .../app/base/adapter/RecyclerAdapter.kt | 81 ++++++++++++------- 2 files changed, 69 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/io/legado/app/base/adapter/DiffRecyclerAdapter.kt b/app/src/main/java/io/legado/app/base/adapter/DiffRecyclerAdapter.kt index 258f93c87..9f9a69dc2 100644 --- a/app/src/main/java/io/legado/app/base/adapter/DiffRecyclerAdapter.kt +++ b/app/src/main/java/io/legado/app/base/adapter/DiffRecyclerAdapter.kt @@ -47,39 +47,46 @@ abstract class DiffRecyclerAdapter(protected val context recyclerView.adapter = this } + @Synchronized fun setItems(items: List?) { - synchronized(lock) { + kotlin.runCatching { asyncListDiffer.submitList(items) } } + @Synchronized fun setItem(position: Int, item: ITEM) { - synchronized(lock) { + kotlin.runCatching { val list = ArrayList(asyncListDiffer.currentList) list[position] = item asyncListDiffer.submitList(list) } } - fun updateItem(item: ITEM) = - synchronized(lock) { + @Synchronized + fun updateItem(item: ITEM) { + kotlin.runCatching { val index = asyncListDiffer.currentList.indexOf(item) if (index >= 0) { asyncListDiffer.currentList[index] = item notifyItemChanged(index) } } + } - fun updateItem(position: Int, payload: Any) = - synchronized(lock) { + @Synchronized + fun updateItem(position: Int, payload: Any) { + kotlin.runCatching { val size = itemCount if (position in 0 until size) { notifyItemChanged(position, payload) } } + } - fun updateItems(fromPosition: Int, toPosition: Int, payloads: Any) = - synchronized(lock) { + @Synchronized + fun updateItems(fromPosition: Int, toPosition: Int, payloads: Any) { + kotlin.runCatching { val size = itemCount if (fromPosition in 0 until size && toPosition in 0 until size) { notifyItemRangeChanged( @@ -89,6 +96,7 @@ abstract class DiffRecyclerAdapter(protected val context ) } } + } fun isEmpty() = asyncListDiffer.currentList.isEmpty() diff --git a/app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt b/app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt index 7ddbaf581..9815a6516 100644 --- a/app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt +++ b/app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt @@ -45,42 +45,49 @@ abstract class RecyclerAdapter(protected val context: Co recyclerView.adapter = this } + @Synchronized fun addHeaderView(header: ((parent: ViewGroup) -> ViewBinding)) { - synchronized(lock) { + kotlin.runCatching { val index = headerItems.size() headerItems.put(TYPE_HEADER_VIEW + headerItems.size(), header) notifyItemInserted(index) } } - fun addFooterView(footer: ((parent: ViewGroup) -> ViewBinding)) = - synchronized(lock) { + @Synchronized + fun addFooterView(footer: ((parent: ViewGroup) -> ViewBinding)) { + kotlin.runCatching { val index = getActualItemCount() + footerItems.size() footerItems.put(TYPE_FOOTER_VIEW + footerItems.size(), footer) notifyItemInserted(index) } + } - - fun removeHeaderView(header: ((parent: ViewGroup) -> ViewBinding)) = - synchronized(lock) { + @Synchronized + fun removeHeaderView(header: ((parent: ViewGroup) -> ViewBinding)) { + kotlin.runCatching { val index = headerItems.indexOfValue(header) if (index >= 0) { headerItems.remove(index) notifyItemRemoved(index) } } + } - fun removeFooterView(footer: ((parent: ViewGroup) -> ViewBinding)) = - synchronized(lock) { + @Synchronized + fun removeFooterView(footer: ((parent: ViewGroup) -> ViewBinding)) { + kotlin.runCatching { val index = footerItems.indexOfValue(footer) if (index >= 0) { footerItems.remove(index) notifyItemRemoved(getActualItemCount() + index - 2) } } + } + @Synchronized fun setItems(items: List?) { - synchronized(lock) { + kotlin.runCatching { if (this.items.isNotEmpty()) { this.items.clear() } @@ -92,8 +99,9 @@ abstract class RecyclerAdapter(protected val context: Co } } + @Synchronized fun setItems(items: List?, diffResult: DiffUtil.DiffResult) { - synchronized(lock) { + kotlin.runCatching { if (this.items.isNotEmpty()) { this.items.clear() } @@ -105,8 +113,9 @@ abstract class RecyclerAdapter(protected val context: Co } } + @Synchronized fun setItem(position: Int, item: ITEM) { - synchronized(lock) { + kotlin.runCatching { val oldSize = getActualItemCount() if (position in 0 until oldSize) { this.items[position] = item @@ -116,8 +125,9 @@ abstract class RecyclerAdapter(protected val context: Co } } + @Synchronized fun addItem(item: ITEM) { - synchronized(lock) { + kotlin.runCatching { val oldSize = getActualItemCount() if (this.items.add(item)) { notifyItemInserted(oldSize + getHeaderCount()) @@ -126,8 +136,9 @@ abstract class RecyclerAdapter(protected val context: Co } } + @Synchronized fun addItems(position: Int, newItems: List) { - synchronized(lock) { + kotlin.runCatching { if (this.items.addAll(position, newItems)) { notifyItemRangeInserted(position + getHeaderCount(), newItems.size) } @@ -135,8 +146,9 @@ abstract class RecyclerAdapter(protected val context: Co } } + @Synchronized fun addItems(newItems: List) { - synchronized(lock) { + kotlin.runCatching { val oldSize = getActualItemCount() if (this.items.addAll(newItems)) { if (oldSize == 0 && getHeaderCount() == 0) { @@ -149,8 +161,9 @@ abstract class RecyclerAdapter(protected val context: Co } } + @Synchronized fun removeItem(position: Int) { - synchronized(lock) { + kotlin.runCatching { if (this.items.removeAt(position) != null) { notifyItemRemoved(position + getHeaderCount()) } @@ -158,8 +171,9 @@ abstract class RecyclerAdapter(protected val context: Co } } + @Synchronized fun removeItem(item: ITEM) { - synchronized(lock) { + kotlin.runCatching { if (this.items.remove(item)) { notifyItemRemoved(this.items.indexOf(item) + getHeaderCount()) } @@ -167,8 +181,9 @@ abstract class RecyclerAdapter(protected val context: Co } } + @Synchronized fun removeItems(items: List) { - synchronized(lock) { + kotlin.runCatching { if (this.items.removeAll(items)) { notifyDataSetChanged() } @@ -176,8 +191,9 @@ abstract class RecyclerAdapter(protected val context: Co } } + @Synchronized fun swapItem(oldPosition: Int, newPosition: Int) { - synchronized(lock) { + kotlin.runCatching { val size = getActualItemCount() if (oldPosition in 0 until size && newPosition in 0 until size) { val srcPosition = oldPosition + getHeaderCount() @@ -189,8 +205,9 @@ abstract class RecyclerAdapter(protected val context: Co } } - fun updateItem(item: ITEM) = - synchronized(lock) { + @Synchronized + fun updateItem(item: ITEM) { + kotlin.runCatching { val index = this.items.indexOf(item) if (index >= 0) { this.items[index] = item @@ -198,17 +215,21 @@ abstract class RecyclerAdapter(protected val context: Co } onCurrentListChanged() } + } - fun updateItem(position: Int, payload: Any) = - synchronized(lock) { + @Synchronized + fun updateItem(position: Int, payload: Any) { + kotlin.runCatching { val size = getActualItemCount() if (position in 0 until size) { notifyItemChanged(position + getHeaderCount(), payload) } } + } - fun updateItems(fromPosition: Int, toPosition: Int, payloads: Any) = - synchronized(lock) { + @Synchronized + fun updateItems(fromPosition: Int, toPosition: Int, payloads: Any) { + kotlin.runCatching { val size = getActualItemCount() if (fromPosition in 0 until size && toPosition in 0 until size) { notifyItemRangeChanged( @@ -218,11 +239,15 @@ abstract class RecyclerAdapter(protected val context: Co ) } } + } - fun clearItems() = synchronized(lock) { - this.items.clear() - notifyDataSetChanged() - onCurrentListChanged() + @Synchronized + fun clearItems() { + kotlin.runCatching { + this.items.clear() + notifyDataSetChanged() + onCurrentListChanged() + } } fun isEmpty() = items.isEmpty() From 7cbb2038d216a58f39badd67ebae708321072d3a Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 27 Dec 2020 15:30:15 +0800 Subject: [PATCH 07/68] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/base/adapter/DiffRecyclerAdapter.kt | 2 -- app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt | 2 -- 2 files changed, 4 deletions(-) diff --git a/app/src/main/java/io/legado/app/base/adapter/DiffRecyclerAdapter.kt b/app/src/main/java/io/legado/app/base/adapter/DiffRecyclerAdapter.kt index 9f9a69dc2..60d3600ed 100644 --- a/app/src/main/java/io/legado/app/base/adapter/DiffRecyclerAdapter.kt +++ b/app/src/main/java/io/legado/app/base/adapter/DiffRecyclerAdapter.kt @@ -26,8 +26,6 @@ abstract class DiffRecyclerAdapter(protected val context } } - private val lock = Object() - private var itemClickListener: ((holder: ItemViewHolder, item: ITEM) -> Unit)? = null private var itemLongClickListener: ((holder: ItemViewHolder, item: ITEM) -> Boolean)? = null diff --git a/app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt b/app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt index 9815a6516..1f374acdf 100644 --- a/app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt +++ b/app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt @@ -26,8 +26,6 @@ abstract class RecyclerAdapter(protected val context: Co private val items: MutableList = mutableListOf() - private val lock = Object() - private var itemClickListener: ((holder: ItemViewHolder, item: ITEM) -> Unit)? = null private var itemLongClickListener: ((holder: ItemViewHolder, item: ITEM) -> Boolean)? = null From 26f17a1341a1fb0bf7e74e6aea3eb0da1304cb00 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 27 Dec 2020 15:40:44 +0800 Subject: [PATCH 08/68] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 07232a967..35207bcbc 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -200,7 +200,7 @@ + android:launchMode="standard" /> Date: Sun, 27 Dec 2020 15:48:56 +0800 Subject: [PATCH 09/68] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/ui/book/search/SearchActivity.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt b/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt index 7aa11f1c5..3f1d377bb 100644 --- a/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt @@ -160,6 +160,13 @@ class SearchActivity : VMBaseActivity Date: Sun, 27 Dec 2020 18:52:43 +0800 Subject: [PATCH 10/68] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt b/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt index efad70917..1e417a1a0 100644 --- a/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt @@ -82,7 +82,7 @@ class CacheActivity : VMBaseActivity() override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { - R.id.menu_download -> launch(IO) { + R.id.menu_download -> { if (adapter.downloadMap.isNullOrEmpty()) { adapter.getItems().forEach { book -> CacheBook.start( From fa72c4e6987ed128ead622aed9fd1ad9fc9a72af Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 27 Dec 2020 20:44:22 +0800 Subject: [PATCH 11/68] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/utils/FragmentExtensions.kt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/io/legado/app/utils/FragmentExtensions.kt b/app/src/main/java/io/legado/app/utils/FragmentExtensions.kt index 2e812a241..15787e7fe 100644 --- a/app/src/main/java/io/legado/app/utils/FragmentExtensions.kt +++ b/app/src/main/java/io/legado/app/utils/FragmentExtensions.kt @@ -69,11 +69,10 @@ inline fun Fragment.startActivity(vararg params: Pair Fragment.startActivityForResult( requestCode: Int, vararg params: Pair -) = - startActivityForResult( - AnkoInternals.createIntent(requireActivity(), T::class.java, params), - requestCode - ) +) = startActivityForResult( + AnkoInternals.createIntent(requireActivity(), T::class.java, params), + requestCode +) inline fun Fragment.startService(vararg params: Pair) = AnkoInternals.internalStartService(requireActivity(), T::class.java, params) From 1adce9267b5b0b27daa445a4d8b413c83bbc9d6e Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 27 Dec 2020 20:46:16 +0800 Subject: [PATCH 12/68] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/utils/StringUtils.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/main/java/io/legado/app/utils/StringUtils.kt b/app/src/main/java/io/legado/app/utils/StringUtils.kt index a2e2c4388..89d561cbf 100644 --- a/app/src/main/java/io/legado/app/utils/StringUtils.kt +++ b/app/src/main/java/io/legado/app/utils/StringUtils.kt @@ -106,11 +106,9 @@ object StringUtils { if (length <= 0) return "0" val units = arrayOf("b", "kb", "M", "G", "T") //计算单位的,原理是利用lg,公式是 lg(1024^n) = nlg(1024),最后 nlg(1024)/lg(1024) = n。 - //计算单位的,原理是利用lg,公式是 lg(1024^n) = nlg(1024),最后 nlg(1024)/lg(1024) = n。 val digitGroups = (log10(length.toDouble()) / log10(1024.0)).toInt() //计算原理是,size/单位值。单位值指的是:比如说b = 1024,KB = 1024^2 - //计算原理是,size/单位值。单位值指的是:比如说b = 1024,KB = 1024^2 return DecimalFormat("#,##0.##") .format(length / 1024.0.pow(digitGroups.toDouble())) + " " + units[digitGroups] } @@ -306,7 +304,7 @@ object StringUtils { return sb.toString() } - fun hexStringToByte(hexString: String): ByteArray? { + fun hexStringToByte(hexString: String): ByteArray { val hexStr = hexString.replace(" ", "") val len = hexStr.length val bytes = ByteArray(len / 2) From 83fc64d806d943d79d4496e2e7b441f36f4cb60d Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 27 Dec 2020 23:06:09 +0800 Subject: [PATCH 13/68] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/utils/ZipUtils.kt | 40 ++++++------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/io/legado/app/utils/ZipUtils.kt b/app/src/main/java/io/legado/app/utils/ZipUtils.kt index 73311729d..b839066af 100644 --- a/app/src/main/java/io/legado/app/utils/ZipUtils.kt +++ b/app/src/main/java/io/legado/app/utils/ZipUtils.kt @@ -1,13 +1,15 @@ package io.legado.app.utils import android.util.Log +import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.withContext import java.io.* import java.util.* import java.util.zip.ZipEntry import java.util.zip.ZipFile import java.util.zip.ZipOutputStream -@Suppress("unused") +@Suppress("unused", "BlockingMethodInNonBlockingContext") object ZipUtils { /** @@ -38,20 +40,14 @@ object ZipUtils { srcFilePaths: Collection?, zipFilePath: String?, comment: String? - ): Boolean { - if (srcFilePaths == null || zipFilePath == null) return false - var zos: ZipOutputStream? = null - try { - zos = ZipOutputStream(FileOutputStream(zipFilePath)) + ): Boolean = withContext(IO) { + if (srcFilePaths == null || zipFilePath == null) return@withContext false + ZipOutputStream(FileOutputStream(zipFilePath)).use { for (srcFile in srcFilePaths) { - if (!zipFile(getFileByPath(srcFile)!!, "", zos, comment)) return false - } - return true - } finally { - zos?.let { - zos.finish() - zos.close() + if (!zipFile(getFileByPath(srcFile)!!, "", it, comment)) + return@withContext false } + return@withContext true } } @@ -72,18 +68,11 @@ object ZipUtils { comment: String? = null ): Boolean { if (srcFiles == null || zipFile == null) return false - var zos: ZipOutputStream? = null - try { - zos = ZipOutputStream(FileOutputStream(zipFile)) + ZipOutputStream(FileOutputStream(zipFile)).use { for (srcFile in srcFiles) { - if (!zipFile(srcFile, "", zos, comment)) return false + if (!zipFile(srcFile, "", it, comment)) return false } return true - } finally { - zos?.let { - zos.finish() - zos.close() - } } } @@ -139,12 +128,7 @@ object ZipUtils { ): Boolean { if (srcFile == null || zipFile == null) return false ZipOutputStream(FileOutputStream(zipFile)).use { zos -> - return zipFile( - srcFile, - "", - zos, - comment - ) + return zipFile(srcFile, "", zos, comment) } } From 5741c08180b42feb4776bdf41e333bcfc6c64193 Mon Sep 17 00:00:00 2001 From: Celeter <48249130+Celeter@users.noreply.github.com> Date: Mon, 28 Dec 2020 08:56:44 +0800 Subject: [PATCH 14/68] Update README.md --- README.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 82994a452..1327ab258 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,15 @@ -# legado +
+ legado +

Legado

+
+

阅读3.0, 阅读是一款可以自定义来源阅读网络内容的工具,为广大网络文学爱好者提供一种方便、快捷舒适的试读体验。

+
-[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) [![Build Action](https://github.com/gedoor/legado/workflows/Android%20CI/badge.svg)](https://github.com/gedoor/legado/actions) +[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) +[![Build Action](https://github.com/gedoor/legado/workflows/Android%20CI/badge.svg)](https://github.com/gedoor/legado/actions) +[![Downloads](https://img.shields.io/github/downloads/gedoor/legado/total.svg)](https://github.com/gedoor/legado/releases/latest) +[![GitHub issues](https://img.shields.io/github/issues/gedoor/legado)](https://github.com/gedoor/legado/issues) +[![GitHub contributors](https://img.shields.io/github/contributors/gedoor/legado)](https://github.com/gedoor/legado/graphs/contributors) ## 阅读3.0 * [书源规则](https://alanskycn.gitee.io/teachme/) @@ -8,9 +17,9 @@ * [帮助文档](/app/src/main/assets/help/appHelp.md) ## 下载 -Google Play or CoolApk or [Releases](https://github.com/gedoor/legado/releases/latest) +Google Play or CoolApk or [Releases](https://github.com/gedoor/legado/releases/latest) -### 阅读API +## 阅读API 阅读3.0 提供了2种方式的API:`Web方式`和`Content Provider方式`。您可以在[这里](api.md)根据需要自行调用。 ## 感谢 From d588bfae1fadd04a66b4894129f14dac609355c6 Mon Sep 17 00:00:00 2001 From: Celeter <48249130+Celeter@users.noreply.github.com> Date: Mon, 28 Dec 2020 10:13:16 +0800 Subject: [PATCH 15/68] =?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/java/io/legado/app/help/JsExtensions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/help/JsExtensions.kt b/app/src/main/java/io/legado/app/help/JsExtensions.kt index 971f580e9..fc2fc92ff 100644 --- a/app/src/main/java/io/legado/app/help/JsExtensions.kt +++ b/app/src/main/java/io/legado/app/help/JsExtensions.kt @@ -66,7 +66,7 @@ interface JsExtensions { FileUtils.deleteFile(zipPath) val zipFile = FileUtils.createFileIfNotExist(zipPath) StringUtils.hexStringToByte(content).let { - if (it != null) { + if (it.isNotEmpty()) { zipFile.writeBytes(it) } } From 670fc03af747f2abef726d2a3a9ae171696a3aa4 Mon Sep 17 00:00:00 2001 From: Celeter <48249130+Celeter@users.noreply.github.com> Date: Mon, 28 Dec 2020 10:13:57 +0800 Subject: [PATCH 16/68] fix bug --- app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index c5895a0c0..0a0146874 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -358,6 +358,7 @@ class AnalyzeUrl( .setAssemblyEnabled(false) .setOkClient(HttpHelper.getProxyClient(proxy)) .addAllEncoded(fieldMap) + .addAllHeader(headerMap) .toByteArray().await() } } From 48f114affa16ee8db665caafba5142cc6ff33c04 Mon Sep 17 00:00:00 2001 From: Celeter <48249130+Celeter@users.noreply.github.com> Date: Mon, 28 Dec 2020 10:54:58 +0800 Subject: [PATCH 17/68] =?UTF-8?q?=E6=9B=B4=E6=96=B0JDK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/legado.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/legado.yml b/.github/workflows/legado.yml index 4d9940f4d..e49db9726 100644 --- a/.github/workflows/legado.yml +++ b/.github/workflows/legado.yml @@ -28,13 +28,13 @@ jobs: # 蓝奏云里的文件夹名(需手动在蓝奏云创建) LANZOU_FOLDER: '阅读3测试版' # 是否上传到artifact - UPLOAD_ARTIFACT: 'false' + UPLOAD_ARTIFACT: 'true' steps: - uses: actions/checkout@v2 - name: set up JDK 1.8 uses: actions/setup-java@v1 with: - java-version: 1.8 + java-version: 14 - name: clear 18PlusList.txt run: | echo "清空18PlusList.txt" @@ -87,4 +87,4 @@ jobs: if: ${{ env.LANZOU_PSD }} run: python $GITHUB_WORKSPACE/.github/lzy.py env: - UPLOAD_FOLDER: ${{ github.workspace }}/app/build/outputs/apk/app/release/ \ No newline at end of file + UPLOAD_FOLDER: ${{ github.workspace }}/app/build/outputs/apk/app/release/ From 52cb0fbc4c06e9a9b3ff757f86259a42589d462b Mon Sep 17 00:00:00 2001 From: Celeter <48249130+Celeter@users.noreply.github.com> Date: Mon, 28 Dec 2020 10:55:22 +0800 Subject: [PATCH 18/68] =?UTF-8?q?=E6=9B=B4=E6=96=B0JDK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/legado.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/legado.yml b/.github/workflows/legado.yml index e49db9726..87ca425ad 100644 --- a/.github/workflows/legado.yml +++ b/.github/workflows/legado.yml @@ -31,7 +31,7 @@ jobs: UPLOAD_ARTIFACT: 'true' steps: - uses: actions/checkout@v2 - - name: set up JDK 1.8 + - name: set up JDK uses: actions/setup-java@v1 with: java-version: 14 From 79ba9d2a15e92f0c99334435a502b3c47f07f4dc Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 28 Dec 2020 11:03:23 +0800 Subject: [PATCH 19/68] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 75bf8b4ea..5af6a8d74 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -3,6 +3,9 @@ * 关注合作公众号 **[小说拾遗]** 获取好看的小说。 * 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 +**2020/12/28** +* 解决文件下载异常,在线语音可正常播放 by [Celeter](https://github.com/Celeter) + **2020/12/27** * 订阅添加搜索和分组 * 修复部分手机状态栏bug From 7a0a62898eb8740a8da36ecdfcb14a17ea6ed9ec Mon Sep 17 00:00:00 2001 From: Celeter <48249130+Celeter@users.noreply.github.com> Date: Tue, 29 Dec 2020 08:25:37 +0800 Subject: [PATCH 20/68] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/defaultData/httpTTS.json | 143 ++++++++++++++----- 1 file changed, 109 insertions(+), 34 deletions(-) diff --git a/app/src/main/assets/defaultData/httpTTS.json b/app/src/main/assets/defaultData/httpTTS.json index a249a3b29..228cc6d76 100644 --- a/app/src/main/assets/defaultData/httpTTS.json +++ b/app/src/main/assets/defaultData/httpTTS.json @@ -1,62 +1,137 @@ [ { - "id": 1598233029304, - "name": "度小美", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=0&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "id": 1598233029336, + "name": "度丫丫", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029305, - "name": "度小宇", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=1&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "id": 1598233029337, + "name": "度博文①", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029306, - "name": "度逍遥", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=5003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "id": 1598233029338, + "name": "度博文②", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029307, - "name": "度丫丫", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=4&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "id": 1598233029339, + "name": "度博文③", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029308, - "name": "度小娇", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=5&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "id": 1598233029340, + "name": "度某男", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4114&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029309, - "name": "度米朵", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "id": 1598233029341, + "name": "度某女", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4119&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029310, - "name": "度博文", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "id": 1598233029342, + "name": "度小娇", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029311, + "id": 1598233029343, + "name": "度小宇", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=1&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029344, "name": "度小童", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=110&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=110&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029312, + "id": 1598233029345, + "name": "度小美", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=0&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029346, "name": "度小萌", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=111&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=111&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029313, - "name": "百度骚男", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=11&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "id": 1598233029347, + "name": "度小鹿①", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4118&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029314, - "name": "百度评书", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=6&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "id": 1598233029348, + "name": "度小鹿②", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5118&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029349, + "name": "度米朵", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029350, + "name": "度逍遥-基础", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=3&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029351, + "name": "度逍遥-精品①", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029315, + "id": 1598233029352, + "name": "度逍遥-精品②", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029353, + "name": "情感女声", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4105&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029354, + "name": "情感男声", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4115&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029355, + "name": "标准女声", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4100&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029356, + "name": "标准男声", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4121&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029357, + "name": "治愈女声", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5120&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029358, + "name": "治愈男声", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5121&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029359, + "name": "甜美女声①", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029360, + "name": "甜美女声②", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029361, "name": "百度主持", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=9&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=9&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029362, + "name": "百度评书", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=6&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" } -] \ No newline at end of file +] From 60f7b699ddc7dabbd650a98c61bfd9a23087423d Mon Sep 17 00:00:00 2001 From: Celeter <48249130+Celeter@users.noreply.github.com> Date: Tue, 29 Dec 2020 10:01:16 +0800 Subject: [PATCH 21/68] Update httpTTS.json --- app/src/main/assets/defaultData/httpTTS.json | 62 ++++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/app/src/main/assets/defaultData/httpTTS.json b/app/src/main/assets/defaultData/httpTTS.json index 228cc6d76..3a86fe65d 100644 --- a/app/src/main/assets/defaultData/httpTTS.json +++ b/app/src/main/assets/defaultData/httpTTS.json @@ -21,117 +21,117 @@ }, { "id": 1598233029340, - "name": "度某男", - "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4114&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" - }, - { - "id": 1598233029341, - "name": "度某女", - "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4119&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" - }, - { - "id": 1598233029342, "name": "度小娇", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029343, + "id": 1598233029341, "name": "度小宇", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=1&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029344, + "id": 1598233029342, "name": "度小童", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=110&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029345, + "id": 1598233029343, "name": "度小美", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=0&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029346, + "id": 1598233029344, "name": "度小萌", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=111&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029347, + "id": 1598233029345, "name": "度小鹿①", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4118&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029348, + "id": 1598233029346, "name": "度小鹿②", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5118&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029349, + "id": 1598233029347, + "name": "度小鹿③", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4119&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029348, "name": "度米朵", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029350, + "id": 1598233029349, "name": "度逍遥-基础", "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=3&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029351, + "id": 1598233029350, "name": "度逍遥-精品①", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029352, + "id": 1598233029351, "name": "度逍遥-精品②", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029353, + "id": 1598233029352, "name": "情感女声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4105&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029354, + "id": 1598233029353, "name": "情感男声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4115&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029355, + "id": 1598233029354, "name": "标准女声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4100&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029356, + "id": 1598233029355, "name": "标准男声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4121&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029357, + "id": 1598233029356, "name": "治愈女声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5120&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029358, + "id": 1598233029357, "name": "治愈男声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5121&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029359, + "id": 1598233029358, "name": "甜美女声①", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029360, + "id": 1598233029359, "name": "甜美女声②", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029361, + "id": 1598233029360, "name": "百度主持", "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=9&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029362, - "name": "百度评书", + "id": 1598233029361, + "name": "百度评书①", "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=6&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029362, + "name": "百度评书②", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4114&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" } ] From e68b277a80d91777f30ef75fc81ed5884948365f Mon Sep 17 00:00:00 2001 From: Celeter <48249130+Celeter@users.noreply.github.com> Date: Tue, 29 Dec 2020 10:12:51 +0800 Subject: [PATCH 22/68] add tts src --- app/src/main/assets/defaultData/httpTTS.json | 35 +++++++++++--------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/app/src/main/assets/defaultData/httpTTS.json b/app/src/main/assets/defaultData/httpTTS.json index 3a86fe65d..8f12b739a 100644 --- a/app/src/main/assets/defaultData/httpTTS.json +++ b/app/src/main/assets/defaultData/httpTTS.json @@ -61,76 +61,81 @@ }, { "id": 1598233029348, - "name": "度米朵", - "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "name": "度米朵①", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { "id": 1598233029349, + "name": "度米朵②", + "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + }, + { + "id": 1598233029350, "name": "度逍遥-基础", "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=3&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029350, + "id": 1598233029351, "name": "度逍遥-精品①", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029351, + "id": 1598233029352, "name": "度逍遥-精品②", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029352, + "id": 1598233029353, "name": "情感女声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4105&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029353, + "id": 1598233029354, "name": "情感男声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4115&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029354, + "id": 1598233029355, "name": "标准女声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4100&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029355, + "id": 1598233029356, "name": "标准男声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4121&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029356, + "id": 1598233029357, "name": "治愈女声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5120&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029357, + "id": 1598233029358, "name": "治愈男声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5121&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029358, + "id": 1598233029359, "name": "甜美女声①", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029359, + "id": 1598233029360, "name": "甜美女声②", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029360, + "id": 1598233029361, "name": "百度主持", "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=9&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029361, + "id": 1598233029362, "name": "百度评书①", "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=6&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029362, + "id": 1598233029363, "name": "百度评书②", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4114&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" } From 7b7fd0d5690e716db901244cc71dac472a2c0de2 Mon Sep 17 00:00:00 2001 From: Celeter <48249130+Celeter@users.noreply.github.com> Date: Tue, 29 Dec 2020 10:22:19 +0800 Subject: [PATCH 23/68] Update legado.yml --- .github/workflows/legado.yml | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/.github/workflows/legado.yml b/.github/workflows/legado.yml index 87ca425ad..57c22b832 100644 --- a/.github/workflows/legado.yml +++ b/.github/workflows/legado.yml @@ -31,15 +31,20 @@ jobs: UPLOAD_ARTIFACT: 'true' steps: - uses: actions/checkout@v2 - - name: set up JDK + - name: Set Up JDK uses: actions/setup-java@v1 with: java-version: 14 - - name: clear 18PlusList.txt + - name: Clear 18PlusList.txt run: | echo "清空18PlusList.txt" echo "">$GITHUB_WORKSPACE/app/src/main/assets/18PlusList.txt - - name: release apk sign + - name: App Minify + if: ${{ github.event_name == 'release'}} + run: | + sed '/minifyEnabled/i\ shrinkResources true' $GITHUB_WORKSPACE/app/build.gradle -i + sed 's/minifyEnabled false/minifyEnabled true/' $GITHUB_WORKSPACE/app/build.gradle -i + - name: Release Apk Sign run: | echo "给apk增加签名" cp $GITHUB_WORKSPACE/.github/workflows/legado.jks $GITHUB_WORKSPACE/app/legado.jks @@ -47,12 +52,12 @@ jobs: sed '$a\RELEASE_KEY_ALIAS=legado' $GITHUB_WORKSPACE/gradle.properties -i sed '$a\RELEASE_STORE_PASSWORD=gedoor_legado' $GITHUB_WORKSPACE/gradle.properties -i sed '$a\RELEASE_KEY_PASSWORD=gedoor_legado' $GITHUB_WORKSPACE/gradle.properties -i - - name: apk live together + - name: Apk Live Together run: | echo "设置apk共存" sed "s/'.release'/'.releaseA'/" $GITHUB_WORKSPACE/app/build.gradle -i sed 's/.release/.releaseA/' $GITHUB_WORKSPACE/app/google-services.json -i - - name: build with gradle + - name: Build With Gradle run: | echo "开始进行release构建" chmod +x gradlew @@ -63,12 +68,12 @@ jobs: with: name: legado apk path: ${{ github.workspace }}/app/build/outputs/apk/app/release/*.apk - - name: Set up Python 3.8 + - name: Set Up Python 3 if: ${{ env.LANZOU_PSD }} uses: actions/setup-python@v2 with: - python-version: 3.8 - - name: Set up lanzou-api + python-version: 3.x + - name: Dependence Install if: ${{ env.LANZOU_PSD }} run: | pip install requests @@ -79,10 +84,10 @@ jobs: run: | import requests,os res = requests.get('https://raw.githubusercontent.com/Celeter/build/master/.github/scripts/API_lanzou.py') - with open(os.environ["FILEPATH"], 'wb') as f: + with open(os.environ["FILE_PATH"], 'wb') as f: f.write(res.content) env: - FILEPATH: ${{ github.workspace }}/.github/lzy.py + FILE_PATH: ${{ github.workspace }}/.github/lzy.py - name: Upload App To Lanzou if: ${{ env.LANZOU_PSD }} run: python $GITHUB_WORKSPACE/.github/lzy.py From 61b13a70c32c77ef7bba4088cdec9e85c7c3aee0 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 29 Dec 2020 20:26:12 +0800 Subject: [PATCH 24/68] =?UTF-8?q?=E8=8F=9C=E5=8D=95=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E4=B9=A6=E5=8D=95=E5=AF=BC=E5=85=A5=E4=B9=A6?= =?UTF-8?q?=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/menu/main_bookshelf.xml | 19 +++++++++++++++++-- app/src/main/res/values-zh-rHK/strings.xml | 2 ++ app/src/main/res/values-zh-rTW/strings.xml | 2 ++ app/src/main/res/values-zh/strings.xml | 2 ++ app/src/main/res/values/strings.xml | 2 ++ 5 files changed, 25 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/menu/main_bookshelf.xml b/app/src/main/res/menu/main_bookshelf.xml index 9dc1ebf5c..78d754fcc 100644 --- a/app/src/main/res/menu/main_bookshelf.xml +++ b/app/src/main/res/menu/main_bookshelf.xml @@ -1,12 +1,14 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + tools:ignore="AlwaysShowAction"> + app:showAsAction="always" /> + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index bc5b42e2e..44ad0524b 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -795,5 +795,7 @@ 进入退出阅读界面时同步阅读进度 创建书签失败 单URL + 导出书单 + 导入书单 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index b68dbdc72..04601c9a6 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -796,5 +796,7 @@ 進入退出閱讀介面時同步閱讀進度 创建书签失败 单URL + 导出书单 + 导入书单 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 6eda0ea3d..e42728e52 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -799,5 +799,7 @@ 进入退出阅读界面时同步阅读进度 创建书签失败 单URL + 导出书单 + 导入书单 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9a698af4b..70fa7277b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -802,5 +802,7 @@ 进入退出阅读界面时同步阅读进度 创建书签失败 单URL + 导出书单 + 导入书单 From d241fd410d719c19c8e2c7e34ea2a0163af38ab6 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 29 Dec 2020 20:40:06 +0800 Subject: [PATCH 25/68] =?UTF-8?q?=E6=96=B0=E7=89=88=E6=9C=AC=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=9B=B4=E6=96=B0=E5=9C=A8=E7=BA=BF=E6=9C=97=E8=AF=BB?= =?UTF-8?q?=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/help/DefaultData.kt | 6 ++++++ app/src/main/java/io/legado/app/help/LocalConfig.kt | 6 ++++++ .../app/ui/book/read/config/SpeakEngineViewModel.kt | 4 +--- app/src/main/java/io/legado/app/ui/main/MainViewModel.kt | 8 +++++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/DefaultData.kt b/app/src/main/java/io/legado/app/help/DefaultData.kt index db14e1f29..b9708ba91 100644 --- a/app/src/main/java/io/legado/app/help/DefaultData.kt +++ b/app/src/main/java/io/legado/app/help/DefaultData.kt @@ -45,6 +45,12 @@ object DefaultData { GSON.fromJsonArray(json)!! } + fun importDefaultHttpTTS() { + httpTTS.let { + App.db.httpTTSDao.insert(*it.toTypedArray()) + } + } + fun importDefaultTocRules() { App.db.txtTocRule.deleteDefault() txtTocRules.let { diff --git a/app/src/main/java/io/legado/app/help/LocalConfig.kt b/app/src/main/java/io/legado/app/help/LocalConfig.kt index 084113293..ac0d3034d 100644 --- a/app/src/main/java/io/legado/app/help/LocalConfig.kt +++ b/app/src/main/java/io/legado/app/help/LocalConfig.kt @@ -63,4 +63,10 @@ object LocalConfig { val ruleHelpVersionIsLast: Boolean get() = isLastVersion(1, "ruleHelpVersion") + + val hasUpHttpTTS: Boolean + get() = isLastVersion(1, "httpTtsVersion") + + val hasUpTxtTocRule: Boolean + get() = isLastVersion(1, "txtTocRuleVersion") } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt index b72f65343..bfcb8ae2b 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt @@ -14,9 +14,7 @@ class SpeakEngineViewModel(application: Application) : BaseViewModel(application fun importDefault() { execute { - DefaultData.httpTTS.let { - App.db.httpTTSDao.insert(*it.toTypedArray()) - } + DefaultData.importDefaultHttpTTS() } } diff --git a/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt b/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt index 239b0c9ff..242e94baa 100644 --- a/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt @@ -9,6 +9,7 @@ import io.legado.app.data.entities.Book import io.legado.app.help.AppConfig import io.legado.app.help.BookHelp import io.legado.app.help.DefaultData +import io.legado.app.help.LocalConfig import io.legado.app.model.webBook.WebBook import io.legado.app.service.help.CacheBook import io.legado.app.utils.FileUtils @@ -148,7 +149,12 @@ class MainViewModel(application: Application) : BaseViewModel(application) { fun upVersion() { execute { - DefaultData.importDefaultTocRules() + if (LocalConfig.hasUpHttpTTS) { + DefaultData.importDefaultHttpTTS() + } + if (LocalConfig.hasUpTxtTocRule) { + DefaultData.importDefaultTocRules() + } } } } \ No newline at end of file From fe2c89179fc8f7b7d75d9e66d1d28f702a4059ee Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 29 Dec 2020 20:51:24 +0800 Subject: [PATCH 26/68] =?UTF-8?q?=E9=BB=98=E8=AE=A4=E8=A7=84=E5=88=99id?= =?UTF-8?q?=E5=B0=8F=E4=BA=8E0=E6=96=B9=E4=BE=BF=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=97=B6=E5=88=A0=E9=99=A4=E6=97=A7=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/defaultData/httpTTS.json | 56 +++++++++---------- .../java/io/legado/app/data/dao/HttpTTSDao.kt | 2 + .../java/io/legado/app/help/DefaultData.kt | 1 + 3 files changed, 31 insertions(+), 28 deletions(-) diff --git a/app/src/main/assets/defaultData/httpTTS.json b/app/src/main/assets/defaultData/httpTTS.json index 8f12b739a..b62ea90e5 100644 --- a/app/src/main/assets/defaultData/httpTTS.json +++ b/app/src/main/assets/defaultData/httpTTS.json @@ -1,141 +1,141 @@ [ { - "id": 1598233029336, + "id": -1, "name": "度丫丫", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029337, + "id": -2, "name": "度博文①", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029338, + "id": -3, "name": "度博文②", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029339, + "id": -4, "name": "度博文③", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029340, + "id": -5, "name": "度小娇", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029341, + "id": -6, "name": "度小宇", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=1&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029342, + "id": -7, "name": "度小童", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=110&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029343, + "id": -8, "name": "度小美", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=0&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029344, + "id": -9, "name": "度小萌", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=111&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029345, + "id": -10, "name": "度小鹿①", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4118&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029346, + "id": -11, "name": "度小鹿②", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5118&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029347, + "id": -12, "name": "度小鹿③", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4119&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029348, + "id": -13, "name": "度米朵①", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029349, + "id": -14, "name": "度米朵②", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029350, + "id": -15, "name": "度逍遥-基础", "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=3&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029351, + "id": -16, "name": "度逍遥-精品①", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029352, + "id": -17, "name": "度逍遥-精品②", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029353, + "id": -18, "name": "情感女声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4105&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029354, + "id": -19, "name": "情感男声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4115&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029355, + "id": -20, "name": "标准女声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4100&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029356, + "id": -21, "name": "标准男声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4121&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029357, + "id": -22, "name": "治愈女声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5120&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029358, + "id": -23, "name": "治愈男声", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5121&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029359, + "id": -24, "name": "甜美女声①", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029360, + "id": -25, "name": "甜美女声②", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=5117&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029361, + "id": -26, "name": "百度主持", "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=9&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029362, + "id": -27, "name": "百度评书①", "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=6&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 1598233029363, + "id": -28, "name": "百度评书②", "url": "http://tsn.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{(speakSpeed + 5) / 10 + 4}}&per=4114&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" } diff --git a/app/src/main/java/io/legado/app/data/dao/HttpTTSDao.kt b/app/src/main/java/io/legado/app/data/dao/HttpTTSDao.kt index f71169bb1..f97c17af1 100644 --- a/app/src/main/java/io/legado/app/data/dao/HttpTTSDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/HttpTTSDao.kt @@ -28,4 +28,6 @@ interface HttpTTSDao { @Update fun update(vararg httpTTS: HttpTTS) + @Query("delete from httpTTS where id < 0") + fun deleteDefault() } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/DefaultData.kt b/app/src/main/java/io/legado/app/help/DefaultData.kt index b9708ba91..d2bab07f1 100644 --- a/app/src/main/java/io/legado/app/help/DefaultData.kt +++ b/app/src/main/java/io/legado/app/help/DefaultData.kt @@ -46,6 +46,7 @@ object DefaultData { } fun importDefaultHttpTTS() { + App.db.httpTTSDao.deleteDefault() httpTTS.let { App.db.httpTTSDao.insert(*it.toTypedArray()) } From 7f1eaa7386d613fa2753fdffd5127c0cd014b1ad Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 29 Dec 2020 21:06:40 +0800 Subject: [PATCH 27/68] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 3 ++- .../io/legado/app/ui/book/read/config/SpeakEngineDialog.kt | 2 -- .../io/legado/app/ui/book/source/manage/BookSourceActivity.kt | 2 -- .../io/legado/app/ui/rss/source/manage/RssSourceActivity.kt | 2 -- app/src/main/res/layout/activity_book_source.xml | 3 ++- app/src/main/res/layout/activity_rss_source.xml | 3 ++- app/src/main/res/layout/dialog_recycler_view.xml | 3 ++- 7 files changed, 8 insertions(+), 10 deletions(-) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 5af6a8d74..0e616d639 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -3,8 +3,9 @@ * 关注合作公众号 **[小说拾遗]** 获取好看的小说。 * 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 -**2020/12/28** +**2020/12/29** * 解决文件下载异常,在线语音可正常播放 by [Celeter](https://github.com/Celeter) +* 更新默认在线朗读库, 默认id小于0方便下次更新时删除旧数据, 有重复的自己删除 **2020/12/27** * 订阅添加搜索和分组 diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt index 542853559..ab5219b82 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt @@ -9,7 +9,6 @@ import android.view.View import android.view.ViewGroup import androidx.appcompat.widget.Toolbar import androidx.lifecycle.LiveData -import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.App import io.legado.app.R import io.legado.app.base.BaseDialogFragment @@ -59,7 +58,6 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener private fun initView() = with(binding) { toolBar.setBackgroundColor(primaryColor) toolBar.setTitle(R.string.speak_engine) - recyclerView.layoutManager = LinearLayoutManager(requireContext()) adapter = Adapter(requireContext()) recyclerView.adapter = adapter tvFooterLeft.setText(R.string.local_tts) diff --git a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt index c14809aaf..86e99b361 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt @@ -12,7 +12,6 @@ import androidx.appcompat.widget.SearchView import androidx.documentfile.provider.DocumentFile import androidx.lifecycle.LiveData import androidx.recyclerview.widget.ItemTouchHelper -import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.snackbar.Snackbar import io.legado.app.App import io.legado.app.R @@ -147,7 +146,6 @@ class BookSourceActivity : VMBaseActivity + android:layout_height="match_parent" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> diff --git a/app/src/main/res/layout/activity_rss_source.xml b/app/src/main/res/layout/activity_rss_source.xml index 527a9444f..703eea64f 100644 --- a/app/src/main/res/layout/activity_rss_source.xml +++ b/app/src/main/res/layout/activity_rss_source.xml @@ -22,7 +22,8 @@ + android:layout_height="match_parent" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> diff --git a/app/src/main/res/layout/dialog_recycler_view.xml b/app/src/main/res/layout/dialog_recycler_view.xml index 34ba05c5f..29d018cea 100644 --- a/app/src/main/res/layout/dialog_recycler_view.xml +++ b/app/src/main/res/layout/dialog_recycler_view.xml @@ -22,7 +22,8 @@ + android:layout_height="match_parent" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> From a5a6eda39af6e679a010218564b5885fda86a4ba Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 29 Dec 2020 21:12:38 +0800 Subject: [PATCH 28/68] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/item_http_tts.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/res/layout/item_http_tts.xml b/app/src/main/res/layout/item_http_tts.xml index fae2a3bcc..6a65d5827 100644 --- a/app/src/main/res/layout/item_http_tts.xml +++ b/app/src/main/res/layout/item_http_tts.xml @@ -34,4 +34,9 @@ android:src="@drawable/ic_clear_all" android:tint="@color/primaryText" tools:ignore="RtlHardcoded" /> + + + \ No newline at end of file From 6ed918f9ada2cc827cabae19d260a4896dade27c Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 29 Dec 2020 21:14:09 +0800 Subject: [PATCH 29/68] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/ui/book/read/config/SpeakEngineDialog.kt | 2 ++ app/src/main/res/layout/dialog_recycler_view.xml | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt index ab5219b82..fb58e12a0 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt @@ -9,6 +9,7 @@ import android.view.View import android.view.ViewGroup import androidx.appcompat.widget.Toolbar import androidx.lifecycle.LiveData +import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.App import io.legado.app.R import io.legado.app.base.BaseDialogFragment @@ -59,6 +60,7 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener toolBar.setBackgroundColor(primaryColor) toolBar.setTitle(R.string.speak_engine) adapter = Adapter(requireContext()) + recyclerView.layoutManager = LinearLayoutManager(requireContext()) recyclerView.adapter = adapter tvFooterLeft.setText(R.string.local_tts) tvFooterLeft.visible() diff --git a/app/src/main/res/layout/dialog_recycler_view.xml b/app/src/main/res/layout/dialog_recycler_view.xml index 29d018cea..34ba05c5f 100644 --- a/app/src/main/res/layout/dialog_recycler_view.xml +++ b/app/src/main/res/layout/dialog_recycler_view.xml @@ -22,8 +22,7 @@ + android:layout_height="match_parent" /> From acc459cbb32aafee24415fd7b74c95ae5cbbfe4a Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 29 Dec 2020 21:42:18 +0800 Subject: [PATCH 30/68] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/book/read/config/SpeakEngineDialog.kt | 4 +++- app/src/main/res/layout/dialog_recycler_view.xml | 13 +++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt index fb58e12a0..2c807a279 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt @@ -21,6 +21,7 @@ import io.legado.app.databinding.DialogHttpTtsEditBinding import io.legado.app.databinding.DialogRecyclerViewBinding import io.legado.app.databinding.ItemHttpTtsBinding import io.legado.app.lib.dialogs.alert +import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.primaryColor import io.legado.app.service.help.ReadAloud import io.legado.app.ui.widget.dialog.TextDialog @@ -59,8 +60,9 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener private fun initView() = with(binding) { toolBar.setBackgroundColor(primaryColor) toolBar.setTitle(R.string.speak_engine) - adapter = Adapter(requireContext()) + ATH.applyEdgeEffectColor(recyclerView) recyclerView.layoutManager = LinearLayoutManager(requireContext()) + adapter = Adapter(requireContext()) recyclerView.adapter = adapter tvFooterLeft.setText(R.string.local_tts) tvFooterLeft.visible() diff --git a/app/src/main/res/layout/dialog_recycler_view.xml b/app/src/main/res/layout/dialog_recycler_view.xml index 34ba05c5f..2fcee5249 100644 --- a/app/src/main/res/layout/dialog_recycler_view.xml +++ b/app/src/main/res/layout/dialog_recycler_view.xml @@ -1,18 +1,18 @@ + android:layout_height="match_parent" + android:orientation="vertical"> + app:popupTheme="@style/AppTheme.PopupOverlay" + app:titleTextAppearance="@style/ToolbarTitle" /> + android:layout_height="match_parent" + android:scrollbars="none" /> From 14fb5dc1ac12e759fb2f7bf089275603bfb7d526 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 29 Dec 2020 22:22:09 +0800 Subject: [PATCH 31/68] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../legado/app/ui/main/bookshelf/BookshelfFragment.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt index fd4f39ee4..58a11e2c6 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt @@ -86,6 +86,17 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b Pair("groupId", selectedGroup?.groupId ?: 0), Pair("groupName", selectedGroup?.groupName ?: 0) ) + R.id.menu_export_bookshelf -> { + val group = bookGroups[tabLayout.selectedTabPosition] + val fragment = fragmentMap[group.groupId] + fragment?.getBooks()?.let { + + } + } + R.id.menu_import_bookshelf -> { + val group = bookGroups[tabLayout.selectedTabPosition] + + } } } From c7ac4e74c4d35f37e5ba22eaece42023a4522fa8 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 30 Dec 2020 10:06:19 +0800 Subject: [PATCH 32/68] =?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/base/adapter/RecyclerAdapter.kt | 33 ++++++++++++- .../book/source/manage/BookSourceActivity.kt | 2 +- .../book/source/manage/BookSourceAdapter.kt | 46 +++++++++++++++++++ .../ui/rss/source/manage/RssSourceActivity.kt | 2 +- .../ui/rss/source/manage/RssSourceAdapter.kt | 32 +++++++++++++ 5 files changed, 112 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt b/app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt index 1f374acdf..c2882c048 100644 --- a/app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt +++ b/app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt @@ -98,8 +98,39 @@ abstract class RecyclerAdapter(protected val context: Co } @Synchronized - fun setItems(items: List?, diffResult: DiffUtil.DiffResult) { + fun setItems(items: List?, itemCallback: DiffUtil.ItemCallback) { kotlin.runCatching { + val callback = object : DiffUtil.Callback() { + override fun getOldListSize(): Int { + return itemCount + } + + override fun getNewListSize(): Int { + return items?.size ?: 0 + } + + override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { + val oldItem = getItem(oldItemPosition) ?: return false + val newItem = items?.getOrNull(newItemPosition) ?: return false + return itemCallback.areItemsTheSame(oldItem, newItem) + } + + override fun areContentsTheSame( + oldItemPosition: Int, + newItemPosition: Int + ): Boolean { + val oldItem = getItem(oldItemPosition) ?: return false + val newItem = items?.getOrNull(newItemPosition) ?: return false + return itemCallback.areContentsTheSame(oldItem, newItem) + } + + override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? { + val oldItem = getItem(oldItemPosition) ?: return null + val newItem = items?.getOrNull(newItemPosition) ?: return null + return itemCallback.getChangePayload(oldItem, newItem) + } + } + val diffResult = DiffUtil.calculateDiff(callback) if (this.items.isNotEmpty()) { this.items.clear() } diff --git a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt index 86e99b361..38c138482 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt @@ -204,7 +204,7 @@ class BookSourceActivity : VMBaseActivity data.sortedBy { it.lastUpdateTime } else -> data.reversed() } - adapter.setItems(sourceList) + adapter.setItems(sourceList, adapter.diffItemCallback) }) } diff --git a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceAdapter.kt b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceAdapter.kt index 55f179023..1545a3108 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceAdapter.kt @@ -8,6 +8,7 @@ import android.view.ViewGroup import android.widget.ImageView import android.widget.PopupMenu import androidx.core.os.bundleOf +import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import io.legado.app.R import io.legado.app.base.adapter.ItemViewHolder @@ -27,6 +28,51 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) : private val selected = linkedSetOf() + val diffItemCallback: DiffUtil.ItemCallback + get() = object : DiffUtil.ItemCallback() { + + override fun areItemsTheSame(oldItem: BookSource, newItem: BookSource): Boolean { + return oldItem.bookSourceUrl == newItem.bookSourceUrl + } + + override fun areContentsTheSame(oldItem: BookSource, newItem: BookSource): Boolean { + if (oldItem.bookSourceName != newItem.bookSourceName) + return false + if (oldItem.bookSourceGroup != newItem.bookSourceGroup) + return false + if (oldItem.enabled != newItem.enabled) + return false + if (oldItem.enabledExplore != newItem.enabledExplore + || oldItem.exploreUrl != newItem.exploreUrl + ) { + return false + } + return true + } + + override fun getChangePayload(oldItem: BookSource, newItem: BookSource): Any? { + val payload = Bundle() + if (oldItem.bookSourceName != newItem.bookSourceName) { + payload.putString("name", newItem.bookSourceName) + } + if (oldItem.bookSourceGroup != newItem.bookSourceGroup) { + payload.putString("group", newItem.bookSourceGroup) + } + if (oldItem.enabled != newItem.enabled) { + payload.putBoolean("enabled", newItem.enabled) + } + if (oldItem.enabledExplore != newItem.enabledExplore + || oldItem.exploreUrl != newItem.exploreUrl + ) { + payload.putBoolean("showExplore", true) + } + if (payload.isEmpty) { + return null + } + return payload + } + } + override fun getViewBinding(parent: ViewGroup): ItemBookSourceBinding { return ItemBookSourceBinding.inflate(inflater, parent, false) } diff --git a/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt b/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt index 0edd9304a..e6db8c73e 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt @@ -206,7 +206,7 @@ class RssSourceActivity : VMBaseActivity() + val diffItemCallback: DiffUtil.ItemCallback + get() = object : DiffUtil.ItemCallback() { + + override fun areItemsTheSame(oldItem: RssSource, newItem: RssSource): Boolean { + return oldItem.sourceUrl == newItem.sourceUrl + } + + override fun areContentsTheSame(oldItem: RssSource, newItem: RssSource): Boolean { + return oldItem.sourceName == newItem.sourceName + && oldItem.sourceGroup == newItem.sourceGroup + && oldItem.enabled == newItem.enabled + } + + override fun getChangePayload(oldItem: RssSource, newItem: RssSource): Any? { + val payload = Bundle() + if (oldItem.sourceName != newItem.sourceName) { + payload.putString("name", newItem.sourceName) + } + if (oldItem.sourceGroup != newItem.sourceGroup) { + payload.putString("group", newItem.sourceGroup) + } + if (oldItem.enabled != newItem.enabled) { + payload.putBoolean("enabled", newItem.enabled) + } + if (payload.isEmpty) { + return null + } + return payload + } + } + override fun getViewBinding(parent: ViewGroup): ItemRssSourceBinding { return ItemRssSourceBinding.inflate(inflater, parent, false) } From 00ede1036280f6aef6c6bd4d4833cfd8db62dfb8 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 30 Dec 2020 10:17:49 +0800 Subject: [PATCH 33/68] =?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/base/adapter/RecyclerAdapter.kt | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt b/app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt index c2882c048..0d6e3b668 100644 --- a/app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt +++ b/app/src/main/java/io/legado/app/base/adapter/RecyclerAdapter.kt @@ -106,12 +106,14 @@ abstract class RecyclerAdapter(protected val context: Co } override fun getNewListSize(): Int { - return items?.size ?: 0 + return (items?.size ?: 0) + getHeaderCount() + getFooterCount() } override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { - val oldItem = getItem(oldItemPosition) ?: return false - val newItem = items?.getOrNull(newItemPosition) ?: return false + val oldItem = getItem(oldItemPosition - getHeaderCount()) + ?: return true + val newItem = items?.getOrNull(newItemPosition - getHeaderCount()) + ?: return true return itemCallback.areItemsTheSame(oldItem, newItem) } @@ -119,14 +121,18 @@ abstract class RecyclerAdapter(protected val context: Co oldItemPosition: Int, newItemPosition: Int ): Boolean { - val oldItem = getItem(oldItemPosition) ?: return false - val newItem = items?.getOrNull(newItemPosition) ?: return false + val oldItem = getItem(oldItemPosition - getHeaderCount()) + ?: return true + val newItem = items?.getOrNull(newItemPosition - getHeaderCount()) + ?: return true return itemCallback.areContentsTheSame(oldItem, newItem) } override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? { - val oldItem = getItem(oldItemPosition) ?: return null - val newItem = items?.getOrNull(newItemPosition) ?: return null + val oldItem = getItem(oldItemPosition - getHeaderCount()) + ?: return null + val newItem = items?.getOrNull(newItemPosition - getHeaderCount()) + ?: return null return itemCallback.getChangePayload(oldItem, newItem) } } From b83034bc0b093b767dbe67773fe33e5a682db87f Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 30 Dec 2020 14:05:16 +0800 Subject: [PATCH 34/68] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/main/bookshelf/BookshelfFragment.kt | 76 ++++++++++++++----- .../ui/main/bookshelf/BookshelfViewModel.kt | 57 +++++++++++++- 2 files changed, 113 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt index 58a11e2c6..300ba646d 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt @@ -1,6 +1,8 @@ package io.legado.app.ui.main.bookshelf import android.annotation.SuppressLint +import android.app.Activity.RESULT_OK +import android.content.Intent import android.os.Bundle import android.view.Menu import android.view.MenuItem @@ -29,17 +31,23 @@ import io.legado.app.ui.book.cache.CacheActivity import io.legado.app.ui.book.group.GroupManageDialog import io.legado.app.ui.book.local.ImportBookActivity import io.legado.app.ui.book.search.SearchActivity +import io.legado.app.ui.filepicker.FilePicker +import io.legado.app.ui.filepicker.FilePickerDialog import io.legado.app.ui.main.MainViewModel import io.legado.app.ui.main.bookshelf.books.BooksFragment import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding +import org.jetbrains.anko.share /** * 书架界面 */ class BookshelfFragment : VMBaseFragment(R.layout.fragment_bookshelf), TabLayout.OnTabSelectedListener, + FilePickerDialog.CallBack, SearchView.OnQueryTextListener { + + private val requestCodeImportBookshelf = 312 private val binding by viewBinding(FragmentBookshelfBinding::bind) override val viewModel: BookshelfViewModel get() = getViewModel(BookshelfViewModel::class.java) @@ -67,8 +75,7 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b when (item.itemId) { R.id.menu_search -> startActivity() R.id.menu_update_toc -> { - val group = bookGroups[tabLayout.selectedTabPosition] - val fragment = fragmentMap[group.groupId] + val fragment = fragmentMap[selectedGroup.groupId] fragment?.getBooks()?.let { activityViewModel.upToc(it) } @@ -79,29 +86,25 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b R.id.menu_add_local -> startActivity() R.id.menu_add_url -> addBookByUrl() R.id.menu_arrange_bookshelf -> startActivity( - Pair("groupId", selectedGroup?.groupId ?: 0), - Pair("groupName", selectedGroup?.groupName ?: 0) + Pair("groupId", selectedGroup.groupId ?: 0), + Pair("groupName", selectedGroup.groupName ?: 0) ) R.id.menu_download -> startActivity( - Pair("groupId", selectedGroup?.groupId ?: 0), - Pair("groupName", selectedGroup?.groupName ?: 0) + Pair("groupId", selectedGroup.groupId ?: 0), + Pair("groupName", selectedGroup.groupName ?: 0) ) R.id.menu_export_bookshelf -> { - val group = bookGroups[tabLayout.selectedTabPosition] - val fragment = fragmentMap[group.groupId] - fragment?.getBooks()?.let { - + val fragment = fragmentMap[selectedGroup.groupId] + viewModel.exportBookshelf(fragment?.getBooks()) { + activity?.share(it) } } - R.id.menu_import_bookshelf -> { - val group = bookGroups[tabLayout.selectedTabPosition] - - } + R.id.menu_import_bookshelf -> importBookshelfAlert() } } - private val selectedGroup: BookGroup? - get() = bookGroups.getOrNull(binding.viewPagerBookshelf.currentItem) + private val selectedGroup: BookGroup + get() = bookGroups[tabLayout.selectedTabPosition] private fun initView() { ATH.applyEdgeEffectColor(binding.viewPagerBookshelf) @@ -201,8 +204,8 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b } override fun onTabReselected(tab: TabLayout.Tab) { - fragmentMap[selectedGroup?.groupId]?.let { - toast("${selectedGroup?.groupName}(${it.getBooksCount()})") + fragmentMap[selectedGroup.groupId]?.let { + toast("${selectedGroup.groupName}(${it.getBooksCount()})") } } @@ -213,7 +216,42 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b } fun gotoTop() { - fragmentMap[selectedGroup?.groupId]?.gotoTop() + fragmentMap[selectedGroup.groupId]?.gotoTop() + } + + private fun importBookshelfAlert() { + alert(titleResource = R.string.import_bookshelf) { + val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { + editView.hint = "url/json" + } + customView = alertBinding.root + okButton { + alertBinding.editView.text?.toString()?.let { + viewModel.importBookshelf(it, selectedGroup.groupId) + } + } + noButton() + neutralButton(R.string.select_file) { + FilePicker.selectFile( + this@BookshelfFragment, + requestCodeImportBookshelf, + allowExtensions = arrayOf("txt", "json") + ) + } + }.show() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + when (requestCode) { + requestCodeImportBookshelf -> if (resultCode == RESULT_OK) { + data?.data?.let { uri -> + uri.readText(requireContext())?.let { + viewModel.importBookshelf(it, selectedGroup.groupId) + } + } + } + } } private inner class TabFragmentPageAdapter(fm: FragmentManager) : diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt index 0e159277c..1d26c7159 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt @@ -8,8 +8,10 @@ import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookGroup import io.legado.app.data.entities.BookSource import io.legado.app.model.webBook.WebBook -import io.legado.app.utils.NetworkUtils +import io.legado.app.utils.* import kotlinx.coroutines.Dispatchers.IO +import rxhttp.wrapper.param.RxHttp +import rxhttp.wrapper.param.toText class BookshelfViewModel(application: Application) : BaseViewModel(application) { @@ -62,6 +64,59 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application) } } + fun exportBookshelf(books: List?, success: (json: String) -> Unit) { + execute { + val exportList = arrayListOf>() + books?.forEach { + val bookMap = hashMapOf() + bookMap["name"] = it.name + bookMap["author"] = it.author + bookMap["bookUrl"] = it.bookUrl + bookMap["tocUrl"] = it.tocUrl + bookMap["kind"] = it.kind + bookMap["intro"] = it.getDisplayIntro() + bookMap["origin"] = it.origin + bookMap["originName"] = it.originName + exportList.add(bookMap) + } + GSON.toJson(exportList) + }.onSuccess { + success(it) + } + } + + fun importBookshelf(str: String, groupId: Long) { + execute { + val text = str.trim() + if (text.isAbsUrl()) { + RxHttp.get(text).toText().await().let { + importBookshelf(it, groupId) + } + } else if (text.isJsonArray()) { + GSON.fromJsonArray>(text)?.forEach { + val book = Book( + bookUrl = it["bookUrl"] ?: "", + name = it["name"] ?: "", + author = it["author"] ?: "", + tocUrl = it["tocUrl"] ?: "", + kind = it["kind"], + intro = it["intro"] ?: "", + origin = it["origin"] ?: "", + originName = it["originName"] ?: "" + ) + if (groupId > 0) { + book.group = groupId + } + App.db.bookDao.insert(book) + } + } else { + throw Exception("格式不对") + } + }.onError { + toast(it.localizedMessage ?: "ERROR") + } + } + fun checkGroup(groups: List) { groups.forEach { group -> if (group.groupId >= 0 && group.groupId and (group.groupId - 1) != 0L) { From 0d75a58445cb0b8fd43250074b9cf27bd2db3e9b Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 30 Dec 2020 16:09:10 +0800 Subject: [PATCH 35/68] =?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/updateLog.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 0e616d639..16618ce76 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -3,9 +3,10 @@ * 关注合作公众号 **[小说拾遗]** 获取好看的小说。 * 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 -**2020/12/29** +**2020/12/30** * 解决文件下载异常,在线语音可正常播放 by [Celeter](https://github.com/Celeter) * 更新默认在线朗读库, 默认id小于0方便下次更新时删除旧数据, 有重复的自己删除 +* 导入导出书单 **2020/12/27** * 订阅添加搜索和分组 From f954dd20b90294d27accc0c08db5be892e716bca Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 30 Dec 2020 16:56:22 +0800 Subject: [PATCH 36/68] =?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/updateLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 16618ce76..8c5e0c693 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -7,6 +7,7 @@ * 解决文件下载异常,在线语音可正常播放 by [Celeter](https://github.com/Celeter) * 更新默认在线朗读库, 默认id小于0方便下次更新时删除旧数据, 有重复的自己删除 * 导入导出书单 +* 其它一些优化 **2020/12/27** * 订阅添加搜索和分组 From c43b9b2b07fbbd1f887d7a2bbdfb356f7c94633b Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 30 Dec 2020 17:03:36 +0800 Subject: [PATCH 37/68] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/main/bookshelf/BookshelfViewModel.kt | 48 +++++++++++-------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt index 1d26c7159..d8ec442ad 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt @@ -72,6 +72,7 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application) bookMap["name"] = it.name bookMap["author"] = it.author bookMap["bookUrl"] = it.bookUrl + bookMap["coverUrl"] = it.coverUrl bookMap["tocUrl"] = it.tocUrl bookMap["kind"] = it.kind bookMap["intro"] = it.getDisplayIntro() @@ -88,29 +89,36 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application) fun importBookshelf(str: String, groupId: Long) { execute { val text = str.trim() - if (text.isAbsUrl()) { - RxHttp.get(text).toText().await().let { - importBookshelf(it, groupId) + when { + text.isAbsUrl() -> { + RxHttp.get(text).toText().await().let { + importBookshelf(it, groupId) + } } - } else if (text.isJsonArray()) { - GSON.fromJsonArray>(text)?.forEach { - val book = Book( - bookUrl = it["bookUrl"] ?: "", - name = it["name"] ?: "", - author = it["author"] ?: "", - tocUrl = it["tocUrl"] ?: "", - kind = it["kind"], - intro = it["intro"] ?: "", - origin = it["origin"] ?: "", - originName = it["originName"] ?: "" - ) - if (groupId > 0) { - book.group = groupId + text.isJsonArray() -> { + GSON.fromJsonArray>(text)?.forEach { + val book = Book( + bookUrl = it["bookUrl"] ?: "", + name = it["name"] ?: "", + author = it["author"] ?: "", + coverUrl = it["coverUrl"], + tocUrl = it["tocUrl"] ?: "", + kind = it["kind"], + intro = it["intro"] ?: "", + origin = it["origin"] ?: "", + originName = it["originName"] ?: "" + ) + if (groupId > 0) { + book.group = groupId + } + if (App.db.bookDao.getBook(book.name, book.author) == null) { + App.db.bookDao.insert(book) + } } - App.db.bookDao.insert(book) } - } else { - throw Exception("格式不对") + else -> { + throw Exception("格式不对") + } } }.onError { toast(it.localizedMessage ?: "ERROR") From 9f1fdf048c1cca653ad44d3410a85e8bff2986b0 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 30 Dec 2020 17:08:49 +0800 Subject: [PATCH 38/68] =?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/ui/replace/DiffCallBack.kt | 42 ------------------- .../app/ui/replace/ReplaceRuleActivity.kt | 2 +- .../app/ui/replace/ReplaceRuleAdapter.kt | 38 +++++++++++++++++ 3 files changed, 39 insertions(+), 43 deletions(-) delete mode 100644 app/src/main/java/io/legado/app/ui/replace/DiffCallBack.kt diff --git a/app/src/main/java/io/legado/app/ui/replace/DiffCallBack.kt b/app/src/main/java/io/legado/app/ui/replace/DiffCallBack.kt deleted file mode 100644 index ea58a1fa4..000000000 --- a/app/src/main/java/io/legado/app/ui/replace/DiffCallBack.kt +++ /dev/null @@ -1,42 +0,0 @@ -package io.legado.app.ui.replace - -import android.os.Bundle -import androidx.recyclerview.widget.DiffUtil -import io.legado.app.data.entities.ReplaceRule - -class DiffCallBack : DiffUtil.ItemCallback() { - - override fun areItemsTheSame(oldItem: ReplaceRule, newItem: ReplaceRule): Boolean { - return oldItem.id == newItem.id - } - - override fun areContentsTheSame(oldItem: ReplaceRule, newItem: ReplaceRule): Boolean { - if (oldItem.name != newItem.name) { - return false - } - if (oldItem.group != newItem.group) { - return false - } - if (oldItem.isEnabled != newItem.isEnabled) { - return false - } - return true - } - - override fun getChangePayload(oldItem: ReplaceRule, newItem: ReplaceRule): Any? { - val payload = Bundle() - if (oldItem.name != newItem.name) { - payload.putString("name", newItem.name) - } - if (oldItem.group != newItem.group) { - payload.putString("group", newItem.group) - } - if (oldItem.isEnabled != newItem.isEnabled) { - payload.putBoolean("enabled", newItem.isEnabled) - } - if (payload.isEmpty) { - return null - } - return payload - } -} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt b/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt index e8da27023..118992269 100644 --- a/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt +++ b/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt @@ -152,7 +152,7 @@ class ReplaceRuleActivity : VMBaseActivity() + val diffItemCallBack = object : DiffUtil.ItemCallback() { + + override fun areItemsTheSame(oldItem: ReplaceRule, newItem: ReplaceRule): Boolean { + return oldItem.id == newItem.id + } + + override fun areContentsTheSame(oldItem: ReplaceRule, newItem: ReplaceRule): Boolean { + if (oldItem.name != newItem.name) { + return false + } + if (oldItem.group != newItem.group) { + return false + } + if (oldItem.isEnabled != newItem.isEnabled) { + return false + } + return true + } + + override fun getChangePayload(oldItem: ReplaceRule, newItem: ReplaceRule): Any? { + val payload = Bundle() + if (oldItem.name != newItem.name) { + payload.putString("name", newItem.name) + } + if (oldItem.group != newItem.group) { + payload.putString("group", newItem.group) + } + if (oldItem.isEnabled != newItem.isEnabled) { + payload.putBoolean("enabled", newItem.isEnabled) + } + if (payload.isEmpty) { + return null + } + return payload + } + } + fun selectAll() { getItems().forEach { selected.add(it) From 829f4dc164673d41f195714bfff29060f853e4ef Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 30 Dec 2020 20:51:27 +0800 Subject: [PATCH 39/68] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../legado/app/ui/book/read/ReadBookActivity.kt | 16 ++++++++++++++++ app/src/main/res/menu/book_read.xml | 5 +++++ 2 files changed, 21 insertions(+) diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt index f2cd19baa..926bc8d1e 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt @@ -21,6 +21,7 @@ import io.legado.app.constant.Status import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookProgress +import io.legado.app.data.entities.Bookmark import io.legado.app.help.ReadBookConfig import io.legado.app.help.ReadTipConfig import io.legado.app.help.storage.Backup @@ -204,6 +205,21 @@ class ReadBookActivity : ReadBookBaseActivity(), } } R.id.menu_download -> showDownloadDialog() + R.id.menu_add_bookmark -> { + val book = ReadBook.book + val page = ReadBook.curTextChapter?.page(ReadBook.durPageIndex()) + if (book != null && page != null) { + val bookmark = Bookmark( + bookUrl = book.bookUrl, + bookName = book.name, + chapterIndex = ReadBook.durChapterIndex, + chapterPos = ReadBook.durChapterPos, + chapterName = page.title, + bookText = page.text + ) + showBookMark(bookmark) + } + } R.id.menu_copy_text -> TextDialog.show(supportFragmentManager, ReadBook.curTextChapter?.getContent()) R.id.menu_update_toc -> ReadBook.book?.let { diff --git a/app/src/main/res/menu/book_read.xml b/app/src/main/res/menu/book_read.xml index d7bb23caf..f35b5b901 100644 --- a/app/src/main/res/menu/book_read.xml +++ b/app/src/main/res/menu/book_read.xml @@ -44,6 +44,11 @@ + + Date: Wed, 30 Dec 2020 21:27:46 +0800 Subject: [PATCH 40/68] =?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/read/ReadBookActivity.kt | 2 +- .../app/ui/book/read/ReadBookBaseActivity.kt | 15 +++--- app/src/main/res/layout/dialog_bookmark.xml | 46 +++++++++++++++++++ 3 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 app/src/main/res/layout/dialog_bookmark.xml diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt index 926bc8d1e..02040e26d 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt @@ -215,7 +215,7 @@ class ReadBookActivity : ReadBookBaseActivity(), chapterIndex = ReadBook.durChapterIndex, chapterPos = ReadBook.durChapterPos, chapterName = page.title, - bookText = page.text + bookText = page.text.trim() ) showBookMark(bookmark) } diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookBaseActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookBaseActivity.kt index 56165f6ee..6a305f928 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookBaseActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookBaseActivity.kt @@ -13,6 +13,7 @@ import io.legado.app.base.VMBaseActivity import io.legado.app.constant.PreferKey import io.legado.app.data.entities.Bookmark import io.legado.app.databinding.ActivityBookReadBinding +import io.legado.app.databinding.DialogBookmarkBinding import io.legado.app.databinding.DialogDownloadChoiceBinding import io.legado.app.databinding.DialogEditTextBinding import io.legado.app.help.AppConfig @@ -200,18 +201,18 @@ abstract class ReadBookBaseActivity : @SuppressLint("InflateParams") fun showBookMark(bookmark: Bookmark) { - val book = ReadBook.book ?: return - val textChapter = ReadBook.curTextChapter ?: return alert(title = getString(R.string.bookmark_add)) { - val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { - editView.setHint(R.string.note_content) + message = bookmark.chapterName + val alertBinding = DialogBookmarkBinding.inflate(layoutInflater).apply { + editBookText.setText(bookmark.bookText) + editView.setText(bookmark.content) } - message = bookmark.bookText customView = alertBinding.root yesButton { - alertBinding.editView.text?.toString()?.let { editContent -> + alertBinding.apply { Coroutine.async { - bookmark.content = editContent + bookmark.bookText = editBookText.text.toString() + bookmark.content = editView.text.toString() App.db.bookmarkDao.insert(bookmark) } } diff --git a/app/src/main/res/layout/dialog_bookmark.xml b/app/src/main/res/layout/dialog_bookmark.xml new file mode 100644 index 000000000..af68de721 --- /dev/null +++ b/app/src/main/res/layout/dialog_bookmark.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From f7f1c880f5d90d61acff9e7891b2ca7ab74e902c Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 30 Dec 2020 21:37:09 +0800 Subject: [PATCH 41/68] =?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/toc/BookmarkFragment.kt | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/toc/BookmarkFragment.kt b/app/src/main/java/io/legado/app/ui/book/toc/BookmarkFragment.kt index 2fb5a4085..5c0524302 100644 --- a/app/src/main/java/io/legado/app/ui/book/toc/BookmarkFragment.kt +++ b/app/src/main/java/io/legado/app/ui/book/toc/BookmarkFragment.kt @@ -13,8 +13,9 @@ import io.legado.app.App import io.legado.app.R import io.legado.app.base.VMBaseFragment import io.legado.app.data.entities.Bookmark -import io.legado.app.databinding.DialogEditTextBinding +import io.legado.app.databinding.DialogBookmarkBinding import io.legado.app.databinding.FragmentBookmarkBinding +import io.legado.app.help.coroutine.Coroutine import io.legado.app.lib.dialogs.alert import io.legado.app.lib.theme.ATH import io.legado.app.ui.widget.recycler.VerticalDivider @@ -84,18 +85,19 @@ class BookmarkFragment : VMBaseFragment(R.layout.fragment_ @SuppressLint("InflateParams") override fun onLongClick(bookmark: Bookmark) { requireContext().alert(R.string.bookmark) { - val alertBinding = DialogEditTextBinding.inflate(layoutInflater) - message = bookmark.bookText - customView { - alertBinding.apply { - editView.setHint(R.string.note_content) - editView.setText(bookmark.content) - }.root + message = bookmark.chapterName + val alertBinding = DialogBookmarkBinding.inflate(layoutInflater).apply { + editBookText.setText(bookmark.bookText) + editView.setText(bookmark.content) } + customView = alertBinding.root yesButton { - alertBinding.editView.text?.toString()?.let { editContent -> - bookmark.content = editContent - App.db.bookmarkDao.update(bookmark) + alertBinding.apply { + Coroutine.async { + bookmark.bookText = editBookText.text.toString() + bookmark.content = editView.text.toString() + App.db.bookmarkDao.insert(bookmark) + } } } noButton() From c3daf66bd9f9934d3df8bd6d6e8eaf9eff05131a Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 30 Dec 2020 21:40:32 +0800 Subject: [PATCH 42/68] =?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/res/layout/dialog_bookmark.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/layout/dialog_bookmark.xml b/app/src/main/res/layout/dialog_bookmark.xml index af68de721..83bc712bb 100644 --- a/app/src/main/res/layout/dialog_bookmark.xml +++ b/app/src/main/res/layout/dialog_bookmark.xml @@ -22,7 +22,7 @@ android:id="@+id/edit_book_text" android:layout_width="match_parent" android:layout_height="wrap_content" - android:hint="@string/bookmark" /> + android:hint="@string/content" /> From cc80be585981cf2bf3807d86944732310769b210 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 30 Dec 2020 21:57:23 +0800 Subject: [PATCH 43/68] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../legado/app/ui/book/read/page/provider/ChapterProvider.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt index ef4e8a0db..4895e2373 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt @@ -13,6 +13,7 @@ import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.help.AppConfig import io.legado.app.help.ReadBookConfig +import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.ui.book.read.page.entities.TextChapter import io.legado.app.ui.book.read.page.entities.TextChar import io.legado.app.ui.book.read.page.entities.TextLine @@ -118,7 +119,7 @@ object ChapterProvider { return TextChapter( bookChapter.index, bookChapter.title, - bookChapter.getAbsoluteURL().substringBefore(","), + bookChapter.getAbsoluteURL().split(AnalyzeUrl.splitUrlRegex)[0], textPages, chapterSize ) } From a8e41a0f2fd40593dc086359bf0fe1284342f998 Mon Sep 17 00:00:00 2001 From: kunfei Date: Wed, 30 Dec 2020 22:04:27 +0800 Subject: [PATCH 44/68] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1327ab258..ad2863b80 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,11 @@ * [帮助文档](/app/src/main/assets/help/appHelp.md) ## 下载 -Google Play or CoolApk or [Releases](https://github.com/gedoor/legado/releases/latest) + + Google Play + or + CoolApk + or [Releases](https://github.com/gedoor/legado/releases/latest) ## 阅读API 阅读3.0 提供了2种方式的API:`Web方式`和`Content Provider方式`。您可以在[这里](api.md)根据需要自行调用。 From 9ebe1c003edd860f98a2b1f0d9e7b634a236f38a Mon Sep 17 00:00:00 2001 From: gedoor Date: Thu, 31 Dec 2020 11:10:32 +0800 Subject: [PATCH 45/68] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/api/controller/BookshelfController.kt | 2 +- .../io/legado/app/model/webBook/BookInfo.kt | 2 + .../io/legado/app/model/webBook/WebBook.kt | 143 ++++++++++-------- .../app/ui/book/read/ReadBookViewModel.kt | 2 +- 4 files changed, 82 insertions(+), 67 deletions(-) diff --git a/app/src/main/java/io/legado/app/api/controller/BookshelfController.kt b/app/src/main/java/io/legado/app/api/controller/BookshelfController.kt index 55410156e..cb3e4a9f2 100644 --- a/app/src/main/java/io/legado/app/api/controller/BookshelfController.kt +++ b/app/src/main/java/io/legado/app/api/controller/BookshelfController.kt @@ -66,7 +66,7 @@ object BookshelfController { } else { App.db.bookSourceDao.getBookSource(book.origin)?.let { source -> runBlocking { - WebBook(source).getContentSuspend(book, chapter) + WebBook(source).getContentAwait(book, chapter) }.let { saveBookReadIndex(book, index) returnData.setData(it) diff --git a/app/src/main/java/io/legado/app/model/webBook/BookInfo.kt b/app/src/main/java/io/legado/app/model/webBook/BookInfo.kt index 877081cbc..851995f37 100644 --- a/app/src/main/java/io/legado/app/model/webBook/BookInfo.kt +++ b/app/src/main/java/io/legado/app/model/webBook/BookInfo.kt @@ -10,11 +10,13 @@ import io.legado.app.model.analyzeRule.AnalyzeRule import io.legado.app.utils.NetworkUtils import io.legado.app.utils.StringUtils.wordCountFormat import io.legado.app.utils.htmlFormat +import kotlinx.coroutines.CoroutineScope object BookInfo { @Throws(Exception::class) fun analyzeBookInfo( + scope: CoroutineScope, book: Book, body: String?, bookSource: BookSource, diff --git a/app/src/main/java/io/legado/app/model/webBook/WebBook.kt b/app/src/main/java/io/legado/app/model/webBook/WebBook.kt index 952ec1993..d864616e9 100644 --- a/app/src/main/java/io/legado/app/model/webBook/WebBook.kt +++ b/app/src/main/java/io/legado/app/model/webBook/WebBook.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlin.coroutines.CoroutineContext +@Suppress("MemberVisibilityCanBePrivate") class WebBook(val bookSource: BookSource) { val sourceUrl: String @@ -26,11 +27,11 @@ class WebBook(val bookSource: BookSource) { context: CoroutineContext = Dispatchers.IO, ): Coroutine> { return Coroutine.async(scope, context) { - searchBookSuspend(scope, key, page) + searchBookAwait(scope, key, page) } } - suspend fun searchBookSuspend( + suspend fun searchBookAwait( scope: CoroutineScope, key: String, page: Int? = 1, @@ -68,28 +69,36 @@ class WebBook(val bookSource: BookSource) { scope: CoroutineScope = Coroutine.DEFAULT, context: CoroutineContext = Dispatchers.IO, ): Coroutine> { - val variableBook = SearchBook() return Coroutine.async(scope, context) { - val analyzeUrl = AnalyzeUrl( - ruleUrl = url, - page = page, - baseUrl = sourceUrl, - book = variableBook, - headerMapF = bookSource.getHeaderMap() - ) - val res = analyzeUrl.getStrResponse(bookSource.bookSourceUrl) - BookList.analyzeBookList( - scope, - res.body, - bookSource, - analyzeUrl, - res.url, - variableBook, - false - ) + exploreBookAwait(url, page, scope) } } + suspend fun exploreBookAwait( + url: String, + page: Int? = 1, + scope: CoroutineScope = Coroutine.DEFAULT + ): ArrayList { + val variableBook = SearchBook() + val analyzeUrl = AnalyzeUrl( + ruleUrl = url, + page = page, + baseUrl = sourceUrl, + book = variableBook, + headerMapF = bookSource.getHeaderMap() + ) + val res = analyzeUrl.getStrResponse(bookSource.bookSourceUrl) + return BookList.analyzeBookList( + scope, + res.body, + bookSource, + analyzeUrl, + res.url, + variableBook, + false + ) + } + /** * 书籍信息 */ @@ -100,23 +109,38 @@ class WebBook(val bookSource: BookSource) { canReName: Boolean = true, ): Coroutine { return Coroutine.async(scope, context) { - book.type = bookSource.bookSourceType - if (!book.infoHtml.isNullOrEmpty()) { - book.infoHtml - BookInfo.analyzeBookInfo(book, book.infoHtml, bookSource, book.bookUrl, canReName) - } else { - val res = AnalyzeUrl( - ruleUrl = book.bookUrl, - baseUrl = sourceUrl, - headerMapF = bookSource.getHeaderMap(), - book = book - ).getStrResponse(bookSource.bookSourceUrl) - BookInfo.analyzeBookInfo(book, res.body, bookSource, book.bookUrl, canReName) - } - book + getBookInfoAwait(book, scope, canReName) } } + suspend fun getBookInfoAwait( + book: Book, + scope: CoroutineScope = Coroutine.DEFAULT, + canReName: Boolean = true, + ): Book { + book.type = bookSource.bookSourceType + if (!book.infoHtml.isNullOrEmpty()) { + book.infoHtml + BookInfo.analyzeBookInfo( + scope, + book, + book.infoHtml, + bookSource, + book.bookUrl, + canReName + ) + } else { + val res = AnalyzeUrl( + ruleUrl = book.bookUrl, + baseUrl = sourceUrl, + headerMapF = bookSource.getHeaderMap(), + book = book + ).getStrResponse(bookSource.bookSourceUrl) + BookInfo.analyzeBookInfo(scope, book, res.body, bookSource, book.bookUrl, canReName) + } + return book + } + /** * 目录 */ @@ -126,31 +150,25 @@ class WebBook(val bookSource: BookSource) { context: CoroutineContext = Dispatchers.IO ): Coroutine> { return Coroutine.async(scope, context) { - book.type = bookSource.bookSourceType - if (book.bookUrl == book.tocUrl && !book.tocHtml.isNullOrEmpty()) { - BookChapterList.analyzeChapterList( - this, - book, - book.tocHtml, - bookSource, - book.tocUrl - ) - } else { - val res = AnalyzeUrl( - book = book, - ruleUrl = book.tocUrl, - baseUrl = book.bookUrl, - headerMapF = bookSource.getHeaderMap() - ).getStrResponse(bookSource.bookSourceUrl) - BookChapterList.analyzeChapterList( - this, - book, - res.body, - bookSource, - book.tocUrl - ) - } + getChapterListAwait(book, scope) + } + } + suspend fun getChapterListAwait( + book: Book, + scope: CoroutineScope = Coroutine.DEFAULT + ): List { + book.type = bookSource.bookSourceType + return if (book.bookUrl == book.tocUrl && !book.tocHtml.isNullOrEmpty()) { + BookChapterList.analyzeChapterList(scope, book, book.tocHtml, bookSource, book.tocUrl) + } else { + val res = AnalyzeUrl( + book = book, + ruleUrl = book.tocUrl, + baseUrl = book.bookUrl, + headerMapF = bookSource.getHeaderMap() + ).getStrResponse(bookSource.bookSourceUrl) + BookChapterList.analyzeChapterList(scope, book, res.body, bookSource, book.tocUrl) } } @@ -165,16 +183,11 @@ class WebBook(val bookSource: BookSource) { context: CoroutineContext = Dispatchers.IO ): Coroutine { return Coroutine.async(scope, context) { - getContentSuspend( - book, bookChapter, nextChapterUrl, scope - ) + getContentAwait(book, bookChapter, nextChapterUrl, scope) } } - /** - * 章节内容 - */ - suspend fun getContentSuspend( + suspend fun getContentAwait( book: Book, bookChapter: BookChapter, nextChapterUrl: String? = null, diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt index 7f0962663..1cdb92986 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt @@ -216,7 +216,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { App.db.bookSourceDao.allTextEnabled.forEach { source -> try { WebBook(source) - .searchBookSuspend(this, name) + .searchBookAwait(this, name) .getOrNull(0)?.let { if (it.name == name && (it.author == author || author == "")) { val book = it.toBook() From ea3999e1ce485714ea3ee00de3f09ab2dc6ac203 Mon Sep 17 00:00:00 2001 From: kunfei Date: Thu, 31 Dec 2020 12:25:57 +0800 Subject: [PATCH 46/68] Update README.md --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index ad2863b80..1327ab258 100644 --- a/README.md +++ b/README.md @@ -17,11 +17,7 @@ * [帮助文档](/app/src/main/assets/help/appHelp.md) ## 下载 - - Google Play - or - CoolApk - or [Releases](https://github.com/gedoor/legado/releases/latest) +Google Play or CoolApk or [Releases](https://github.com/gedoor/legado/releases/latest) ## 阅读API 阅读3.0 提供了2种方式的API:`Web方式`和`Content Provider方式`。您可以在[这里](api.md)根据需要自行调用。 From a9fa608da483b74a5b3285eddc6e3d5bc91e0207 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 1 Jan 2021 15:58:10 +0800 Subject: [PATCH 47/68] =?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/api/controller/BookshelfController.kt | 2 +- .../main/java/io/legado/app/model/Debug.kt | 40 ++++++++++--------- .../legado/app/model/webBook/PreciseSearch.kt | 20 ++++++++++ .../app/model/webBook/SearchBookModel.kt | 2 +- .../io/legado/app/model/webBook/WebBook.kt | 26 ++++++------ .../io/legado/app/service/AudioPlayService.kt | 2 +- .../io/legado/app/service/CacheBookService.kt | 8 +--- .../io/legado/app/service/help/CacheBook.kt | 4 +- .../io/legado/app/service/help/CheckSource.kt | 2 +- .../io/legado/app/service/help/ReadBook.kt | 2 +- .../legado/app/ui/audio/AudioPlayViewModel.kt | 4 +- .../book/changecover/ChangeCoverViewModel.kt | 2 +- .../changesource/ChangeSourceViewModel.kt | 6 +-- .../ui/book/explore/ExploreShowViewModel.kt | 2 +- .../app/ui/book/info/BookInfoViewModel.kt | 4 +- .../app/ui/book/read/ReadBookViewModel.kt | 7 ++-- .../book/source/debug/BookSourceDebugModel.kt | 11 +++-- .../io/legado/app/ui/main/MainViewModel.kt | 4 +- .../ui/main/bookshelf/BookshelfViewModel.kt | 38 +++++++----------- .../app/web/utils/SourceDebugWebSocket.kt | 2 +- 20 files changed, 100 insertions(+), 88 deletions(-) create mode 100644 app/src/main/java/io/legado/app/model/webBook/PreciseSearch.kt diff --git a/app/src/main/java/io/legado/app/api/controller/BookshelfController.kt b/app/src/main/java/io/legado/app/api/controller/BookshelfController.kt index cb3e4a9f2..df3c96d1c 100644 --- a/app/src/main/java/io/legado/app/api/controller/BookshelfController.kt +++ b/app/src/main/java/io/legado/app/api/controller/BookshelfController.kt @@ -66,7 +66,7 @@ object BookshelfController { } else { App.db.bookSourceDao.getBookSource(book.origin)?.let { source -> runBlocking { - WebBook(source).getContentAwait(book, chapter) + WebBook(source).getContentAwait(this, book, chapter) }.let { saveBookReadIndex(book, index) returnData.setData(it) diff --git a/app/src/main/java/io/legado/app/model/Debug.kt b/app/src/main/java/io/legado/app/model/Debug.kt index d9a9fa49c..ec3d31097 100644 --- a/app/src/main/java/io/legado/app/model/Debug.kt +++ b/app/src/main/java/io/legado/app/model/Debug.kt @@ -11,6 +11,7 @@ import io.legado.app.model.webBook.WebBook import io.legado.app.utils.htmlFormat import io.legado.app.utils.isAbsUrl import io.legado.app.utils.msg +import kotlinx.coroutines.CoroutineScope import java.text.SimpleDateFormat import java.util.* @@ -101,7 +102,7 @@ object Debug { } } - fun startDebug(webBook: WebBook, key: String) { + fun startDebug(scope: CoroutineScope, webBook: WebBook, key: String) { cancelDebug() debugSource = webBook.sourceUrl startTime = System.currentTimeMillis() @@ -111,12 +112,12 @@ object Debug { book.origin = webBook.sourceUrl book.bookUrl = key log(webBook.sourceUrl, "⇒开始访问详情页:$key") - infoDebug(webBook, book) + infoDebug(scope, webBook, book) } key.contains("::") -> { val url = key.substring(key.indexOf("::") + 2) log(webBook.sourceUrl, "⇒开始访问发现页:$url") - exploreDebug(webBook, url) + exploreDebug(scope, webBook, url) } key.startsWith("++")-> { val url = key.substring(2) @@ -124,7 +125,7 @@ object Debug { book.origin = webBook.sourceUrl book.tocUrl = url log(webBook.sourceUrl, "⇒开始访目录页:$url") - tocDebug(webBook, book) + tocDebug(scope, webBook, book) } key.startsWith("--")-> { val url = key.substring(2) @@ -134,23 +135,23 @@ object Debug { val chapter = BookChapter() chapter.title = "调试" chapter.url = url - contentDebug(webBook, book, chapter, null) + contentDebug(scope, webBook, book, chapter, null) } else -> { log(webBook.sourceUrl, "⇒开始搜索关键字:$key") - searchDebug(webBook, key) + searchDebug(scope, webBook, key) } } } - private fun exploreDebug(webBook: WebBook, url: String) { + private fun exploreDebug(scope: CoroutineScope, webBook: WebBook, url: String) { log(debugSource, "︾开始解析发现页") - val explore = webBook.exploreBook(url, 1) + val explore = webBook.exploreBook(scope, url, 1) .onSuccess { exploreBooks -> if (exploreBooks.isNotEmpty()) { log(debugSource, "︽发现页解析完成") log(debugSource, showTime = false) - infoDebug(webBook, exploreBooks[0].toBook()) + infoDebug(scope, webBook, exploreBooks[0].toBook()) } else { log(debugSource, "︽未获取到书籍", state = -1) } @@ -161,14 +162,14 @@ object Debug { tasks.add(explore) } - private fun searchDebug(webBook: WebBook, key: String) { + private fun searchDebug(scope: CoroutineScope, webBook: WebBook, key: String) { log(debugSource, "︾开始解析搜索页") - val search = webBook.searchBook(key, 1) + val search = webBook.searchBook(scope, key, 1) .onSuccess { searchBooks -> if (searchBooks.isNotEmpty()) { log(debugSource, "︽搜索页解析完成") log(debugSource, showTime = false) - infoDebug(webBook, searchBooks[0].toBook()) + infoDebug(scope, webBook, searchBooks[0].toBook()) } else { log(debugSource, "︽未获取到书籍", state = -1) } @@ -179,13 +180,13 @@ object Debug { tasks.add(search) } - private fun infoDebug(webBook: WebBook, book: Book) { + private fun infoDebug(scope: CoroutineScope, webBook: WebBook, book: Book) { log(debugSource, "︾开始解析详情页") - val info = webBook.getBookInfo(book) + val info = webBook.getBookInfo(scope, book) .onSuccess { log(debugSource, "︽详情页解析完成") log(debugSource, showTime = false) - tocDebug(webBook, book) + tocDebug(scope, webBook, book) } .onError { log(debugSource, it.msg, state = -1) @@ -193,15 +194,15 @@ object Debug { tasks.add(info) } - private fun tocDebug(webBook: WebBook, book: Book) { + private fun tocDebug(scope: CoroutineScope, webBook: WebBook, book: Book) { log(debugSource, "︾开始解析目录页") - val chapterList = webBook.getChapterList(book) + val chapterList = webBook.getChapterList(scope, book) .onSuccess { if (it.isNotEmpty()) { log(debugSource, "︽目录页解析完成") log(debugSource, showTime = false) val nextChapterUrl = if (it.size > 1) it[1].url else null - contentDebug(webBook, book, it[0], nextChapterUrl) + contentDebug(scope, webBook, book, it[0], nextChapterUrl) } else { log(debugSource, "︽目录列表为空", state = -1) } @@ -213,13 +214,14 @@ object Debug { } private fun contentDebug( + scope: CoroutineScope, webBook: WebBook, book: Book, bookChapter: BookChapter, nextChapterUrl: String? ) { log(debugSource, "︾开始解析正文页") - val content = webBook.getContent(book, bookChapter, nextChapterUrl) + val content = webBook.getContent(scope, book, bookChapter, nextChapterUrl) .onSuccess { log(debugSource, "︽正文页解析完成", state = 1000) } diff --git a/app/src/main/java/io/legado/app/model/webBook/PreciseSearch.kt b/app/src/main/java/io/legado/app/model/webBook/PreciseSearch.kt new file mode 100644 index 000000000..fe1cd36ce --- /dev/null +++ b/app/src/main/java/io/legado/app/model/webBook/PreciseSearch.kt @@ -0,0 +1,20 @@ +package io.legado.app.model.webBook + +import io.legado.app.data.entities.BookSource +import kotlinx.coroutines.CoroutineScope + +/** + * 精准搜索 + */ +object PreciseSearch { + + suspend fun searchFirstBook( + scope: CoroutineScope, + bookSources: List, + name: String, + author: String + ) { + + } + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/model/webBook/SearchBookModel.kt b/app/src/main/java/io/legado/app/model/webBook/SearchBookModel.kt index d94c4df10..95aa3a95e 100644 --- a/app/src/main/java/io/legado/app/model/webBook/SearchBookModel.kt +++ b/app/src/main/java/io/legado/app/model/webBook/SearchBookModel.kt @@ -68,9 +68,9 @@ class SearchBookModel(private val scope: CoroutineScope, private val callBack: C searchIndex++ val source = bookSourceList[searchIndex] val task = WebBook(source).searchBook( + scope, searchKey, searchPage, - scope = scope, context = searchPool!! ).timeout(30000L) .onSuccess(IO) { diff --git a/app/src/main/java/io/legado/app/model/webBook/WebBook.kt b/app/src/main/java/io/legado/app/model/webBook/WebBook.kt index d864616e9..bafc0ca0f 100644 --- a/app/src/main/java/io/legado/app/model/webBook/WebBook.kt +++ b/app/src/main/java/io/legado/app/model/webBook/WebBook.kt @@ -21,9 +21,9 @@ class WebBook(val bookSource: BookSource) { * 搜索 */ fun searchBook( + scope: CoroutineScope, key: String, page: Int? = 1, - scope: CoroutineScope = Coroutine.DEFAULT, context: CoroutineContext = Dispatchers.IO, ): Coroutine> { return Coroutine.async(scope, context) { @@ -64,20 +64,20 @@ class WebBook(val bookSource: BookSource) { * 发现 */ fun exploreBook( + scope: CoroutineScope, url: String, page: Int? = 1, - scope: CoroutineScope = Coroutine.DEFAULT, context: CoroutineContext = Dispatchers.IO, ): Coroutine> { return Coroutine.async(scope, context) { - exploreBookAwait(url, page, scope) + exploreBookAwait(scope, url, page) } } suspend fun exploreBookAwait( + scope: CoroutineScope = Coroutine.DEFAULT, url: String, page: Int? = 1, - scope: CoroutineScope = Coroutine.DEFAULT ): ArrayList { val variableBook = SearchBook() val analyzeUrl = AnalyzeUrl( @@ -103,19 +103,19 @@ class WebBook(val bookSource: BookSource) { * 书籍信息 */ fun getBookInfo( + scope: CoroutineScope, book: Book, - scope: CoroutineScope = Coroutine.DEFAULT, context: CoroutineContext = Dispatchers.IO, canReName: Boolean = true, ): Coroutine { return Coroutine.async(scope, context) { - getBookInfoAwait(book, scope, canReName) + getBookInfoAwait(scope, book, canReName) } } suspend fun getBookInfoAwait( - book: Book, scope: CoroutineScope = Coroutine.DEFAULT, + book: Book, canReName: Boolean = true, ): Book { book.type = bookSource.bookSourceType @@ -145,18 +145,18 @@ class WebBook(val bookSource: BookSource) { * 目录 */ fun getChapterList( + scope: CoroutineScope, book: Book, - scope: CoroutineScope = Coroutine.DEFAULT, context: CoroutineContext = Dispatchers.IO ): Coroutine> { return Coroutine.async(scope, context) { - getChapterListAwait(book, scope) + getChapterListAwait(scope, book) } } suspend fun getChapterListAwait( + scope: CoroutineScope = Coroutine.DEFAULT, book: Book, - scope: CoroutineScope = Coroutine.DEFAULT ): List { book.type = bookSource.bookSourceType return if (book.bookUrl == book.tocUrl && !book.tocHtml.isNullOrEmpty()) { @@ -176,22 +176,22 @@ class WebBook(val bookSource: BookSource) { * 章节内容 */ fun getContent( + scope: CoroutineScope, book: Book, bookChapter: BookChapter, nextChapterUrl: String? = null, - scope: CoroutineScope = Coroutine.DEFAULT, context: CoroutineContext = Dispatchers.IO ): Coroutine { return Coroutine.async(scope, context) { - getContentAwait(book, bookChapter, nextChapterUrl, scope) + getContentAwait(scope, book, bookChapter, nextChapterUrl) } } suspend fun getContentAwait( + scope: CoroutineScope, book: Book, bookChapter: BookChapter, nextChapterUrl: String? = null, - scope: CoroutineScope = Coroutine.DEFAULT ): String { if (bookSource.getContentRule().content.isNullOrEmpty()) { Debug.log(sourceUrl, "⇒正文规则为空,使用章节链接:${bookChapter.url}") diff --git a/app/src/main/java/io/legado/app/service/AudioPlayService.kt b/app/src/main/java/io/legado/app/service/AudioPlayService.kt index b268adea1..d895def23 100644 --- a/app/src/main/java/io/legado/app/service/AudioPlayService.kt +++ b/app/src/main/java/io/legado/app/service/AudioPlayService.kt @@ -270,7 +270,7 @@ class AudioPlayService : BaseService(), val book = AudioPlay.book val webBook = AudioPlay.webBook if (book != null && webBook != null) { - webBook.getContent(book, chapter, scope = this@AudioPlayService) + webBook.getContent(this@AudioPlayService, book, chapter) .onSuccess { content -> if (content.isEmpty()) { withContext(Main) { diff --git a/app/src/main/java/io/legado/app/service/CacheBookService.kt b/app/src/main/java/io/legado/app/service/CacheBookService.kt index 181985df3..06a6dea35 100644 --- a/app/src/main/java/io/legado/app/service/CacheBookService.kt +++ b/app/src/main/java/io/legado/app/service/CacheBookService.kt @@ -184,12 +184,8 @@ class CacheBookService : BaseService() { return@async } if (!BookHelp.hasContent(book, bookChapter)) { - webBook.getContent( - book, - bookChapter, - scope = this, - context = searchPool - ).timeout(60000L) + webBook.getContent(this, book, bookChapter, context = searchPool) + .timeout(60000L) .onError { synchronized(this) { downloadingList.remove(bookChapter.url) diff --git a/app/src/main/java/io/legado/app/service/help/CacheBook.kt b/app/src/main/java/io/legado/app/service/help/CacheBook.kt index 1c69ac09c..782ab3bf8 100644 --- a/app/src/main/java/io/legado/app/service/help/CacheBook.kt +++ b/app/src/main/java/io/legado/app/service/help/CacheBook.kt @@ -10,6 +10,7 @@ import io.legado.app.data.entities.BookChapter import io.legado.app.model.webBook.WebBook import io.legado.app.service.CacheBookService import io.legado.app.utils.msg +import kotlinx.coroutines.CoroutineScope import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.CopyOnWriteArraySet @@ -61,6 +62,7 @@ object CacheBook { } fun download( + scope: CoroutineScope, webBook: WebBook, book: Book, chapter: BookChapter, @@ -73,7 +75,7 @@ object CacheBook { downloadMap[book.bookUrl] = CopyOnWriteArraySet() } downloadMap[book.bookUrl]?.add(chapter.index) - webBook.getContent(book, chapter) + webBook.getContent(scope, book, chapter) .onSuccess { content -> if (ReadBook.book?.bookUrl == book.bookUrl) { ReadBook.contentLoadFinish( diff --git a/app/src/main/java/io/legado/app/service/help/CheckSource.kt b/app/src/main/java/io/legado/app/service/help/CheckSource.kt index 88d1dbcca..596662429 100644 --- a/app/src/main/java/io/legado/app/service/help/CheckSource.kt +++ b/app/src/main/java/io/legado/app/service/help/CheckSource.kt @@ -50,7 +50,7 @@ class CheckSource(val source: BookSource) { ): Coroutine<*> { val webBook = WebBook(source) return webBook - .searchBook(keyword, scope = scope, context = context) + .searchBook(scope, keyword, context = context) .timeout(60000L) .onError(Dispatchers.IO) { source.addGroup("失效") diff --git a/app/src/main/java/io/legado/app/service/help/ReadBook.kt b/app/src/main/java/io/legado/app/service/help/ReadBook.kt index c4fb40204..3a331ab33 100644 --- a/app/src/main/java/io/legado/app/service/help/ReadBook.kt +++ b/app/src/main/java/io/legado/app/service/help/ReadBook.kt @@ -282,7 +282,7 @@ object ReadBook { val book = book val webBook = webBook if (book != null && webBook != null) { - CacheBook.download(webBook, book, chapter) + CacheBook.download(Coroutine.DEFAULT, webBook, book, chapter) } else if (book != null) { contentLoadFinish( book, chapter, "没有书源", resetPageOffset = resetPageOffset diff --git a/app/src/main/java/io/legado/app/ui/audio/AudioPlayViewModel.kt b/app/src/main/java/io/legado/app/ui/audio/AudioPlayViewModel.kt index 793c8b2d6..184663f3d 100644 --- a/app/src/main/java/io/legado/app/ui/audio/AudioPlayViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/audio/AudioPlayViewModel.kt @@ -53,7 +53,7 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application) changeDruChapterIndex: ((chapters: List) -> Unit)? = null ) { execute { - AudioPlay.webBook?.getBookInfo(book, this) + AudioPlay.webBook?.getBookInfo(this, book) ?.onSuccess { loadChapterList(book, changeDruChapterIndex) } @@ -65,7 +65,7 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application) changeDruChapterIndex: ((chapters: List) -> Unit)? = null ) { execute { - AudioPlay.webBook?.getChapterList(book, this) + AudioPlay.webBook?.getChapterList(this, book) ?.onSuccess(Dispatchers.IO) { cList -> if (cList.isNotEmpty()) { if (changeDruChapterIndex == null) { diff --git a/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverViewModel.kt b/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverViewModel.kt index 305126b36..2bfcffdaa 100644 --- a/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverViewModel.kt @@ -98,7 +98,7 @@ class ChangeCoverViewModel(application: Application) : BaseViewModel(application searchIndex++ val source = bookSourceList[searchIndex] val task = WebBook(source) - .searchBook(name, scope = this, context = searchPool!!) + .searchBook(this, name, context = searchPool!!) .timeout(60000L) .onSuccess(Dispatchers.IO) { if (it.isNotEmpty()) { diff --git a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt index 7c61b8d62..279cf7d79 100644 --- a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt @@ -123,7 +123,7 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio val source = bookSourceList[searchIndex] val webBook = WebBook(source) val task = webBook - .searchBook(name, scope = this, context = searchPool!!) + .searchBook(this, name, context = searchPool!!) .timeout(60000L) .onSuccess(IO) { it.forEach { searchBook -> @@ -159,7 +159,7 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio } private fun loadBookInfo(webBook: WebBook, book: Book) { - webBook.getBookInfo(book, this) + webBook.getBookInfo(this, book) .onSuccess { if (context.getPrefBoolean(PreferKey.changeSourceLoadToc)) { loadBookToc(webBook, book) @@ -175,7 +175,7 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio } private fun loadBookToc(webBook: WebBook, book: Book) { - webBook.getChapterList(book, this) + webBook.getChapterList(this, book) .onSuccess(IO) { chapters -> if (chapters.isNotEmpty()) { book.latestChapterTitle = chapters.last().title diff --git a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt index 5781eb555..502fdefa5 100644 --- a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt @@ -34,7 +34,7 @@ class ExploreShowViewModel(application: Application) : BaseViewModel(application val source = bookSource val url = exploreUrl if (source != null && url != null) { - WebBook(source).exploreBook(url, page, this) + WebBook(source).exploreBook(this, url, page) .timeout(30000L) .onSuccess(IO) { searchBooks -> booksData.postValue(searchBooks) diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt index ae0be9479..21f2dd157 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt @@ -57,7 +57,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) { loadChapter(book, changeDruChapterIndex) } else { App.db.bookSourceDao.getBookSource(book.origin)?.let { bookSource -> - WebBook(bookSource).getBookInfo(book, this, canReName = canReName) + WebBook(bookSource).getBookInfo(this, book, canReName = canReName) .onSuccess(IO) { bookData.postValue(book) if (inBookshelf) { @@ -88,7 +88,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) { } } else { App.db.bookSourceDao.getBookSource(book.origin)?.let { bookSource -> - WebBook(bookSource).getChapterList(book, this) + WebBook(bookSource).getChapterList(this, book) .onSuccess(IO) { if (it.isNotEmpty()) { if (inBookshelf) { diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt index 1cdb92986..a6d39b804 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt @@ -109,7 +109,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { if (book.isLocalBook()) { loadChapterList(book, changeDruChapterIndex) } else { - ReadBook.webBook?.getBookInfo(book, this, canReName = false) + ReadBook.webBook?.getBookInfo(this, book, canReName = false) ?.onSuccess { loadChapterList(book, changeDruChapterIndex) } @@ -138,7 +138,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { ReadBook.upMsg("LoadTocError:${it.localizedMessage}") } } else { - ReadBook.webBook?.getChapterList(book, this) + ReadBook.webBook?.getChapterList(this, book) ?.onSuccess(IO) { cList -> if (cList.isNotEmpty()) { if (changeDruChapterIndex == null) { @@ -215,8 +215,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { execute { App.db.bookSourceDao.allTextEnabled.forEach { source -> try { - WebBook(source) - .searchBookAwait(this, name) + WebBook(source).searchBookAwait(this, name) .getOrNull(0)?.let { if (it.name == name && (it.author == author || author == "")) { val book = it.toBook() diff --git a/app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugModel.kt b/app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugModel.kt index 82ce0736c..58c8a5307 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugModel.kt @@ -28,11 +28,14 @@ class BookSourceDebugModel(application: Application) : BaseViewModel(application } fun startDebug(key: String, start: (() -> Unit)? = null, error: (() -> Unit)? = null) { - webBook?.let { + execute { + Debug.callback = this@BookSourceDebugModel + Debug.startDebug(this, webBook!!, key) + }.onStart { start?.invoke() - Debug.callback = this - Debug.startDebug(it, key) - } ?: error?.invoke() + }.onError { + error?.invoke() + } } override fun printLog(state: Int, msg: String) { diff --git a/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt b/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt index 242e94baa..eea5da5e1 100644 --- a/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt @@ -75,7 +75,7 @@ class MainViewModel(application: Application) : BaseViewModel(application) { } App.db.bookSourceDao.getBookSource(book.origin)?.let { bookSource -> val webBook = WebBook(bookSource) - webBook.getChapterList(book, context = upTocPool) + webBook.getChapterList(this, book, context = upTocPool) .timeout(300000) .onSuccess(IO) { App.db.bookDao.update(book) @@ -115,7 +115,7 @@ class MainViewModel(application: Application) : BaseViewModel(application) { var addToCache = false while (!addToCache) { if (CacheBook.downloadCount() < 5) { - CacheBook.download(webBook, book, chapter) + CacheBook.download(this, webBook, book, chapter) addToCache = true } else { delay(1000) diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt index d8ec442ad..5d3fafb4b 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt @@ -43,7 +43,7 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application) origin = bookSource.bookSourceUrl, originName = bookSource.bookSourceName ) - WebBook(bookSource).getBookInfo(book, this) + WebBook(bookSource).getBookInfo(this, book) .onSuccess(IO) { it.order = App.db.bookDao.maxOrder + 1 App.db.bookDao.insert(it) @@ -71,13 +71,6 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application) val bookMap = hashMapOf() bookMap["name"] = it.name bookMap["author"] = it.author - bookMap["bookUrl"] = it.bookUrl - bookMap["coverUrl"] = it.coverUrl - bookMap["tocUrl"] = it.tocUrl - bookMap["kind"] = it.kind - bookMap["intro"] = it.getDisplayIntro() - bookMap["origin"] = it.origin - bookMap["originName"] = it.originName exportList.add(bookMap) } GSON.toJson(exportList) @@ -96,23 +89,20 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application) } } text.isJsonArray() -> { + val bookSources = App.db.bookSourceDao.allEnabled GSON.fromJsonArray>(text)?.forEach { - val book = Book( - bookUrl = it["bookUrl"] ?: "", - name = it["name"] ?: "", - author = it["author"] ?: "", - coverUrl = it["coverUrl"], - tocUrl = it["tocUrl"] ?: "", - kind = it["kind"], - intro = it["intro"] ?: "", - origin = it["origin"] ?: "", - originName = it["originName"] ?: "" - ) - if (groupId > 0) { - book.group = groupId - } - if (App.db.bookDao.getBook(book.name, book.author) == null) { - App.db.bookDao.insert(book) + val name = it["name"] ?: "" + val author = it["author"] ?: "" + bookSources.forEach { bookSource -> + runCatching { + val webBook = WebBook(bookSource) + val searchBooks = webBook.searchBookAwait(this, name) + val searchBook = searchBooks.firstOrNull() + if (searchBook != null && searchBook.name == name && searchBook.author == author) { + val book = webBook.getBookInfoAwait(this, searchBook.toBook()) + App.db.bookDao.insert(book) + } + } } } } diff --git a/app/src/main/java/io/legado/app/web/utils/SourceDebugWebSocket.kt b/app/src/main/java/io/legado/app/web/utils/SourceDebugWebSocket.kt index 3e68f1fd1..136035a80 100644 --- a/app/src/main/java/io/legado/app/web/utils/SourceDebugWebSocket.kt +++ b/app/src/main/java/io/legado/app/web/utils/SourceDebugWebSocket.kt @@ -57,7 +57,7 @@ class SourceDebugWebSocket(handshakeRequest: NanoHTTPD.IHTTPSession) : } App.db.bookSourceDao.getBookSource(tag)?.let { Debug.callback = this - Debug.startDebug(WebBook(it), key) + Debug.startDebug(this, WebBook(it), key) } } } From f47e49f984db8ae2338140f85ba530985d8bb36a Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 1 Jan 2021 16:38:14 +0800 Subject: [PATCH 48/68] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../legado/app/model/webBook/PreciseSearch.kt | 19 ++++++++- .../app/ui/book/read/ReadBookViewModel.kt | 25 ++++++------ .../ui/main/bookshelf/BookshelfViewModel.kt | 39 +++++++++++-------- 3 files changed, 51 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/webBook/PreciseSearch.kt b/app/src/main/java/io/legado/app/model/webBook/PreciseSearch.kt index fe1cd36ce..1615d57cc 100644 --- a/app/src/main/java/io/legado/app/model/webBook/PreciseSearch.kt +++ b/app/src/main/java/io/legado/app/model/webBook/PreciseSearch.kt @@ -1,5 +1,6 @@ package io.legado.app.model.webBook +import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookSource import kotlinx.coroutines.CoroutineScope @@ -13,8 +14,22 @@ object PreciseSearch { bookSources: List, name: String, author: String - ) { - + ): Book? { + bookSources.forEach { bookSource -> + val webBook = WebBook(bookSource) + kotlin.runCatching { + webBook.searchBookAwait(scope, name).firstOrNull { + it.name == name && it.author == author + }?.let { + return if (it.tocUrl.isBlank()) { + webBook.getBookInfoAwait(scope, it.toBook()) + } else { + it.toBook() + } + } + } + } + return null } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt index a6d39b804..de9c080d7 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt @@ -13,10 +13,12 @@ import io.legado.app.help.BookHelp import io.legado.app.help.IntentDataHelp import io.legado.app.help.storage.BookWebDav import io.legado.app.model.localBook.LocalBook +import io.legado.app.model.webBook.PreciseSearch import io.legado.app.model.webBook.WebBook import io.legado.app.service.BaseReadAloudService import io.legado.app.service.help.ReadAloud import io.legado.app.service.help.ReadBook +import io.legado.app.utils.msg import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.withContext @@ -213,23 +215,18 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { private fun autoChangeSource(name: String, author: String) { if (!AppConfig.autoChangeSource) return execute { - App.db.bookSourceDao.allTextEnabled.forEach { source -> - try { - WebBook(source).searchBookAwait(this, name) - .getOrNull(0)?.let { - if (it.name == name && (it.author == author || author == "")) { - val book = it.toBook() - book.upInfoFromOld(ReadBook.book) - changeTo(book) - return@execute - } - } - } catch (e: Exception) { - //nothing - } + val sources = App.db.bookSourceDao.allTextEnabled + val book = PreciseSearch.searchFirstBook(this, sources, name, author) + if (book != null) { + book.upInfoFromOld(ReadBook.book) + changeTo(book) + } else { + throw Exception("自动换源失败") } }.onStart { ReadBook.upMsg(context.getString(R.string.source_auto_changing)) + }.onError { + toast(it.msg) }.onFinally { ReadBook.upMsg(null) } diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt index 5d3fafb4b..a0d98dd44 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt @@ -7,6 +7,7 @@ import io.legado.app.base.BaseViewModel import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookGroup import io.legado.app.data.entities.BookSource +import io.legado.app.model.webBook.PreciseSearch import io.legado.app.model.webBook.WebBook import io.legado.app.utils.* import kotlinx.coroutines.Dispatchers.IO @@ -89,22 +90,7 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application) } } text.isJsonArray() -> { - val bookSources = App.db.bookSourceDao.allEnabled - GSON.fromJsonArray>(text)?.forEach { - val name = it["name"] ?: "" - val author = it["author"] ?: "" - bookSources.forEach { bookSource -> - runCatching { - val webBook = WebBook(bookSource) - val searchBooks = webBook.searchBookAwait(this, name) - val searchBook = searchBooks.firstOrNull() - if (searchBook != null && searchBook.name == name && searchBook.author == author) { - val book = webBook.getBookInfoAwait(this, searchBook.toBook()) - App.db.bookDao.insert(book) - } - } - } - } + importBookshelfByJson(text, groupId) } else -> { throw Exception("格式不对") @@ -115,6 +101,27 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application) } } + private fun importBookshelfByJson(json: String, groupId: Long) { + execute { + val bookSources = App.db.bookSourceDao.allEnabled + GSON.fromJsonArray>(json)?.forEach { + val name = it["name"] ?: "" + val author = it["author"] ?: "" + if (name.isNotEmpty() && App.db.bookDao.getBook(name, author) == null) { + val book = PreciseSearch + .searchFirstBook(this, bookSources, name, author) + book?.let { + if (groupId > 0) { + book.group = groupId + } + } + } + } + }.onFinally { + toast(R.string.success) + } + } + fun checkGroup(groups: List) { groups.forEach { group -> if (group.groupId >= 0 && group.groupId and (group.groupId - 1) != 0L) { From c6e65c5c294dcbad949a20de49a682c66de2e617 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 1 Jan 2021 17:13:31 +0800 Subject: [PATCH 49/68] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt index a0d98dd44..6c2d29c23 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt @@ -114,6 +114,7 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application) if (groupId > 0) { book.group = groupId } + App.db.bookDao.insert(book) } } } From 41148e39245d3702f41a0baf7245b082df50fb64 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 1 Jan 2021 17:17:58 +0800 Subject: [PATCH 50/68] =?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/java/io/legado/app/model/webBook/PreciseSearch.kt | 3 +++ .../java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt | 2 ++ 2 files changed, 5 insertions(+) diff --git a/app/src/main/java/io/legado/app/model/webBook/PreciseSearch.kt b/app/src/main/java/io/legado/app/model/webBook/PreciseSearch.kt index 1615d57cc..31d08314c 100644 --- a/app/src/main/java/io/legado/app/model/webBook/PreciseSearch.kt +++ b/app/src/main/java/io/legado/app/model/webBook/PreciseSearch.kt @@ -3,6 +3,7 @@ package io.legado.app.model.webBook import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookSource import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.isActive /** * 精准搜索 @@ -18,10 +19,12 @@ object PreciseSearch { bookSources.forEach { bookSource -> val webBook = WebBook(bookSource) kotlin.runCatching { + if (!scope.isActive) return null webBook.searchBookAwait(scope, name).firstOrNull { it.name == name && it.author == author }?.let { return if (it.tocUrl.isBlank()) { + if (!scope.isActive) return null webBook.getBookInfoAwait(scope, it.toBook()) } else { it.toBook() diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt index 6c2d29c23..e2e1b50e3 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt @@ -11,6 +11,7 @@ import io.legado.app.model.webBook.PreciseSearch import io.legado.app.model.webBook.WebBook import io.legado.app.utils.* import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.isActive import rxhttp.wrapper.param.RxHttp import rxhttp.wrapper.param.toText @@ -105,6 +106,7 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application) execute { val bookSources = App.db.bookSourceDao.allEnabled GSON.fromJsonArray>(json)?.forEach { + if (!isActive) return@execute val name = it["name"] ?: "" val author = it["author"] ?: "" if (name.isNotEmpty() && App.db.bookDao.getBook(name, author) == null) { From 301f21b53132f28ac8cef41722b58e2f38c072c9 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 1 Jan 2021 17:23:13 +0800 Subject: [PATCH 51/68] =?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/updateLog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 8c5e0c693..186c29916 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -3,6 +3,9 @@ * 关注合作公众号 **[小说拾遗]** 获取好看的小说。 * 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 +**2020/01/01** +* 导出书单只保留书名与作者,导入时自动查找可用源 + **2020/12/30** * 解决文件下载异常,在线语音可正常播放 by [Celeter](https://github.com/Celeter) * 更新默认在线朗读库, 默认id小于0方便下次更新时删除旧数据, 有重复的自己删除 From 95f2f1f9a4218f8b2d0320e1d40b7914d22fa55b Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 1 Jan 2021 20:38:00 +0800 Subject: [PATCH 52/68] =?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/utils/ToolBarExtensions.kt | 19 +++++++++++++++++++ .../main/java/io/legado/app/utils/UIUtils.kt | 18 ------------------ 2 files changed, 19 insertions(+), 18 deletions(-) create mode 100644 app/src/main/java/io/legado/app/utils/ToolBarExtensions.kt diff --git a/app/src/main/java/io/legado/app/utils/ToolBarExtensions.kt b/app/src/main/java/io/legado/app/utils/ToolBarExtensions.kt new file mode 100644 index 000000000..325923f15 --- /dev/null +++ b/app/src/main/java/io/legado/app/utils/ToolBarExtensions.kt @@ -0,0 +1,19 @@ +package io.legado.app.utils + +import android.graphics.PorterDuff +import android.graphics.PorterDuffColorFilter +import android.os.Build +import android.widget.Toolbar +import androidx.core.content.ContextCompat +import io.legado.app.R + +/** + * 设置toolBar更多图标颜色 + */ +fun Toolbar.setMoreIconColor(color: Int) { + val moreIcon = ContextCompat.getDrawable(context, R.drawable.ic_more) + if (moreIcon != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + moreIcon.colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP) + overflowIcon = moreIcon + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/utils/UIUtils.kt b/app/src/main/java/io/legado/app/utils/UIUtils.kt index b50a4c493..059f94a07 100644 --- a/app/src/main/java/io/legado/app/utils/UIUtils.kt +++ b/app/src/main/java/io/legado/app/utils/UIUtils.kt @@ -1,11 +1,6 @@ package io.legado.app.utils import android.content.Context -import android.graphics.PorterDuff -import android.graphics.PorterDuffColorFilter -import android.os.Build -import androidx.appcompat.widget.Toolbar -import androidx.core.content.ContextCompat import io.legado.app.R import io.legado.app.constant.Theme import io.legado.app.lib.theme.primaryTextColor @@ -13,19 +8,6 @@ import io.legado.app.lib.theme.primaryTextColor @Suppress("unused") object UIUtils { - /** 设置更多工具条图标和颜色 */ - fun setToolbarMoreIconCustomColor(toolbar: Toolbar?, color: Int? = null) { - toolbar ?: return - val moreIcon = ContextCompat.getDrawable(toolbar.context, R.drawable.ic_more) - if (moreIcon != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (color != null) { - moreIcon.colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP) - } - toolbar.overflowIcon = moreIcon - } - } - - fun getMenuColor( context: Context, theme: Theme = Theme.Auto, From f07a291a96ddb49d6922cb34dba969731297e481 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 1 Jan 2021 21:30:33 +0800 Subject: [PATCH 53/68] =?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/model/webBook/BookChapterList.kt | 65 ++++++++----------- .../legado/app/model/webBook/BookContent.kt | 4 +- .../io/legado/app/model/webBook/BookInfo.kt | 11 +++- .../io/legado/app/model/webBook/BookList.kt | 39 ++++++----- 4 files changed, 59 insertions(+), 60 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt b/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt index 94ba0baf7..1bba73ec1 100644 --- a/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt +++ b/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt @@ -12,6 +12,7 @@ import io.legado.app.model.Debug import io.legado.app.model.analyzeRule.AnalyzeRule import io.legado.app.model.analyzeRule.AnalyzeUrl import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ensureActive import kotlinx.coroutines.suspendCancellableCoroutine import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException @@ -19,13 +20,13 @@ import kotlin.coroutines.resumeWithException object BookChapterList { suspend fun analyzeChapterList( - coroutineScope: CoroutineScope, + scope: CoroutineScope, book: Book, body: String?, bookSource: BookSource, baseUrl: String ): List = suspendCancellableCoroutine { block -> - try { + kotlin.runCatching { val chapterList = ArrayList() body ?: throw Exception( App.INSTANCE.getString(R.string.error_get_web_content, baseUrl) @@ -45,7 +46,7 @@ object BookChapterList { } var chapterData = analyzeChapterList( - book, baseUrl, body, tocRule, listRule, bookSource, log = true + scope, book, baseUrl, body, tocRule, listRule, bookSource, log = true ) chapterData.chapterList?.let { chapterList.addAll(it) @@ -55,7 +56,7 @@ object BookChapterList { block.resume(finish(book, chapterList, reverse)) } 1 -> { - Coroutine.async(scope = coroutineScope) { + Coroutine.async(scope = scope) { var nextUrl = chapterData.nextUrl[0] while (nextUrl.isNotEmpty() && !nextUrlList.contains(nextUrl)) { nextUrlList.add(nextUrl) @@ -63,18 +64,15 @@ object BookChapterList { ruleUrl = nextUrl, book = book, headerMapF = bookSource.getHeaderMap() - ).getStrResponse(bookSource.bookSourceUrl) - .body?.let { nextBody -> - chapterData = analyzeChapterList( - book, nextUrl, nextBody, tocRule, listRule, bookSource - ) - nextUrl = if (chapterData.nextUrl.isNotEmpty()) { - chapterData.nextUrl[0] - } else "" - chapterData.chapterList?.let { - chapterList.addAll(it) - } + ).getStrResponse(bookSource.bookSourceUrl).body?.let { nextBody -> + chapterData = analyzeChapterList( + this, book, nextUrl, nextBody, tocRule, listRule, bookSource + ) + nextUrl = chapterData.nextUrl.firstOrNull() ?: "" + chapterData.chapterList?.let { + chapterList.addAll(it) } + } } Debug.log(bookSource.bookSourceUrl, "◇目录总页数:${nextUrlList.size}") block.resume(finish(book, chapterList, reverse)) @@ -94,29 +92,21 @@ object BookChapterList { Debug.log(bookSource.bookSourceUrl, "◇目录总页数:${nextUrlList.size}") for (item in chapterDataList) { downloadToc( - coroutineScope, - item, - book, - bookSource, - tocRule, - listRule, - chapterList, - chapterDataList, - { - block.resume(finish(book, chapterList, reverse)) - }, { - block.cancel(it) - }) + scope, item, book, bookSource, + tocRule, listRule, chapterList, chapterDataList + ) { + block.resume(finish(book, chapterList, reverse)) + } } } } - } catch (e: Exception) { - block.resumeWithException(e) + }.onFailure { + block.resumeWithException(it) } } private fun downloadToc( - coroutineScope: CoroutineScope, + scope: CoroutineScope, chapterData: ChapterData, book: Book, bookSource: BookSource, @@ -124,10 +114,9 @@ object BookChapterList { listRule: String, chapterList: ArrayList, chapterDataList: ArrayList>, - onFinish: () -> Unit, - onError: (e: Throwable) -> Unit + onFinish: () -> Unit ) { - Coroutine.async(scope = coroutineScope) { + Coroutine.async(scope = scope) { val nextBody = AnalyzeUrl( ruleUrl = chapterData.nextUrl, book = book, @@ -135,8 +124,7 @@ object BookChapterList { ).getStrResponse(bookSource.bookSourceUrl).body ?: throw Exception("${chapterData.nextUrl}, 下载失败") val nextChapterData = analyzeChapterList( - book, chapterData.nextUrl, nextBody, tocRule, listRule, bookSource, - false + this, book, chapterData.nextUrl, nextBody, tocRule, listRule, bookSource, false ) synchronized(chapterDataList) { val isFinished = addChapterListIsFinish( @@ -154,7 +142,7 @@ object BookChapterList { } } }.onError { - onError(it) + throw it } } @@ -200,6 +188,7 @@ object BookChapterList { } private fun analyzeChapterList( + scope: CoroutineScope, book: Book, baseUrl: String, body: String, @@ -232,6 +221,7 @@ object BookChapterList { Debug.log(bookSource.bookSourceUrl, "┌获取目录列表", log) val elements = analyzeRule.getElements(listRule) Debug.log(bookSource.bookSourceUrl, "└列表大小:${elements.size}", log) + scope.ensureActive() if (elements.isNotEmpty()) { val nameRule = analyzeRule.splitSourceRule(tocRule.chapterName) val urlRule = analyzeRule.splitSourceRule(tocRule.chapterUrl) @@ -239,6 +229,7 @@ object BookChapterList { val update = analyzeRule.splitSourceRule(tocRule.updateTime) var isVip: String? for (item in elements) { + scope.ensureActive() analyzeRule.setContent(item) val bookChapter = BookChapter(bookUrl = book.bookUrl, baseUrl = baseUrl) analyzeRule.chapter = bookChapter diff --git a/app/src/main/java/io/legado/app/model/webBook/BookContent.kt b/app/src/main/java/io/legado/app/model/webBook/BookContent.kt index f1bb8d405..25fcfa512 100644 --- a/app/src/main/java/io/legado/app/model/webBook/BookContent.kt +++ b/app/src/main/java/io/legado/app/model/webBook/BookContent.kt @@ -19,7 +19,7 @@ object BookContent { @Throws(Exception::class) suspend fun analyzeContent( - coroutineScope: CoroutineScope, + scope: CoroutineScope, body: String?, book: Book, bookChapter: BookChapter, @@ -73,7 +73,7 @@ object BookContent { contentDataList.add(ContentData(nextUrl = item)) } for (item in contentDataList) { - withContext(coroutineScope.coroutineContext) { + withContext(scope.coroutineContext) { AnalyzeUrl( ruleUrl = item.nextUrl, book = book, diff --git a/app/src/main/java/io/legado/app/model/webBook/BookInfo.kt b/app/src/main/java/io/legado/app/model/webBook/BookInfo.kt index 851995f37..d4eb8b9d9 100644 --- a/app/src/main/java/io/legado/app/model/webBook/BookInfo.kt +++ b/app/src/main/java/io/legado/app/model/webBook/BookInfo.kt @@ -11,6 +11,7 @@ import io.legado.app.utils.NetworkUtils import io.legado.app.utils.StringUtils.wordCountFormat import io.legado.app.utils.htmlFormat import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ensureActive object BookInfo { @@ -32,11 +33,13 @@ object BookInfo { analyzeRule.setContent(body).setBaseUrl(baseUrl) infoRule.init?.let { if (it.isNotBlank()) { + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "≡执行详情页初始化规则") analyzeRule.setContent(analyzeRule.getElement(it)) } } val mCanReName = canReName && !infoRule.canReName.isNullOrBlank() + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取书名") BookHelp.formatBookName(analyzeRule.getString(infoRule.name)).let { if (it.isNotEmpty() && (mCanReName || book.name.isEmpty())) { @@ -44,6 +47,7 @@ object BookInfo { } Debug.log(bookSource.bookSourceUrl, "└${it}") } + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取作者") BookHelp.formatBookAuthor(analyzeRule.getString(infoRule.author)).let { if (it.isNotEmpty() && (mCanReName || book.author.isEmpty())) { @@ -51,6 +55,7 @@ object BookInfo { } Debug.log(bookSource.bookSourceUrl, "└${it}") } + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取分类") analyzeRule.getStringList(infoRule.kind) ?.joinToString(",") @@ -58,27 +63,31 @@ object BookInfo { if (it.isNotEmpty()) book.kind = it } Debug.log(bookSource.bookSourceUrl, "└${book.kind}") + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取字数") wordCountFormat(analyzeRule.getString(infoRule.wordCount)).let { if (it.isNotEmpty()) book.wordCount = it } Debug.log(bookSource.bookSourceUrl, "└${book.wordCount}") + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取最新章节") analyzeRule.getString(infoRule.lastChapter).let { if (it.isNotEmpty()) book.latestChapterTitle = it } Debug.log(bookSource.bookSourceUrl, "└${book.latestChapterTitle}") + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取简介") analyzeRule.getString(infoRule.intro).let { if (it.isNotEmpty()) book.intro = it.htmlFormat() } Debug.log(bookSource.bookSourceUrl, "└${book.intro}") - + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取封面链接") analyzeRule.getString(infoRule.coverUrl).let { if (it.isNotEmpty()) book.coverUrl = NetworkUtils.getAbsoluteURL(baseUrl, it) } Debug.log(bookSource.bookSourceUrl, "└${book.coverUrl}") + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取目录链接") book.tocUrl = analyzeRule.getString(infoRule.tocUrl, true) if (book.tocUrl.isEmpty()) book.tocUrl = baseUrl diff --git a/app/src/main/java/io/legado/app/model/webBook/BookList.kt b/app/src/main/java/io/legado/app/model/webBook/BookList.kt index 464580854..25ab215e6 100644 --- a/app/src/main/java/io/legado/app/model/webBook/BookList.kt +++ b/app/src/main/java/io/legado/app/model/webBook/BookList.kt @@ -12,9 +12,8 @@ import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.utils.NetworkUtils import io.legado.app.utils.StringUtils.wordCountFormat import io.legado.app.utils.htmlFormat -import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.isActive +import kotlinx.coroutines.ensureActive object BookList { @@ -36,10 +35,10 @@ object BookList { ) ) Debug.log(bookSource.bookSourceUrl, "≡获取成功:${analyzeUrl.ruleUrl}") - if (!scope.isActive) throw CancellationException() val analyzeRule = AnalyzeRule(variableBook) analyzeRule.setContent(body).setBaseUrl(baseUrl) bookSource.bookUrlPattern?.let { + scope.ensureActive() if (baseUrl.matches(it.toRegex())) { Debug.log(bookSource.bookSourceUrl, "≡链接为详情页") getInfoItem(scope, analyzeRule, bookSource, baseUrl, variableBook.variable) @@ -67,6 +66,7 @@ object BookList { } Debug.log(bookSource.bookSourceUrl, "┌获取书籍列表") collections = analyzeRule.getElements(ruleList) + scope.ensureActive() if (collections.isEmpty() && bookSource.bookUrlPattern.isNullOrEmpty()) { Debug.log(bookSource.bookSourceUrl, "└列表为空,按详情页解析") getInfoItem(scope, analyzeRule, bookSource, baseUrl, variableBook.variable) @@ -85,7 +85,6 @@ object BookList { val ruleWordCount = analyzeRule.splitSourceRule(bookListRule.wordCount) Debug.log(bookSource.bookSourceUrl, "└列表大小:${collections.size}") for ((index, item) in collections.withIndex()) { - if (!scope.isActive) throw CancellationException() getSearchItem( scope, item, @@ -134,37 +133,37 @@ object BookList { with(bookSource.getBookInfoRule()) { init?.let { if (it.isNotEmpty()) { - if (!scope.isActive) throw CancellationException() + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "≡执行详情页初始化规则") analyzeRule.setContent(analyzeRule.getElement(it)) } } - if (!scope.isActive) throw CancellationException() + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取书名") searchBook.name = BookHelp.formatBookName(analyzeRule.getString(name)) Debug.log(bookSource.bookSourceUrl, "└${searchBook.name}") if (searchBook.name.isNotEmpty()) { - if (!scope.isActive) throw CancellationException() + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取作者") searchBook.author = BookHelp.formatBookAuthor(analyzeRule.getString(author)) Debug.log(bookSource.bookSourceUrl, "└${searchBook.author}") - if (!scope.isActive) throw CancellationException() + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取分类") searchBook.kind = analyzeRule.getStringList(kind)?.joinToString(",") Debug.log(bookSource.bookSourceUrl, "└${searchBook.kind}") - if (!scope.isActive) throw CancellationException() + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取字数") searchBook.wordCount = wordCountFormat(analyzeRule.getString(wordCount)) Debug.log(bookSource.bookSourceUrl, "└${searchBook.wordCount}") - if (!scope.isActive) throw CancellationException() + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取最新章节") searchBook.latestChapterTitle = analyzeRule.getString(lastChapter) Debug.log(bookSource.bookSourceUrl, "└${searchBook.latestChapterTitle}") - if (!scope.isActive) throw CancellationException() + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取简介") searchBook.intro = analyzeRule.getString(intro).htmlFormat() Debug.log(bookSource.bookSourceUrl, "└${searchBook.intro}") - if (!scope.isActive) throw CancellationException() + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取封面链接") searchBook.coverUrl = analyzeRule.getString(coverUrl, true) Debug.log(bookSource.bookSourceUrl, "└${searchBook.coverUrl}") @@ -199,38 +198,38 @@ object BookList { searchBook.originOrder = bookSource.customOrder analyzeRule.book = searchBook analyzeRule.setContent(item) - if (!scope.isActive) throw CancellationException() + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取书名", log) searchBook.name = BookHelp.formatBookName(analyzeRule.getString(ruleName)) Debug.log(bookSource.bookSourceUrl, "└${searchBook.name}", log) if (searchBook.name.isNotEmpty()) { - if (!scope.isActive) throw CancellationException() + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取作者", log) searchBook.author = BookHelp.formatBookAuthor(analyzeRule.getString(ruleAuthor)) Debug.log(bookSource.bookSourceUrl, "└${searchBook.author}", log) - if (!scope.isActive) throw CancellationException() + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取分类", log) searchBook.kind = analyzeRule.getStringList(ruleKind)?.joinToString(",") Debug.log(bookSource.bookSourceUrl, "└${searchBook.kind}", log) - if (!scope.isActive) throw CancellationException() + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取字数", log) searchBook.wordCount = wordCountFormat(analyzeRule.getString(ruleWordCount)) Debug.log(bookSource.bookSourceUrl, "└${searchBook.wordCount}", log) - if (!scope.isActive) throw CancellationException() + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取最新章节", log) searchBook.latestChapterTitle = analyzeRule.getString(ruleLastChapter) Debug.log(bookSource.bookSourceUrl, "└${searchBook.latestChapterTitle}", log) - if (!scope.isActive) throw CancellationException() + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取简介", log) searchBook.intro = analyzeRule.getString(ruleIntro).htmlFormat() Debug.log(bookSource.bookSourceUrl, "└${searchBook.intro}", log) - if (!scope.isActive) throw CancellationException() + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取封面链接", log) analyzeRule.getString(ruleCoverUrl).let { if (it.isNotEmpty()) searchBook.coverUrl = NetworkUtils.getAbsoluteURL(baseUrl, it) } Debug.log(bookSource.bookSourceUrl, "└${searchBook.coverUrl}", log) - if (!scope.isActive) throw CancellationException() + scope.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取详情页链接", log) searchBook.bookUrl = analyzeRule.getString(ruleBookUrl, true) if (searchBook.bookUrl.isEmpty()) { From 98fc831706c2994591a333b4470cbd005afea9c3 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 1 Jan 2021 21:35:22 +0800 Subject: [PATCH 54/68] =?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/data/entities/ReplaceRule.kt | 3 +-- app/src/main/java/io/legado/app/help/IntentHelp.kt | 8 ++++---- app/src/main/java/io/legado/app/help/ThemeConfig.kt | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/io/legado/app/data/entities/ReplaceRule.kt b/app/src/main/java/io/legado/app/data/entities/ReplaceRule.kt index 1b5f7f8f0..d805d9dd0 100644 --- a/app/src/main/java/io/legado/app/data/entities/ReplaceRule.kt +++ b/app/src/main/java/io/legado/app/data/entities/ReplaceRule.kt @@ -49,8 +49,7 @@ data class ReplaceRule( if (isRegex){ try { Pattern.compile(pattern) - } - catch (ex: PatternSyntaxException){ + } catch (ex: PatternSyntaxException) { return false } } diff --git a/app/src/main/java/io/legado/app/help/IntentHelp.kt b/app/src/main/java/io/legado/app/help/IntentHelp.kt index 05b580272..7524bed78 100644 --- a/app/src/main/java/io/legado/app/help/IntentHelp.kt +++ b/app/src/main/java/io/legado/app/help/IntentHelp.kt @@ -13,23 +13,23 @@ object IntentHelp { fun toTTSSetting(context: Context) { //跳转到文字转语音设置界面 - try { + kotlin.runCatching { val intent = Intent() intent.action = "com.android.settings.TTS_SETTINGS" intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK context.startActivity(intent) - } catch (ignored: Exception) { + }.onFailure { context.toast(R.string.tip_cannot_jump_setting_page) } } fun toInstallUnknown(context: Context) { - try { + kotlin.runCatching { val intent = Intent() intent.action = "android.settings.MANAGE_UNKNOWN_APP_SOURCES" intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK context.startActivity(intent) - } catch (ignored: Exception) { + }.onFailure { context.toast("无法打开设置") } } diff --git a/app/src/main/java/io/legado/app/help/ThemeConfig.kt b/app/src/main/java/io/legado/app/help/ThemeConfig.kt index b4875ef8b..9de5ceade 100644 --- a/app/src/main/java/io/legado/app/help/ThemeConfig.kt +++ b/app/src/main/java/io/legado/app/help/ThemeConfig.kt @@ -61,11 +61,11 @@ object ThemeConfig { private fun getConfigs(): List? { val configFile = File(configFilePath) if (configFile.exists()) { - try { + kotlin.runCatching { val json = configFile.readText() return GSON.fromJsonArray(json) - } catch (e: Exception) { - e.printStackTrace() + }.onFailure { + it.printStackTrace() } } return null From ad3eca3a556c916b94ef271b9f38ed836f0c6142 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 1 Jan 2021 22:06:32 +0800 Subject: [PATCH 55/68] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/help/JsExtensions.kt | 21 +++++++++++-------- .../app/model/analyzeRule/AnalyzeRule.kt | 21 +++++++++---------- .../io/legado/app/service/AudioPlayService.kt | 8 +++---- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/JsExtensions.kt b/app/src/main/java/io/legado/app/help/JsExtensions.kt index fc2fc92ff..7a38e2a33 100644 --- a/app/src/main/java/io/legado/app/help/JsExtensions.kt +++ b/app/src/main/java/io/legado/app/help/JsExtensions.kt @@ -30,12 +30,13 @@ interface JsExtensions { */ fun ajax(urlStr: String): String? { return runBlocking { - try { + kotlin.runCatching { val analyzeUrl = AnalyzeUrl(urlStr) analyzeUrl.getStrResponse(urlStr).body - } catch (e: Exception) { - e.printStackTrace() - e.msg + }.onFailure { + it.printStackTrace() + }.getOrElse { + it.msg } } } @@ -44,13 +45,15 @@ interface JsExtensions { * 访问网络,返回Response */ fun connect(urlStr: String): Any { - return try { - val analyzeUrl = AnalyzeUrl(urlStr) - runBlocking { + return runBlocking { + kotlin.runCatching { + val analyzeUrl = AnalyzeUrl(urlStr) analyzeUrl.getStrResponse(urlStr) + }.onFailure { + it.printStackTrace() + }.getOrElse { + it.msg } - } catch (e: Exception) { - e.msg } } diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt index 6fc8e2146..a1d75941c 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt @@ -62,10 +62,10 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions { fun setBaseUrl(baseUrl: String?): AnalyzeRule { baseUrl?.let { this.baseUrl = baseUrl - try { + kotlin.runCatching { baseURL = URL(baseUrl.substringBefore(",")) - } catch (e: Exception) { - e.printStackTrace() + }.onFailure { + it.printStackTrace() } } return this @@ -229,11 +229,9 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions { } } if (result == null) result = "" - val str = try { + val str = kotlin.runCatching { Entities.unescape(result.toString()) - } catch (e: Exception) { - result.toString() - } + }.getOrDefault(result.toString()) if (isUrl) { return if (str.isBlank()) { baseUrl ?: "" @@ -654,12 +652,13 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions { */ override fun ajax(urlStr: String): String? { return runBlocking { - try { + kotlin.runCatching { val analyzeUrl = AnalyzeUrl(urlStr, book = book) analyzeUrl.getStrResponse(urlStr).body - } catch (e: Exception) { - e.printStackTrace() - e.msg + }.onFailure { + it.printStackTrace() + }.getOrElse { + it.msg } } } diff --git a/app/src/main/java/io/legado/app/service/AudioPlayService.kt b/app/src/main/java/io/legado/app/service/AudioPlayService.kt index d895def23..805fdfc14 100644 --- a/app/src/main/java/io/legado/app/service/AudioPlayService.kt +++ b/app/src/main/java/io/legado/app/service/AudioPlayService.kt @@ -120,7 +120,7 @@ class AudioPlayService : BaseService(), private fun play() { upNotification() if (requestFocus()) { - try { + kotlin.runCatching { AudioPlay.status = Status.STOP postEvent(EventBus.AUDIO_STATE, Status.STOP) mediaPlayer.reset() @@ -130,10 +130,10 @@ class AudioPlayService : BaseService(), mediaPlayer.setDataSource(this, uri, analyzeUrl.headerMap) mediaPlayer.prepareAsync() handler.removeCallbacks(mpRunnable) - } catch (e: Exception) { - e.printStackTrace() + }.onFailure { + it.printStackTrace() launch { - toast("$url ${e.localizedMessage}") + toast("$url ${it.localizedMessage}") stopSelf() } } From 28623487e536c03eff6dd4178af3a7baa0973dbd Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 1 Jan 2021 22:11:05 +0800 Subject: [PATCH 56/68] =?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/model/analyzeRule/AnalyzeRule.kt | 4 +++- app/src/main/java/io/legado/app/utils/StringUtils.kt | 5 ++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt index a1d75941c..5445884bf 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt @@ -231,7 +231,9 @@ class AnalyzeRule(val ruleData: RuleDataInterface) : JsExtensions { if (result == null) result = "" val str = kotlin.runCatching { Entities.unescape(result.toString()) - }.getOrDefault(result.toString()) + }.getOrElse { + result.toString() + } if (isUrl) { return if (str.isBlank()) { baseUrl ?: "" diff --git a/app/src/main/java/io/legado/app/utils/StringUtils.kt b/app/src/main/java/io/legado/app/utils/StringUtils.kt index 89d561cbf..b810ffa0d 100644 --- a/app/src/main/java/io/legado/app/utils/StringUtils.kt +++ b/app/src/main/java/io/legado/app/utils/StringUtils.kt @@ -214,12 +214,11 @@ object StringUtils { fun stringToInt(str: String?): Int { if (str != null) { val num = fullToHalf(str).replace("\\s+".toRegex(), "") - return try { + return kotlin.runCatching { Integer.parseInt(num) - } catch (e: Exception) { + }.getOrElse { chineseNumToInt(num) } - } return -1 } From 795623d1ff6c507c6333982558757378a41d3f07 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sat, 2 Jan 2021 09:24:31 +0800 Subject: [PATCH 57/68] =?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/java/io/legado/app/api/ReaderProvider.kt | 1 - .../io/legado/app/{web/utils => api}/ReturnData.kt | 11 +++-------- .../legado/app/api/controller/BookshelfController.kt | 2 +- .../io/legado/app/api/controller/SourceController.kt | 9 +++++---- app/src/main/java/io/legado/app/web/HttpServer.kt | 2 +- .../app/web/{utils => }/SourceDebugWebSocket.kt | 5 ++--- .../main/java/io/legado/app/web/WebSocketServer.kt | 1 - 7 files changed, 12 insertions(+), 19 deletions(-) rename app/src/main/java/io/legado/app/{web/utils => api}/ReturnData.kt (63%) rename app/src/main/java/io/legado/app/web/{utils => }/SourceDebugWebSocket.kt (96%) diff --git a/app/src/main/java/io/legado/app/api/ReaderProvider.kt b/app/src/main/java/io/legado/app/api/ReaderProvider.kt index b45d2f5c0..897b0d757 100644 --- a/app/src/main/java/io/legado/app/api/ReaderProvider.kt +++ b/app/src/main/java/io/legado/app/api/ReaderProvider.kt @@ -12,7 +12,6 @@ import android.net.Uri import com.google.gson.Gson import io.legado.app.api.controller.BookshelfController import io.legado.app.api.controller.SourceController -import io.legado.app.web.utils.ReturnData import java.util.* /** diff --git a/app/src/main/java/io/legado/app/web/utils/ReturnData.kt b/app/src/main/java/io/legado/app/api/ReturnData.kt similarity index 63% rename from app/src/main/java/io/legado/app/web/utils/ReturnData.kt rename to app/src/main/java/io/legado/app/api/ReturnData.kt index 7c460e5e2..f6d6aefdc 100644 --- a/app/src/main/java/io/legado/app/web/utils/ReturnData.kt +++ b/app/src/main/java/io/legado/app/api/ReturnData.kt @@ -1,4 +1,4 @@ -package io.legado.app.web.utils +package io.legado.app.api class ReturnData { @@ -6,18 +6,13 @@ class ReturnData { var isSuccess: Boolean = false private set - var errorMsg: String? = null + var errorMsg: String = "未知错误,请联系开发者!" private set var data: Any? = null private set - init { - this.isSuccess = false - this.errorMsg = "未知错误,请联系开发者!" - } - - fun setErrorMsg(errorMsg: String?): ReturnData { + fun setErrorMsg(errorMsg: String): ReturnData { this.isSuccess = false this.errorMsg = errorMsg return this diff --git a/app/src/main/java/io/legado/app/api/controller/BookshelfController.kt b/app/src/main/java/io/legado/app/api/controller/BookshelfController.kt index df3c96d1c..c8e878f0f 100644 --- a/app/src/main/java/io/legado/app/api/controller/BookshelfController.kt +++ b/app/src/main/java/io/legado/app/api/controller/BookshelfController.kt @@ -1,6 +1,7 @@ package io.legado.app.api.controller import io.legado.app.App +import io.legado.app.api.ReturnData import io.legado.app.constant.PreferKey import io.legado.app.data.entities.Book import io.legado.app.help.BookHelp @@ -10,7 +11,6 @@ import io.legado.app.utils.GSON import io.legado.app.utils.cnCompare import io.legado.app.utils.fromJsonObject import io.legado.app.utils.getPrefInt -import io.legado.app.web.utils.ReturnData import kotlinx.coroutines.runBlocking object BookshelfController { diff --git a/app/src/main/java/io/legado/app/api/controller/SourceController.kt b/app/src/main/java/io/legado/app/api/controller/SourceController.kt index 69d609931..6dc142804 100644 --- a/app/src/main/java/io/legado/app/api/controller/SourceController.kt +++ b/app/src/main/java/io/legado/app/api/controller/SourceController.kt @@ -3,11 +3,12 @@ package io.legado.app.api.controller import android.text.TextUtils import io.legado.app.App +import io.legado.app.api.ReturnData import io.legado.app.data.entities.BookSource import io.legado.app.utils.GSON import io.legado.app.utils.fromJsonArray import io.legado.app.utils.fromJsonObject -import io.legado.app.web.utils.ReturnData +import io.legado.app.utils.msg object SourceController { @@ -22,7 +23,7 @@ object SourceController { fun saveSource(postData: String?): ReturnData { val returnData = ReturnData() - try { + kotlin.runCatching { val bookSource = GSON.fromJsonObject(postData) if (bookSource != null) { if (TextUtils.isEmpty(bookSource.bookSourceName) || TextUtils.isEmpty(bookSource.bookSourceUrl)) { @@ -34,8 +35,8 @@ object SourceController { } else { returnData.setErrorMsg("转换书源失败") } - } catch (e: Exception) { - returnData.setErrorMsg(e.localizedMessage) + }.onFailure { + returnData.setErrorMsg(it.msg) } return returnData } diff --git a/app/src/main/java/io/legado/app/web/HttpServer.kt b/app/src/main/java/io/legado/app/web/HttpServer.kt index da7c03400..1b8b47eed 100644 --- a/app/src/main/java/io/legado/app/web/HttpServer.kt +++ b/app/src/main/java/io/legado/app/web/HttpServer.kt @@ -2,10 +2,10 @@ package io.legado.app.web import com.google.gson.Gson import fi.iki.elonen.NanoHTTPD +import io.legado.app.api.ReturnData import io.legado.app.api.controller.BookshelfController import io.legado.app.api.controller.SourceController import io.legado.app.web.utils.AssetsWeb -import io.legado.app.web.utils.ReturnData import java.util.* class HttpServer(port: Int) : NanoHTTPD(port) { diff --git a/app/src/main/java/io/legado/app/web/utils/SourceDebugWebSocket.kt b/app/src/main/java/io/legado/app/web/SourceDebugWebSocket.kt similarity index 96% rename from app/src/main/java/io/legado/app/web/utils/SourceDebugWebSocket.kt rename to app/src/main/java/io/legado/app/web/SourceDebugWebSocket.kt index 136035a80..8b18d1179 100644 --- a/app/src/main/java/io/legado/app/web/utils/SourceDebugWebSocket.kt +++ b/app/src/main/java/io/legado/app/web/SourceDebugWebSocket.kt @@ -1,4 +1,4 @@ -package io.legado.app.web.utils +package io.legado.app.web import fi.iki.elonen.NanoHTTPD @@ -20,13 +20,12 @@ class SourceDebugWebSocket(handshakeRequest: NanoHTTPD.IHTTPSession) : CoroutineScope by MainScope(), Debug.Callback { - override fun onOpen() { launch(IO) { do { delay(30000) runCatching { - ping(byteArrayOf("ping".toByte())) + ping("ping".toByteArray()) } } while (isOpen) } diff --git a/app/src/main/java/io/legado/app/web/WebSocketServer.kt b/app/src/main/java/io/legado/app/web/WebSocketServer.kt index a32b5f2a3..d6a259687 100644 --- a/app/src/main/java/io/legado/app/web/WebSocketServer.kt +++ b/app/src/main/java/io/legado/app/web/WebSocketServer.kt @@ -1,7 +1,6 @@ package io.legado.app.web import fi.iki.elonen.NanoWSD -import io.legado.app.web.utils.SourceDebugWebSocket class WebSocketServer(port: Int) : NanoWSD(port) { From 16d29aeb551ae86d0593d00603fbdbdaadb4b0d6 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sat, 2 Jan 2021 12:09:48 +0800 Subject: [PATCH 58/68] =?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/base/BaseDialogFragment.kt | 5 +- .../io/legado/app/data/entities/BookSource.kt | 93 ++++++++++--------- .../java/io/legado/app/help/ImageLoader.kt | 4 +- .../legado/app/help/storage/ImportOldData.kt | 50 +++++----- .../java/io/legado/app/lib/webdav/WebDav.kt | 10 +- .../io/legado/app/ui/about/AboutActivity.kt | 4 +- .../io/legado/app/ui/about/AboutFragment.kt | 6 +- .../legado/app/ui/book/read/TextActionMenu.kt | 14 +-- .../legado/app/ui/book/read/page/ReadView.kt | 4 +- .../read/page/provider/ChapterProvider.kt | 4 +- .../io/legado/app/ui/filepicker/FilePicker.kt | 20 ++-- .../app/ui/filepicker/entity/JavaBean.kt | 4 +- .../app/ui/filepicker/utils/ConvertUtils.kt | 20 ++-- .../app/ui/replace/ReplaceRuleActivity.kt | 6 +- .../ui/rss/source/manage/RssSourceActivity.kt | 6 +- .../legado/app/ui/widget/font/FontAdapter.kt | 8 +- .../io/legado/app/ui/widget/text/BadgeView.kt | 7 +- .../java/io/legado/app/utils/StringUtils.kt | 16 ++-- .../java/io/legado/app/utils/SystemUtils.kt | 6 +- .../io/legado/app/utils/ViewExtensions.kt | 8 +- 20 files changed, 131 insertions(+), 164 deletions(-) diff --git a/app/src/main/java/io/legado/app/base/BaseDialogFragment.kt b/app/src/main/java/io/legado/app/base/BaseDialogFragment.kt index 6b2ca45ba..468dd4c95 100644 --- a/app/src/main/java/io/legado/app/base/BaseDialogFragment.kt +++ b/app/src/main/java/io/legado/app/base/BaseDialogFragment.kt @@ -32,13 +32,10 @@ abstract class BaseDialogFragment : DialogFragment(), CoroutineScope { abstract fun onFragmentCreated(view: View, savedInstanceState: Bundle?) override fun show(manager: FragmentManager, tag: String?) { - try { + kotlin.runCatching { //在每个add事务前增加一个remove事务,防止连续的add manager.beginTransaction().remove(this).commit() super.show(manager, tag) - } catch (e: Exception) { - //同一实例使用不同的tag会异常,这里捕获一下 - e.printStackTrace() } } 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 5604cec7c..b439fb367 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 @@ -46,14 +46,15 @@ data class BookSource( var ruleBookInfo: BookInfoRule? = null, // 书籍信息页规则 var ruleToc: TocRule? = null, // 目录页规则 var ruleContent: ContentRule? = null // 正文页规则 -): Parcelable, JsExtensions { - +) : Parcelable, JsExtensions { + override fun hashCode(): Int { return bookSourceUrl.hashCode() } - - override fun equals(other: Any?) = if (other is BookSource) other.bookSourceUrl == bookSourceUrl else false - + + override fun equals(other: Any?) = + if (other is BookSource) other.bookSourceUrl == bookSourceUrl else false + @Throws(Exception::class) fun getHeaderMap() = (HashMap().apply { this[AppConst.UA_NAME] = AppConfig.userAgent @@ -71,17 +72,17 @@ data class BookSource( } } }) as Map - + fun getSearchRule() = ruleSearch ?: SearchRule() - + fun getExploreRule() = ruleExplore ?: ExploreRule() - + fun getBookInfoRule() = ruleBookInfo ?: BookInfoRule() - + fun getTocRule() = ruleToc ?: TocRule() - + fun getContentRule() = ruleContent ?: ContentRule() - + fun addGroup(group: String) { bookSourceGroup?.let { if (!it.contains(group)) { @@ -91,20 +92,20 @@ data class BookSource( bookSourceGroup = group } } - + fun removeGroup(group: String) { bookSourceGroup?.splitNotBlank("[,;,;]".toRegex())?.toHashSet()?.let { it.remove(group) bookSourceGroup = TextUtils.join(",", it) } } - + fun getExploreKinds() = arrayListOf().apply { - exploreUrl?.let { - var a = it + exploreUrl?.let { urlRule -> + var a = urlRule if (a.isNotBlank()) { - try { - if (it.startsWith("", false)) { + kotlin.runCatching { + if (urlRule.startsWith("", false)) { val aCache = ACache.get(App.INSTANCE, "explore") a = aCache.getAsString(bookSourceUrl) ?: "" if (a.isBlank()) { @@ -114,7 +115,7 @@ data class BookSource( bindings["cookie"] = CookieStore bindings["cache"] = CacheManager a = AppConst.SCRIPT_ENGINE.eval( - it.substring(4, it.lastIndexOf("<")), + urlRule.substring(4, urlRule.lastIndexOf("<")), bindings ).toString() aCache.put(bookSourceUrl, a) @@ -126,13 +127,13 @@ data class BookSource( if (d.size > 1) add(ExploreKind(d[0], d[1])) } - } catch (e: Exception) { - add(ExploreKind(e.localizedMessage ?: "")) + }.onFailure { + add(ExploreKind(it.localizedMessage ?: "")) } } } } - + /** * 执行JS */ @@ -147,60 +148,60 @@ data class BookSource( fun equal(source: BookSource) = equal(bookSourceName, source.bookSourceName) - && equal(bookSourceUrl, source.bookSourceUrl) - && equal(bookSourceGroup, source.bookSourceGroup) - && bookSourceType == source.bookSourceType - && equal(bookUrlPattern, source.bookUrlPattern) - && equal(bookSourceComment, source.bookSourceComment) - && enabled == source.enabled - && enabledExplore == source.enabledExplore - && equal(header, source.header) - && equal(loginUrl, source.loginUrl) - && equal(exploreUrl, source.exploreUrl) - && equal(searchUrl, source.searchUrl) - && getSearchRule() == source.getSearchRule() - && getExploreRule() == source.getExploreRule() - && getBookInfoRule() == source.getBookInfoRule() - && getTocRule() == source.getTocRule() - && getContentRule() == source.getContentRule() - + && equal(bookSourceUrl, source.bookSourceUrl) + && equal(bookSourceGroup, source.bookSourceGroup) + && bookSourceType == source.bookSourceType + && equal(bookUrlPattern, source.bookUrlPattern) + && equal(bookSourceComment, source.bookSourceComment) + && enabled == source.enabled + && enabledExplore == source.enabledExplore + && equal(header, source.header) + && equal(loginUrl, source.loginUrl) + && equal(exploreUrl, source.exploreUrl) + && equal(searchUrl, source.searchUrl) + && getSearchRule() == source.getSearchRule() + && getExploreRule() == source.getExploreRule() + && getBookInfoRule() == source.getBookInfoRule() + && getTocRule() == source.getTocRule() + && getContentRule() == source.getContentRule() + private fun equal(a: String?, b: String?) = a == b || (a.isNullOrEmpty() && b.isNullOrEmpty()) data class ExploreKind( var title: String, var url: String? = null ) - + class Converters { @TypeConverter fun exploreRuleToString(exploreRule: ExploreRule?): String = GSON.toJson(exploreRule) - + @TypeConverter fun stringToExploreRule(json: String?) = GSON.fromJsonObject(json) @TypeConverter fun searchRuleToString(searchRule: SearchRule?): String = GSON.toJson(searchRule) - + @TypeConverter fun stringToSearchRule(json: String?) = GSON.fromJsonObject(json) @TypeConverter fun bookInfoRuleToString(bookInfoRule: BookInfoRule?): String = GSON.toJson(bookInfoRule) - + @TypeConverter fun stringToBookInfoRule(json: String?) = GSON.fromJsonObject(json) @TypeConverter fun tocRuleToString(tocRule: TocRule?): String = GSON.toJson(tocRule) - + @TypeConverter fun stringToTocRule(json: String?) = GSON.fromJsonObject(json) - + @TypeConverter fun contentRuleToString(contentRule: ContentRule?): String = GSON.toJson(contentRule) - + @TypeConverter fun stringToContentRule(json: String?) = GSON.fromJsonObject(json) - + } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/ImageLoader.kt b/app/src/main/java/io/legado/app/help/ImageLoader.kt index 2184d03d3..cc702ff0f 100644 --- a/app/src/main/java/io/legado/app/help/ImageLoader.kt +++ b/app/src/main/java/io/legado/app/help/ImageLoader.kt @@ -22,9 +22,9 @@ object ImageLoader { path.isNullOrEmpty() -> Glide.with(context).load(path) path.isAbsUrl() -> Glide.with(context).load(AnalyzeUrl(path).getGlideUrl()) path.isContentScheme() -> Glide.with(context).load(Uri.parse(path)) - else -> try { + else -> kotlin.runCatching { Glide.with(context).load(File(path)) - } catch (e: Exception) { + }.getOrElse { Glide.with(context).load(path) } } diff --git a/app/src/main/java/io/legado/app/help/storage/ImportOldData.kt b/app/src/main/java/io/legado/app/help/storage/ImportOldData.kt index 33827f829..178f8369a 100644 --- a/app/src/main/java/io/legado/app/help/storage/ImportOldData.kt +++ b/app/src/main/java/io/legado/app/help/storage/ImportOldData.kt @@ -15,61 +15,61 @@ object ImportOldData { fun importUri(context: Context, uri: Uri) { if (uri.isContentScheme()) { - DocumentFile.fromTreeUri(context, uri)?.listFiles()?.forEach { - when (it.name) { + DocumentFile.fromTreeUri(context, uri)?.listFiles()?.forEach { doc -> + when (doc.name) { "myBookShelf.json" -> - try { - DocumentUtils.readText(context, it.uri)?.let { json -> + kotlin.runCatching { + DocumentUtils.readText(context, doc.uri)?.let { json -> val importCount = importOldBookshelf(json) context.toast("成功导入书籍${importCount}") } - } catch (e: java.lang.Exception) { - context.toast("导入书籍失败\n${e.localizedMessage}") + }.onFailure { + context.toast("导入书籍失败\n${it.localizedMessage}") } "myBookSource.json" -> - try { - DocumentUtils.readText(context, it.uri)?.let { json -> + kotlin.runCatching { + DocumentUtils.readText(context, doc.uri)?.let { json -> val importCount = importOldSource(json) context.toast("成功导入书源${importCount}") } - } catch (e: Exception) { - context.toast("导入源失败\n${e.localizedMessage}") + }.onFailure { + context.toast("导入源失败\n${it.localizedMessage}") } "myBookReplaceRule.json" -> - try { - DocumentUtils.readText(context, it.uri)?.let { json -> + kotlin.runCatching { + DocumentUtils.readText(context, doc.uri)?.let { json -> val importCount = importOldReplaceRule(json) context.toast("成功导入替换规则${importCount}") } - } catch (e: Exception) { - context.toast("导入替换规则失败\n${e.localizedMessage}") + }.onFailure { + context.toast("导入替换规则失败\n${it.localizedMessage}") } } } } else { - uri.path?.let { - val file = File(it) - try {// 导入书架 + uri.path?.let { path -> + val file = File(path) + kotlin.runCatching {// 导入书架 val shelfFile = FileUtils.createFileIfNotExist(file, "myBookShelf.json") val json = shelfFile.readText() val importCount = importOldBookshelf(json) context.toast("成功导入书籍${importCount}") - } catch (e: Exception) { - context.toast("导入书籍失败\n${e.localizedMessage}") + }.onFailure { + context.toast("导入书籍失败\n${it.localizedMessage}") } - try {// Book source + kotlin.runCatching {// Book source val sourceFile = FileUtils.getFile(file, "myBookSource.json") val json = sourceFile.readText() val importCount = importOldSource(json) context.toast("成功导入书源${importCount}") - } catch (e: Exception) { - context.toast("导入源失败\n${e.localizedMessage}") + }.onFailure { + context.toast("导入源失败\n${it.localizedMessage}") } - try {// Replace rules + kotlin.runCatching {// Replace rules val ruleFile = FileUtils.getFile(file, "myBookReplaceRule.json") if (ruleFile.exists()) { val json = ruleFile.readText() @@ -78,8 +78,8 @@ object ImportOldData { } else { context.toast("未找到替换规则") } - } catch (e: Exception) { - context.toast("导入替换规则失败\n${e.localizedMessage}") + }.onFailure { + context.toast("导入替换规则失败\n${it.localizedMessage}") } } } diff --git a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt index cfcf094ad..dafedc128 100644 --- a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt +++ b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt @@ -12,7 +12,6 @@ import rxhttp.wrapper.param.toInputStream import java.io.File import java.io.IOException import java.io.InputStream -import java.io.UnsupportedEncodingException import java.net.MalformedURLException import java.net.URL import java.net.URLEncoder @@ -39,15 +38,12 @@ class WebDav(urlStr: String) { private val url: URL = URL(urlStr) private val httpUrl: String? by lazy { val raw = url.toString().replace("davs://", "https://").replace("dav://", "http://") - try { - return@lazy URLEncoder.encode(raw, "UTF-8") + return@lazy kotlin.runCatching { + URLEncoder.encode(raw, "UTF-8") .replace("\\+".toRegex(), "%20") .replace("%3A".toRegex(), ":") .replace("%2F".toRegex(), "/") - } catch (e: UnsupportedEncodingException) { - e.printStackTrace() - return@lazy null - } + }.getOrNull() } val host: String? get() = url.host val path get() = url.toString() diff --git a/app/src/main/java/io/legado/app/ui/about/AboutActivity.kt b/app/src/main/java/io/legado/app/ui/about/AboutActivity.kt index abfa31b03..f6c9088de 100644 --- a/app/src/main/java/io/legado/app/ui/about/AboutActivity.kt +++ b/app/src/main/java/io/legado/app/ui/about/AboutActivity.kt @@ -30,7 +30,7 @@ class AboutActivity : BaseActivity() { .replace(R.id.fl_fragment, aboutFragment, fTag) .commit() binding.tvAppSummary.post { - try { + kotlin.runCatching { val span = ForegroundColorSpan(accentColor) val spannableString = SpannableString(binding.tvAppSummary.text) val gzh = getString(R.string.legado_gzh) @@ -40,8 +40,6 @@ class AboutActivity : BaseActivity() { Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ) binding.tvAppSummary.text = spannableString - } catch (e: Exception) { - e.printStackTrace() } } } diff --git a/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt b/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt index 68ff8d0fa..010be8839 100644 --- a/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt +++ b/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt @@ -93,12 +93,10 @@ class AboutFragment : PreferenceFragmentCompat() { Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D$key") // 此Flag可根据具体产品需要自定义,如设置,则在加群界面按返回,返回手Q主界面,不设置,按返回会返回到呼起产品界面 // intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - return try { + return kotlin.runCatching { startActivity(intent) true - } catch (e: java.lang.Exception) { - false - } + }.getOrDefault(false) } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/read/TextActionMenu.kt b/app/src/main/java/io/legado/app/ui/book/read/TextActionMenu.kt index 6ec4d86fe..4a75e05c0 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/TextActionMenu.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/TextActionMenu.kt @@ -130,7 +130,7 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac readAloud(callBack.selectedText) } R.id.menu_browser -> { - try { + kotlin.runCatching { val intent = if (callBack.selectedText.isAbsUrl()) { Intent(Intent.ACTION_VIEW).apply { data = Uri.parse(callBack.selectedText) @@ -141,9 +141,9 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac } } context.startActivity(intent) - } catch (e: Exception) { - e.printStackTrace() - context.toast(e.localizedMessage ?: "ERROR") + }.onFailure { + it.printStackTrace() + context.toast(it.localizedMessage ?: "ERROR") } } else -> item.intent?.let { @@ -210,7 +210,7 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac */ @RequiresApi(Build.VERSION_CODES.M) private fun onInitializeMenu(menu: Menu) { - try { + kotlin.runCatching { var menuItemOrder = 100 for (resolveInfo in getSupportedActivities()) { menu.add( @@ -218,8 +218,8 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac menuItemOrder++, resolveInfo.loadLabel(context.packageManager) ).intent = createProcessTextIntentForResolveInfo(resolveInfo) } - } catch (e: Exception) { - context.toast("获取文字操作菜单出错:${e.localizedMessage}") + }.onFailure { + context.toast("获取文字操作菜单出错:${it.localizedMessage}") } } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt index 25803ac2a..8bc72438b 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt @@ -338,10 +338,10 @@ class ReadView(context: Context, attrs: AttributeSet) : } end -= 1 } - try { + kotlin.runCatching { curPage.selectStartMoveIndex(firstRelativePage, lineStart, start) curPage.selectEndMoveIndex(firstRelativePage, lineEnd, end) - } catch (e: Exception) { + }.onFailure { print( """ curPage.selectStartMoveIndex($firstRelativePage, $lineStart, $start) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt index 4895e2373..af7f8ecd8 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt @@ -352,7 +352,7 @@ object ChapterProvider { } private fun getTypeface(fontPath: String): Typeface { - return try { + return kotlin.runCatching { when { fontPath.isContentScheme() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> { val fd = App.INSTANCE.contentResolver @@ -370,7 +370,7 @@ object ChapterProvider { else -> Typeface.SANS_SERIF } } - } catch (e: Exception) { + }.getOrElse { ReadBookConfig.textFont = "" ReadBookConfig.save() Typeface.SANS_SERIF diff --git a/app/src/main/java/io/legado/app/ui/filepicker/FilePicker.kt b/app/src/main/java/io/legado/app/ui/filepicker/FilePicker.kt index 631b2da66..b464c1657 100644 --- a/app/src/main/java/io/legado/app/ui/filepicker/FilePicker.kt +++ b/app/src/main/java/io/legado/app/ui/filepicker/FilePicker.kt @@ -30,11 +30,10 @@ object FilePicker { items(selectList) { _, index -> when (index) { 0 -> { - try { + kotlin.runCatching { val intent = createSelectDirIntent() activity.startActivityForResult(intent, requestCode) - } catch (e: java.lang.Exception) { - e.printStackTrace() + }.onFailure { checkPermissions(activity) { FilePickerDialog.show( activity.supportFragmentManager, @@ -81,11 +80,10 @@ object FilePicker { items(selectList) { _, index -> when (index) { 0 -> { - try { + kotlin.runCatching { val intent = createSelectDirIntent() fragment.startActivityForResult(intent, requestCode) - } catch (e: java.lang.Exception) { - e.printStackTrace() + }.onFailure { checkPermissions(fragment) { FilePickerDialog.show( fragment.childFragmentManager, @@ -133,15 +131,14 @@ object FilePicker { items(selectList) { _, index -> when (index) { 0 -> { - try { + kotlin.runCatching { val intent = createSelectFileIntent() intent.putExtra( Intent.EXTRA_MIME_TYPES, typesOfExtensions(allowExtensions) ) activity.startActivityForResult(intent, requestCode) - } catch (e: java.lang.Exception) { - e.printStackTrace() + }.onFailure { checkPermissions(activity) { FilePickerDialog.show( activity.supportFragmentManager, @@ -191,15 +188,14 @@ object FilePicker { items(selectList) { _, index -> when (index) { 0 -> { - try { + kotlin.runCatching { val intent = createSelectFileIntent() intent.putExtra( Intent.EXTRA_MIME_TYPES, typesOfExtensions(allowExtensions) ) fragment.startActivityForResult(intent, requestCode) - } catch (e: java.lang.Exception) { - e.printStackTrace() + }.onFailure { checkPermissions(fragment) { FilePickerDialog.show( fragment.childFragmentManager, diff --git a/app/src/main/java/io/legado/app/ui/filepicker/entity/JavaBean.kt b/app/src/main/java/io/legado/app/ui/filepicker/entity/JavaBean.kt index c23a827fb..a6fb0c2bc 100644 --- a/app/src/main/java/io/legado/app/ui/filepicker/entity/JavaBean.kt +++ b/app/src/main/java/io/legado/app/ui/filepicker/entity/JavaBean.kt @@ -34,15 +34,13 @@ open class JavaBean : Serializable { val fields = list.toTypedArray() for (field in fields) { val fieldName = field.name - try { + kotlin.runCatching { val obj = field.get(this) sb.append(fieldName) sb.append("=") sb.append(obj) sb.append("\n") - } catch (ignored: IllegalAccessException) { } - } return sb.toString() } diff --git a/app/src/main/java/io/legado/app/ui/filepicker/utils/ConvertUtils.kt b/app/src/main/java/io/legado/app/ui/filepicker/utils/ConvertUtils.kt index 1af75ebe8..b4f0f0b7e 100644 --- a/app/src/main/java/io/legado/app/ui/filepicker/utils/ConvertUtils.kt +++ b/app/src/main/java/io/legado/app/ui/filepicker/utils/ConvertUtils.kt @@ -6,7 +6,6 @@ import android.graphics.BitmapFactory import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import java.io.BufferedReader -import java.io.IOException import java.io.InputStream import java.io.InputStreamReader import java.text.DecimalFormat @@ -24,11 +23,9 @@ object ConvertUtils { const val KB: Long = 1024 fun toInt(obj: Any): Int { - return try { + return kotlin.runCatching { Integer.parseInt(obj.toString()) - } catch (e: NumberFormatException) { - -1 - } + }.getOrDefault(-1) } fun toInt(bytes: ByteArray): Int { @@ -42,11 +39,9 @@ object ConvertUtils { } fun toFloat(obj: Any): Float { - return try { + return kotlin.runCatching { java.lang.Float.parseFloat(obj.toString()) - } catch (e: NumberFormatException) { - -1f - } + }.getOrDefault(-1f) } fun toString(objects: Array, tag: String): String { @@ -62,7 +57,7 @@ object ConvertUtils { fun toBitmap(bytes: ByteArray, width: Int = -1, height: Int = -1): Bitmap? { var bitmap: Bitmap? = null if (bytes.isNotEmpty()) { - try { + kotlin.runCatching { val options = BitmapFactory.Options() // 设置让解码器以最佳方式解码 options.inPreferredConfig = null @@ -72,7 +67,6 @@ object ConvertUtils { } bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size, options) bitmap!!.density = 96// 96 dpi - } catch (e: Exception) { } } return bitmap @@ -101,7 +95,7 @@ object ConvertUtils { @JvmOverloads fun toString(`is`: InputStream, charset: String = "utf-8"): String { val sb = StringBuilder() - try { + kotlin.runCatching { val reader = BufferedReader(InputStreamReader(`is`, charset)) while (true) { val line = reader.readLine() @@ -113,9 +107,7 @@ object ConvertUtils { } reader.close() `is`.close() - } catch (e: IOException) { } - return sb.toString() } diff --git a/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt b/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt index 118992269..5710f929a 100644 --- a/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt +++ b/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt @@ -246,13 +246,13 @@ class ReplaceRuleActivity : VMBaseActivity if (resultCode == Activity.RESULT_OK) { data?.data?.let { uri -> - try { + kotlin.runCatching { uri.readText(this)?.let { val dataKey = IntentDataHelp.putData(it) startActivity("dataKey" to dataKey) } - } catch (e: Exception) { - toast("readTextError:${e.localizedMessage}") + }.onFailure { + toast("readTextError:${it.localizedMessage}") } } } diff --git a/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt b/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt index e6db8c73e..717278bd8 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt @@ -257,13 +257,13 @@ class RssSourceActivity : VMBaseActivity if (resultCode == Activity.RESULT_OK) { data?.data?.let { uri -> - try { + kotlin.runCatching { uri.readText(this)?.let { val dataKey = IntentDataHelp.putData(it) startActivity("dataKey" to dataKey) } - } catch (e: Exception) { - toast("readTextError:${e.localizedMessage}") + }.onFailure { + toast("readTextError:${it.localizedMessage}") } } } diff --git a/app/src/main/java/io/legado/app/ui/widget/font/FontAdapter.kt b/app/src/main/java/io/legado/app/ui/widget/font/FontAdapter.kt index c2b1619be..9f8bb77ca 100644 --- a/app/src/main/java/io/legado/app/ui/widget/font/FontAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/widget/font/FontAdapter.kt @@ -29,7 +29,7 @@ class FontAdapter(context: Context, val callBack: CallBack) : payloads: MutableList ) { with(binding) { - try { + kotlin.runCatching { val typeface: Typeface? = if (item.isContentPath) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { context.contentResolver @@ -44,9 +44,9 @@ class FontAdapter(context: Context, val callBack: CallBack) : Typeface.createFromFile(item.uri.toString()) } tvFont.typeface = typeface - } catch (e: Exception) { - e.printStackTrace() - context.toast("Read ${item.name} Error: ${e.localizedMessage}") + }.onFailure { + it.printStackTrace() + context.toast("Read ${item.name} Error: ${it.localizedMessage}") } tvFont.text = item.name root.onClick { callBack.onClick(item) } diff --git a/app/src/main/java/io/legado/app/ui/widget/text/BadgeView.kt b/app/src/main/java/io/legado/app/ui/widget/text/BadgeView.kt index 4f26a9ad2..4bde81262 100644 --- a/app/src/main/java/io/legado/app/ui/widget/text/BadgeView.kt +++ b/app/src/main/java/io/legado/app/ui/widget/text/BadgeView.kt @@ -43,12 +43,9 @@ class BadgeView @JvmOverloads constructor( return null } val text = text.toString() - return try { + return kotlin.runCatching { Integer.parseInt(text) - } catch (e: NumberFormatException) { - null - } - + }.getOrNull() } var badgeGravity: Int diff --git a/app/src/main/java/io/legado/app/utils/StringUtils.kt b/app/src/main/java/io/legado/app/utils/StringUtils.kt index b810ffa0d..feb428337 100644 --- a/app/src/main/java/io/legado/app/utils/StringUtils.kt +++ b/app/src/main/java/io/legado/app/utils/StringUtils.kt @@ -3,7 +3,6 @@ package io.legado.app.utils import android.annotation.SuppressLint import android.text.TextUtils.isEmpty import java.text.DecimalFormat -import java.text.ParseException import java.text.SimpleDateFormat import java.util.* import java.util.regex.Matcher @@ -56,7 +55,7 @@ object StringUtils { @SuppressLint("SimpleDateFormat") val format = SimpleDateFormat(pattern) val calendar = Calendar.getInstance() - try { + kotlin.runCatching { val date = format.parse(source) ?: return "" val curTime = calendar.timeInMillis calendar.time = date @@ -95,8 +94,8 @@ object StringUtils { convertFormat.format(date) } } - } catch (e: ParseException) { - e.printStackTrace() + }.onFailure { + it.printStackTrace() } return "" @@ -173,7 +172,7 @@ object StringUtils { } // "一千零二十五", "一千二" 形式 - try { + return kotlin.runCatching { for (i in cn.indices) { val tmpNum = ChnMap[cn[i]]!! when { @@ -204,11 +203,8 @@ object StringUtils { } } result += tmp + billion - return result - } catch (e: Exception) { - return -1 - } - + result + }.getOrDefault(-1) } fun stringToInt(str: String?): Int { diff --git a/app/src/main/java/io/legado/app/utils/SystemUtils.kt b/app/src/main/java/io/legado/app/utils/SystemUtils.kt index 7faccc935..4625ebeb1 100644 --- a/app/src/main/java/io/legado/app/utils/SystemUtils.kt +++ b/app/src/main/java/io/legado/app/utils/SystemUtils.kt @@ -19,13 +19,13 @@ object SystemUtils { fun getScreenOffTime(context: Context): Int { var screenOffTime = 0 - try { + kotlin.runCatching { screenOffTime = Settings.System.getInt( context.contentResolver, Settings.System.SCREEN_OFF_TIMEOUT ) - } catch (e: Exception) { - e.printStackTrace() + }.onFailure { + it.printStackTrace() } return screenOffTime diff --git a/app/src/main/java/io/legado/app/utils/ViewExtensions.kt b/app/src/main/java/io/legado/app/utils/ViewExtensions.kt index 122f814a0..988072bb3 100644 --- a/app/src/main/java/io/legado/app/utils/ViewExtensions.kt +++ b/app/src/main/java/io/legado/app/utils/ViewExtensions.kt @@ -107,13 +107,11 @@ fun RadioGroup.checkByIndex(index: Int) { @SuppressLint("RestrictedApi") fun PopupMenu.show(x: Int, y: Int) { - try { + kotlin.runCatching { val field: Field = this.javaClass.getDeclaredField("mPopup") field.isAccessible = true (field.get(this) as MenuPopupHelper).show(x, y) - } catch (e: NoSuchFieldException) { - e.printStackTrace() - } catch (e: IllegalAccessException) { - e.printStackTrace() + }.onFailure { + it.printStackTrace() } } \ No newline at end of file From 1767f96de2f9d26d69c8d0edb53110406fa5acfa Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 3 Jan 2021 20:09:10 +0800 Subject: [PATCH 59/68] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A2=84=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/constant/PreferKey.kt | 1 + .../main/java/io/legado/app/help/AppConfig.kt | 2 ++ .../io/legado/app/service/help/ReadBook.kt | 20 +++++++++++-------- .../io/legado/app/ui/main/MainViewModel.kt | 4 +++- app/src/main/res/values-zh-rHK/strings.xml | 2 ++ app/src/main/res/values-zh-rTW/strings.xml | 2 ++ app/src/main/res/values-zh/strings.xml | 2 ++ app/src/main/res/values/strings.xml | 2 ++ app/src/main/res/xml/pref_config_other.xml | 6 ++++++ 9 files changed, 32 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/io/legado/app/constant/PreferKey.kt b/app/src/main/java/io/legado/app/constant/PreferKey.kt index de28caddc..f4e902ba0 100644 --- a/app/src/main/java/io/legado/app/constant/PreferKey.kt +++ b/app/src/main/java/io/legado/app/constant/PreferKey.kt @@ -64,6 +64,7 @@ object PreferKey { const val importKeepName = "importKeepName" const val screenOrientation = "screenOrientation" const val syncBookProgress = "syncBookProgress" + const val preDownload = "preDownload" const val cPrimary = "colorPrimary" const val cAccent = "colorAccent" diff --git a/app/src/main/java/io/legado/app/help/AppConfig.kt b/app/src/main/java/io/legado/app/help/AppConfig.kt index 076bbfdc4..1c5c10a72 100644 --- a/app/src/main/java/io/legado/app/help/AppConfig.kt +++ b/app/src/main/java/io/legado/app/help/AppConfig.kt @@ -149,6 +149,8 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener { val syncBookProgress get() = context.getPrefBoolean(PreferKey.syncBookProgress, true) + val preDownload get() = context.getPrefBoolean(PreferKey.preDownload, true) + private fun getPrefUserAgent(): String { val ua = context.getPrefString(PreferKey.userAgent) if (ua.isNullOrBlank()) { diff --git a/app/src/main/java/io/legado/app/service/help/ReadBook.kt b/app/src/main/java/io/legado/app/service/help/ReadBook.kt index 3a331ab33..c76386bd6 100644 --- a/app/src/main/java/io/legado/app/service/help/ReadBook.kt +++ b/app/src/main/java/io/legado/app/service/help/ReadBook.kt @@ -133,10 +133,12 @@ object ReadBook { callBack?.upContent() } loadContent(durChapterIndex.plus(1), upContent, false) - GlobalScope.launch(Dispatchers.IO) { - for (i in 2..10) { - delay(100) - download(durChapterIndex + i) + if (AppConfig.preDownload) { + GlobalScope.launch(Dispatchers.IO) { + for (i in 2..9) { + delay(1000) + download(durChapterIndex + i) + } } } } @@ -163,10 +165,12 @@ object ReadBook { callBack?.upContent() } loadContent(durChapterIndex.minus(1), upContent, false) - GlobalScope.launch(Dispatchers.IO) { - for (i in -5..-2) { - delay(100) - download(durChapterIndex + i) + if (AppConfig.preDownload) { + GlobalScope.launch(Dispatchers.IO) { + for (i in 2..9) { + delay(1000) + download(durChapterIndex - i) + } } } } diff --git a/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt b/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt index eea5da5e1..88969fe5d 100644 --- a/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt @@ -81,7 +81,9 @@ class MainViewModel(application: Application) : BaseViewModel(application) { App.db.bookDao.update(book) App.db.bookChapterDao.delByBook(book.bookUrl) App.db.bookChapterDao.insert(*it.toTypedArray()) - cacheBook(webBook, book) + if (AppConfig.preDownload) { + cacheBook(webBook, book) + } } .onError { it.printStackTrace() diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 44ad0524b..63f2ec2e1 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -797,5 +797,7 @@ 单URL 导出书单 导入书单 + 预下载 + 预先下载10章正文 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 04601c9a6..af90b7f86 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -798,5 +798,7 @@ 单URL 导出书单 导入书单 + 预下载 + 预先下载10章正文 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index e42728e52..48eb53cb6 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -801,5 +801,7 @@ 单URL 导出书单 导入书单 + 预下载 + 预先下载10章正文 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 70fa7277b..d2c078fec 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -804,5 +804,7 @@ 单URL 导出书单 导入书单 + 预下载 + 预先下载10章正文 diff --git a/app/src/main/res/xml/pref_config_other.xml b/app/src/main/res/xml/pref_config_other.xml index 7077d665b..c3439baf8 100644 --- a/app/src/main/res/xml/pref_config_other.xml +++ b/app/src/main/res/xml/pref_config_other.xml @@ -55,6 +55,12 @@ android:key="userAgent" android:title="UserAgent" /> + + Date: Sun, 3 Jan 2021 20:21:41 +0800 Subject: [PATCH 60/68] =?UTF-8?q?=E4=B9=A6=E6=BA=90=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=88=86=E7=BB=84=E6=97=B6=E5=8F=AA=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E5=88=86=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 3 ++- app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt | 3 +++ .../legado/app/ui/book/source/manage/BookSourceActivity.kt | 6 +++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 186c29916..5a61a7d4e 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -3,8 +3,9 @@ * 关注合作公众号 **[小说拾遗]** 获取好看的小说。 * 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 -**2020/01/01** +**2020/01/03** * 导出书单只保留书名与作者,导入时自动查找可用源 +* 添加预加载设置 **2020/12/30** * 解决文件下载异常,在线语音可正常播放 by [Celeter](https://github.com/Celeter) diff --git a/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt b/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt index e7ffc7fe0..560a92a76 100644 --- a/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt @@ -14,6 +14,9 @@ interface BookSourceDao { @Query("select * from book_sources where bookSourceName like :searchKey or bookSourceGroup like :searchKey or bookSourceUrl like :searchKey or bookSourceComment like :searchKey order by customOrder asc") fun liveDataSearch(searchKey: String = ""): LiveData> + @Query("select * from book_sources where bookSourceGroup like :searchKey order by customOrder asc") + fun liveDataGroupSearch(searchKey: String = ""): LiveData> + @Query("select * from book_sources where enabled = 1 order by customOrder asc") fun liveDataEnabled(): LiveData> diff --git a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt index 38c138482..0aeceded0 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt @@ -139,7 +139,7 @@ class BookSourceActivity : VMBaseActivity showHelp() } if (item.groupId == R.id.source_group) { - searchView.setQuery(item.title, true) + searchView.setQuery("group:${item.title}", true) } return super.onCompatOptionsItemSelected(item) } @@ -180,6 +180,10 @@ class BookSourceActivity : VMBaseActivity { App.db.bookSourceDao.liveDataDisabled() } + searchKey.startsWith("group:") -> { + val key = searchKey.substringAfter("group:") + App.db.bookSourceDao.liveDataGroupSearch("%$key%") + } else -> { App.db.bookSourceDao.liveDataSearch("%$searchKey%") } From 8aa68e6199efd7d94e47f908e3f97354cf843703 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 3 Jan 2021 20:29:29 +0800 Subject: [PATCH 61/68] =?UTF-8?q?=E5=8F=91=E7=8E=B0=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=88=86=E7=BB=84=E6=97=B6=E5=8F=AA=E6=90=9C=E7=B4=A2=E5=88=86?= =?UTF-8?q?=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/data/dao/BookSourceDao.kt | 5 ++++- .../app/ui/main/explore/ExploreFragment.kt | 21 ++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt b/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt index 560a92a76..3655e0117 100644 --- a/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt @@ -29,6 +29,9 @@ interface BookSourceDao { @Query("select * from book_sources where enabledExplore = 1 and trim(exploreUrl) <> '' and (bookSourceGroup like :key or bookSourceName like :key) order by customOrder asc") fun liveExplore(key: String): LiveData> + @Query("select * from book_sources where enabledExplore = 1 and trim(exploreUrl) <> '' and (bookSourceGroup like :key) order by customOrder asc") + fun liveGroupExplore(key: String): LiveData> + @Query("select bookSourceGroup from book_sources where trim(bookSourceGroup) <> ''") fun liveGroup(): LiveData> @@ -36,7 +39,7 @@ interface BookSourceDao { fun liveGroupEnabled(): LiveData> @Query("select bookSourceGroup from book_sources where enabledExplore = 1 and trim(exploreUrl) <> '' and trim(bookSourceGroup) <> ''") - fun liveGroupExplore(): LiveData> + fun liveExploreGroup(): LiveData> @Query("select distinct enabled from book_sources where bookSourceName like :searchKey or bookSourceGroup like :searchKey or bookSourceUrl like :searchKey") fun searchIsEnable(searchKey: String = ""): List diff --git a/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt b/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt index e4ea63bd7..ff311f503 100644 --- a/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt @@ -97,7 +97,7 @@ class ExploreFragment : VMBaseFragment(R.layout.fragment_explo private fun initGroupData() { liveGroup?.removeObservers(viewLifecycleOwner) - liveGroup = App.db.bookSourceDao.liveGroupExplore() + liveGroup = App.db.bookSourceDao.liveExploreGroup() liveGroup?.observe(viewLifecycleOwner, { groups.clear() it.map { group -> @@ -107,12 +107,19 @@ class ExploreFragment : VMBaseFragment(R.layout.fragment_explo }) } - private fun initExploreData(key: String? = null) { + private fun initExploreData(searchKey: String? = null) { liveExplore?.removeObservers(viewLifecycleOwner) - liveExplore = if (key.isNullOrBlank()) { - App.db.bookSourceDao.liveExplore() - } else { - App.db.bookSourceDao.liveExplore("%$key%") + liveExplore = when { + searchKey.isNullOrBlank() -> { + App.db.bookSourceDao.liveExplore() + } + searchKey.startsWith("group:") -> { + val key = searchKey.substringAfter("group:") + App.db.bookSourceDao.liveGroupExplore("%$key%") + } + else -> { + App.db.bookSourceDao.liveExplore("%$searchKey%") + } } liveExplore?.observe(viewLifecycleOwner, { binding.tvEmptyMsg.isGone = it.isNotEmpty() || searchView.query.isNotEmpty() @@ -135,7 +142,7 @@ class ExploreFragment : VMBaseFragment(R.layout.fragment_explo override fun onCompatOptionsItemSelected(item: MenuItem) { super.onCompatOptionsItemSelected(item) if (item.groupId == R.id.menu_group_text) { - searchView.setQuery(item.title, true) + searchView.setQuery("group:${item.title}", true) } } From 6e03649e7d597743bf6086eb63a2bf4732576cd6 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 3 Jan 2021 20:48:52 +0800 Subject: [PATCH 62/68] =?UTF-8?q?=E8=AE=A2=E9=98=85=E6=BA=90=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E5=88=86=E7=BB=84=E6=97=B6=E5=8F=AA=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E5=88=86=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/data/dao/RssSourceDao.kt | 3 +++ .../ui/rss/source/manage/RssSourceActivity.kt | 19 +++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/io/legado/app/data/dao/RssSourceDao.kt b/app/src/main/java/io/legado/app/data/dao/RssSourceDao.kt index c2d1b80ee..ad2b25706 100644 --- a/app/src/main/java/io/legado/app/data/dao/RssSourceDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/RssSourceDao.kt @@ -25,6 +25,9 @@ interface RssSourceDao { @Query("SELECT * FROM rssSources where sourceName like :key or sourceUrl like :key or sourceGroup like :key order by customOrder") fun liveSearch(key: String): LiveData> + @Query("SELECT * FROM rssSources where sourceGroup like :key order by customOrder") + fun liveGroupSearch(key: String): LiveData> + @Query("SELECT * FROM rssSources where enabled = 1 and (sourceName like '%'||:searchKey||'%' or sourceGroup like '%'||:searchKey||'%' or sourceUrl like '%'||:searchKey||'%') order by customOrder") fun liveEnabled(searchKey: String): LiveData> diff --git a/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt b/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt index 717278bd8..0f7d10e8d 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt @@ -95,7 +95,7 @@ class RssSourceActivity : VMBaseActivity showHelp() else -> if (item.groupId == R.id.source_group) { binding.titleBar.findViewById(R.id.search_view) - .setQuery(item.title, true) + .setQuery("group:${item.title}", true) } } return super.onCompatOptionsItemSelected(item) @@ -197,13 +197,20 @@ class RssSourceActivity : VMBaseActivity { + App.db.rssSourceDao.liveAll() + } + searchKey.startsWith("group:") -> { + val key = searchKey.substringAfter("group:") + App.db.rssSourceDao.liveGroupSearch("%$key%") + } + else -> { + App.db.rssSourceDao.liveSearch("%$searchKey%") + } } sourceLiveData?.observe(this, { adapter.setItems(it, adapter.diffItemCallback) From ac3c7eed22298a4456d0435da30e474bad068776 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 3 Jan 2021 21:05:11 +0800 Subject: [PATCH 63/68] =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E8=A7=84=E5=88=99?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=88=86=E7=BB=84=E6=97=B6=E5=8F=AA=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E5=88=86=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/data/dao/ReplaceRuleDao.kt | 3 ++ .../app/ui/replace/ReplaceRuleActivity.kt | 34 +++++++++++-------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/io/legado/app/data/dao/ReplaceRuleDao.kt b/app/src/main/java/io/legado/app/data/dao/ReplaceRuleDao.kt index ad374f5c9..2a0e1149c 100644 --- a/app/src/main/java/io/legado/app/data/dao/ReplaceRuleDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/ReplaceRuleDao.kt @@ -14,6 +14,9 @@ interface ReplaceRuleDao { @Query("SELECT * FROM replace_rules where `group` like :key or name like :key ORDER BY sortOrder ASC") fun liveDataSearch(key: String): LiveData> + @Query("SELECT * FROM replace_rules where `group` like :key ORDER BY sortOrder ASC") + fun liveDataGroupSearch(key: String): LiveData> + @get:Query("SELECT MIN(sortOrder) FROM replace_rules") val minOrder: Int diff --git a/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt b/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt index 5710f929a..548d9a481 100644 --- a/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt +++ b/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt @@ -54,6 +54,7 @@ class ReplaceRuleActivity : VMBaseActivity() private var groupMenu: SubMenu? = null private var replaceRuleLiveData: LiveData>? = null @@ -64,6 +65,7 @@ class ReplaceRuleActivity : VMBaseActivity(R.id.search_view).let { - ATH.setTint(it, primaryTextColor) - it.onActionViewExpanded() - it.queryHint = getString(R.string.replace_purify_search) - it.clearFocus() - it.setOnQueryTextListener(this) - } + ATH.setTint(searchView, primaryTextColor) + searchView.onActionViewExpanded() + searchView.queryHint = getString(R.string.replace_purify_search) + searchView.clearFocus() + searchView.setOnQueryTextListener(this) } override fun selectAll(selectAll: Boolean) { @@ -140,13 +140,20 @@ class ReplaceRuleActivity : VMBaseActivity { + App.db.replaceRuleDao.liveDataAll() + } + searchKey.startsWith("group:") -> { + val key = searchKey.substringAfter("group:") + App.db.replaceRuleDao.liveDataGroupSearch("%$key%") + } + else -> { + App.db.replaceRuleDao.liveDataSearch("%$searchKey%") + } } replaceRuleLiveData?.observe(this, { if (dataInit) { @@ -179,8 +186,7 @@ class ReplaceRuleActivity : VMBaseActivity FilePicker .selectFile(this, importRequestCode, allowExtensions = arrayOf("txt", "json")) else -> if (item.groupId == R.id.replace_group) { - binding.titleBar.findViewById(R.id.search_view) - .setQuery(item.title, true) + searchView.setQuery("group:${item.title}", true) } } return super.onCompatOptionsItemSelected(item) From e2bf8df205122ab12771e11f58d6a06d5f842910 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 3 Jan 2021 21:06:17 +0800 Subject: [PATCH 64/68] update updateLog.md --- app/src/main/assets/updateLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 5a61a7d4e..6c7cd17be 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -6,6 +6,7 @@ **2020/01/03** * 导出书单只保留书名与作者,导入时自动查找可用源 * 添加预加载设置 +* 选择分组时只搜索分组 **2020/12/30** * 解决文件下载异常,在线语音可正常播放 by [Celeter](https://github.com/Celeter) From 9dea05cbc09c5cc3f32b8f30779315c14eb5a7c8 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 3 Jan 2021 21:15:55 +0800 Subject: [PATCH 65/68] =?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/about/AboutFragment.kt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt b/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt index 010be8839..ca805475b 100644 --- a/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt +++ b/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt @@ -14,6 +14,7 @@ import io.legado.app.ui.widget.dialog.TextDialog import io.legado.app.utils.openUrl import io.legado.app.utils.sendMail import io.legado.app.utils.sendToClip +import io.legado.app.utils.toast class AboutFragment : PreferenceFragmentCompat() { @@ -93,10 +94,13 @@ class AboutFragment : PreferenceFragmentCompat() { Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D$key") // 此Flag可根据具体产品需要自定义,如设置,则在加群界面按返回,返回手Q主界面,不设置,按返回会返回到呼起产品界面 // intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - return kotlin.runCatching { + kotlin.runCatching { startActivity(intent) - true - }.getOrDefault(false) + return true + }.onFailure { + toast("添加失败,请手动添加") + } + return false } } \ No newline at end of file From 6deb600481f0acad602dafb63e074bfee0edf0c0 Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 4 Jan 2021 09:23:33 +0800 Subject: [PATCH 66/68] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/build.gradle b/build.gradle index 61497bec2..4e4d97e17 100644 --- a/build.gradle +++ b/build.gradle @@ -5,17 +5,17 @@ buildscript { repositories { google() jcenter() - maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' } - maven { url 'https://s3.amazonaws.com/fabric-artifacts/public' } - maven { url 'https://maven.aliyun.com/repository/gradle-plugin' } - maven { url 'https://plugins.gradle.org/m2/' } + maven { url "https://maven.aliyun.com/nexus/content/groups/public/" } + maven { url "https://s3.amazonaws.com/fabric-artifacts/public" } + maven { url "https://maven.aliyun.com/repository/gradle-plugin" } + maven { url "https://plugins.gradle.org/m2/" } } dependencies { - classpath 'com.android.tools.build:gradle:4.1.1' + classpath "com.android.tools.build:gradle:4.1.1" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'de.timfreiheit.resourceplaceholders:placeholders:0.3' - classpath 'com.google.gms:google-services:4.3.4' - classpath 'com.google.firebase:firebase-crashlytics-gradle:2.4.1' + classpath "de.timfreiheit.resourceplaceholders:placeholders:0.3" + classpath "com.google.gms:google-services:4.3.4" + classpath "com.google.firebase:firebase-crashlytics-gradle:2.4.1" } } @@ -23,10 +23,10 @@ allprojects { repositories { google() jcenter() - maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' } + maven { url "https://maven.aliyun.com/nexus/content/groups/public/" } maven { url "https://jitpack.io" } - maven { url 'https://maven.google.com/' } - maven { url 'https://github.com/psiegman/mvn-repo/raw/master/releases' } + maven { url "https://maven.google.com/" } + maven { url "https://github.com/psiegman/mvn-repo/raw/master/releases" } } } From c3a17d9cafd45145261a89014df96486bb4473c2 Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 4 Jan 2021 15:42:51 +0800 Subject: [PATCH 67/68] =?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/res/mipmap-anydpi-v26/launcher3.xml | 2 +- app/src/main/res/mipmap-anydpi-v26/launcher4.xml | 2 +- app/src/main/res/mipmap-anydpi-v26/launcher5.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/mipmap-anydpi-v26/launcher3.xml b/app/src/main/res/mipmap-anydpi-v26/launcher3.xml index 9e7ef6711..8234460dd 100644 --- a/app/src/main/res/mipmap-anydpi-v26/launcher3.xml +++ b/app/src/main/res/mipmap-anydpi-v26/launcher3.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/launcher4.xml b/app/src/main/res/mipmap-anydpi-v26/launcher4.xml index 63e51b918..6eb41f1a7 100644 --- a/app/src/main/res/mipmap-anydpi-v26/launcher4.xml +++ b/app/src/main/res/mipmap-anydpi-v26/launcher4.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/launcher5.xml b/app/src/main/res/mipmap-anydpi-v26/launcher5.xml index 7a23c7c66..f26ce23e3 100644 --- a/app/src/main/res/mipmap-anydpi-v26/launcher5.xml +++ b/app/src/main/res/mipmap-anydpi-v26/launcher5.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file From 5d4036ed2f16b0bec9dee301620649ffb5df0e91 Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 4 Jan 2021 22:05:17 +0800 Subject: [PATCH 68/68] =?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/updateLog.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 6c7cd17be..f3d953e59 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -3,7 +3,10 @@ * 关注合作公众号 **[小说拾遗]** 获取好看的小说。 * 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 -**2020/01/03** +**2021/01/04** +* 修复bug + +**2021/01/03** * 导出书单只保留书名与作者,导入时自动查找可用源 * 添加预加载设置 * 选择分组时只搜索分组