Просмотр исходного кода

Merge remote-tracking branch 'upstream/master'

# Conflicts:
#	app/src/main/java/io/legado/app/help/SourceAnalyzer.kt
#	app/src/main/res/values-es-rES/strings.xml
#	app/src/main/res/values-ja-rJP/strings.xml
#	app/src/main/res/values-pt-rBR/strings.xml
#	app/src/main/res/values-zh-rHK/strings.xml
#	app/src/main/res/values-zh-rTW/strings.xml
#	app/src/main/res/values-zh/strings.xml
#	app/src/main/res/values/strings.xml
Seidko 4 лет назад
Родитель
Сommit
27454b21b4
52 измененных файлов с 406 добавлено и 124 удалено
  1. 0 1
      English.md
  2. 0 1
      README.md
  3. BIN
      app/cronetlib/cronet_api.jar
  4. BIN
      app/cronetlib/cronet_impl_common_java.jar
  5. BIN
      app/cronetlib/cronet_impl_native_java.jar
  6. BIN
      app/cronetlib/cronet_impl_platform_java.jar
  7. 1 1
      app/src/main/assets/cronet.json
  8. 1 2
      app/src/main/assets/help/ruleHelp.md
  9. 7 0
      app/src/main/assets/updateLog.md
  10. 1 1
      app/src/main/java/io/legado/app/api/controller/BookController.kt
  11. 2 0
      app/src/main/java/io/legado/app/api/controller/BookSourceController.kt
  12. 1 1
      app/src/main/java/io/legado/app/help/BookHelp.kt
  13. 2 0
      app/src/main/java/io/legado/app/help/SourceAnalyzer.kt
  14. 45 0
      app/src/main/java/io/legado/app/help/config/SourceConfig.kt
  15. 1 2
      app/src/main/java/io/legado/app/model/webBook/WebBook.kt
  16. 0 1
      app/src/main/java/io/legado/app/service/CheckSourceService.kt
  17. 1 1
      app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt
  18. 54 0
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceAdapter.kt
  19. 8 0
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceDialog.kt
  20. 30 1
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceViewModel.kt
  21. 54 0
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceAdapter.kt
  22. 8 0
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceDialog.kt
  23. 1 1
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceViewModel.kt
  24. 5 2
      app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
  25. 1 1
      app/src/main/java/io/legado/app/ui/book/read/ContentEditDialog.kt
  26. 33 22
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  27. 0 1
      app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt
  28. 2 2
      app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt
  29. 2 0
      app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt
  30. 2 0
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceAdapter.kt
  31. 7 1
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt
  32. 2 0
      app/src/main/java/io/legado/app/ui/browser/WebViewActivity.kt
  33. 2 0
      app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt
  34. 3 1
      app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt
  35. 7 0
      app/src/main/res/drawable/ic_praise.xml
  36. 55 62
      app/src/main/res/layout/dialog_read_book_style.xml
  37. 1 1
      app/src/main/res/layout/item_book_source.xml
  38. 44 13
      app/src/main/res/layout/item_change_source.xml
  39. 1 0
      app/src/main/res/layout/item_replace_rule.xml
  40. 1 0
      app/src/main/res/layout/item_rss_source.xml
  41. 1 0
      app/src/main/res/layout/item_rule_sub.xml
  42. 2 2
      app/src/main/res/layout/item_theme_config.xml
  43. 2 2
      app/src/main/res/layout/item_toc_regex.xml
  44. 1 0
      app/src/main/res/layout/item_txt_toc_rule.xml
  45. 2 0
      app/src/main/res/values-es-rES/strings.xml
  46. 2 0
      app/src/main/res/values-ja-rJP/strings.xml
  47. 2 0
      app/src/main/res/values-pt-rBR/strings.xml
  48. 2 0
      app/src/main/res/values-zh-rHK/strings.xml
  49. 2 0
      app/src/main/res/values-zh-rTW/strings.xml
  50. 2 0
      app/src/main/res/values-zh/strings.xml
  51. 2 0
      app/src/main/res/values/strings.xml
  52. 1 1
      gradle.properties

+ 0 - 1
English.md

@@ -56,7 +56,6 @@ You can customize the book source, set your own rules, and capture web page data
 * [Releases](https://github.com/gedoor/legado/releases/latest)
 * [Google play - $1.99](https://play.google.com/store/apps/details?id=io.legado.play.release)
 * [Coolapk](https://www.coolapk.com/apk/io.legado.app.release)
-* [Jsdelivr](https://cdn.jsdelivr.net/gh/gedoor/release@release/)
 * [\#Beta](https://kunfei.lanzoui.com/b0f810h4b)
 * [IzzyOnDroid F-Droid Repository](https://apt.izzysoft.de/fdroid/index/apk/io.legado.app.release)
 

+ 0 - 1
README.md

@@ -46,7 +46,6 @@ Legado is a free and open source novel reader for Android.
 * [Releases](https://github.com/gedoor/legado/releases/latest)
 * [Google play - $1.99](https://play.google.com/store/apps/details?id=io.legado.play.release)
 * [Coolapk](https://www.coolapk.com/apk/io.legado.app.release)
-* [Jsdelivr](https://cdn.jsdelivr.net/gh/gedoor/release@release/)
 * [\#Beta](https://kunfei.lanzoui.com/b0f810h4b)
 * [IzzyOnDroid F-Droid Repository](https://apt.izzysoft.de/fdroid/index/apk/io.legado.app.release)
 

BIN
app/cronetlib/cronet_api.jar


BIN
app/cronetlib/cronet_impl_common_java.jar


BIN
app/cronetlib/cronet_impl_native_java.jar


BIN
app/cronetlib/cronet_impl_platform_java.jar


+ 1 - 1
app/src/main/assets/cronet.json

@@ -1 +1 @@
-{"arm64-v8a":"983026b83f3d1dafe223d63e157fb37d","armeabi-v7a":"98d6d0ec3fec519c48a4451b08806c27","x86_64":"7f96e681740c0f7080fcb4623f6294a6","x86":"24b6985f3cd6fe26541b440ef50c12bb","version":"104.0.5112.97"}
+{"arm64-v8a":"974957b4deb6281424de9efa33efe143","armeabi-v7a":"277d780f141a99df77fb78c79edec05f","x86_64":"12bd6ec5c9d90307498b6b44dd2e9cd1","x86":"e9d116221dfd9de432a3e11a239b5bd7","version":"105.0.5195.68"}

+ 1 - 2
app/src/main/assets/help/ruleHelp.md

@@ -152,5 +152,4 @@ let options = {
 ```
 
 * 购买操作
-> 返回购买链接,可直接填写链接或者JavaScript  
-> 可用变量 book chapter java(不支持AnalyzeRule函数) source
+> 可直接填写链接或者JavaScript,如果执行结果是字符串链接将会自动打开浏览器

+ 7 - 0
app/src/main/assets/updateLog.md

@@ -11,6 +11,13 @@
 * 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则或简繁转换出现问题。
 * 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源!
 
+**2022/08/31**
+
+* 更新cronet: 105.0.5195.68
+* 修复一些bug
+* 给书源点赞 by SJJ-dot
+* 墨水屏模式下,书籍信息页不显示模糊书籍封面作为背景
+
 **2022/08/23**
 
 * 验证码输入框显示来自哪个书源

+ 1 - 1
app/src/main/java/io/legado/app/api/controller/BookController.kt

@@ -180,7 +180,7 @@ object BookController {
             ?: return returnData.setErrorMsg("未找到书源")
         try {
             content = runBlocking {
-                WebBook.getContentAwait(this, bookSource, book, chapter).let {
+                WebBook.getContentAwait(bookSource, book, chapter).let {
                     val contentProcessor = ContentProcessor.get(book.name, book.origin)
                     contentProcessor.getContent(book, chapter, it, includeTitle = false)
                         .joinToString("\n")

+ 2 - 0
app/src/main/java/io/legado/app/api/controller/BookSourceController.kt

@@ -5,6 +5,7 @@ import android.text.TextUtils
 import io.legado.app.api.ReturnData
 import io.legado.app.data.appDb
 import io.legado.app.data.entities.BookSource
+import io.legado.app.help.config.SourceConfig
 import io.legado.app.utils.GSON
 import io.legado.app.utils.fromJsonArray
 
@@ -70,6 +71,7 @@ object BookSourceController {
             GSON.fromJsonArray<BookSource>(postData).getOrThrow()?.let {
                 it.forEach { source ->
                     appDb.bookSourceDao.delete(source)
+                    SourceConfig.removeSource(source.bookSourceUrl)
                 }
             }
         }.onFailure {

+ 1 - 1
app/src/main/java/io/legado/app/help/BookHelp.kt

@@ -165,7 +165,7 @@ object BookHelp {
     fun getEpubFile(book: Book): ZipFile {
         val uri = Uri.parse(book.bookUrl)
         if (uri.isContentScheme()) {
-            val path = FileUtils.getPath(downloadDir, cacheFolderName, book.originName)
+            val path = FileUtils.getPath(downloadDir, cacheFolderName, book.getFolderName(), book.originName)
             val file = File(path)
             val doc = DocumentFile.fromSingleUri(appCtx, uri)
                 ?: throw IOException("文件不存在")

+ 2 - 0
app/src/main/java/io/legado/app/help/SourceAnalyzer.kt

@@ -166,6 +166,7 @@ object SourceAnalyzer {
                 }
                 source.loginCheckJs = sourceAny.loginCheckJs
                 source.bookSourceComment = sourceAny.bookSourceComment
+                source.variableComment = sourceAny.variableComment
                 source.lastUpdateTime = sourceAny.lastUpdateTime
                 source.respondTime = sourceAny.respondTime
                 source.weight = sourceAny.weight
@@ -236,6 +237,7 @@ object SourceAnalyzer {
         var loginUi: Any? = null,                       // 登录UI
         var loginCheckJs: String? = null,               // 登录检测js
         var bookSourceComment: String? = "",            // 书源注释
+        var variableComment: String? = null,            // 变量说明
         var lastUpdateTime: Long = 0,                   // 最后更新时间,用于排序
         var respondTime: Long = 180000L,                // 响应时间,用于排序
         var weight: Int = 0,                            // 智能排序的权重

+ 45 - 0
app/src/main/java/io/legado/app/help/config/SourceConfig.kt

@@ -0,0 +1,45 @@
+package io.legado.app.help.config
+
+import android.content.Context.MODE_PRIVATE
+import androidx.core.content.edit
+import splitties.init.appCtx
+
+object SourceConfig {
+    private val sp = appCtx.getSharedPreferences("SourceConfig", MODE_PRIVATE)
+    fun setBookScore(origin: String, name: String, author: String, score: Int) {
+        sp.edit {
+            val preScore = getBookScore(origin, name, author)
+            var newScore = score
+            if (preScore != 0) {
+                newScore = score - preScore
+            }
+
+            putInt(origin, getSourceScore(origin) + newScore)
+
+            putInt("${origin}_${name}_${author}", score)
+        }
+    }
+
+    fun getBookScore(origin: String, name: String, author: String): Int {
+        return sp.getInt("${origin}_${name}_${author}", 0)
+    }
+
+    fun getSourceScore(origin: String): Int {
+        return sp.getInt(origin, 0)
+    }
+
+
+    fun removeSource(origin: String) {
+        sp.all.keys.filter {
+            it.startsWith(origin)
+        }.let {
+            sp.edit {
+                it.forEach {
+                    remove(it)
+                }
+            }
+        }
+    }
+
+
+}

+ 1 - 2
app/src/main/java/io/legado/app/model/webBook/WebBook.kt

@@ -238,12 +238,11 @@ object WebBook {
         context: CoroutineContext = Dispatchers.IO
     ): Coroutine<String> {
         return Coroutine.async(scope, context) {
-            getContentAwait(scope, bookSource, book, bookChapter, nextChapterUrl, needSave)
+            getContentAwait(bookSource, book, bookChapter, nextChapterUrl, needSave)
         }
     }
 
     suspend fun getContentAwait(
-        scope: CoroutineScope,
         bookSource: BookSource,
         book: Book,
         bookChapter: BookChapter,

+ 0 - 1
app/src/main/java/io/legado/app/service/CheckSourceService.kt

@@ -219,7 +219,6 @@ class CheckSourceService : BaseService() {
                     //校验正文
                     if (CheckSource.checkContent) {
                         WebBook.getContentAwait(
-                            this,
                             bookSource = source,
                             book = mBook,
                             bookChapter = toc.first(),

+ 1 - 1
app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt

@@ -1,7 +1,7 @@
 package io.legado.app.ui.about
 
+import java.text.SimpleDateFormat
 import android.content.Context
-import android.icu.text.SimpleDateFormat
 import android.os.Bundle
 import android.view.Menu
 import android.view.MenuItem

+ 54 - 0
app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceAdapter.kt

@@ -5,14 +5,19 @@ import android.os.Bundle
 import android.view.View
 import android.view.ViewGroup
 import androidx.appcompat.widget.PopupMenu
+import androidx.core.graphics.drawable.DrawableCompat
+import androidx.core.view.isVisible
 import androidx.recyclerview.widget.DiffUtil
 import io.legado.app.R
 import io.legado.app.base.adapter.DiffRecyclerAdapter
 import io.legado.app.base.adapter.ItemViewHolder
 import io.legado.app.data.entities.SearchBook
 import io.legado.app.databinding.ItemChangeSourceBinding
+import io.legado.app.utils.getCompatColor
+import io.legado.app.utils.gone
 import io.legado.app.utils.invisible
 import io.legado.app.utils.visible
+import splitties.init.appCtx
 import splitties.views.onLongClick
 
 
@@ -68,10 +73,57 @@ class ChangeBookSourceAdapter(
                     }
                 }
             }
+            val score = callBack.getBookScore(item)
+            if (score > 0) {
+                binding.ivBad.gone()
+                binding.ivGood.visible()
+                DrawableCompat.setTint(binding.ivGood.drawable, appCtx.getCompatColor(R.color.md_red_A200))
+                DrawableCompat.setTint(binding.ivBad.drawable, appCtx.getCompatColor(R.color.md_blue_100))
+            } else if (score < 0) {
+                binding.ivGood.gone()
+                binding.ivBad.visible()
+                DrawableCompat.setTint(binding.ivGood.drawable, appCtx.getCompatColor(R.color.md_red_100))
+                DrawableCompat.setTint(binding.ivBad.drawable, appCtx.getCompatColor(R.color.md_blue_A200))
+            } else {
+                binding.ivGood.visible()
+                binding.ivBad.visible()
+                DrawableCompat.setTint(binding.ivGood.drawable, appCtx.getCompatColor(R.color.md_red_100))
+                DrawableCompat.setTint(binding.ivBad.drawable, appCtx.getCompatColor(R.color.md_blue_100))
+            }
         }
     }
 
     override fun registerListener(holder: ItemViewHolder, binding: ItemChangeSourceBinding) {
+        binding.ivGood.setOnClickListener {
+            if (binding.ivBad.isVisible) {
+                DrawableCompat.setTint(binding.ivGood.drawable, appCtx.getCompatColor(R.color.md_red_A200))
+                binding.ivBad.gone()
+                getItem(holder.layoutPosition)?.let {
+                    callBack.setBookScore(it, 1)
+                }
+            } else {
+                DrawableCompat.setTint(binding.ivGood.drawable, appCtx.getCompatColor(R.color.md_red_100))
+                binding.ivBad.visible()
+                getItem(holder.layoutPosition)?.let {
+                    callBack.setBookScore(it, 0)
+                }
+            }
+        }
+        binding.ivBad.setOnClickListener {
+            if (binding.ivGood.isVisible) {
+                DrawableCompat.setTint(binding.ivBad.drawable, appCtx.getCompatColor(R.color.md_blue_A200))
+                binding.ivGood.gone()
+                getItem(holder.layoutPosition)?.let {
+                    callBack.setBookScore(it, -1)
+                }
+            } else {
+                DrawableCompat.setTint(binding.ivBad.drawable, appCtx.getCompatColor(R.color.md_blue_100))
+                binding.ivGood.visible()
+                getItem(holder.layoutPosition)?.let {
+                    callBack.setBookScore(it, 0)
+                }
+            }
+        }
         holder.itemView.setOnClickListener {
             getItem(holder.layoutPosition)?.let {
                 if (it.bookUrl != callBack.bookUrl) {
@@ -120,5 +172,7 @@ class ChangeBookSourceAdapter(
         fun editSource(searchBook: SearchBook)
         fun disableSource(searchBook: SearchBook)
         fun deleteSource(searchBook: SearchBook)
+        fun setBookScore(searchBook: SearchBook, score: Int)
+        fun getBookScore(searchBook: SearchBook): Int
     }
 }

+ 8 - 0
app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceDialog.kt

@@ -294,6 +294,14 @@ class ChangeBookSourceDialog() : BaseDialogFragment(R.layout.dialog_book_change_
         }
     }
 
+    override fun setBookScore(searchBook: SearchBook, score: Int) {
+        viewModel.setBookScore(searchBook,score)
+    }
+
+    override fun getBookScore(searchBook: SearchBook): Int {
+        return viewModel.getBookScore(searchBook)
+    }
+
     private fun changeSource(searchBook: SearchBook, onSuccess: (() -> Unit)? = null) {
         waitDialog.setText(R.string.load_toc)
         waitDialog.show()

+ 30 - 1
app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceViewModel.kt

@@ -16,6 +16,7 @@ import io.legado.app.data.entities.BookSource
 import io.legado.app.data.entities.SearchBook
 import io.legado.app.exception.NoStackTraceException
 import io.legado.app.help.config.AppConfig
+import io.legado.app.help.config.SourceConfig
 import io.legado.app.help.coroutine.CompositeCoroutine
 import io.legado.app.help.coroutine.Coroutine
 import io.legado.app.model.webBook.WebBook
@@ -82,7 +83,23 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
             searchCallback = null
         }
     }.map {
-        searchBooks.sortedBy { it.originOrder }
+        searchBooks.sortedWith { o1, o2 ->
+            val o1bs = SourceConfig.getBookScore(o1.origin, o1.name, o1.author)
+            val o2bs = SourceConfig.getBookScore(o2.origin, o2.name, o2.author)
+            when {
+                o1bs - o2bs > 0 -> -1
+                o1bs - o2bs < 0 -> 1
+                else -> {
+                    val o1ss = SourceConfig.getSourceScore(o1.origin)
+                    val o2ss = SourceConfig.getSourceScore(o2.origin)
+                    when {
+                        o1ss - o2ss > 0 -> -1
+                        o1ss - o2ss < 0 -> 1
+                        else -> o1.originOrder - o2.originOrder
+                    }
+                }
+            }
+        }
     }.flowOn(IO)
 
     @Volatile
@@ -351,6 +368,7 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
             appDb.bookSourceDao.getBookSource(searchBook.origin)?.let { source ->
                 appDb.bookSourceDao.delete(source)
                 appDb.searchBookDao.delete(searchBook)
+                SourceConfig.removeSource(source.bookSourceUrl)
             }
         }
         searchBooks.remove(searchBook)
@@ -379,6 +397,17 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
         }
     }
 
+    fun setBookScore(searchBook: SearchBook, score: Int) {
+        execute {
+            SourceConfig.setBookScore(searchBook.origin, searchBook.name, searchBook.author, score)
+            searchCallback?.upAdapter()
+        }
+    }
+
+    fun getBookScore(searchBook: SearchBook): Int {
+        return SourceConfig.getBookScore(searchBook.origin, searchBook.name, searchBook.author)
+    }
+
     interface SourceCallback {
 
         fun searchSuccess(searchBook: SearchBook)

+ 54 - 0
app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceAdapter.kt

@@ -5,14 +5,19 @@ import android.os.Bundle
 import android.view.View
 import android.view.ViewGroup
 import androidx.appcompat.widget.PopupMenu
+import androidx.core.graphics.drawable.DrawableCompat
+import androidx.core.view.isVisible
 import androidx.recyclerview.widget.DiffUtil
 import io.legado.app.R
 import io.legado.app.base.adapter.DiffRecyclerAdapter
 import io.legado.app.base.adapter.ItemViewHolder
 import io.legado.app.data.entities.SearchBook
 import io.legado.app.databinding.ItemChangeSourceBinding
+import io.legado.app.utils.getCompatColor
+import io.legado.app.utils.gone
 import io.legado.app.utils.invisible
 import io.legado.app.utils.visible
+import splitties.init.appCtx
 import splitties.views.onLongClick
 
 
@@ -68,10 +73,57 @@ class ChangeChapterSourceAdapter(
                     }
                 }
             }
+            val score = callBack.getBookScore(item)
+            if (score > 0) {
+                binding.ivBad.gone()
+                binding.ivGood.visible()
+                DrawableCompat.setTint(binding.ivGood.drawable, appCtx.getCompatColor(R.color.md_red_A200))
+                DrawableCompat.setTint(binding.ivBad.drawable, appCtx.getCompatColor(R.color.md_blue_100))
+            } else if (score < 0) {
+                binding.ivGood.gone()
+                binding.ivBad.visible()
+                DrawableCompat.setTint(binding.ivGood.drawable, appCtx.getCompatColor(R.color.md_red_100))
+                DrawableCompat.setTint(binding.ivBad.drawable, appCtx.getCompatColor(R.color.md_blue_A200))
+            } else {
+                binding.ivGood.visible()
+                binding.ivBad.visible()
+                DrawableCompat.setTint(binding.ivGood.drawable, appCtx.getCompatColor(R.color.md_red_100))
+                DrawableCompat.setTint(binding.ivBad.drawable, appCtx.getCompatColor(R.color.md_blue_100))
+            }
         }
     }
 
     override fun registerListener(holder: ItemViewHolder, binding: ItemChangeSourceBinding) {
+        binding.ivGood.setOnClickListener {
+            if (binding.ivBad.isVisible) {
+                DrawableCompat.setTint(binding.ivGood.drawable, appCtx.getCompatColor(R.color.md_red_A200))
+                binding.ivBad.gone()
+                getItem(holder.layoutPosition)?.let {
+                    callBack.setBookScore(it, 1)
+                }
+            } else {
+                DrawableCompat.setTint(binding.ivGood.drawable, appCtx.getCompatColor(R.color.md_red_100))
+                binding.ivBad.visible()
+                getItem(holder.layoutPosition)?.let {
+                    callBack.setBookScore(it, 0)
+                }
+            }
+        }
+        binding.ivBad.setOnClickListener {
+            if (binding.ivGood.isVisible) {
+                DrawableCompat.setTint(binding.ivBad.drawable, appCtx.getCompatColor(R.color.md_blue_A200))
+                binding.ivGood.gone()
+                getItem(holder.layoutPosition)?.let {
+                    callBack.setBookScore(it, -1)
+                }
+            } else {
+                DrawableCompat.setTint(binding.ivBad.drawable, appCtx.getCompatColor(R.color.md_blue_100))
+                binding.ivGood.visible()
+                getItem(holder.layoutPosition)?.let {
+                    callBack.setBookScore(it, 0)
+                }
+            }
+        }
         holder.itemView.setOnClickListener {
             getItem(holder.layoutPosition)?.let {
                 callBack.openToc(it)
@@ -118,5 +170,7 @@ class ChangeChapterSourceAdapter(
         fun editSource(searchBook: SearchBook)
         fun disableSource(searchBook: SearchBook)
         fun deleteSource(searchBook: SearchBook)
+        fun setBookScore(searchBook: SearchBook, score: Int)
+        fun getBookScore(searchBook: SearchBook): Int
     }
 }

+ 8 - 0
app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceDialog.kt

@@ -314,6 +314,14 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c
         }
     }
 
+    override fun setBookScore(searchBook: SearchBook, score: Int) {
+        viewModel.setBookScore(searchBook, score)
+    }
+
+    override fun getBookScore(searchBook: SearchBook): Int {
+        return viewModel.getBookScore(searchBook)
+    }
+
     override fun clickChapter(bookChapter: BookChapter, nextChapterUrl: String?) {
         searchBook?.let {
             binding.loadingToc.show()

+ 1 - 1
app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceViewModel.kt

@@ -35,7 +35,7 @@ class ChangeChapterSourceViewModel(application: Application) :
         execute {
             val bookSource = appDb.bookSourceDao.getBookSource(book.origin)
                 ?: throw NoStackTraceException("书源不存在")
-            WebBook.getContentAwait(this, bookSource, book, chapter, nextChapterUrl, false)
+            WebBook.getContentAwait(bookSource, book, chapter, nextChapterUrl, false)
         }.onSuccess {
             success.invoke(it)
         }.onError {

+ 5 - 2
app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt

@@ -21,6 +21,7 @@ import io.legado.app.data.entities.BookChapter
 import io.legado.app.data.entities.BookSource
 import io.legado.app.databinding.ActivityBookInfoBinding
 import io.legado.app.databinding.DialogEditTextBinding
+import io.legado.app.help.config.AppConfig
 import io.legado.app.lib.dialogs.alert
 import io.legado.app.lib.theme.backgroundColor
 import io.legado.app.lib.theme.bottomBackground
@@ -247,8 +248,10 @@ class BookInfoActivity :
 
     private fun showCover(book: Book) {
         binding.ivCover.load(book.getDisplayCover(), book.name, book.author, false, book.origin)
-        BookCover.loadBlur(this, book.getDisplayCover())
-            .into(binding.bgBook)
+        if(!AppConfig.isEInkMode) {
+            BookCover.loadBlur(this, book.getDisplayCover())
+                .into(binding.bgBook)
+        }
     }
 
     private fun upLoading(isLoading: Boolean, chapterList: List<BookChapter>? = null) {

+ 1 - 1
app/src/main/java/io/legado/app/ui/book/read/ContentEditDialog.kt

@@ -126,7 +126,7 @@ class ContentEditDialog : BaseDialogFragment(R.layout.dialog_content_edit) {
                     content = null
                     BookHelp.delContent(book, chapter)
                     if (!book.isLocalBook()) ReadBook.bookSource?.let { bookSource ->
-                        WebBook.getContentAwait(this, bookSource, book, chapter)
+                        WebBook.getContentAwait(bookSource, book, chapter)
                     }
                 }
                 return@execute content ?: let {

+ 33 - 22
app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt

@@ -36,6 +36,7 @@ import io.legado.app.lib.dialogs.selector
 import io.legado.app.lib.theme.accentColor
 import io.legado.app.model.ReadAloud
 import io.legado.app.model.ReadBook
+import io.legado.app.model.analyzeRule.AnalyzeRule
 import io.legado.app.receiver.TimeBatteryReceiver
 import io.legado.app.service.BaseReadAloudService
 import io.legado.app.ui.about.AppLogDialog
@@ -962,31 +963,41 @@ class ReadBookActivity : BaseReadBookActivity(),
     }
 
     override fun payAction() {
-        Coroutine.async(this) {
-            val book = ReadBook.book ?: throw NoStackTraceException("no book")
+        ReadBook.book?.let { book ->
+            if (book.isLocalBook()) return
             val chapter = appDb.bookChapterDao.getChapter(book.bookUrl, ReadBook.durChapterIndex)
-                ?: throw NoStackTraceException("no chapter")
-            val source = ReadBook.bookSource ?: throw NoStackTraceException("no book source")
-            val payAction = source.getContentRule().payAction
-            if (payAction.isNullOrEmpty()) {
-                throw NoStackTraceException("no pay action")
-            }
-            JsUtils.evalJs(payAction) {
-                it["java"] = source
-                it["source"] = source
-                it["book"] = book
-                it["chapter"] = chapter
-            }
-        }.onSuccess {
-            if (it.isNotBlank()) {
-                startActivity<WebViewActivity> {
-                    putExtra("title", getString(R.string.chapter_pay))
-                    putExtra("url", it)
-                    IntentData.put(it, ReadBook.bookSource?.getHeaderMap(true))
+            if (chapter == null) {
+                toastOnUi("no chapter")
+                return
+            }
+            alert(R.string.chapter_pay) {
+                setMessage(chapter.title)
+                yesButton {
+                    Coroutine.async {
+                        val source = ReadBook.bookSource ?: throw NoStackTraceException("no book source")
+                        val payAction = source.getContentRule().payAction
+                        if (payAction.isNullOrEmpty()) {
+                            throw NoStackTraceException("no pay action")
+                        }
+                        val analyzeRule = AnalyzeRule(book, source)
+                        analyzeRule.setBaseUrl(chapter.url)
+                        analyzeRule.chapter = chapter
+                        analyzeRule.evalJS(payAction).toString()
+                    }.onSuccess {
+                        if (it.isNotBlank()) {
+                            startActivity<WebViewActivity> {
+                                putExtra("title", R.string.chapter_pay)
+                                putExtra("url", it)
+                                IntentData.put(it, ReadBook.bookSource?.getHeaderMap(true))
+                            }
+                        }
+                    }.onError {
+                        AppLog.putDebug(it.localizedMessage)
+                        toastOnUi(it.localizedMessage)
+                    }
                 }
+                noButton()
             }
-        }.onError {
-            toastOnUi(it.localizedMessage)
         }
     }
 

+ 0 - 1
app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt

@@ -216,7 +216,6 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
                 toc.first()
             }
             WebBook.getContentAwait(
-                this,
                 bookSource = source,
                 book = book,
                 bookChapter = toc[book.durChapterIndex],

+ 2 - 2
app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt

@@ -201,7 +201,7 @@ class ReadMenu @JvmOverloads constructor(
         activity?.window?.attributes = params
     }
 
-    fun runMenuIn(anim: Boolean = AppConfig.isEInkMode) {
+    fun runMenuIn(anim: Boolean = !AppConfig.isEInkMode) {
         this.visible()
         binding.titleBar.visible()
         binding.bottomMenu.visible()
@@ -214,7 +214,7 @@ class ReadMenu @JvmOverloads constructor(
         }
     }
 
-    fun runMenuOut(anim: Boolean = AppConfig.isEInkMode, onMenuOutEnd: (() -> Unit)? = null) {
+    fun runMenuOut(anim: Boolean = !AppConfig.isEInkMode, onMenuOutEnd: (() -> Unit)? = null) {
         this.onMenuOutEnd = onMenuOutEnd
         if (this.isVisible) {
             if (anim) {

+ 2 - 0
app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt

@@ -7,6 +7,7 @@ import io.legado.app.data.appDb
 import io.legado.app.data.entities.BookSource
 import io.legado.app.exception.NoStackTraceException
 import io.legado.app.help.RuleComplete
+import io.legado.app.help.config.SourceConfig
 import io.legado.app.help.http.CookieStore
 import io.legado.app.help.http.newCallStrResponse
 import io.legado.app.help.http.okHttpClient
@@ -40,6 +41,7 @@ class BookSourceEditViewModel(application: Application) : BaseViewModel(applicat
             oldSourceUrl?.let {
                 if (oldSourceUrl != source.bookSourceUrl) {
                     appDb.bookSourceDao.delete(it)
+                    SourceConfig.removeSource(it)
                 }
             }
             oldSourceUrl = source.bookSourceUrl

+ 2 - 0
app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceAdapter.kt

@@ -207,10 +207,12 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) :
             source.enabledExplore -> {
                 iv.setColorFilter(Color.GREEN)
                 iv.visible()
+                iv.contentDescription = context.getString(R.string.tag_explore_enabled)
             }
             else -> {
                 iv.setColorFilter(Color.RED)
                 iv.visible()
+                iv.contentDescription = context.getString(R.string.tag_explore_disabled)
             }
         }
     }

+ 7 - 1
app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt

@@ -5,6 +5,7 @@ import android.text.TextUtils
 import io.legado.app.base.BaseViewModel
 import io.legado.app.data.appDb
 import io.legado.app.data.entities.BookSource
+import io.legado.app.help.config.SourceConfig
 import io.legado.app.utils.*
 import java.io.File
 import java.io.FileOutputStream
@@ -38,7 +39,12 @@ class BookSourceViewModel(application: Application) : BaseViewModel(application)
     }
 
     fun del(vararg sources: BookSource) {
-        execute { appDb.bookSourceDao.delete(*sources) }
+        execute {
+            appDb.bookSourceDao.delete(*sources)
+            sources.forEach {
+                SourceConfig.removeSource(it.bookSourceUrl)
+            }
+        }
     }
 
     fun update(vararg bookSource: BookSource) {

+ 2 - 0
app/src/main/java/io/legado/app/ui/browser/WebViewActivity.kt

@@ -125,12 +125,14 @@ class WebViewActivity : VMBaseActivity<ActivityWebViewBinding, WebViewModel>() {
     private fun upWebViewTheme() {
         if (AppConfig.isNightTheme) {
             if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) {
+                @Suppress("DEPRECATION")
                 WebSettingsCompat.setForceDarkStrategy(
                     binding.webView.settings,
                     WebSettingsCompat.DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING
                 )
             }
             if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
+                @Suppress("DEPRECATION")
                 WebSettingsCompat.setForceDark(
                     binding.webView.settings,
                     WebSettingsCompat.FORCE_DARK_ON

+ 2 - 0
app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt

@@ -15,6 +15,7 @@ import io.legado.app.data.entities.BookSource
 import io.legado.app.data.entities.rule.ExploreKind
 import io.legado.app.databinding.ItemFilletTextBinding
 import io.legado.app.databinding.ItemFindBookBinding
+import io.legado.app.help.config.SourceConfig
 import io.legado.app.help.coroutine.Coroutine
 import io.legado.app.lib.theme.accentColor
 import io.legado.app.ui.login.SourceLoginActivity
@@ -174,6 +175,7 @@ class ExploreAdapter(context: Context, val callBack: CallBack) :
                 }
                 R.id.menu_del -> Coroutine.async(callBack.scope) {
                     appDb.bookSourceDao.delete(source)
+                    SourceConfig.removeSource(source.bookSourceUrl)
                 }
             }
             true

+ 3 - 1
app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt

@@ -141,7 +141,7 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
                             SelectItem(getString(R.string.action_save), "save"),
                             SelectItem(getString(R.string.select_folder), "selectFolder")
                         )
-                    ) { _, charSequence, i ->
+                    ) { _, charSequence, _ ->
                         when (charSequence.value) {
                             "save" -> saveImage(webPic)
                             "selectFolder" -> selectSaveFolder(null)
@@ -219,12 +219,14 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
     private fun upWebViewTheme() {
         if (AppConfig.isNightTheme) {
             if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) {
+                @Suppress("DEPRECATION")
                 WebSettingsCompat.setForceDarkStrategy(
                     binding.webView.settings,
                     WebSettingsCompat.DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING
                 )
             }
             if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
+                @Suppress("DEPRECATION")
                 WebSettingsCompat.setForceDark(
                     binding.webView.settings,
                     WebSettingsCompat.FORCE_DARK_ON

+ 7 - 0
app/src/main/res/drawable/ic_praise.xml

@@ -0,0 +1,7 @@
+<vector android:height="24dp" android:viewportHeight="1024"
+    android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="#FF000000" android:pathData="M939.4,423.4c-23,-37.3 -62.9,-60.8 -107,-63.2 -2.8,-0.4 -5.5,-0.6 -8.3,-0.6l-152.2,-0.1c6.6,-29 10,-58.7 10,-88.7 0,-28.2 -3.2,-57.1 -9.6,-86 -0.4,-2 -1.1,-4 -1.9,-5.9 -15.8,-57.3 -67.4,-96.8 -127.3,-96.8 -72.8,0 -132.1,59.3 -132.1,132.1 0,3.3 0.1,6.7 0.4,10 -2.2,57.2 -32.1,109.9 -80.3,141.4 -14.4,9.4 -18.5,28.8 -9.1,43.2 9.4,14.4 28.8,18.5 43.2,9.1 65.8,-42.9 106.4,-115.3 108.7,-193.7 0,-1.3 -0,-2.7 -0.1,-4 -0.2,-2 -0.3,-4 -0.3,-6 0,-38.4 31.2,-69.6 69.6,-69.6 32.6,0 60.5,22.2 67.8,54 0.4,1.5 0.8,3 1.4,4.5 4.7,22.8 7.1,45.6 7.1,67.7 0,37.5 -6.2,74.4 -18.5,109.6 -3.3,9.5 -1.8,20.1 4,28.3 5.9,8.2 15.3,13.1 25.4,13.2l193.2,0.1c1.4,0.3 2.9,0.4 4.3,0.5 24.1,1 45.9,13.6 58.6,34.1 7.8,12.3 11.4,26.8 10.4,41.9 -0.1,0.9 -0.1,1.9 -0.1,2.9 0,0.9 0,1.7 0.1,2.5 0,0.3 -0,0.7 -0.1,1 -0.1,0.4 -0.2,0.8 -0.3,1.2l-75,330.4c-0.9,1.3 -1.7,2.6 -2.4,4 -5.9,11.8 -14.7,21.5 -25.3,28.2 -10.7,6.8 -23.1,10.6 -35.8,11.1 -0.9,-0.1 -513.8,-0.2 -513.8,-0.2 -0.5,-0 -0.9,-0 -1.4,-0 0,0 -111,0.2 -112.7,0.5 -1.9,0 -3.4,-1.5 -3.4,-3.4l0.3,-416.3c0,-1.9 1.5,-3.4 3,-3.5l1.2,0.1c1.2,0.1 2.7,0.3 3.5,0.2l83.8,-0.2 0,339.4c0,17.3 14,31.2 31.2,31.2s31.2,-14 31.2,-31.2L281,435.4c0,-1.8 0,-8.6 0,-10.4 0,-17.3 -14,-30.9 -31.2,-30.9 -1.5,0 -117.5,0.3 -119.4,0.3 -36.3,0 -65.9,29.6 -65.9,65.9l-0.3,416.3c0,36.3 29.6,65.9 65.9,65.9 2.5,0 111.4,-0.5 111.4,-0.5 0.5,0 0.9,0 1.4,0 0,0 511.5,0.3 512.5,0.3 25.5,0 50.3,-7.2 71.6,-20.7 19.6,-12.3 35.8,-29.9 46.8,-51 3.7,-5.6 6.4,-11.9 8.3,-18.6 0.1,-0.4 0.2,-0.8 0.3,-1.2l74.9,-330.3c1.6,-6.2 2.3,-12.6 2,-19C960.9,473.4 953.9,446.3 939.4,423.4z"/>
+    <path android:fillColor="#FF000000" android:pathData="M450,518.7c-17.3,0 -31.2,14 -31.2,31.2l0,30.5c0,17.3 14,31.2 31.2,31.2 17.3,0 31.2,-14 31.2,-31.2l0,-30.5C481.3,532.6 467.3,518.7 450,518.7z"/>
+    <path android:fillColor="#FF000000" android:pathData="M693.8,518.7c-17.3,0 -31.2,14 -31.2,31.2l0,30.5c0,17.3 14,31.2 31.2,31.2 17.3,0 31.2,-14 31.2,-31.2l0,-30.5C725,532.6 711.1,518.7 693.8,518.7z"/>
+    <path android:fillColor="#FF000000" android:pathData="M648.9,660.1c-14.3,-9.4 -33.6,-5.4 -43.2,8.8 -0.1,0.2 -13.6,19.8 -34.2,19.8 -20,0 -32.4,-18.1 -33.3,-19.4 -9.2,-14.4 -28.3,-18.8 -42.8,-9.8 -14.7,9.1 -19.2,28.4 -10.1,43 11.2,18 42,48.6 86.2,48.6 44,0 75.1,-30.3 86.6,-48.2C667.4,688.5 663.2,669.5 648.9,660.1z"/>
+</vector>

+ 55 - 62
app/src/main/res/layout/dialog_read_book_style.xml

@@ -3,32 +3,28 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tool="http://schemas.android.com/tools"
     android:id="@+id/root_view"
-    android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="@color/background"
-    android:padding="10dp">
+    android:orientation="vertical">
 
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:gravity="center_vertical"
         android:orientation="horizontal"
-        android:gravity="center_vertical">
-
-        <Space
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_weight="0.5" />
+        android:paddingHorizontal="16dp">
 
         <io.legado.app.ui.book.read.config.TextFontWeightConverter
             android:id="@+id/text_font_weight_converter"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:gravity="center"
             android:paddingLeft="6dp"
-            android:paddingRight="6dp"
             android:paddingTop="4dp"
+            android:paddingRight="6dp"
             android:paddingBottom="4dp"
-            android:gravity="center"
             android:textSize="14sp"
             app:isBottomBackground="true"
             app:radius="3dp" />
@@ -42,12 +38,12 @@
             android:id="@+id/tv_text_font"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:gravity="center"
             android:paddingLeft="6dp"
-            android:paddingRight="6dp"
             android:paddingTop="4dp"
+            android:paddingRight="6dp"
             android:paddingBottom="4dp"
             android:text="@string/text_font"
-            android:gravity="center"
             android:textSize="14sp"
             app:isBottomBackground="true"
             app:radius="3dp" />
@@ -61,12 +57,12 @@
             android:id="@+id/tv_text_indent"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:gravity="center"
             android:paddingLeft="6dp"
-            android:paddingRight="6dp"
             android:paddingTop="4dp"
+            android:paddingRight="6dp"
             android:paddingBottom="4dp"
             android:text="@string/text_indent"
-            android:gravity="center"
             android:textSize="14sp"
             app:isBottomBackground="true"
             app:radius="3dp" />
@@ -80,11 +76,11 @@
             android:id="@+id/chinese_converter"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:gravity="center"
             android:paddingLeft="6dp"
-            android:paddingRight="6dp"
             android:paddingTop="4dp"
+            android:paddingRight="6dp"
             android:paddingBottom="4dp"
-            android:gravity="center"
             android:textSize="14sp"
             app:isBottomBackground="true"
             app:radius="3dp" />
@@ -98,12 +94,12 @@
             android:id="@+id/tv_padding"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:gravity="center"
             android:paddingLeft="6dp"
-            android:paddingRight="6dp"
             android:paddingTop="4dp"
+            android:paddingRight="6dp"
             android:paddingBottom="4dp"
             android:text="@string/padding"
-            android:gravity="center"
             android:textSize="14sp"
             app:isBottomBackground="true"
             app:radius="3dp" />
@@ -117,30 +113,24 @@
             android:id="@+id/tv_tip"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:gravity="center"
             android:paddingLeft="6dp"
-            android:paddingRight="6dp"
             android:paddingTop="4dp"
+            android:paddingRight="6dp"
             android:paddingBottom="4dp"
             android:text="@string/information"
-            android:gravity="center"
             android:textSize="14sp"
             app:isBottomBackground="true"
             app:radius="3dp" />
 
-        <Space
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_weight="0.5" />
-
     </LinearLayout>
 
     <io.legado.app.ui.widget.DetailSeekBar
         android:id="@+id/dsb_text_size"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginTop="10dp"
-        android:paddingLeft="10dp"
-        android:paddingRight="10dp"
+        android:layout_marginHorizontal="16dp"
+        android:layout_marginTop="8dp"
         app:isBottomBackground="true"
         app:max="45"
         app:title="@string/text_size" />
@@ -149,8 +139,7 @@
         android:id="@+id/dsb_text_letter_spacing"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingLeft="10dp"
-        android:paddingRight="10dp"
+        android:layout_marginHorizontal="16dp"
         app:isBottomBackground="true"
         app:max="100"
         app:title="@string/text_letter_spacing" />
@@ -159,8 +148,7 @@
         android:id="@+id/dsb_line_size"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingLeft="10dp"
-        android:paddingRight="10dp"
+        android:layout_marginHorizontal="16dp"
         app:isBottomBackground="true"
         app:max="20"
         app:title="@string/line_size" />
@@ -169,8 +157,7 @@
         android:id="@+id/dsb_paragraph_spacing"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingLeft="10dp"
-        android:paddingRight="10dp"
+        android:layout_marginHorizontal="16dp"
         app:isBottomBackground="true"
         app:max="20"
         app:title="@string/paragraph_size" />
@@ -179,36 +166,37 @@
         android:id="@+id/vw_bg_fg"
         android:layout_width="match_parent"
         android:layout_height="0.8dp"
+        android:layout_marginHorizontal="16dp"
+        android:layout_marginVertical="8dp"
         android:background="@color/btn_bg_press" />
 
     <TextView
         android:id="@+id/tv_page_anim"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingTop="3dp"
-        android:paddingBottom="3dp"
-        android:paddingStart="6dp"
-        android:paddingEnd="6dp"
-        android:text="@string/page_anim" />
+        android:layout_marginHorizontal="16dp"
+        android:layout_marginBottom="4dp"
+        android:alpha="0.75"
+        android:text="@string/page_anim"
+        android:textSize="12sp" />
 
     <RadioGroup
         android:id="@+id/rg_page_anim"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingLeft="10dp"
-        android:paddingRight="10dp"
-        android:orientation="horizontal"
-        android:gravity="center">
+        android:layout_marginHorizontal="11dp"
+        android:gravity="center"
+        android:orientation="horizontal">
 
         <io.legado.app.lib.theme.view.ThemeRadioNoButton
             android:id="@+id/rb_anim0"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
+            android:layout_margin="4dp"
             android:layout_weight="1"
-            android:layout_margin="5dp"
-            android:padding="5dp"
             android:button="@null"
             android:gravity="center"
+            android:padding="5dp"
             android:singleLine="true"
             android:text="@string/page_anim_cover"
             app:isBottomBackground="true" />
@@ -217,11 +205,11 @@
             android:id="@+id/rb_anim1"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
+            android:layout_margin="4dp"
             android:layout_weight="1"
-            android:layout_margin="5dp"
-            android:padding="5dp"
             android:button="@null"
             android:gravity="center"
+            android:padding="5dp"
             android:singleLine="true"
             android:text="@string/page_anim_slide"
             app:isBottomBackground="true" />
@@ -230,11 +218,11 @@
             android:id="@+id/rb_simulation_anim"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
+            android:layout_margin="4dp"
             android:layout_weight="1"
-            android:layout_margin="5dp"
-            android:padding="5dp"
             android:button="@null"
             android:gravity="center"
+            android:padding="5dp"
             android:singleLine="true"
             android:text="@string/page_anim_simulation"
             app:isBottomBackground="true" />
@@ -243,11 +231,11 @@
             android:id="@+id/rb_scroll_anim"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
+            android:layout_margin="4dp"
             android:layout_weight="1"
-            android:layout_margin="5dp"
-            android:padding="5dp"
             android:button="@null"
             android:gravity="center"
+            android:padding="5dp"
             android:singleLine="true"
             android:text="@string/page_anim_scroll"
             app:isBottomBackground="true" />
@@ -256,11 +244,11 @@
             android:id="@+id/rb_no_anim"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
+            android:layout_margin="4dp"
             android:layout_weight="1"
-            android:layout_margin="5dp"
-            android:padding="5dp"
             android:button="@null"
             android:gravity="center"
+            android:padding="5dp"
             android:singleLine="true"
             android:text="@string/page_anim_none"
             app:isBottomBackground="true" />
@@ -271,24 +259,25 @@
         android:id="@+id/vw_bg_fg1"
         android:layout_width="match_parent"
         android:layout_height="0.8dp"
+        android:layout_marginHorizontal="16dp"
+        android:layout_marginVertical="8dp"
         android:background="@color/btn_bg_press" />
 
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:gravity="center_vertical">
+        android:gravity="center_vertical"
+        android:orientation="horizontal">
 
         <TextView
             android:id="@+id/tv_bg_ts"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
+            android:layout_marginStart="16dp"
             android:layout_weight="1"
-            android:paddingStart="6dp"
-            android:paddingEnd="6dp"
-            android:paddingTop="5dp"
-            android:paddingBottom="5dp"
-            android:text="@string/text_bg_style" />
+            android:alpha="0.75"
+            android:text="@string/text_bg_style"
+            android:textSize="12sp" />
 
         <TextView
             android:id="@+id/tv_share_layout"
@@ -300,8 +289,8 @@
             android:id="@+id/cb_share_layout"
             android:layout_width="20dp"
             android:layout_height="20dp"
-            android:layout_marginRight="6dp"
-            android:layout_marginLeft="6dp" />
+            android:layout_marginStart="6dp"
+            android:layout_marginEnd="16dp" />
 
     </LinearLayout>
 
@@ -309,7 +298,11 @@
         android:id="@+id/rv_style"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:layout_marginBottom="16dp"
+        android:clipToPadding="false"
         android:orientation="horizontal"
+        android:paddingHorizontal="12dp"
         app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
         tool:listitem="@layout/item_read_style" />
 

+ 1 - 1
app/src/main/res/layout/item_book_source.xml

@@ -54,6 +54,7 @@
         android:padding="6dp"
         android:src="@drawable/ic_more_vert"
         android:tint="@color/primaryText"
+        android:contentDescription="@string/more_menu"
         app:layout_constraintBottom_toTopOf="@id/iv_debug_text"
         app:layout_constraintRight_toRightOf="parent"
         app:layout_constraintTop_toTopOf="parent"
@@ -63,7 +64,6 @@
         android:id="@+id/iv_explore"
         android:layout_width="8dp"
         android:layout_height="8dp"
-        android:contentDescription="@string/more_menu"
         android:scaleType="centerCrop"
         android:src="@color/md_green_600"
         app:layout_constraintRight_toRightOf="@id/iv_menu_more"

+ 44 - 13
app/src/main/res/layout/item_change_source.xml

@@ -1,56 +1,87 @@
 <?xml version="1.0" encoding="utf-8"?>
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:background="?android:attr/selectableItemBackground"
-    android:paddingLeft="10dp"
-    android:paddingTop="10dp"
-    android:paddingBottom="10dp"
     tools:ignore="RtlHardcoded,RtlSymmetry">
 
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/iv_good"
+        android:layout_width="30dp"
+        android:layout_height="0dp"
+        android:layout_marginTop="5dp"
+        android:padding="5dp"
+        android:src="@drawable/ic_praise"
+        app:layout_constraintBottom_toTopOf="@+id/iv_bad"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:tint="@color/md_red_A200" />
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/iv_bad"
+        android:layout_width="30dp"
+        android:layout_height="0dp"
+        android:layout_marginBottom="5dp"
+        android:padding="5dp"
+        android:rotationX="180"
+        android:src="@drawable/ic_praise"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/iv_good"
+        app:tint="@color/md_blue_A200" />
+
     <TextView
         android:id="@+id/tv_origin"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
+        android:layout_marginLeft="30dp"
+        android:layout_marginTop="10dp"
         android:singleLine="true"
         android:textColor="@color/primaryText"
-        app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toLeftOf="@+id/tv_author" />
+        app:layout_constraintRight_toLeftOf="@+id/tv_author"
+        app:layout_constraintTop_toTopOf="parent" />
 
     <TextView
         android:id="@+id/tv_author"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_marginTop="10dp"
+        android:maxWidth="160dp"
         android:singleLine="true"
         android:textColor="@color/secondaryText"
-        android:maxWidth="160dp"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintRight_toLeftOf="@+id/iv_checked" />
+        app:layout_constraintRight_toLeftOf="@+id/iv_checked"
+        app:layout_constraintTop_toTopOf="parent" />
 
     <TextView
         android:id="@+id/tv_last"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
+        android:layout_marginLeft="30dp"
+        android:layout_marginBottom="10dp"
         android:singleLine="true"
         android:textColor="@color/secondaryText"
-        app:layout_constraintTop_toBottomOf="@+id/tv_origin"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toLeftOf="@+id/iv_checked" />
+        app:layout_constraintRight_toLeftOf="@+id/iv_checked"
+        app:layout_constraintTop_toBottomOf="@+id/tv_origin" />
 
     <androidx.appcompat.widget.AppCompatImageView
         android:id="@+id/iv_checked"
         android:layout_width="40dp"
         android:layout_height="40dp"
+        android:layout_marginTop="10dp"
+        android:layout_marginBottom="10dp"
         android:padding="8dp"
         android:src="@drawable/ic_check"
         android:visibility="invisible"
-        app:tint="@color/primaryText"
+        app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintRight_toRightOf="parent"
         app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent" />
+        app:tint="@color/primaryText"
+        tools:visibility="visible" />
+
 
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 1 - 0
app/src/main/res/layout/item_replace_rule.xml

@@ -42,5 +42,6 @@
         android:background="?attr/selectableItemBackgroundBorderless"
         android:src="@drawable/ic_more_vert"
         android:tint="@color/primaryText"
+        android:contentDescription="@string/more_menu"
         tools:ignore="RtlHardcoded" />
 </LinearLayout>

+ 1 - 0
app/src/main/res/layout/item_rss_source.xml

@@ -42,6 +42,7 @@
         android:layout_width="36dp"
         android:layout_height="36dp"
         android:background="?attr/selectableItemBackgroundBorderless"
+        android:contentDescription="@string/more_menu"
         android:padding="6dp"
         android:src="@drawable/ic_more_vert"
         android:tint="@color/primaryText"

+ 1 - 0
app/src/main/res/layout/item_rule_sub.xml

@@ -65,6 +65,7 @@
         android:padding="6dp"
         android:src="@drawable/ic_more_vert"
         android:tint="@color/primaryText"
+        android:contentDescription="@string/more_menu"
         app:layout_constraintRight_toRightOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintBottom_toBottomOf="parent"

+ 2 - 2
app/src/main/res/layout/item_theme_config.xml

@@ -34,8 +34,8 @@
         android:layout_width="36dp"
         android:layout_height="36dp"
         android:background="?attr/selectableItemBackgroundBorderless"
-        android:contentDescription="@string/more_menu"
-        android:tooltipText="@string/more_menu"
+        android:contentDescription="@string/delete"
+        android:tooltipText="@string/delete"
         android:padding="6dp"
         android:src="@drawable/ic_clear_all"
         android:tint="@color/primaryText"

+ 2 - 2
app/src/main/res/layout/item_toc_regex.xml

@@ -41,8 +41,8 @@
             android:layout_width="36dp"
             android:layout_height="36dp"
             android:background="?attr/selectableItemBackgroundBorderless"
-            android:contentDescription="@string/more_menu"
-            android:tooltipText="@string/more_menu"
+            android:contentDescription="@string/delete"
+            android:tooltipText="@string/delete"
             android:padding="6dp"
             android:src="@drawable/ic_clear_all"
             android:tint="@color/primaryText"

+ 1 - 0
app/src/main/res/layout/item_txt_toc_rule.xml

@@ -50,6 +50,7 @@
             android:padding="6dp"
             android:src="@drawable/ic_more_vert"
             android:tint="@color/primaryText"
+            android:contentDescription="@string/more_menu"
             tools:ignore="RtlHardcoded" />
 
     </LinearLayout>

+ 2 - 0
app/src/main/res/values-es-rES/strings.xml

@@ -1021,4 +1021,6 @@
     <string name="post_review_url">发送回复URL(postReviewUrl)</string>
     <string name="post_quote_url">发送回复段评URL(postQuoteUrl)</string>
     <string name="delete_review_url">删除段评URL(deleteUrl)</string>
+    <string name="tag_explore_enabled">标志:发现已启用</string>
+    <string name="tag_explore_disabled">标志:发现已禁用</string>
 </resources>

+ 2 - 0
app/src/main/res/values-ja-rJP/strings.xml

@@ -1024,4 +1024,6 @@
     <string name="post_review_url">发送回复URL(postReviewUrl)</string>
     <string name="post_quote_url">发送回复段评URL(postQuoteUrl)</string>
     <string name="delete_review_url">删除段评URL(deleteUrl)</string>
+    <string name="tag_explore_enabled">标志:发现已启用</string>
+    <string name="tag_explore_disabled">标志:发现已禁用</string>
 </resources>

+ 2 - 0
app/src/main/res/values-pt-rBR/strings.xml

@@ -1024,4 +1024,6 @@
     <string name="post_review_url">发送回复URL(postReviewUrl)</string>
     <string name="post_quote_url">发送回复段评URL(postQuoteUrl)</string>
     <string name="delete_review_url">删除段评URL(deleteUrl)</string>
+    <string name="tag_explore_enabled">标志:发现已启用</string>
+    <string name="tag_explore_disabled">标志:发现已禁用</string>
 </resources>

+ 2 - 0
app/src/main/res/values-zh-rHK/strings.xml

@@ -1021,4 +1021,6 @@
     <string name="post_review_url">发送回复URL(postReviewUrl)</string>
     <string name="post_quote_url">发送回复段评URL(postQuoteUrl)</string>
     <string name="delete_review_url">删除段评URL(deleteUrl)</string>
+    <string name="tag_explore_enabled">标志:发现已启用</string>
+    <string name="tag_explore_disabled">标志:发现已禁用</string>
 </resources>

+ 2 - 0
app/src/main/res/values-zh-rTW/strings.xml

@@ -1023,4 +1023,6 @@
     <string name="post_review_url">发送回复URL(postReviewUrl)</string>
     <string name="post_quote_url">发送回复段评URL(postQuoteUrl)</string>
     <string name="delete_review_url">删除段评URL(deleteUrl)</string>
+    <string name="tag_explore_enabled">标志:发现已启用</string>
+    <string name="tag_explore_disabled">标志:发现已禁用</string>
 </resources>

+ 2 - 0
app/src/main/res/values-zh/strings.xml

@@ -1023,4 +1023,6 @@
     <string name="post_review_url">发送回复URL(postReviewUrl)</string>
     <string name="post_quote_url">发送回复段评URL(postQuoteUrl)</string>
     <string name="delete_review_url">删除段评URL(deleteUrl)</string>
+    <string name="tag_explore_enabled">标志:发现已启用</string>
+    <string name="tag_explore_disabled">标志:发现已禁用</string>
 </resources>

+ 2 - 0
app/src/main/res/values/strings.xml

@@ -1024,4 +1024,6 @@
     <string name="post_review_url">发送回复URL(postReviewUrl)</string>
     <string name="post_quote_url">发送回复段评URL(postQuoteUrl)</string>
     <string name="delete_review_url">删除段评URL(deleteUrl)</string>
+    <string name="tag_explore_enabled">标志:发现已启用</string>
+    <string name="tag_explore_disabled">标志:发现已禁用</string>
 </resources>

+ 1 - 1
gradle.properties

@@ -26,4 +26,4 @@ android.experimental.enableNewResourceShrinker.preciseShrinking=true
 # and none from the library's dependencies, thereby reducing the size of the R class for that library.
 android.nonTransitiveRClass=true
 #https://chromiumdash.appspot.com/releases?platform=Android
-CronetVersion=104.0.5112.97
+CronetVersion=105.0.5195.68