Procházet zdrojové kódy

Merge branch 'master' into master

Xwite před 4 roky
rodič
revize
2b0c240852
49 změnil soubory, kde provedl 435 přidání a 351 odebrání
  1. 3 3
      app/build.gradle
  2. 7 0
      app/src/main/assets/updateLog.md
  3. 6 1
      app/src/main/java/io/legado/app/data/entities/BookChapter.kt
  4. 11 13
      app/src/main/java/io/legado/app/help/ContentProcessor.kt
  5. 19 15
      app/src/main/java/io/legado/app/help/ReplaceAnalyzer.kt
  6. 3 2
      app/src/main/java/io/legado/app/help/http/BackstageWebView.kt
  7. 2 2
      app/src/main/java/io/legado/app/help/http/CookieStore.kt
  8. 6 3
      app/src/main/java/io/legado/app/help/storage/ImportOldData.kt
  9. 2 2
      app/src/main/java/io/legado/app/lib/prefs/ColorPreference.kt
  10. 36 0
      app/src/main/java/io/legado/app/lib/prefs/EditTextPreference.kt
  11. 10 1
      app/src/main/java/io/legado/app/lib/prefs/EditTextPreferenceDialog.kt
  12. 1 1
      app/src/main/java/io/legado/app/lib/prefs/IconListPreference.kt
  13. 10 1
      app/src/main/java/io/legado/app/lib/prefs/ListPreferenceDialog.kt
  14. 10 1
      app/src/main/java/io/legado/app/lib/prefs/MultiSelectListPreferenceDialog.kt
  15. 1 1
      app/src/main/java/io/legado/app/lib/prefs/NameListPreference.kt
  16. 1 1
      app/src/main/java/io/legado/app/lib/prefs/Preference.kt
  17. 1 1
      app/src/main/java/io/legado/app/lib/prefs/PreferenceCategory.kt
  18. 1 1
      app/src/main/java/io/legado/app/lib/prefs/SwitchPreference.kt
  19. 8 9
      app/src/main/java/io/legado/app/lib/prefs/fragment/PreferenceFragment.kt
  20. 4 4
      app/src/main/java/io/legado/app/model/CacheBook.kt
  21. 1 2
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt
  22. 19 16
      app/src/main/java/io/legado/app/ui/association/ImportHttpTtsViewModel.kt
  23. 4 4
      app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleDialog.kt
  24. 27 11
      app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleViewModel.kt
  25. 2 2
      app/src/main/java/io/legado/app/ui/book/read/config/MoreConfigDialog.kt
  26. 2 2
      app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudConfigDialog.kt
  27. 43 33
      app/src/main/java/io/legado/app/ui/book/toc/ChapterListAdapter.kt
  28. 11 2
      app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt
  29. 2 0
      app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt
  30. 1 0
      app/src/main/java/io/legado/app/ui/book/toc/TocViewModel.kt
  31. 3 20
      app/src/main/java/io/legado/app/ui/config/BackupConfigFragment.kt
  32. 3 3
      app/src/main/java/io/legado/app/ui/config/CoverConfigFragment.kt
  33. 2 2
      app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt
  34. 3 3
      app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt
  35. 2 2
      app/src/main/java/io/legado/app/ui/config/WelcomeConfigFragment.kt
  36. 6 6
      app/src/main/java/io/legado/app/ui/main/my/MyFragment.kt
  37. 4 2
      app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt
  38. 0 22
      app/src/main/java/io/legado/app/ui/widget/prefs/EditTextPreference.kt
  39. 2 1
      app/src/main/java/io/legado/app/utils/RegexExtensions.kt
  40. 19 19
      app/src/main/res/xml/about.xml
  41. 12 12
      app/src/main/res/xml/donate.xml
  42. 6 6
      app/src/main/res/xml/pref_config_aloud.xml
  43. 14 14
      app/src/main/res/xml/pref_config_backup.xml
  44. 13 13
      app/src/main/res/xml/pref_config_cover.xml
  45. 24 24
      app/src/main/res/xml/pref_config_other.xml
  46. 18 18
      app/src/main/res/xml/pref_config_read.xml
  47. 24 24
      app/src/main/res/xml/pref_config_theme.xml
  48. 11 11
      app/src/main/res/xml/pref_config_welcome.xml
  49. 15 15
      app/src/main/res/xml/pref_main.xml

+ 3 - 3
app/build.gradle

@@ -15,8 +15,8 @@ def version = "3." + releaseTime()
 def gitCommits = Integer.parseInt('git rev-list HEAD --count'.execute().text.trim())
 def gitCommits = Integer.parseInt('git rev-list HEAD --count'.execute().text.trim())
 
 
 android {
 android {
-    compileSdkVersion 31
-    buildToolsVersion '31.0.0'
+    compileSdkVersion 32
+    buildToolsVersion '32.0.0'
     kotlinOptions {
     kotlinOptions {
         jvmTarget = "11"
         jvmTarget = "11"
     }
     }
@@ -38,7 +38,7 @@ android {
     defaultConfig {
     defaultConfig {
         applicationId "io.legado.app"
         applicationId "io.legado.app"
         minSdkVersion 21
         minSdkVersion 21
-        targetSdkVersion 31
+        targetSdkVersion 32
         versionCode 10000 + gitCommits
         versionCode 10000 + gitCommits
         versionName version
         versionName version
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

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

@@ -11,13 +11,20 @@
 * 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则或简繁转换出现问题。
 * 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则或简繁转换出现问题。
 * 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源!
 * 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源!
 
 
+
 **2022/05/13**
 **2022/05/13**
 
 
 * 书源编辑添加cookieJar选项
 * 书源编辑添加cookieJar选项
 
 
+**2022/05/11**
+
+* 修复替换报错的bug
+* 优化目录界面替换
+
 **2022/05/10**
 **2022/05/10**
 
 
 * 更新cronet: 101.0.4951.61
 * 更新cronet: 101.0.4951.61
+* 更新到SDK 32
 * js添加 getVerificationCode startBrowserAwait
 * js添加 getVerificationCode startBrowserAwait
 * 监测网络变化及时更新web服务的IP
 * 监测网络变化及时更新web服务的IP
 * 优化在线tts导入
 * 优化在线tts导入

+ 6 - 1
app/src/main/java/io/legado/app/data/entities/BookChapter.kt

@@ -7,6 +7,7 @@ import androidx.room.Ignore
 import androidx.room.Index
 import androidx.room.Index
 import com.github.liuyueyi.quick.transfer.ChineseUtils
 import com.github.liuyueyi.quick.transfer.ChineseUtils
 import io.legado.app.R
 import io.legado.app.R
+import io.legado.app.constant.AppLog
 import io.legado.app.constant.AppPattern
 import io.legado.app.constant.AppPattern
 import io.legado.app.data.appDb
 import io.legado.app.data.appDb
 import io.legado.app.exception.RegexTimeoutException
 import io.legado.app.exception.RegexTimeoutException
@@ -15,6 +16,7 @@ import io.legado.app.help.config.AppConfig
 import io.legado.app.model.analyzeRule.AnalyzeUrl
 import io.legado.app.model.analyzeRule.AnalyzeUrl
 import io.legado.app.model.analyzeRule.RuleDataInterface
 import io.legado.app.model.analyzeRule.RuleDataInterface
 import io.legado.app.utils.*
 import io.legado.app.utils.*
+import kotlinx.coroutines.CancellationException
 import kotlinx.parcelize.IgnoredOnParcel
 import kotlinx.parcelize.IgnoredOnParcel
 import kotlinx.parcelize.Parcelize
 import kotlinx.parcelize.Parcelize
 import splitties.init.appCtx
 import splitties.init.appCtx
@@ -93,7 +95,7 @@ data class BookChapter(
                 2 -> displayTitle = ChineseUtils.s2t(displayTitle)
                 2 -> displayTitle = ChineseUtils.s2t(displayTitle)
             }
             }
         }
         }
-        if (useReplace && replaceRules != null) {
+        if (useReplace && replaceRules != null) kotlin.run {
             replaceRules.forEach { item ->
             replaceRules.forEach { item ->
                 if (item.pattern.isNotEmpty()) {
                 if (item.pattern.isNotEmpty()) {
                     try {
                     try {
@@ -112,7 +114,10 @@ data class BookChapter(
                     } catch (e: RegexTimeoutException) {
                     } catch (e: RegexTimeoutException) {
                         item.isEnabled = false
                         item.isEnabled = false
                         appDb.replaceRuleDao.update(item)
                         appDb.replaceRuleDao.update(item)
+                    } catch (e: CancellationException) {
+                        return@run
                     } catch (e: Exception) {
                     } catch (e: Exception) {
+                        AppLog.put("${item.name}替换出错\n替换内容\n${displayTitle}", e)
                         appCtx.toastOnUi("${item.name}替换出错")
                         appCtx.toastOnUi("${item.name}替换出错")
                     }
                     }
                 }
                 }

+ 11 - 13
app/src/main/java/io/legado/app/help/ContentProcessor.kt

@@ -12,6 +12,7 @@ import io.legado.app.help.config.ReadBookConfig
 import io.legado.app.utils.msg
 import io.legado.app.utils.msg
 import io.legado.app.utils.replace
 import io.legado.app.utils.replace
 import io.legado.app.utils.toastOnUi
 import io.legado.app.utils.toastOnUi
+import kotlinx.coroutines.CancellationException
 import splitties.init.appCtx
 import splitties.init.appCtx
 import java.lang.ref.WeakReference
 import java.lang.ref.WeakReference
 import java.util.concurrent.CopyOnWriteArrayList
 import java.util.concurrent.CopyOnWriteArrayList
@@ -135,7 +136,7 @@ class ContentProcessor private constructor(
         var mContent = content
         var mContent = content
         getContentReplaceRules().forEach { item ->
         getContentReplaceRules().forEach { item ->
             if (item.pattern.isNotEmpty()) {
             if (item.pattern.isNotEmpty()) {
-                kotlin.runCatching {
+                try {
                     mContent = if (item.isRegex) {
                     mContent = if (item.isRegex) {
                         mContent.replace(
                         mContent.replace(
                             item.pattern.toRegex(),
                             item.pattern.toRegex(),
@@ -145,18 +146,15 @@ class ContentProcessor private constructor(
                     } else {
                     } else {
                         mContent.replace(item.pattern, item.replacement)
                         mContent.replace(item.pattern, item.replacement)
                     }
                     }
-                }.onFailure {
-                    when (it) {
-                        is RegexTimeoutException -> {
-                            item.isEnabled = false
-                            appDb.replaceRuleDao.update(item)
-                            return item.name + it.msg
-                        }
-                        else -> {
-                            AppLog.put("${item.name}替换出错\n${it.localizedMessage}", it)
-                            appCtx.toastOnUi("${item.name}替换出错")
-                        }
-                    }
+                } catch (e: RegexTimeoutException) {
+                    item.isEnabled = false
+                    appDb.replaceRuleDao.update(item)
+                    return item.name + e.msg
+                } catch (e: CancellationException) {
+                    return mContent
+                } catch (e: Exception) {
+                    AppLog.put("${item.name}替换出错\n替换内容\n${mContent}", e)
+                    appCtx.toastOnUi("${item.name}替换出错")
                 }
                 }
             }
             }
         }
         }

+ 19 - 15
app/src/main/java/io/legado/app/help/ReplaceAnalyzer.kt

@@ -1,43 +1,47 @@
 package io.legado.app.help
 package io.legado.app.help
 
 
 import io.legado.app.data.entities.ReplaceRule
 import io.legado.app.data.entities.ReplaceRule
+import io.legado.app.exception.NoStackTraceException
 import io.legado.app.utils.*
 import io.legado.app.utils.*
 
 
 object ReplaceAnalyzer {
 object ReplaceAnalyzer {
 
 
-    fun jsonToReplaceRules(json: String): List<ReplaceRule> {
-        val replaceRules = mutableListOf<ReplaceRule>()
-        val items: List<Map<String, Any>> = jsonPath.parse(json).read("$")
-        for (item in items) {
-            val jsonItem = jsonPath.parse(item)
-            jsonToReplaceRule(jsonItem.jsonString())?.let {
-                if (it.isValid()) {
-                    replaceRules.add(it)
+    fun jsonToReplaceRules(json: String): Result<MutableList<ReplaceRule>> {
+        return kotlin.runCatching {
+            val replaceRules = mutableListOf<ReplaceRule>()
+            val items: List<Map<String, Any>> = jsonPath.parse(json).read("$")
+            for (item in items) {
+                val jsonItem = jsonPath.parse(item)
+                jsonToReplaceRule(jsonItem.jsonString()).getOrThrow().let {
+                    if (it.isValid()) {
+                        replaceRules.add(it)
+                    }
                 }
                 }
             }
             }
+            replaceRules
         }
         }
-        return replaceRules
     }
     }
 
 
-    private fun jsonToReplaceRule(json: String): ReplaceRule? {
-        val replaceRule: ReplaceRule? = GSON.fromJsonObject<ReplaceRule>(json.trim()).getOrNull()
-        runCatching {
+    fun jsonToReplaceRule(json: String): Result<ReplaceRule> {
+        return runCatching {
+            val replaceRule: ReplaceRule? =
+                GSON.fromJsonObject<ReplaceRule>(json.trim()).getOrNull()
             if (replaceRule == null || replaceRule.pattern.isBlank()) {
             if (replaceRule == null || replaceRule.pattern.isBlank()) {
                 val jsonItem = jsonPath.parse(json.trim())
                 val jsonItem = jsonPath.parse(json.trim())
                 val rule = ReplaceRule()
                 val rule = ReplaceRule()
                 rule.id = jsonItem.readLong("$.id") ?: System.currentTimeMillis()
                 rule.id = jsonItem.readLong("$.id") ?: System.currentTimeMillis()
                 rule.pattern = jsonItem.readString("$.regex") ?: ""
                 rule.pattern = jsonItem.readString("$.regex") ?: ""
-                if (rule.pattern.isEmpty()) return null
+                if (rule.pattern.isEmpty()) throw NoStackTraceException("格式不对")
                 rule.name = jsonItem.readString("$.replaceSummary") ?: ""
                 rule.name = jsonItem.readString("$.replaceSummary") ?: ""
                 rule.replacement = jsonItem.readString("$.replacement") ?: ""
                 rule.replacement = jsonItem.readString("$.replacement") ?: ""
                 rule.isRegex = jsonItem.readBool("$.isRegex") == true
                 rule.isRegex = jsonItem.readBool("$.isRegex") == true
                 rule.scope = jsonItem.readString("$.useTo")
                 rule.scope = jsonItem.readString("$.useTo")
                 rule.isEnabled = jsonItem.readBool("$.enable") == true
                 rule.isEnabled = jsonItem.readBool("$.enable") == true
                 rule.order = jsonItem.readInt("$.serialNumber") ?: 0
                 rule.order = jsonItem.readInt("$.serialNumber") ?: 0
-                return rule
+                return@runCatching rule
             }
             }
+            return@runCatching replaceRule
         }
         }
-        return replaceRule
     }
     }
 
 
 }
 }

+ 3 - 2
app/src/main/java/io/legado/app/help/http/BackstageWebView.kt

@@ -18,6 +18,7 @@ import org.apache.commons.text.StringEscapeUtils
 import splitties.init.appCtx
 import splitties.init.appCtx
 import java.lang.ref.WeakReference
 import java.lang.ref.WeakReference
 import kotlin.coroutines.resume
 import kotlin.coroutines.resume
+import kotlin.coroutines.resumeWithException
 
 
 /**
 /**
  * 后台webView
  * 后台webView
@@ -50,14 +51,14 @@ class BackstageWebView(
 
 
             override fun onError(error: Throwable) {
             override fun onError(error: Throwable) {
                 if (!block.isCompleted)
                 if (!block.isCompleted)
-                    block.cancel(error)
+                    block.resumeWithException(error)
             }
             }
         }
         }
         runOnUI {
         runOnUI {
             try {
             try {
                 load()
                 load()
             } catch (error: Throwable) {
             } catch (error: Throwable) {
-                block.cancel(error)
+                block.resumeWithException(error)
             }
             }
         }
         }
     }
     }

+ 2 - 2
app/src/main/java/io/legado/app/help/http/CookieStore.kt

@@ -5,8 +5,8 @@ package io.legado.app.help.http
 import android.text.TextUtils
 import android.text.TextUtils
 import io.legado.app.data.appDb
 import io.legado.app.data.appDb
 import io.legado.app.data.entities.Cookie
 import io.legado.app.data.entities.Cookie
-import io.legado.app.help.http.api.CookieManager
 import io.legado.app.help.CacheManager
 import io.legado.app.help.CacheManager
+import io.legado.app.help.http.api.CookieManager
 import io.legado.app.utils.NetworkUtils
 import io.legado.app.utils.NetworkUtils
 
 
 object CookieStore : CookieManager {
 object CookieStore : CookieManager {
@@ -44,7 +44,7 @@ object CookieStore : CookieManager {
         CacheManager.getFromMemory("${domain}_cookie")?.let { return it }
         CacheManager.getFromMemory("${domain}_cookie")?.let { return it }
         val cookieBean = appDb.cookieDao.get(domain)
         val cookieBean = appDb.cookieDao.get(domain)
         val cookie = cookieBean?.cookie ?: ""
         val cookie = cookieBean?.cookie ?: ""
-        CacheManager.putMemory(url, cookie ?: "")
+        CacheManager.putMemory(url, cookie)
         return cookie
         return cookie
     }
     }
 
 

+ 6 - 3
app/src/main/java/io/legado/app/help/storage/ImportOldData.kt

@@ -98,9 +98,12 @@ object ImportOldData {
     }
     }
 
 
     private fun importOldReplaceRule(json: String): Int {
     private fun importOldReplaceRule(json: String): Int {
-        val rules = ReplaceAnalyzer.jsonToReplaceRules(json)
-        appDb.replaceRuleDao.insert(*rules.toTypedArray())
-        return rules.size
+        val rules = ReplaceAnalyzer.jsonToReplaceRules(json).getOrNull()
+        rules?.let {
+            appDb.replaceRuleDao.insert(*rules.toTypedArray())
+            return rules.size
+        }
+        return 0
     }
     }
 
 
     private fun fromOldBooks(json: String): List<Book> {
     private fun fromOldBooks(json: String): List<Book> {

+ 2 - 2
app/src/main/java/io/legado/app/ui/widget/prefs/ColorPreference.kt → app/src/main/java/io/legado/app/lib/prefs/ColorPreference.kt

@@ -1,4 +1,4 @@
-package io.legado.app.ui.widget.prefs
+package io.legado.app.lib.prefs
 
 
 import android.content.Context
 import android.content.Context
 import android.content.ContextWrapper
 import android.content.ContextWrapper
@@ -118,7 +118,7 @@ class ColorPreference(context: Context, attrs: AttributeSet) : Preference(contex
     }
     }
 
 
     override fun onBindViewHolder(holder: PreferenceViewHolder) {
     override fun onBindViewHolder(holder: PreferenceViewHolder) {
-        val v = io.legado.app.ui.widget.prefs.Preference.bindView<ColorPanelView>(
+        val v = io.legado.app.lib.prefs.Preference.bindView<ColorPanelView>(
             context, holder, icon, title, summary, widgetLayoutResource,
             context, holder, icon, title, summary, widgetLayoutResource,
             io.legado.app.R.id.cpv_preference_preview_color_panel, 30, 30
             io.legado.app.R.id.cpv_preference_preview_color_panel, 30, 30
         )
         )

+ 36 - 0
app/src/main/java/io/legado/app/lib/prefs/EditTextPreference.kt

@@ -0,0 +1,36 @@
+package io.legado.app.lib.prefs
+
+import android.content.Context
+import android.util.AttributeSet
+import android.widget.TextView
+import androidx.preference.EditTextPreference.OnBindEditTextListener
+import androidx.preference.PreferenceViewHolder
+import io.legado.app.R
+import io.legado.app.lib.theme.accentColor
+import io.legado.app.utils.applyTint
+
+class EditTextPreference(context: Context, attrs: AttributeSet) :
+    androidx.preference.EditTextPreference(context, attrs) {
+
+    private var mOnBindEditTextListener: OnBindEditTextListener? = null
+    private val onBindEditTextListener = OnBindEditTextListener { editText ->
+        editText.applyTint(context.accentColor)
+        mOnBindEditTextListener?.onBindEditText(editText)
+    }
+
+    init {
+        // isPersistent = true
+        layoutResource = R.layout.view_preference
+        super.setOnBindEditTextListener(onBindEditTextListener)
+    }
+
+    override fun onBindViewHolder(holder: PreferenceViewHolder) {
+        Preference.bindView<TextView>(context, holder, icon, title, summary, null, null)
+        super.onBindViewHolder(holder)
+    }
+
+    override fun setOnBindEditTextListener(onBindEditTextListener: OnBindEditTextListener?) {
+        mOnBindEditTextListener = onBindEditTextListener
+    }
+
+}

+ 10 - 1
app/src/main/java/io/legado/app/ui/widget/prefs/EditTextPreferenceDialog.kt → app/src/main/java/io/legado/app/lib/prefs/EditTextPreferenceDialog.kt

@@ -1,9 +1,11 @@
-package io.legado.app.ui.widget.prefs
+package io.legado.app.lib.prefs
 
 
 import android.app.Dialog
 import android.app.Dialog
 import android.os.Bundle
 import android.os.Bundle
+import androidx.appcompat.app.AlertDialog
 import androidx.preference.EditTextPreferenceDialogFragmentCompat
 import androidx.preference.EditTextPreferenceDialogFragmentCompat
 import androidx.preference.PreferenceDialogFragmentCompat
 import androidx.preference.PreferenceDialogFragmentCompat
+import io.legado.app.lib.theme.accentColor
 import io.legado.app.lib.theme.filletBackground
 import io.legado.app.lib.theme.filletBackground
 
 
 class EditTextPreferenceDialog : EditTextPreferenceDialogFragmentCompat() {
 class EditTextPreferenceDialog : EditTextPreferenceDialogFragmentCompat() {
@@ -23,6 +25,13 @@ class EditTextPreferenceDialog : EditTextPreferenceDialogFragmentCompat() {
     override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
     override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
         val dialog = super.onCreateDialog(savedInstanceState)
         val dialog = super.onCreateDialog(savedInstanceState)
         dialog.window?.setBackgroundDrawable(requireContext().filletBackground)
         dialog.window?.setBackgroundDrawable(requireContext().filletBackground)
+        dialog.window?.decorView?.post {
+            (dialog as AlertDialog).run {
+                getButton(AlertDialog.BUTTON_NEGATIVE)?.setTextColor(accentColor)
+                getButton(AlertDialog.BUTTON_POSITIVE)?.setTextColor(accentColor)
+                getButton(AlertDialog.BUTTON_NEUTRAL)?.setTextColor(accentColor)
+            }
+        }
         return dialog
         return dialog
     }
     }
 
 

+ 1 - 1
app/src/main/java/io/legado/app/ui/widget/prefs/IconListPreference.kt → app/src/main/java/io/legado/app/lib/prefs/IconListPreference.kt

@@ -1,4 +1,4 @@
-package io.legado.app.ui.widget.prefs
+package io.legado.app.lib.prefs
 
 
 import android.content.Context
 import android.content.Context
 import android.content.ContextWrapper
 import android.content.ContextWrapper

+ 10 - 1
app/src/main/java/io/legado/app/ui/widget/prefs/ListPreferenceDialog.kt → app/src/main/java/io/legado/app/lib/prefs/ListPreferenceDialog.kt

@@ -1,9 +1,11 @@
-package io.legado.app.ui.widget.prefs
+package io.legado.app.lib.prefs
 
 
 import android.app.Dialog
 import android.app.Dialog
 import android.os.Bundle
 import android.os.Bundle
+import androidx.appcompat.app.AlertDialog
 import androidx.preference.ListPreferenceDialogFragmentCompat
 import androidx.preference.ListPreferenceDialogFragmentCompat
 import androidx.preference.PreferenceDialogFragmentCompat
 import androidx.preference.PreferenceDialogFragmentCompat
+import io.legado.app.lib.theme.accentColor
 import io.legado.app.lib.theme.filletBackground
 import io.legado.app.lib.theme.filletBackground
 
 
 class ListPreferenceDialog : ListPreferenceDialogFragmentCompat() {
 class ListPreferenceDialog : ListPreferenceDialogFragmentCompat() {
@@ -23,6 +25,13 @@ class ListPreferenceDialog : ListPreferenceDialogFragmentCompat() {
     override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
     override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
         val dialog = super.onCreateDialog(savedInstanceState)
         val dialog = super.onCreateDialog(savedInstanceState)
         dialog.window?.setBackgroundDrawable(requireContext().filletBackground)
         dialog.window?.setBackgroundDrawable(requireContext().filletBackground)
+        dialog.window?.decorView?.post {
+            (dialog as AlertDialog).run {
+                getButton(AlertDialog.BUTTON_NEGATIVE)?.setTextColor(accentColor)
+                getButton(AlertDialog.BUTTON_POSITIVE)?.setTextColor(accentColor)
+                getButton(AlertDialog.BUTTON_NEUTRAL)?.setTextColor(accentColor)
+            }
+        }
         return dialog
         return dialog
     }
     }
 
 

+ 10 - 1
app/src/main/java/io/legado/app/ui/widget/prefs/MultiSelectListPreferenceDialog.kt → app/src/main/java/io/legado/app/lib/prefs/MultiSelectListPreferenceDialog.kt

@@ -1,9 +1,11 @@
-package io.legado.app.ui.widget.prefs
+package io.legado.app.lib.prefs
 
 
 import android.app.Dialog
 import android.app.Dialog
 import android.os.Bundle
 import android.os.Bundle
+import androidx.appcompat.app.AlertDialog
 import androidx.preference.MultiSelectListPreferenceDialogFragmentCompat
 import androidx.preference.MultiSelectListPreferenceDialogFragmentCompat
 import androidx.preference.PreferenceDialogFragmentCompat
 import androidx.preference.PreferenceDialogFragmentCompat
+import io.legado.app.lib.theme.accentColor
 import io.legado.app.lib.theme.filletBackground
 import io.legado.app.lib.theme.filletBackground
 
 
 class MultiSelectListPreferenceDialog : MultiSelectListPreferenceDialogFragmentCompat() {
 class MultiSelectListPreferenceDialog : MultiSelectListPreferenceDialogFragmentCompat() {
@@ -25,6 +27,13 @@ class MultiSelectListPreferenceDialog : MultiSelectListPreferenceDialogFragmentC
     override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
     override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
         val dialog = super.onCreateDialog(savedInstanceState)
         val dialog = super.onCreateDialog(savedInstanceState)
         dialog.window?.setBackgroundDrawable(requireContext().filletBackground)
         dialog.window?.setBackgroundDrawable(requireContext().filletBackground)
+        dialog.window?.decorView?.post {
+            (dialog as AlertDialog).run {
+                getButton(AlertDialog.BUTTON_NEGATIVE)?.setTextColor(accentColor)
+                getButton(AlertDialog.BUTTON_POSITIVE)?.setTextColor(accentColor)
+                getButton(AlertDialog.BUTTON_NEUTRAL)?.setTextColor(accentColor)
+            }
+        }
         return dialog
         return dialog
     }
     }
 
 

+ 1 - 1
app/src/main/java/io/legado/app/ui/widget/prefs/NameListPreference.kt → app/src/main/java/io/legado/app/lib/prefs/NameListPreference.kt

@@ -1,4 +1,4 @@
-package io.legado.app.ui.widget.prefs
+package io.legado.app.lib.prefs
 
 
 import android.content.Context
 import android.content.Context
 import android.util.AttributeSet
 import android.util.AttributeSet

+ 1 - 1
app/src/main/java/io/legado/app/ui/widget/prefs/Preference.kt → app/src/main/java/io/legado/app/lib/prefs/Preference.kt

@@ -1,4 +1,4 @@
-package io.legado.app.ui.widget.prefs
+package io.legado.app.lib.prefs
 
 
 import android.content.Context
 import android.content.Context
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.Drawable

+ 1 - 1
app/src/main/java/io/legado/app/ui/widget/prefs/PreferenceCategory.kt → app/src/main/java/io/legado/app/lib/prefs/PreferenceCategory.kt

@@ -1,4 +1,4 @@
-package io.legado.app.ui.widget.prefs
+package io.legado.app.lib.prefs
 
 
 import android.content.Context
 import android.content.Context
 import android.util.AttributeSet
 import android.util.AttributeSet

+ 1 - 1
app/src/main/java/io/legado/app/ui/widget/prefs/SwitchPreference.kt → app/src/main/java/io/legado/app/lib/prefs/SwitchPreference.kt

@@ -1,4 +1,4 @@
-package io.legado.app.ui.widget.prefs
+package io.legado.app.lib.prefs
 
 
 import android.content.Context
 import android.content.Context
 import android.util.AttributeSet
 import android.util.AttributeSet

+ 8 - 9
app/src/main/java/io/legado/app/base/BasePreferenceFragment.kt → app/src/main/java/io/legado/app/lib/prefs/fragment/PreferenceFragment.kt

@@ -1,13 +1,13 @@
-package io.legado.app.base
+package io.legado.app.lib.prefs.fragment
 
 
 import android.annotation.SuppressLint
 import android.annotation.SuppressLint
 import androidx.fragment.app.DialogFragment
 import androidx.fragment.app.DialogFragment
 import androidx.preference.*
 import androidx.preference.*
-import io.legado.app.ui.widget.prefs.EditTextPreferenceDialog
-import io.legado.app.ui.widget.prefs.ListPreferenceDialog
-import io.legado.app.ui.widget.prefs.MultiSelectListPreferenceDialog
+import io.legado.app.lib.prefs.EditTextPreferenceDialog
+import io.legado.app.lib.prefs.ListPreferenceDialog
+import io.legado.app.lib.prefs.MultiSelectListPreferenceDialog
 
 
-abstract class BasePreferenceFragment : PreferenceFragmentCompat() {
+abstract class PreferenceFragment : PreferenceFragmentCompat() {
 
 
     private val dialogFragmentTag = "androidx.preference.PreferenceFragment.DIALOG"
     private val dialogFragmentTag = "androidx.preference.PreferenceFragment.DIALOG"
 
 
@@ -34,7 +34,7 @@ abstract class BasePreferenceFragment : PreferenceFragmentCompat() {
             return
             return
         }
         }
 
 
-        val f: DialogFragment = when (preference) {
+        val dialogFragment: DialogFragment = when (preference) {
             is EditTextPreference -> {
             is EditTextPreference -> {
                 EditTextPreferenceDialog.newInstance(preference.getKey())
                 EditTextPreferenceDialog.newInstance(preference.getKey())
             }
             }
@@ -54,10 +54,9 @@ abstract class BasePreferenceFragment : PreferenceFragmentCompat() {
             }
             }
         }
         }
         @Suppress("DEPRECATION")
         @Suppress("DEPRECATION")
-        f.setTargetFragment(this, 0)
+        dialogFragment.setTargetFragment(this, 0)
 
 
-        f.show(parentFragmentManager, dialogFragmentTag)
+        dialogFragment.show(parentFragmentManager, dialogFragmentTag)
     }
     }
 
 
-
 }
 }

+ 4 - 4
app/src/main/java/io/legado/app/model/CacheBook.kt

@@ -131,9 +131,9 @@ object CacheBook {
 
 
     class CacheBookModel(var bookSource: BookSource, var book: Book) {
     class CacheBookModel(var bookSource: BookSource, var book: Book) {
 
 
-        private val waitDownloadSet = hashSetOf<Int>()
-        private val onDownloadSet = hashSetOf<Int>()
-        private val successDownloadSet = hashSetOf<Int>()
+        private val waitDownloadSet = linkedSetOf<Int>()
+        private val onDownloadSet = linkedSetOf<Int>()
+        private val successDownloadSet = linkedSetOf<Int>()
         private val errorDownloadMap = hashMapOf<Int, Int>()
         private val errorDownloadMap = hashMapOf<Int, Int>()
 
 
         val waitCount get() = waitDownloadSet.size
         val waitCount get() = waitDownloadSet.size
@@ -174,7 +174,7 @@ object CacheBook {
             }
             }
             onDownloadSet.remove(index)
             onDownloadSet.remove(index)
             //重试3次
             //重试3次
-            if (errorDownloadMap[index] ?: 0 < 3) {
+            if ((errorDownloadMap[index] ?: 0) < 3) {
                 waitDownloadSet.add(index)
                 waitDownloadSet.add(index)
             } else {
             } else {
                 AppLog.put(
                 AppLog.put(

+ 1 - 2
app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt

@@ -537,8 +537,7 @@ class AnalyzeUrl(
             val cookieMap = CookieStore.cookieToMap(cookie)
             val cookieMap = CookieStore.cookieToMap(cookie)
             val customCookieMap = CookieStore.cookieToMap(headerMap["Cookie"] ?: "")
             val customCookieMap = CookieStore.cookieToMap(headerMap["Cookie"] ?: "")
             cookieMap.putAll(customCookieMap)
             cookieMap.putAll(customCookieMap)
-            val newCookie = CookieStore.mapToCookie(cookieMap)
-            newCookie?.let {
+            CookieStore.mapToCookie(cookieMap)?.let {
                 headerMap.put("Cookie", it)
                 headerMap.put("Cookie", it)
             }
             }
         }
         }

+ 19 - 16
app/src/main/java/io/legado/app/ui/association/ImportHttpTtsViewModel.kt

@@ -61,21 +61,7 @@ class ImportHttpTtsViewModel(app: Application) : BaseViewModel(app) {
 
 
     fun importSource(text: String) {
     fun importSource(text: String) {
         execute {
         execute {
-            val mText = text.trim()
-            when {
-                mText.isJsonObject() -> {
-                    HttpTTS.fromJson(mText).getOrThrow().let {
-                        allSources.add(it)
-                    }
-                }
-                mText.isJsonArray() -> HttpTTS.fromJsonArray(mText).getOrThrow().let { items ->
-                    allSources.addAll(items)
-                }
-                mText.isAbsUrl() -> {
-                    importSourceUrl(mText)
-                }
-                else -> throw NoStackTraceException(context.getString(R.string.wrong_format))
-            }
+            importSourceAwait(text.trim())
         }.onError {
         }.onError {
             it.printOnDebug()
             it.printOnDebug()
             errorLiveData.postValue(it.localizedMessage ?: "")
             errorLiveData.postValue(it.localizedMessage ?: "")
@@ -84,11 +70,28 @@ class ImportHttpTtsViewModel(app: Application) : BaseViewModel(app) {
         }
         }
     }
     }
 
 
+    private suspend fun importSourceAwait(text: String) {
+        when {
+            text.isJsonObject() -> {
+                HttpTTS.fromJson(text).getOrThrow().let {
+                    allSources.add(it)
+                }
+            }
+            text.isJsonArray() -> HttpTTS.fromJsonArray(text).getOrThrow().let { items ->
+                allSources.addAll(items)
+            }
+            text.isAbsUrl() -> {
+                importSourceUrl(text)
+            }
+            else -> throw NoStackTraceException(context.getString(R.string.wrong_format))
+        }
+    }
+
     private suspend fun importSourceUrl(url: String) {
     private suspend fun importSourceUrl(url: String) {
         okHttpClient.newCallResponseBody {
         okHttpClient.newCallResponseBody {
             url(url)
             url(url)
         }.text().let {
         }.text().let {
-            allSources.addAll(HttpTTS.fromJsonArray(it).getOrThrow())
+            importSourceAwait(it)
         }
         }
     }
     }
 
 

+ 4 - 4
app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleDialog.kt

@@ -88,14 +88,14 @@ class ImportReplaceRuleDialog() : BaseDialogFragment(R.layout.dialog_recycler_vi
             adapter.notifyDataSetChanged()
             adapter.notifyDataSetChanged()
             upSelectText()
             upSelectText()
         }
         }
-        viewModel.errorLiveData.observe(this, {
+        viewModel.errorLiveData.observe(this) {
             binding.rotateLoading.hide()
             binding.rotateLoading.hide()
             binding.tvMsg.apply {
             binding.tvMsg.apply {
                 text = it
                 text = it
                 visible()
                 visible()
             }
             }
-        })
-        viewModel.successLiveData.observe(this, {
+        }
+        viewModel.successLiveData.observe(this) {
             binding.rotateLoading.hide()
             binding.rotateLoading.hide()
             if (it > 0) {
             if (it > 0) {
                 adapter.setItems(viewModel.allRules)
                 adapter.setItems(viewModel.allRules)
@@ -106,7 +106,7 @@ class ImportReplaceRuleDialog() : BaseDialogFragment(R.layout.dialog_recycler_vi
                     visible()
                     visible()
                 }
                 }
             }
             }
-        })
+        }
         val source = arguments?.getString("source")
         val source = arguments?.getString("source")
         if (source.isNullOrEmpty()) {
         if (source.isNullOrEmpty()) {
             dismiss()
             dismiss()

+ 27 - 11
app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleViewModel.kt

@@ -6,12 +6,15 @@ import io.legado.app.base.BaseViewModel
 import io.legado.app.constant.AppPattern
 import io.legado.app.constant.AppPattern
 import io.legado.app.data.appDb
 import io.legado.app.data.appDb
 import io.legado.app.data.entities.ReplaceRule
 import io.legado.app.data.entities.ReplaceRule
+import io.legado.app.exception.NoStackTraceException
 import io.legado.app.help.ReplaceAnalyzer
 import io.legado.app.help.ReplaceAnalyzer
 import io.legado.app.help.config.AppConfig
 import io.legado.app.help.config.AppConfig
 import io.legado.app.help.http.newCallResponseBody
 import io.legado.app.help.http.newCallResponseBody
 import io.legado.app.help.http.okHttpClient
 import io.legado.app.help.http.okHttpClient
 import io.legado.app.help.http.text
 import io.legado.app.help.http.text
 import io.legado.app.utils.isAbsUrl
 import io.legado.app.utils.isAbsUrl
+import io.legado.app.utils.isJsonArray
+import io.legado.app.utils.isJsonObject
 import io.legado.app.utils.splitNotBlank
 import io.legado.app.utils.splitNotBlank
 
 
 class ImportReplaceRuleViewModel(app: Application) : BaseViewModel(app) {
 class ImportReplaceRuleViewModel(app: Application) : BaseViewModel(app) {
@@ -83,17 +86,7 @@ class ImportReplaceRuleViewModel(app: Application) : BaseViewModel(app) {
 
 
     fun import(text: String) {
     fun import(text: String) {
         execute {
         execute {
-            if (text.isAbsUrl()) {
-                okHttpClient.newCallResponseBody {
-                    url(text)
-                }.text("utf-8").let {
-                    val rules = ReplaceAnalyzer.jsonToReplaceRules(it)
-                    allRules.addAll(rules)
-                }
-            } else {
-                val rules = ReplaceAnalyzer.jsonToReplaceRules(text)
-                allRules.addAll(rules)
-            }
+            importAwait(text.trim())
         }.onError {
         }.onError {
             errorLiveData.postValue(it.localizedMessage ?: "ERROR")
             errorLiveData.postValue(it.localizedMessage ?: "ERROR")
         }.onSuccess {
         }.onSuccess {
@@ -101,6 +94,29 @@ class ImportReplaceRuleViewModel(app: Application) : BaseViewModel(app) {
         }
         }
     }
     }
 
 
+    private suspend fun importAwait(text: String) {
+        when {
+            text.isAbsUrl() -> importUrl(text)
+            text.isJsonArray() -> {
+                val rules = ReplaceAnalyzer.jsonToReplaceRules(text).getOrThrow()
+                allRules.addAll(rules)
+            }
+            text.isJsonObject() -> {
+                val rule = ReplaceAnalyzer.jsonToReplaceRule(text).getOrThrow()
+                allRules.add(rule)
+            }
+            else -> throw NoStackTraceException("格式不对")
+        }
+    }
+
+    private suspend fun importUrl(url: String) {
+        okHttpClient.newCallResponseBody {
+            url(url)
+        }.text("utf-8").let {
+            importAwait(it)
+        }
+    }
+
     private fun comparisonSource() {
     private fun comparisonSource() {
         execute {
         execute {
             allRules.forEach {
             allRules.forEach {

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

@@ -9,10 +9,10 @@ import android.widget.LinearLayout
 import androidx.fragment.app.DialogFragment
 import androidx.fragment.app.DialogFragment
 import androidx.preference.Preference
 import androidx.preference.Preference
 import io.legado.app.R
 import io.legado.app.R
-import io.legado.app.base.BasePreferenceFragment
 import io.legado.app.constant.EventBus
 import io.legado.app.constant.EventBus
 import io.legado.app.constant.PreferKey
 import io.legado.app.constant.PreferKey
 import io.legado.app.help.config.ReadBookConfig
 import io.legado.app.help.config.ReadBookConfig
+import io.legado.app.lib.prefs.fragment.PreferenceFragment
 import io.legado.app.lib.theme.bottomBackground
 import io.legado.app.lib.theme.bottomBackground
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.model.ReadBook
 import io.legado.app.model.ReadBook
@@ -67,7 +67,7 @@ class MoreConfigDialog : DialogFragment() {
         (activity as ReadBookActivity).bottomDialog--
         (activity as ReadBookActivity).bottomDialog--
     }
     }
 
 
-    class ReadPreferenceFragment : BasePreferenceFragment(),
+    class ReadPreferenceFragment : PreferenceFragment(),
         SharedPreferences.OnSharedPreferenceChangeListener {
         SharedPreferences.OnSharedPreferenceChangeListener {
 
 
         @SuppressLint("RestrictedApi")
         @SuppressLint("RestrictedApi")

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

@@ -10,12 +10,12 @@ import androidx.fragment.app.DialogFragment
 import androidx.preference.ListPreference
 import androidx.preference.ListPreference
 import androidx.preference.Preference
 import androidx.preference.Preference
 import io.legado.app.R
 import io.legado.app.R
-import io.legado.app.base.BasePreferenceFragment
 import io.legado.app.constant.EventBus
 import io.legado.app.constant.EventBus
 import io.legado.app.constant.PreferKey
 import io.legado.app.constant.PreferKey
 import io.legado.app.data.appDb
 import io.legado.app.data.appDb
 import io.legado.app.help.IntentHelp
 import io.legado.app.help.IntentHelp
 import io.legado.app.lib.dialogs.SelectItem
 import io.legado.app.lib.dialogs.SelectItem
+import io.legado.app.lib.prefs.fragment.PreferenceFragment
 import io.legado.app.lib.theme.backgroundColor
 import io.legado.app.lib.theme.backgroundColor
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.model.ReadAloud
 import io.legado.app.model.ReadAloud
@@ -54,7 +54,7 @@ class ReadAloudConfigDialog : DialogFragment() {
             .commit()
             .commit()
     }
     }
 
 
-    class ReadAloudPreferenceFragment : BasePreferenceFragment(),
+    class ReadAloudPreferenceFragment : PreferenceFragment(),
         SpeakEngineDialog.CallBack,
         SpeakEngineDialog.CallBack,
         SharedPreferences.OnSharedPreferenceChangeListener {
         SharedPreferences.OnSharedPreferenceChangeListener {
 
 

+ 43 - 33
app/src/main/java/io/legado/app/ui/book/toc/ChapterListAdapter.kt

@@ -19,8 +19,10 @@ import io.legado.app.utils.gone
 import io.legado.app.utils.longToastOnUi
 import io.legado.app.utils.longToastOnUi
 import io.legado.app.utils.visible
 import io.legado.app.utils.visible
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.isActive
-import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.Dispatchers.Main
+import kotlinx.coroutines.async
+import kotlinx.coroutines.ensureActive
+import kotlinx.coroutines.withContext
 import java.util.concurrent.ConcurrentHashMap
 import java.util.concurrent.ConcurrentHashMap
 
 
 class ChapterListAdapter(context: Context, val callback: Callback) :
 class ChapterListAdapter(context: Context, val callback: Callback) :
@@ -54,17 +56,10 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
 
 
         }
         }
 
 
-    private val replaceRules
-        get() = callback.book?.let {
-            ContentProcessor.get(it.name, it.origin).getTitleReplaceRules()
-        }
-    private val useReplace
-        get() = AppConfig.tocUiUseReplace && callback.book?.getUseReplaceRule() == true
     private var upDisplayTileJob: Coroutine<*>? = null
     private var upDisplayTileJob: Coroutine<*>? = null
 
 
     override fun onCurrentListChanged() {
     override fun onCurrentListChanged() {
         super.onCurrentListChanged()
         super.onCurrentListChanged()
-        upDisplayTitle()
         callback.onListChanged()
         callback.onListChanged()
     }
     }
 
 
@@ -73,36 +68,50 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
         displayTitleMap.clear()
         displayTitleMap.clear()
     }
     }
 
 
-    fun upDisplayTitle() {
+    fun upDisplayTitles(startIndex: Int) {
         upDisplayTileJob?.cancel()
         upDisplayTileJob?.cancel()
         upDisplayTileJob = Coroutine.async(callback.scope) {
         upDisplayTileJob = Coroutine.async(callback.scope) {
-            val replaceRules = replaceRules
-            val useReplace = useReplace
-            getItems().forEach {
-                if (!isActive) {
-                    return@async
+            val book = callback.book ?: return@async
+            val replaceRules = ContentProcessor.get(book.name, book.origin).getTitleReplaceRules()
+            val useReplace = AppConfig.tocUiUseReplace && book.getUseReplaceRule()
+            val items = getItems()
+            async {
+                for (i in startIndex until items.size) {
+                    val item = items[i]
+                    if (displayTitleMap[item.title] == null) {
+                        ensureActive()
+                        val displayTitle = item.getDisplayTitle(replaceRules, useReplace)
+                        ensureActive()
+                        displayTitleMap[item.title] = displayTitle
+                        withContext(Main) {
+                            notifyItemChanged(i, true)
+                        }
+                    }
                 }
                 }
-                if (displayTitleMap[it.title] == null) {
-                    displayTitleMap[it.title] = it.getDisplayTitle(replaceRules, useReplace)
+            }.start()
+            async {
+                for (i in startIndex downTo 0) {
+                    val item = items[i]
+                    if (displayTitleMap[item.title] == null) {
+                        ensureActive()
+                        val displayTitle = item.getDisplayTitle(replaceRules, useReplace)
+                        ensureActive()
+                        displayTitleMap[item.title] = displayTitle
+                        withContext(Main) {
+                            notifyItemChanged(i, true)
+                        }
+                    }
                 }
                 }
-            }
+            }.start()
         }
         }
     }
     }
 
 
-    override fun getViewBinding(parent: ViewGroup): ItemChapterListBinding {
-        return ItemChapterListBinding.inflate(inflater, parent, false)
+    private fun getDisplayTitle(chapter: BookChapter): String {
+        return displayTitleMap[chapter.title] ?: chapter.title
     }
     }
 
 
-    private fun getDisplayTile(chapter: BookChapter): String {
-        var displayTitle = displayTitleMap[chapter.title]
-        if (displayTitle != null) {
-            return displayTitle
-        }
-        displayTitle = runBlocking {
-            chapter.getDisplayTitle(replaceRules, useReplace)
-        }
-        displayTitleMap[chapter.title] = displayTitle
-        return displayTitle
+    override fun getViewBinding(parent: ViewGroup): ItemChapterListBinding {
+        return ItemChapterListBinding.inflate(inflater, parent, false)
     }
     }
 
 
     override fun convert(
     override fun convert(
@@ -120,7 +129,7 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
                 } else {
                 } else {
                     tvChapterName.setTextColor(context.getCompatColor(R.color.primaryText))
                     tvChapterName.setTextColor(context.getCompatColor(R.color.primaryText))
                 }
                 }
-                tvChapterName.text = getDisplayTile(item)
+                tvChapterName.text = getDisplayTitle(item)
                 if (item.isVolume) {
                 if (item.isVolume) {
                     //卷名,如第一卷 突出显示
                     //卷名,如第一卷 突出显示
                     tvChapterItem.setBackgroundColor(context.getCompatColor(R.color.btn_bg_press))
                     tvChapterItem.setBackgroundColor(context.getCompatColor(R.color.btn_bg_press))
@@ -138,6 +147,7 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
                 }
                 }
                 upHasCache(binding, isDur, cached)
                 upHasCache(binding, isDur, cached)
             } else {
             } else {
+                tvChapterName.text = getDisplayTitle(item)
                 upHasCache(binding, isDur, cached)
                 upHasCache(binding, isDur, cached)
             }
             }
         }
         }
@@ -150,8 +160,8 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
             }
             }
         }
         }
         holder.itemView.setOnLongClickListener {
         holder.itemView.setOnLongClickListener {
-            getItem(holder.layoutPosition)?.let {
-                context.longToastOnUi(getDisplayTile(it))
+            getItem(holder.layoutPosition)?.let { item ->
+                context.longToastOnUi(getDisplayTitle(item))
             }
             }
             true
             true
         }
         }

+ 11 - 2
app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt

@@ -97,7 +97,15 @@ class ChapterListFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_chapt
             viewModel.bookData.value?.bookUrl?.let { bookUrl ->
             viewModel.bookData.value?.bookUrl?.let { bookUrl ->
                 if (chapter.bookUrl == bookUrl) {
                 if (chapter.bookUrl == bookUrl) {
                     adapter.cacheFileNames.add(chapter.getFileName())
                     adapter.cacheFileNames.add(chapter.getFileName())
-                    adapter.notifyItemChanged(chapter.index, true)
+                    if (viewModel.searchKey.isNullOrEmpty()) {
+                        adapter.notifyItemChanged(chapter.index, true)
+                    } else {
+                        adapter.getItems().forEachIndexed { index, bookChapter ->
+                            if (bookChapter.index == chapter.index) {
+                                adapter.notifyItemChanged(index, true)
+                            }
+                        }
+                    }
                 }
                 }
             }
             }
         }
         }
@@ -128,12 +136,13 @@ class ChapterListFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_chapt
                 }
                 }
             }
             }
             mLayoutManager.scrollToPositionWithOffset(scrollPos, 0)
             mLayoutManager.scrollToPositionWithOffset(scrollPos, 0)
+            adapter.upDisplayTitles(scrollPos)
         }
         }
     }
     }
 
 
     override fun clearDisplayTitle() {
     override fun clearDisplayTitle() {
         adapter.clearDisplayTitle()
         adapter.clearDisplayTitle()
-        adapter.upDisplayTitle()
+        adapter.upDisplayTitles(mLayoutManager.findFirstVisibleItemPosition())
     }
     }
 
 
     override val scope: CoroutineScope
     override val scope: CoroutineScope

+ 2 - 0
app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt

@@ -59,10 +59,12 @@ class TocActivity : VMBaseActivity<ActivityChapterListBinding, TocViewModel>() {
             setOnSearchClickListener { tabLayout.gone() }
             setOnSearchClickListener { tabLayout.gone() }
             setOnQueryTextListener(object : SearchView.OnQueryTextListener {
             setOnQueryTextListener(object : SearchView.OnQueryTextListener {
                 override fun onQueryTextSubmit(query: String): Boolean {
                 override fun onQueryTextSubmit(query: String): Boolean {
+                    viewModel.searchKey = query
                     return false
                     return false
                 }
                 }
 
 
                 override fun onQueryTextChange(newText: String): Boolean {
                 override fun onQueryTextChange(newText: String): Boolean {
+                    viewModel.searchKey = newText
                     if (tabLayout.selectedTabPosition == 1) {
                     if (tabLayout.selectedTabPosition == 1) {
                         viewModel.startBookmarkSearch(newText)
                         viewModel.startBookmarkSearch(newText)
                     } else {
                     } else {

+ 1 - 0
app/src/main/java/io/legado/app/ui/book/toc/TocViewModel.kt

@@ -12,6 +12,7 @@ class TocViewModel(application: Application) : BaseViewModel(application) {
     var bookData = MutableLiveData<Book>()
     var bookData = MutableLiveData<Book>()
     var chapterListCallBack: ChapterListCallBack? = null
     var chapterListCallBack: ChapterListCallBack? = null
     var bookMarkCallBack: BookmarkCallBack? = null
     var bookMarkCallBack: BookmarkCallBack? = null
+    var searchKey: String? = null
 
 
     fun initBook(bookUrl: String) {
     fun initBook(bookUrl: String) {
         this.bookUrl = bookUrl
         this.bookUrl = bookUrl

+ 3 - 20
app/src/main/java/io/legado/app/ui/config/BackupConfigFragment.kt

@@ -15,7 +15,6 @@ import androidx.preference.EditTextPreference
 import androidx.preference.ListPreference
 import androidx.preference.ListPreference
 import androidx.preference.Preference
 import androidx.preference.Preference
 import io.legado.app.R
 import io.legado.app.R
-import io.legado.app.base.BasePreferenceFragment
 import io.legado.app.constant.AppLog
 import io.legado.app.constant.AppLog
 import io.legado.app.constant.PreferKey
 import io.legado.app.constant.PreferKey
 import io.legado.app.help.config.AppConfig
 import io.legado.app.help.config.AppConfig
@@ -25,7 +24,7 @@ import io.legado.app.help.storage.*
 import io.legado.app.lib.dialogs.alert
 import io.legado.app.lib.dialogs.alert
 import io.legado.app.lib.permission.Permissions
 import io.legado.app.lib.permission.Permissions
 import io.legado.app.lib.permission.PermissionsCompat
 import io.legado.app.lib.permission.PermissionsCompat
-import io.legado.app.lib.theme.accentColor
+import io.legado.app.lib.prefs.fragment.PreferenceFragment
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.ui.document.HandleFileContract
 import io.legado.app.ui.document.HandleFileContract
 import io.legado.app.ui.widget.dialog.TextDialog
 import io.legado.app.ui.widget.dialog.TextDialog
@@ -34,7 +33,7 @@ import kotlinx.coroutines.Dispatchers.Main
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.launch
 import splitties.init.appCtx
 import splitties.init.appCtx
 
 
-class BackupConfigFragment : BasePreferenceFragment(),
+class BackupConfigFragment : PreferenceFragment(),
     SharedPreferences.OnSharedPreferenceChangeListener {
     SharedPreferences.OnSharedPreferenceChangeListener {
 
 
     private val viewModel by activityViewModels<ConfigViewModel>()
     private val viewModel by activityViewModels<ConfigViewModel>()
@@ -100,34 +99,18 @@ class BackupConfigFragment : BasePreferenceFragment(),
 
 
     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
     override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
         addPreferencesFromResource(R.xml.pref_config_backup)
         addPreferencesFromResource(R.xml.pref_config_backup)
-        findPreference<EditTextPreference>(PreferKey.webDavUrl)?.let {
-            it.setOnBindEditTextListener { editText ->
-                editText.applyTint(requireContext().accentColor)
-            }
-        }
-        findPreference<EditTextPreference>(PreferKey.webDavAccount)?.let {
-            it.setOnBindEditTextListener { editText ->
-                editText.applyTint(requireContext().accentColor)
-            }
-        }
         findPreference<EditTextPreference>(PreferKey.webDavPassword)?.let {
         findPreference<EditTextPreference>(PreferKey.webDavPassword)?.let {
             it.setOnBindEditTextListener { editText ->
             it.setOnBindEditTextListener { editText ->
-                editText.applyTint(requireContext().accentColor)
                 editText.inputType =
                 editText.inputType =
                     InputType.TYPE_TEXT_VARIATION_PASSWORD or InputType.TYPE_CLASS_TEXT
                     InputType.TYPE_TEXT_VARIATION_PASSWORD or InputType.TYPE_CLASS_TEXT
             }
             }
         }
         }
-        findPreference<EditTextPreference>(PreferKey.webDavDir)?.let {
-            it.setOnBindEditTextListener { editText ->
-                editText.applyTint(requireContext().accentColor)
-            }
-        }
         upPreferenceSummary(PreferKey.webDavUrl, getPrefString(PreferKey.webDavUrl))
         upPreferenceSummary(PreferKey.webDavUrl, getPrefString(PreferKey.webDavUrl))
         upPreferenceSummary(PreferKey.webDavAccount, getPrefString(PreferKey.webDavAccount))
         upPreferenceSummary(PreferKey.webDavAccount, getPrefString(PreferKey.webDavAccount))
         upPreferenceSummary(PreferKey.webDavPassword, getPrefString(PreferKey.webDavPassword))
         upPreferenceSummary(PreferKey.webDavPassword, getPrefString(PreferKey.webDavPassword))
         upPreferenceSummary(PreferKey.webDavDir, AppConfig.webDavDir)
         upPreferenceSummary(PreferKey.webDavDir, AppConfig.webDavDir)
         upPreferenceSummary(PreferKey.backupPath, getPrefString(PreferKey.backupPath))
         upPreferenceSummary(PreferKey.backupPath, getPrefString(PreferKey.backupPath))
-        findPreference<io.legado.app.ui.widget.prefs.Preference>("web_dav_restore")
+        findPreference<io.legado.app.lib.prefs.Preference>("web_dav_restore")
             ?.onLongClick { restoreDir.launch(); true }
             ?.onLongClick { restoreDir.launch(); true }
     }
     }
 
 

+ 3 - 3
app/src/main/java/io/legado/app/ui/config/CoverConfigFragment.kt

@@ -7,16 +7,16 @@ import android.os.Bundle
 import android.view.View
 import android.view.View
 import androidx.preference.Preference
 import androidx.preference.Preference
 import io.legado.app.R
 import io.legado.app.R
-import io.legado.app.base.BasePreferenceFragment
 import io.legado.app.constant.PreferKey
 import io.legado.app.constant.PreferKey
 import io.legado.app.lib.dialogs.selector
 import io.legado.app.lib.dialogs.selector
+import io.legado.app.lib.prefs.SwitchPreference
+import io.legado.app.lib.prefs.fragment.PreferenceFragment
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.model.BookCover
 import io.legado.app.model.BookCover
-import io.legado.app.ui.widget.prefs.SwitchPreference
 import io.legado.app.utils.*
 import io.legado.app.utils.*
 import java.io.FileOutputStream
 import java.io.FileOutputStream
 
 
-class CoverConfigFragment : BasePreferenceFragment(),
+class CoverConfigFragment : PreferenceFragment(),
     SharedPreferences.OnSharedPreferenceChangeListener {
     SharedPreferences.OnSharedPreferenceChangeListener {
 
 
     private val requestCodeCover = 111
     private val requestCodeCover = 111

+ 2 - 2
app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt

@@ -10,12 +10,12 @@ import androidx.fragment.app.activityViewModels
 import androidx.preference.ListPreference
 import androidx.preference.ListPreference
 import androidx.preference.Preference
 import androidx.preference.Preference
 import io.legado.app.R
 import io.legado.app.R
-import io.legado.app.base.BasePreferenceFragment
 import io.legado.app.constant.EventBus
 import io.legado.app.constant.EventBus
 import io.legado.app.constant.PreferKey
 import io.legado.app.constant.PreferKey
 import io.legado.app.databinding.DialogEditTextBinding
 import io.legado.app.databinding.DialogEditTextBinding
 import io.legado.app.help.config.AppConfig
 import io.legado.app.help.config.AppConfig
 import io.legado.app.lib.dialogs.alert
 import io.legado.app.lib.dialogs.alert
+import io.legado.app.lib.prefs.fragment.PreferenceFragment
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.model.CheckSource
 import io.legado.app.model.CheckSource
 import io.legado.app.receiver.SharedReceiverActivity
 import io.legado.app.receiver.SharedReceiverActivity
@@ -26,7 +26,7 @@ import io.legado.app.utils.*
 import splitties.init.appCtx
 import splitties.init.appCtx
 
 
 
 
-class OtherConfigFragment : BasePreferenceFragment(),
+class OtherConfigFragment : PreferenceFragment(),
     SharedPreferences.OnSharedPreferenceChangeListener {
     SharedPreferences.OnSharedPreferenceChangeListener {
 
 
     private val viewModel by activityViewModels<ConfigViewModel>()
     private val viewModel by activityViewModels<ConfigViewModel>()

+ 3 - 3
app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt

@@ -13,7 +13,6 @@ import android.widget.SeekBar
 import androidx.preference.Preference
 import androidx.preference.Preference
 import io.legado.app.R
 import io.legado.app.R
 import io.legado.app.base.AppContextWrapper
 import io.legado.app.base.AppContextWrapper
-import io.legado.app.base.BasePreferenceFragment
 import io.legado.app.constant.AppConst
 import io.legado.app.constant.AppConst
 import io.legado.app.constant.EventBus
 import io.legado.app.constant.EventBus
 import io.legado.app.constant.PreferKey
 import io.legado.app.constant.PreferKey
@@ -24,16 +23,17 @@ import io.legado.app.help.config.AppConfig
 import io.legado.app.help.config.ThemeConfig
 import io.legado.app.help.config.ThemeConfig
 import io.legado.app.lib.dialogs.alert
 import io.legado.app.lib.dialogs.alert
 import io.legado.app.lib.dialogs.selector
 import io.legado.app.lib.dialogs.selector
+import io.legado.app.lib.prefs.ColorPreference
+import io.legado.app.lib.prefs.fragment.PreferenceFragment
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.ui.widget.number.NumberPickerDialog
 import io.legado.app.ui.widget.number.NumberPickerDialog
-import io.legado.app.ui.widget.prefs.ColorPreference
 import io.legado.app.ui.widget.seekbar.SeekBarChangeListener
 import io.legado.app.ui.widget.seekbar.SeekBarChangeListener
 import io.legado.app.utils.*
 import io.legado.app.utils.*
 import java.io.FileOutputStream
 import java.io.FileOutputStream
 
 
 
 
 @Suppress("SameParameterValue")
 @Suppress("SameParameterValue")
-class ThemeConfigFragment : BasePreferenceFragment(),
+class ThemeConfigFragment : PreferenceFragment(),
     SharedPreferences.OnSharedPreferenceChangeListener {
     SharedPreferences.OnSharedPreferenceChangeListener {
 
 
     private val requestCodeBgLight = 121
     private val requestCodeBgLight = 121

+ 2 - 2
app/src/main/java/io/legado/app/ui/config/WelcomeConfigFragment.kt

@@ -7,15 +7,15 @@ import android.os.Bundle
 import android.view.View
 import android.view.View
 import androidx.preference.Preference
 import androidx.preference.Preference
 import io.legado.app.R
 import io.legado.app.R
-import io.legado.app.base.BasePreferenceFragment
 import io.legado.app.constant.PreferKey
 import io.legado.app.constant.PreferKey
 import io.legado.app.lib.dialogs.selector
 import io.legado.app.lib.dialogs.selector
+import io.legado.app.lib.prefs.fragment.PreferenceFragment
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.model.BookCover
 import io.legado.app.model.BookCover
 import io.legado.app.utils.*
 import io.legado.app.utils.*
 import java.io.FileOutputStream
 import java.io.FileOutputStream
 
 
-class WelcomeConfigFragment : BasePreferenceFragment(),
+class WelcomeConfigFragment : PreferenceFragment(),
     SharedPreferences.OnSharedPreferenceChangeListener {
     SharedPreferences.OnSharedPreferenceChangeListener {
 
 
     private val requestWelcomeImage = 221
     private val requestWelcomeImage = 221

+ 6 - 6
app/src/main/java/io/legado/app/ui/main/my/MyFragment.kt

@@ -8,13 +8,16 @@ import android.view.View
 import androidx.preference.Preference
 import androidx.preference.Preference
 import io.legado.app.R
 import io.legado.app.R
 import io.legado.app.base.BaseFragment
 import io.legado.app.base.BaseFragment
-import io.legado.app.base.BasePreferenceFragment
 import io.legado.app.constant.EventBus
 import io.legado.app.constant.EventBus
 import io.legado.app.constant.PreferKey
 import io.legado.app.constant.PreferKey
 import io.legado.app.databinding.FragmentMyConfigBinding
 import io.legado.app.databinding.FragmentMyConfigBinding
 import io.legado.app.help.config.AppConfig
 import io.legado.app.help.config.AppConfig
 import io.legado.app.help.config.ThemeConfig
 import io.legado.app.help.config.ThemeConfig
 import io.legado.app.lib.dialogs.selector
 import io.legado.app.lib.dialogs.selector
+import io.legado.app.lib.prefs.NameListPreference
+import io.legado.app.lib.prefs.PreferenceCategory
+import io.legado.app.lib.prefs.SwitchPreference
+import io.legado.app.lib.prefs.fragment.PreferenceFragment
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.service.WebService
 import io.legado.app.service.WebService
 import io.legado.app.ui.about.AboutActivity
 import io.legado.app.ui.about.AboutActivity
@@ -26,9 +29,6 @@ import io.legado.app.ui.config.ConfigActivity
 import io.legado.app.ui.config.ConfigTag
 import io.legado.app.ui.config.ConfigTag
 import io.legado.app.ui.replace.ReplaceRuleActivity
 import io.legado.app.ui.replace.ReplaceRuleActivity
 import io.legado.app.ui.widget.dialog.TextDialog
 import io.legado.app.ui.widget.dialog.TextDialog
-import io.legado.app.ui.widget.prefs.NameListPreference
-import io.legado.app.ui.widget.prefs.PreferenceCategory
-import io.legado.app.ui.widget.prefs.SwitchPreference
 import io.legado.app.utils.*
 import io.legado.app.utils.*
 import io.legado.app.utils.viewbindingdelegate.viewBinding
 import io.legado.app.utils.viewbindingdelegate.viewBinding
 
 
@@ -40,7 +40,7 @@ class MyFragment : BaseFragment(R.layout.fragment_my_config) {
         setSupportToolbar(binding.titleBar.toolbar)
         setSupportToolbar(binding.titleBar.toolbar)
         val fragmentTag = "prefFragment"
         val fragmentTag = "prefFragment"
         var preferenceFragment = childFragmentManager.findFragmentByTag(fragmentTag)
         var preferenceFragment = childFragmentManager.findFragmentByTag(fragmentTag)
-        if (preferenceFragment == null) preferenceFragment = PreferenceFragment()
+        if (preferenceFragment == null) preferenceFragment = MyPreferenceFragment()
         childFragmentManager.beginTransaction()
         childFragmentManager.beginTransaction()
             .replace(R.id.pre_fragment, preferenceFragment, fragmentTag).commit()
             .replace(R.id.pre_fragment, preferenceFragment, fragmentTag).commit()
     }
     }
@@ -61,7 +61,7 @@ class MyFragment : BaseFragment(R.layout.fragment_my_config) {
     /**
     /**
      * 配置
      * 配置
      */
      */
-    class PreferenceFragment : BasePreferenceFragment(),
+    class MyPreferenceFragment : PreferenceFragment(),
         SharedPreferences.OnSharedPreferenceChangeListener {
         SharedPreferences.OnSharedPreferenceChangeListener {
 
 
         override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
         override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {

+ 4 - 2
app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt

@@ -14,6 +14,7 @@ import io.legado.app.base.VMBaseActivity
 import io.legado.app.databinding.ActivityRssArtivlesBinding
 import io.legado.app.databinding.ActivityRssArtivlesBinding
 import io.legado.app.databinding.DialogEditTextBinding
 import io.legado.app.databinding.DialogEditTextBinding
 import io.legado.app.lib.dialogs.alert
 import io.legado.app.lib.dialogs.alert
+import io.legado.app.lib.theme.accentColor
 import io.legado.app.ui.login.SourceLoginActivity
 import io.legado.app.ui.login.SourceLoginActivity
 import io.legado.app.ui.rss.source.edit.RssSourceEditActivity
 import io.legado.app.ui.rss.source.edit.RssSourceEditActivity
 import io.legado.app.utils.StartActivityContract
 import io.legado.app.utils.StartActivityContract
@@ -45,9 +46,10 @@ class RssSortActivity : VMBaseActivity<ActivityRssArtivlesBinding, RssSortViewMo
     override fun onActivityCreated(savedInstanceState: Bundle?) {
     override fun onActivityCreated(savedInstanceState: Bundle?) {
         binding.viewPager.adapter = adapter
         binding.viewPager.adapter = adapter
         binding.tabLayout.setupWithViewPager(binding.viewPager)
         binding.tabLayout.setupWithViewPager(binding.viewPager)
-        viewModel.titleLiveData.observe(this, {
+        binding.tabLayout.setSelectedTabIndicatorColor(accentColor)
+        viewModel.titleLiveData.observe(this) {
             binding.titleBar.title = it
             binding.titleBar.title = it
-        })
+        }
         viewModel.initData(intent) {
         viewModel.initData(intent) {
             upFragments()
             upFragments()
         }
         }

+ 0 - 22
app/src/main/java/io/legado/app/ui/widget/prefs/EditTextPreference.kt

@@ -1,22 +0,0 @@
-package io.legado.app.ui.widget.prefs
-
-import android.content.Context
-import android.util.AttributeSet
-import android.widget.TextView
-import androidx.preference.PreferenceViewHolder
-import io.legado.app.R
-
-class EditTextPreference(context: Context, attrs: AttributeSet) :
-    androidx.preference.EditTextPreference(context, attrs) {
-
-    init {
-        // isPersistent = true
-        layoutResource = R.layout.view_preference
-    }
-
-    override fun onBindViewHolder(holder: PreferenceViewHolder) {
-        Preference.bindView<TextView>(context, holder, icon, title, summary, null, null)
-        super.onBindViewHolder(holder)
-    }
-
-}

+ 2 - 1
app/src/main/java/io/legado/app/utils/RegexExtensions.kt

@@ -6,6 +6,7 @@ import kotlinx.coroutines.suspendCancellableCoroutine
 import splitties.init.appCtx
 import splitties.init.appCtx
 import kotlin.concurrent.thread
 import kotlin.concurrent.thread
 import kotlin.coroutines.resume
 import kotlin.coroutines.resume
+import kotlin.coroutines.resumeWithException
 
 
 /**
 /**
  * 带有超时检测的正则替换
  * 带有超时检测的正则替换
@@ -19,7 +20,7 @@ suspend fun CharSequence.replace(regex: Regex, replacement: String, timeout: Lon
                 val result = regex.replace(charSequence, replacement)
                 val result = regex.replace(charSequence, replacement)
                 block.resume(result)
                 block.resume(result)
             } catch (e: Exception) {
             } catch (e: Exception) {
-                block.cancel(e)
+                block.resumeWithException(e)
             }
             }
         }
         }
         mainHandler.postDelayed({
         mainHandler.postDelayed({

+ 19 - 19
app/src/main/res/xml/about.xml

@@ -2,82 +2,82 @@
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto">
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
 
-    <io.legado.app.ui.widget.prefs.Preference
+    <io.legado.app.lib.prefs.Preference
         android:key="contributors"
         android:key="contributors"
         android:summary="@string/contributors_summary"
         android:summary="@string/contributors_summary"
         android:title="@string/contributors"
         android:title="@string/contributors"
         app:iconSpaceReserved="false" />
         app:iconSpaceReserved="false" />
 
 
-    <io.legado.app.ui.widget.prefs.Preference
+    <io.legado.app.lib.prefs.Preference
         android:key="update_log"
         android:key="update_log"
         android:title="@string/update_log"
         android:title="@string/update_log"
         app:allowDividerAbove="false"
         app:allowDividerAbove="false"
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false" />
         app:iconSpaceReserved="false" />
 
 
-    <io.legado.app.ui.widget.prefs.Preference
+    <io.legado.app.lib.prefs.Preference
         android:key="check_update"
         android:key="check_update"
         android:title="@string/check_update"
         android:title="@string/check_update"
         app:allowDividerAbove="false"
         app:allowDividerAbove="false"
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false" />
         app:iconSpaceReserved="false" />
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:title="@string/contact"
         android:title="@string/contact"
         app:allowDividerAbove="true"
         app:allowDividerAbove="true"
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
         app:layout="@layout/view_preference_category">
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="gzGzh"
             android:key="gzGzh"
             android:summary="@string/official_account"
             android:summary="@string/official_account"
             android:title="@string/follow_official_account"
             android:title="@string/follow_official_account"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="qqChannel"
             android:key="qqChannel"
             android:title="@string/join_qq_channel"
             android:title="@string/join_qq_channel"
             android:summary="@string/qq_channel_summary"
             android:summary="@string/qq_channel_summary"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="qq"
             android:key="qq"
             android:summary="@string/click_to_apply"
             android:summary="@string/click_to_apply"
             android:title="@string/join_qq_group"
             android:title="@string/join_qq_group"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="mail"
             android:key="mail"
             android:summary="@string/email"
             android:summary="@string/email"
             android:title="@string/send_mail"
             android:title="@string/send_mail"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="git"
             android:key="git"
             android:summary="@string/this_github_url"
             android:summary="@string/this_github_url"
             android:title="@string/git_hub"
             android:title="@string/git_hub"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="discord"
             android:key="discord"
             android:summary="@string/discord_url"
             android:summary="@string/discord_url"
             android:title="Discord"
             android:title="Discord"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="tg"
             android:key="tg"
             android:summary="@string/tg_url"
             android:summary="@string/tg_url"
             android:title="TG"
             android:title="TG"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="sourceRuleSummary"
             android:key="sourceRuleSummary"
             android:summary="@string/source_rule_url"
             android:summary="@string/source_rule_url"
             android:title="@string/source_rule_s"
             android:title="@string/source_rule_s"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="home_page"
             android:key="home_page"
             android:summary="@string/home_page_url"
             android:summary="@string/home_page_url"
             android:title="@string/home_page"
             android:title="@string/home_page"
@@ -85,30 +85,30 @@
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:title="@string/other"
         android:title="@string/other"
         app:allowDividerAbove="true"
         app:allowDividerAbove="true"
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
         app:layout="@layout/view_preference_category">
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="crashLog"
             android:key="crashLog"
             android:title="@string/crash_log"
             android:title="@string/crash_log"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="license"
             android:key="license"
             android:title="@string/license"
             android:title="@string/license"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="disclaimer"
             android:key="disclaimer"
             android:title="@string/disclaimer"
             android:title="@string/disclaimer"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
 </androidx.preference.PreferenceScreen>
 </androidx.preference.PreferenceScreen>

+ 12 - 12
app/src/main/res/xml/donate.xml

@@ -2,20 +2,20 @@
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto">
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:title="@string/wechat"
         android:title="@string/wechat"
         app:allowDividerAbove="false"
         app:allowDividerAbove="false"
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
         app:layout="@layout/view_preference_category">
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="gzGzh"
             android:key="gzGzh"
             android:summary="@string/follow_public_account_summary"
             android:summary="@string/follow_public_account_summary"
             android:title="@string/follow_official_account"
             android:title="@string/follow_official_account"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="wxZsm"
             android:key="wxZsm"
             android:summary="@string/click_to_open"
             android:summary="@string/click_to_open"
             android:title="@string/weChat_appreciation_code"
             android:title="@string/weChat_appreciation_code"
@@ -23,28 +23,28 @@
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:title="@string/alipay"
         android:title="@string/alipay"
         app:allowDividerAbove="true"
         app:allowDividerAbove="true"
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
         app:layout="@layout/view_preference_category">
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="zfbHbSsm"
             android:key="zfbHbSsm"
             android:summary="@string/alipay_red_envelope_copy"
             android:summary="@string/alipay_red_envelope_copy"
             android:title="@string/alipay_red_envelope_search_code"
             android:title="@string/alipay_red_envelope_search_code"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="zfbHbRwm"
             android:key="zfbHbRwm"
             android:summary="@string/click_to_open"
             android:summary="@string/click_to_open"
             android:title="@string/alipay_red_envelope_qr_code"
             android:title="@string/alipay_red_envelope_qr_code"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="zfbSkRwm"
             android:key="zfbSkRwm"
             android:summary="@string/click_to_open"
             android:summary="@string/click_to_open"
             android:title="@string/alipay_payment_qr_code"
             android:title="@string/alipay_payment_qr_code"
@@ -52,21 +52,21 @@
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:title="QQ"
         android:title="QQ"
         app:allowDividerAbove="true"
         app:allowDividerAbove="true"
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
         app:layout="@layout/view_preference_category">
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="qqSkRwm"
             android:key="qqSkRwm"
             android:summary="@string/click_to_open"
             android:summary="@string/click_to_open"
             android:title="@string/qq_collection_qr_code"
             android:title="@string/qq_collection_qr_code"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
 </androidx.preference.PreferenceScreen>
 </androidx.preference.PreferenceScreen>

+ 6 - 6
app/src/main/res/xml/pref_config_aloud.xml

@@ -2,38 +2,38 @@
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto">
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:title="@string/aloud_config"
         android:title="@string/aloud_config"
         app:allowDividerAbove="false"
         app:allowDividerAbove="false"
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false">
         app:iconSpaceReserved="false">
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="false"
             android:defaultValue="false"
             android:title="@string/pref_media_button_per_next"
             android:title="@string/pref_media_button_per_next"
             android:summary="@string/pref_media_button_per_next_summary"
             android:summary="@string/pref_media_button_per_next_summary"
             android:key="mediaButtonPerNext"
             android:key="mediaButtonPerNext"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="false"
             android:defaultValue="false"
             android:title="@string/read_aloud_by_page"
             android:title="@string/read_aloud_by_page"
             android:summary="@string/read_aloud_by_page_summary"
             android:summary="@string/read_aloud_by_page_summary"
             android:key="readAloudByPage"
             android:key="readAloudByPage"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:title="@string/speak_engine"
             android:title="@string/speak_engine"
             android:summary="TTS"
             android:summary="TTS"
             android:key="appTtsEngine"
             android:key="appTtsEngine"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:title="@string/sys_tts_config"
             android:title="@string/sys_tts_config"
             android:summary="@string/sys_tts_config_summary"
             android:summary="@string/sys_tts_config_summary"
             android:key="sysTtsConfig"
             android:key="sysTtsConfig"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
 </androidx.preference.PreferenceScreen>
 </androidx.preference.PreferenceScreen>

+ 14 - 14
app/src/main/res/xml/pref_config_backup.xml

@@ -2,39 +2,39 @@
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto">
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:title="@string/web_dav_set"
         android:title="@string/web_dav_set"
         app:allowDividerAbove="false"
         app:allowDividerAbove="false"
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
         app:layout="@layout/view_preference_category">
 
 
-        <io.legado.app.ui.widget.prefs.EditTextPreference
+        <io.legado.app.lib.prefs.EditTextPreference
             android:key="web_dav_url"
             android:key="web_dav_url"
             android:title="@string/web_dav_url"
             android:title="@string/web_dav_url"
             android:summary="@string/web_dav_url_s"
             android:summary="@string/web_dav_url_s"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.EditTextPreference
+        <io.legado.app.lib.prefs.EditTextPreference
             android:key="web_dav_account"
             android:key="web_dav_account"
             android:title="@string/web_dav_account"
             android:title="@string/web_dav_account"
             android:summary="@string/web_dav_account_s"
             android:summary="@string/web_dav_account_s"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.EditTextPreference
+        <io.legado.app.lib.prefs.EditTextPreference
             android:key="web_dav_password"
             android:key="web_dav_password"
             android:title="@string/web_dav_pw"
             android:title="@string/web_dav_pw"
             android:summary="@string/web_dav_pw_s"
             android:summary="@string/web_dav_pw_s"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.EditTextPreference
+        <io.legado.app.lib.prefs.EditTextPreference
             android:key="webDavDir"
             android:key="webDavDir"
             android:title="@string/sub_dir"
             android:title="@string/sub_dir"
             app:allowDividerAbove="false"
             app:allowDividerAbove="false"
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:key="syncBookProgress"
             android:key="syncBookProgress"
             android:defaultValue="true"
             android:defaultValue="true"
             android:title="@string/sync_book_progress_t"
             android:title="@string/sync_book_progress_t"
@@ -43,44 +43,44 @@
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:title="@string/backup_restore"
         android:title="@string/backup_restore"
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
         app:layout="@layout/view_preference_category">
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="backupUri"
             android:key="backupUri"
             android:title="@string/backup_path"
             android:title="@string/backup_path"
             android:summary="@string/select_backup_path"
             android:summary="@string/select_backup_path"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="web_dav_backup"
             android:key="web_dav_backup"
             android:title="@string/backup"
             android:title="@string/backup"
             android:summary="@string/backup_summary"
             android:summary="@string/backup_summary"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="web_dav_restore"
             android:key="web_dav_restore"
             android:title="@string/restore"
             android:title="@string/restore"
             android:summary="@string/restore_summary"
             android:summary="@string/restore_summary"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="restoreIgnore"
             android:key="restoreIgnore"
             android:title="@string/restore_ignore"
             android:title="@string/restore_ignore"
             android:summary="@string/restore_ignore_summary"
             android:summary="@string/restore_ignore_summary"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="import_old"
             android:key="import_old"
             android:title="@string/menu_import_old_version"
             android:title="@string/menu_import_old_version"
             android:summary="@string/import_old_summary"
             android:summary="@string/import_old_summary"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
 </androidx.preference.PreferenceScreen>
 </androidx.preference.PreferenceScreen>

+ 13 - 13
app/src/main/res/xml/pref_config_cover.xml

@@ -2,13 +2,13 @@
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto">
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:key="loadCoverOnlyWifi"
         android:key="loadCoverOnlyWifi"
         android:defaultValue="false"
         android:defaultValue="false"
         android:title="@string/only_wifi"
         android:title="@string/only_wifi"
         android:summary="@string/only_wifi_summary" />
         android:summary="@string/only_wifi_summary" />
 
 
-    <io.legado.app.ui.widget.prefs.Preference
+    <io.legado.app.lib.prefs.Preference
         android:key="coverRule"
         android:key="coverRule"
         android:title="@string/cover_rule"
         android:title="@string/cover_rule"
         android:summary="@string/cover_rule_summary"
         android:summary="@string/cover_rule_summary"
@@ -16,7 +16,7 @@
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false" />
         app:iconSpaceReserved="false" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="false"
         android:defaultValue="false"
         android:key="useDefaultCover"
         android:key="useDefaultCover"
         android:summary="@string/use_default_cover_s"
         android:summary="@string/use_default_cover_s"
@@ -25,7 +25,7 @@
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false" />
         app:iconSpaceReserved="false" />
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:key="dayThemeCategory"
         android:key="dayThemeCategory"
         android:title="@string/day"
         android:title="@string/day"
         app:allowDividerAbove="true"
         app:allowDividerAbove="true"
@@ -33,14 +33,14 @@
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
         app:layout="@layout/view_preference_category">
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="defaultCover"
             android:key="defaultCover"
             android:title="@string/default_cover"
             android:title="@string/default_cover"
             app:allowDividerAbove="false"
             app:allowDividerAbove="false"
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="true"
             android:defaultValue="true"
             android:key="coverShowName"
             android:key="coverShowName"
             android:title="@string/cover_show_name"
             android:title="@string/cover_show_name"
@@ -49,7 +49,7 @@
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="true"
             android:defaultValue="true"
             android:key="coverShowAuthor"
             android:key="coverShowAuthor"
             android:title="@string/cover_show_author"
             android:title="@string/cover_show_author"
@@ -58,9 +58,9 @@
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:key="nightThemeCategory"
         android:key="nightThemeCategory"
         android:title="@string/night"
         android:title="@string/night"
         app:allowDividerAbove="true"
         app:allowDividerAbove="true"
@@ -68,14 +68,14 @@
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
         app:layout="@layout/view_preference_category">
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="defaultCoverDark"
             android:key="defaultCoverDark"
             android:title="@string/default_cover"
             android:title="@string/default_cover"
             app:allowDividerAbove="false"
             app:allowDividerAbove="false"
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="true"
             android:defaultValue="true"
             android:key="coverShowNameN"
             android:key="coverShowNameN"
             android:title="@string/cover_show_name"
             android:title="@string/cover_show_name"
@@ -84,7 +84,7 @@
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="true"
             android:defaultValue="true"
             android:key="coverShowAuthorN"
             android:key="coverShowAuthorN"
             android:title="@string/cover_show_author"
             android:title="@string/cover_show_author"
@@ -93,6 +93,6 @@
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
 </androidx.preference.PreferenceScreen>
 </androidx.preference.PreferenceScreen>

+ 24 - 24
app/src/main/res/xml/pref_config_other.xml

@@ -2,41 +2,41 @@
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto">
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
 
-    <io.legado.app.ui.widget.prefs.NameListPreference
+    <io.legado.app.lib.prefs.NameListPreference
         android:defaultValue="auto"
         android:defaultValue="auto"
         android:key="language"
         android:key="language"
         android:title="@string/language"
         android:title="@string/language"
         app:entries="@array/language"
         app:entries="@array/language"
         app:entryValues="@array/language_value" />
         app:entryValues="@array/language_value" />
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:title="@string/main_activity"
         android:title="@string/main_activity"
         app:allowDividerAbove="false"
         app:allowDividerAbove="false"
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
         app:layout="@layout/view_preference_category">
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="false"
             android:defaultValue="false"
             android:key="auto_refresh"
             android:key="auto_refresh"
             android:summary="@string/ps_auto_refresh"
             android:summary="@string/ps_auto_refresh"
             android:title="@string/pt_auto_refresh"
             android:title="@string/pt_auto_refresh"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="false"
             android:defaultValue="false"
             android:key="defaultToRead"
             android:key="defaultToRead"
             android:summary="@string/ps_default_read"
             android:summary="@string/ps_default_read"
             android:title="@string/pt_default_read"
             android:title="@string/pt_default_read"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="true"
             android:defaultValue="true"
             android:key="showDiscovery"
             android:key="showDiscovery"
             android:title="@string/show_discovery"
             android:title="@string/show_discovery"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="true"
             android:defaultValue="true"
             android:key="showRss"
             android:key="showRss"
             android:title="@string/show_rss"
             android:title="@string/show_rss"
@@ -44,99 +44,99 @@
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:title="@string/other_setting"
         android:title="@string/other_setting"
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
         app:layout="@layout/view_preference_category">
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="userAgent"
             android:key="userAgent"
             android:title="@string/user_agent" />
             android:title="@string/user_agent" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="defaultBookTreeUri"
             android:key="defaultBookTreeUri"
             android:summary="@string/book_tree_uri_s"
             android:summary="@string/book_tree_uri_s"
             android:title="@string/book_tree_uri_t" />
             android:title="@string/book_tree_uri_t" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="checkSource"
             android:key="checkSource"
             android:title="@string/check_source_config" />
             android:title="@string/check_source_config" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="uploadRule"
             android:key="uploadRule"
             android:summary="@string/direct_link_upload_rule_summary"
             android:summary="@string/direct_link_upload_rule_summary"
             android:title="@string/direct_link_upload_rule" />
             android:title="@string/direct_link_upload_rule" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="false"
             android:defaultValue="false"
             android:key="Cronet"
             android:key="Cronet"
             android:summary="@string/pref_cronet_summary"
             android:summary="@string/pref_cronet_summary"
             android:title="Cronet" />
             android:title="Cronet" />
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="false"
             android:defaultValue="false"
             android:key="antiAlias"
             android:key="antiAlias"
             android:summary="@string/pref_anti_alias_summary"
             android:summary="@string/pref_anti_alias_summary"
             android:title="@string/anti_alias" />
             android:title="@string/anti_alias" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="preDownloadNum"
             android:key="preDownloadNum"
             android:summary="@string/pre_download_s"
             android:summary="@string/pre_download_s"
             android:title="@string/pre_download" />
             android:title="@string/pre_download" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="true"
             android:defaultValue="true"
             android:key="replaceEnableDefault"
             android:key="replaceEnableDefault"
             android:summary="@string/replace_enable_default_s"
             android:summary="@string/replace_enable_default_s"
             android:title="@string/replace_enable_default_t"
             android:title="@string/replace_enable_default_t"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="true"
             android:defaultValue="true"
             android:key="mediaButtonOnExit"
             android:key="mediaButtonOnExit"
             android:summary="@string/media_button_on_exit_summary"
             android:summary="@string/media_button_on_exit_summary"
             android:title="@string/media_button_on_exit_title"
             android:title="@string/media_button_on_exit_title"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="true"
             android:defaultValue="true"
             android:key="autoClearExpired"
             android:key="autoClearExpired"
             android:summary="@string/auto_clear_expired_summary"
             android:summary="@string/auto_clear_expired_summary"
             android:title="@string/auto_clear_expired" />
             android:title="@string/auto_clear_expired" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="webPort"
             android:key="webPort"
             android:title="@string/web_port_title"
             android:title="@string/web_port_title"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="cleanCache"
             android:key="cleanCache"
             android:summary="@string/clear_cache_summary"
             android:summary="@string/clear_cache_summary"
             android:title="@string/clear_cache"
             android:title="@string/clear_cache"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="threadCount"
             android:key="threadCount"
             android:title="@string/threads_num_title"
             android:title="@string/threads_num_title"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="true"
             android:defaultValue="true"
             android:key="process_text"
             android:key="process_text"
             android:summary="@string/add_to_text_context_menu_s"
             android:summary="@string/add_to_text_context_menu_s"
             android:title="@string/add_to_text_context_menu_t"
             android:title="@string/add_to_text_context_menu_t"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="false"
             android:defaultValue="false"
             android:key="recordLog"
             android:key="recordLog"
             android:summary="@string/record_debug_log"
             android:summary="@string/record_debug_log"
             android:title="@string/record_log"
             android:title="@string/record_log"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
 
 
 </androidx.preference.PreferenceScreen>
 </androidx.preference.PreferenceScreen>

+ 18 - 18
app/src/main/res/xml/pref_config_read.xml

@@ -2,7 +2,7 @@
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto">
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
 
-    <io.legado.app.ui.widget.prefs.NameListPreference
+    <io.legado.app.lib.prefs.NameListPreference
         android:key="screenOrientation"
         android:key="screenOrientation"
         android:defaultValue="0"
         android:defaultValue="0"
         android:title="@string/screen_direction"
         android:title="@string/screen_direction"
@@ -11,7 +11,7 @@
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:isBottomBackground="true" />
         app:isBottomBackground="true" />
 
 
-    <io.legado.app.ui.widget.prefs.NameListPreference
+    <io.legado.app.lib.prefs.NameListPreference
         android:key="keep_light"
         android:key="keep_light"
         android:defaultValue="0"
         android:defaultValue="0"
         android:entryValues="@array/screen_time_out_value"
         android:entryValues="@array/screen_time_out_value"
@@ -20,110 +20,110 @@
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:isBottomBackground="true" />
         app:isBottomBackground="true" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="false"
         android:defaultValue="false"
         android:title="@string/pt_hide_status_bar"
         android:title="@string/pt_hide_status_bar"
         android:key="hideStatusBar"
         android:key="hideStatusBar"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:isBottomBackground="true" />
         app:isBottomBackground="true" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="true"
         android:defaultValue="true"
         android:title="@string/read_body_to_lh"
         android:title="@string/read_body_to_lh"
         android:key="readBodyToLh"
         android:key="readBodyToLh"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:isBottomBackground="true" />
         app:isBottomBackground="true" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="false"
         android:defaultValue="false"
         android:title="@string/pt_hide_navigation_bar"
         android:title="@string/pt_hide_navigation_bar"
         android:key="hideNavigationBar"
         android:key="hideNavigationBar"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:isBottomBackground="true" />
         app:isBottomBackground="true" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="true"
         android:defaultValue="true"
         android:title="@string/double_page_horizontal"
         android:title="@string/double_page_horizontal"
         android:key="doublePageHorizontal"
         android:key="doublePageHorizontal"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:isBottomBackground="true" />
         app:isBottomBackground="true" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="false"
         android:defaultValue="false"
         android:title="@string/use_zh_layout"
         android:title="@string/use_zh_layout"
         android:key="useZhLayout"
         android:key="useZhLayout"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:isBottomBackground="true" />
         app:isBottomBackground="true" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="true"
         android:defaultValue="true"
         android:title="@string/text_full_justify"
         android:title="@string/text_full_justify"
         android:key="textFullJustify"
         android:key="textFullJustify"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:isBottomBackground="true" />
         app:isBottomBackground="true" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="true"
         android:defaultValue="true"
         android:title="@string/text_bottom_justify"
         android:title="@string/text_bottom_justify"
         android:key="textBottomJustify"
         android:key="textBottomJustify"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:isBottomBackground="true" />
         app:isBottomBackground="true" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="true"
         android:defaultValue="true"
         android:title="@string/volume_key_page"
         android:title="@string/volume_key_page"
         android:key="volumeKeyPage"
         android:key="volumeKeyPage"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:isBottomBackground="true" />
         app:isBottomBackground="true" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="false"
         android:defaultValue="false"
         android:title="@string/volume_key_page_on_play"
         android:title="@string/volume_key_page_on_play"
         android:key="volumeKeyPageOnPlay"
         android:key="volumeKeyPageOnPlay"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:isBottomBackground="true" />
         app:isBottomBackground="true" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="true"
         android:defaultValue="true"
         android:title="@string/auto_change_source"
         android:title="@string/auto_change_source"
         android:key="autoChangeSource"
         android:key="autoChangeSource"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:isBottomBackground="true" />
         app:isBottomBackground="true" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="true"
         android:defaultValue="true"
         android:title="@string/selectText"
         android:title="@string/selectText"
         android:key="selectText"
         android:key="selectText"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:isBottomBackground="true" />
         app:isBottomBackground="true" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="true"
         android:defaultValue="true"
         android:title="@string/show_brightness_view"
         android:title="@string/show_brightness_view"
         android:key="showBrightnessView"
         android:key="showBrightnessView"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:isBottomBackground="true" />
         app:isBottomBackground="true" />
 
 
-    <io.legado.app.ui.widget.prefs.Preference
+    <io.legado.app.lib.prefs.Preference
         android:title="@string/click_regional_config"
         android:title="@string/click_regional_config"
         android:key="clickRegionalConfig"
         android:key="clickRegionalConfig"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:isBottomBackground="true" />
         app:isBottomBackground="true" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="false"
         android:defaultValue="false"
         android:key="disableReturnKey"
         android:key="disableReturnKey"
         android:title="@string/disable_return_key"
         android:title="@string/disable_return_key"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:isBottomBackground="true" />
         app:isBottomBackground="true" />
 
 
-    <io.legado.app.ui.widget.prefs.Preference
+    <io.legado.app.lib.prefs.Preference
         android:key="customPageKey"
         android:key="customPageKey"
         android:title="@string/custom_page_key"
         android:title="@string/custom_page_key"
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:isBottomBackground="true" />
         app:isBottomBackground="true" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="false"
         android:defaultValue="false"
         android:key="expandTextMenu"
         android:key="expandTextMenu"
         android:title="@string/expand_text_menu"
         android:title="@string/expand_text_menu"

+ 24 - 24
app/src/main/res/xml/pref_config_theme.xml

@@ -2,7 +2,7 @@
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto">
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
 
-    <io.legado.app.ui.widget.prefs.IconListPreference
+    <io.legado.app.lib.prefs.IconListPreference
         android:defaultValue="ic_launcher"
         android:defaultValue="ic_launcher"
         android:entries="@array/icon_names"
         android:entries="@array/icon_names"
         android:entryValues="@array/icons"
         android:entryValues="@array/icons"
@@ -12,38 +12,38 @@
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:icons="@array/icons" />
         app:icons="@array/icons" />
 
 
-    <io.legado.app.ui.widget.prefs.Preference
+    <io.legado.app.lib.prefs.Preference
         android:key="welcomeStyle"
         android:key="welcomeStyle"
         android:title="@string/welcome_style"
         android:title="@string/welcome_style"
         android:summary="@string/welcome_style_summary" />
         android:summary="@string/welcome_style_summary" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="true"
         android:defaultValue="true"
         android:key="transparentStatusBar"
         android:key="transparentStatusBar"
         android:summary="@string/status_bar_immersion"
         android:summary="@string/status_bar_immersion"
         android:title="@string/immersion_status_bar"
         android:title="@string/immersion_status_bar"
         app:iconSpaceReserved="false" />
         app:iconSpaceReserved="false" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="true"
         android:defaultValue="true"
         android:key="immNavigationBar"
         android:key="immNavigationBar"
         android:summary="@string/imm_navigation_bar_s"
         android:summary="@string/imm_navigation_bar_s"
         android:title="@string/imm_navigation_bar"
         android:title="@string/imm_navigation_bar"
         app:iconSpaceReserved="false" />
         app:iconSpaceReserved="false" />
 
 
-    <io.legado.app.ui.widget.prefs.Preference
+    <io.legado.app.lib.prefs.Preference
         android:key="barElevation"
         android:key="barElevation"
         android:summary="@string/bar_elevation_s"
         android:summary="@string/bar_elevation_s"
         android:title="@string/bar_elevation"
         android:title="@string/bar_elevation"
         app:iconSpaceReserved="false" />
         app:iconSpaceReserved="false" />
 
 
-    <io.legado.app.ui.widget.prefs.Preference
+    <io.legado.app.lib.prefs.Preference
         android:key="fontScale"
         android:key="fontScale"
         android:summary="@string/font_scale_summary"
         android:summary="@string/font_scale_summary"
         android:title="@string/font_scale"
         android:title="@string/font_scale"
         app:iconSpaceReserved="false" />
         app:iconSpaceReserved="false" />
 
 
-    <io.legado.app.ui.widget.prefs.Preference
+    <io.legado.app.lib.prefs.Preference
         android:key="coverConfig"
         android:key="coverConfig"
         android:title="@string/cover_config"
         android:title="@string/cover_config"
         android:summary="@string/cover_config_summary"
         android:summary="@string/cover_config_summary"
@@ -51,7 +51,7 @@
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false" />
         app:iconSpaceReserved="false" />
 
 
-    <io.legado.app.ui.widget.prefs.Preference
+    <io.legado.app.lib.prefs.Preference
         android:key="themeList"
         android:key="themeList"
         android:summary="@string/theme_list_summary"
         android:summary="@string/theme_list_summary"
         android:title="@string/theme_list"
         android:title="@string/theme_list"
@@ -59,7 +59,7 @@
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false" />
         app:iconSpaceReserved="false" />
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:key="dayThemeCategory"
         android:key="dayThemeCategory"
         android:title="@string/day"
         android:title="@string/day"
         app:allowDividerAbove="true"
         app:allowDividerAbove="true"
@@ -67,7 +67,7 @@
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
         app:layout="@layout/view_preference_category">
 
 
-        <io.legado.app.ui.widget.prefs.ColorPreference
+        <io.legado.app.lib.prefs.ColorPreference
             android:defaultValue="@color/md_light_blue_600"
             android:defaultValue="@color/md_light_blue_600"
             android:key="colorPrimary"
             android:key="colorPrimary"
             android:summary="@string/day_color_primary"
             android:summary="@string/day_color_primary"
@@ -75,7 +75,7 @@
             app:cpv_dialogType="preset"
             app:cpv_dialogType="preset"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.ColorPreference
+        <io.legado.app.lib.prefs.ColorPreference
             android:defaultValue="@color/md_pink_800"
             android:defaultValue="@color/md_pink_800"
             android:key="colorAccent"
             android:key="colorAccent"
             android:summary="@string/day_color_accent"
             android:summary="@string/day_color_accent"
@@ -83,7 +83,7 @@
             app:cpv_dialogType="preset"
             app:cpv_dialogType="preset"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.ColorPreference
+        <io.legado.app.lib.prefs.ColorPreference
             android:defaultValue="@color/md_grey_100"
             android:defaultValue="@color/md_grey_100"
             android:key="colorBackground"
             android:key="colorBackground"
             android:summary="@string/day_background_color"
             android:summary="@string/day_background_color"
@@ -91,7 +91,7 @@
             app:cpv_dialogType="preset"
             app:cpv_dialogType="preset"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.ColorPreference
+        <io.legado.app.lib.prefs.ColorPreference
             android:defaultValue="@color/md_grey_200"
             android:defaultValue="@color/md_grey_200"
             android:key="colorBottomBackground"
             android:key="colorBottomBackground"
             android:summary="@string/day_navbar_color"
             android:summary="@string/day_navbar_color"
@@ -101,11 +101,11 @@
             app:cpv_dialogType="preset"
             app:cpv_dialogType="preset"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="backgroundImage"
             android:key="backgroundImage"
             android:title="@string/background_image" />
             android:title="@string/background_image" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="saveDayTheme"
             android:key="saveDayTheme"
             android:summary="@string/save_day_theme_summary"
             android:summary="@string/save_day_theme_summary"
             android:title="@string/save_theme_config"
             android:title="@string/save_theme_config"
@@ -113,9 +113,9 @@
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:key="nightThemeCategory"
         android:key="nightThemeCategory"
         android:title="@string/night"
         android:title="@string/night"
         app:allowDividerAbove="true"
         app:allowDividerAbove="true"
@@ -123,7 +123,7 @@
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
         app:layout="@layout/view_preference_category">
 
 
-        <io.legado.app.ui.widget.prefs.ColorPreference
+        <io.legado.app.lib.prefs.ColorPreference
             android:defaultValue="@color/md_grey_900"
             android:defaultValue="@color/md_grey_900"
             android:key="colorPrimaryNight"
             android:key="colorPrimaryNight"
             android:summary="@string/night_primary"
             android:summary="@string/night_primary"
@@ -131,7 +131,7 @@
             app:cpv_dialogType="preset"
             app:cpv_dialogType="preset"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.ColorPreference
+        <io.legado.app.lib.prefs.ColorPreference
             android:defaultValue="@color/md_deep_orange_800"
             android:defaultValue="@color/md_deep_orange_800"
             android:key="colorAccentNight"
             android:key="colorAccentNight"
             android:summary="@string/night_accent"
             android:summary="@string/night_accent"
@@ -139,7 +139,7 @@
             app:cpv_dialogType="preset"
             app:cpv_dialogType="preset"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.ColorPreference
+        <io.legado.app.lib.prefs.ColorPreference
             android:defaultValue="@color/md_black_1000"
             android:defaultValue="@color/md_black_1000"
             android:key="colorBackgroundNight"
             android:key="colorBackgroundNight"
             android:summary="@string/night_background_color"
             android:summary="@string/night_background_color"
@@ -147,7 +147,7 @@
             app:cpv_dialogType="preset"
             app:cpv_dialogType="preset"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.ColorPreference
+        <io.legado.app.lib.prefs.ColorPreference
             android:defaultValue="@color/md_grey_800"
             android:defaultValue="@color/md_grey_800"
             android:key="colorBottomBackgroundNight"
             android:key="colorBottomBackgroundNight"
             android:summary="@string/night_navbar_color"
             android:summary="@string/night_navbar_color"
@@ -155,11 +155,11 @@
             app:cpv_dialogType="preset"
             app:cpv_dialogType="preset"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="backgroundImageNight"
             android:key="backgroundImageNight"
             android:title="@string/background_image" />
             android:title="@string/background_image" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="saveNightTheme"
             android:key="saveNightTheme"
             android:summary="@string/save_night_theme_summary"
             android:summary="@string/save_night_theme_summary"
             android:title="@string/save_theme_config"
             android:title="@string/save_theme_config"
@@ -167,6 +167,6 @@
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
 </androidx.preference.PreferenceScreen>
 </androidx.preference.PreferenceScreen>

+ 11 - 11
app/src/main/res/xml/pref_config_welcome.xml

@@ -2,7 +2,7 @@
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
 <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto">
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="false"
         android:defaultValue="false"
         android:key="customWelcome"
         android:key="customWelcome"
         android:summary="@string/custom_welcome_summary"
         android:summary="@string/custom_welcome_summary"
@@ -11,7 +11,7 @@
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false" />
         app:iconSpaceReserved="false" />
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:key="dayThemeCategory"
         android:key="dayThemeCategory"
         android:title="@string/day"
         android:title="@string/day"
         app:allowDividerAbove="true"
         app:allowDividerAbove="true"
@@ -19,14 +19,14 @@
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
         app:layout="@layout/view_preference_category">
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="welcomeImagePath"
             android:key="welcomeImagePath"
             android:title="@string/background_image"
             android:title="@string/background_image"
             app:allowDividerAbove="false"
             app:allowDividerAbove="false"
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="true"
             android:defaultValue="true"
             android:key="welcomeShowText"
             android:key="welcomeShowText"
             android:summary="@string/welcome_text"
             android:summary="@string/welcome_text"
@@ -35,7 +35,7 @@
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="true"
             android:defaultValue="true"
             android:key="welcomeShowIcon"
             android:key="welcomeShowIcon"
             android:summary="@string/show_default_book_icon"
             android:summary="@string/show_default_book_icon"
@@ -44,9 +44,9 @@
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:key="nightThemeCategory"
         android:key="nightThemeCategory"
         android:title="@string/night"
         android:title="@string/night"
         app:allowDividerAbove="true"
         app:allowDividerAbove="true"
@@ -54,14 +54,14 @@
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
         app:layout="@layout/view_preference_category">
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="welcomeImagePathDark"
             android:key="welcomeImagePathDark"
             android:title="@string/background_image"
             android:title="@string/background_image"
             app:allowDividerAbove="false"
             app:allowDividerAbove="false"
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="true"
             android:defaultValue="true"
             android:key="welcomeShowTextDark"
             android:key="welcomeShowTextDark"
             android:summary="@string/welcome_text"
             android:summary="@string/welcome_text"
@@ -70,7 +70,7 @@
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.SwitchPreference
+        <io.legado.app.lib.prefs.SwitchPreference
             android:defaultValue="true"
             android:defaultValue="true"
             android:key="welcomeShowIconDark"
             android:key="welcomeShowIconDark"
             android:summary="@string/show_default_book_icon"
             android:summary="@string/show_default_book_icon"
@@ -79,6 +79,6 @@
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
 </androidx.preference.PreferenceScreen>
 </androidx.preference.PreferenceScreen>

+ 15 - 15
app/src/main/res/xml/pref_main.xml

@@ -5,21 +5,21 @@
     app:allowDividerAbove="false"
     app:allowDividerAbove="false"
     app:allowDividerBelow="false">
     app:allowDividerBelow="false">
 
 
-    <io.legado.app.ui.widget.prefs.Preference
+    <io.legado.app.lib.prefs.Preference
         android:key="bookSourceManage"
         android:key="bookSourceManage"
         android:title="@string/book_source_manage"
         android:title="@string/book_source_manage"
         android:summary="@string/book_source_manage_desc"
         android:summary="@string/book_source_manage_desc"
         android:icon="@drawable/ic_cfg_source"
         android:icon="@drawable/ic_cfg_source"
         app:iconSpaceReserved="false" />
         app:iconSpaceReserved="false" />
 
 
-    <io.legado.app.ui.widget.prefs.Preference
+    <io.legado.app.lib.prefs.Preference
         android:key="replaceManage"
         android:key="replaceManage"
         android:title="@string/replace_purify"
         android:title="@string/replace_purify"
         android:summary="@string/replace_purify_desc"
         android:summary="@string/replace_purify_desc"
         android:icon="@drawable/ic_cfg_replace"
         android:icon="@drawable/ic_cfg_replace"
         app:iconSpaceReserved="false" />
         app:iconSpaceReserved="false" />
 
 
-    <io.legado.app.ui.widget.prefs.NameListPreference
+    <io.legado.app.lib.prefs.NameListPreference
         android:defaultValue="0"
         android:defaultValue="0"
         android:entries="@array/theme_mode"
         android:entries="@array/theme_mode"
         android:entryValues="@array/theme_mode_v"
         android:entryValues="@array/theme_mode_v"
@@ -29,7 +29,7 @@
         android:icon="@drawable/ic_cfg_theme"
         android:icon="@drawable/ic_cfg_theme"
         app:iconSpaceReserved="false" />
         app:iconSpaceReserved="false" />
 
 
-    <io.legado.app.ui.widget.prefs.SwitchPreference
+    <io.legado.app.lib.prefs.SwitchPreference
         android:defaultValue="false"
         android:defaultValue="false"
         android:key="webService"
         android:key="webService"
         android:title="@string/web_service"
         android:title="@string/web_service"
@@ -38,27 +38,27 @@
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false" />
         app:iconSpaceReserved="false" />
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:title="@string/setting"
         android:title="@string/setting"
         app:allowDividerAbove="true"
         app:allowDividerAbove="true"
         app:allowDividerBelow="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false">
         app:iconSpaceReserved="false">
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="web_dav_setting"
             android:key="web_dav_setting"
             android:summary="@string/web_dav_set_import_old"
             android:summary="@string/web_dav_set_import_old"
             android:title="@string/backup_restore"
             android:title="@string/backup_restore"
             android:icon="@drawable/ic_cfg_backup"
             android:icon="@drawable/ic_cfg_backup"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="theme_setting"
             android:key="theme_setting"
             android:summary="@string/theme_setting_s"
             android:summary="@string/theme_setting_s"
             android:title="@string/theme_setting"
             android:title="@string/theme_setting"
             android:icon="@drawable/ic_cfg_theme"
             android:icon="@drawable/ic_cfg_theme"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="setting"
             android:key="setting"
             android:summary="@string/other_setting_s"
             android:summary="@string/other_setting_s"
             android:title="@string/other_setting"
             android:title="@string/other_setting"
@@ -66,9 +66,9 @@
             app:allowDividerBelow="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
-    <io.legado.app.ui.widget.prefs.PreferenceCategory
+    <io.legado.app.lib.prefs.PreferenceCategory
         android:title="@string/other"
         android:title="@string/other"
         android:key="aboutCategory"
         android:key="aboutCategory"
         app:allowDividerAbove="true"
         app:allowDividerAbove="true"
@@ -76,34 +76,34 @@
         app:iconSpaceReserved="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
         app:layout="@layout/view_preference_category">
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="bookmark"
             android:key="bookmark"
             android:title="@string/bookmark"
             android:title="@string/bookmark"
             android:summary="@string/all_bookmark"
             android:summary="@string/all_bookmark"
             android:icon="@drawable/ic_bookmark"
             android:icon="@drawable/ic_bookmark"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="readRecord"
             android:key="readRecord"
             android:title="@string/read_record"
             android:title="@string/read_record"
             android:summary="@string/read_record_summary"
             android:summary="@string/read_record_summary"
             android:icon="@drawable/ic_history"
             android:icon="@drawable/ic_history"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="donate"
             android:key="donate"
             android:summary="@string/donate_summary"
             android:summary="@string/donate_summary"
             android:title="@string/donate"
             android:title="@string/donate"
             android:icon="@drawable/ic_cfg_donate"
             android:icon="@drawable/ic_cfg_donate"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-        <io.legado.app.ui.widget.prefs.Preference
+        <io.legado.app.lib.prefs.Preference
             android:key="about"
             android:key="about"
             android:summary="@string/about_summary"
             android:summary="@string/about_summary"
             android:title="@string/about"
             android:title="@string/about"
             android:icon="@drawable/ic_cfg_about"
             android:icon="@drawable/ic_cfg_about"
             app:iconSpaceReserved="false" />
             app:iconSpaceReserved="false" />
 
 
-    </io.legado.app.ui.widget.prefs.PreferenceCategory>
+    </io.legado.app.lib.prefs.PreferenceCategory>
 
 
 </androidx.preference.PreferenceScreen>
 </androidx.preference.PreferenceScreen>