Horis před 3 roky
rodič
revize
d82e455f17
24 změnil soubory, kde provedl 134 přidání a 49 odebrání
  1. 2 0
      app/src/main/java/io/legado/app/constant/PreferKey.kt
  2. 12 0
      app/src/main/java/io/legado/app/help/config/AppConfig.kt
  3. 5 3
      app/src/main/java/io/legado/app/model/CacheBook.kt
  4. 28 26
      app/src/main/java/io/legado/app/model/ReadBook.kt
  5. 3 2
      app/src/main/java/io/legado/app/model/webBook/WebBook.kt
  6. 4 8
      app/src/main/java/io/legado/app/service/HttpReadAloudService.kt
  7. 1 2
      app/src/main/java/io/legado/app/service/TTSReadAloudService.kt
  8. 6 3
      app/src/main/java/io/legado/app/ui/book/manage/BookAdapter.kt
  9. 7 0
      app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageActivity.kt
  10. 4 1
      app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageViewModel.kt
  11. 30 1
      app/src/main/java/io/legado/app/ui/book/manage/SourcePickerDialog.kt
  12. 2 0
      app/src/main/java/io/legado/app/ui/widget/keyboard/KeyboardAssistsConfig.kt
  13. 0 1
      app/src/main/res/layout/dialog_source_picker.xml
  14. 0 1
      app/src/main/res/layout/item_1line_text_and_del.xml
  15. 6 1
      app/src/main/res/menu/bookshelf_manage.xml
  16. 8 0
      app/src/main/res/menu/source_picker.xml
  17. 2 0
      app/src/main/res/values-es-rES/strings.xml
  18. 2 0
      app/src/main/res/values-ja-rJP/strings.xml
  19. 2 0
      app/src/main/res/values-pt-rBR/strings.xml
  20. 2 0
      app/src/main/res/values-vi/strings.xml
  21. 2 0
      app/src/main/res/values-zh-rHK/strings.xml
  22. 2 0
      app/src/main/res/values-zh-rTW/strings.xml
  23. 2 0
      app/src/main/res/values-zh/strings.xml
  24. 2 0
      app/src/main/res/values/strings.xml

+ 2 - 0
app/src/main/java/io/legado/app/constant/PreferKey.kt

@@ -133,6 +133,8 @@ object PreferKey {
     const val onlyLatestBackup = "onlyLatestBackup"
     const val brightnessVwPos = "brightnessVwPos"
     const val shrinkDatabase = "shrinkDatabase"
+    const val batchChangeSourceDelay = "batchChangeSourceDelay"
+    const val openBookInfoByClickTitle = "openBookInfoByClickTitle"
 
     const val cPrimary = "colorPrimary"
     const val cAccent = "colorAccent"

+ 12 - 0
app/src/main/java/io/legado/app/help/config/AppConfig.kt

@@ -380,12 +380,24 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
             appCtx.putPrefBoolean(PreferKey.changeSourceLoadWordCount, value)
         }
 
+    var openBookInfoByClickTitle: Boolean
+        get() = appCtx.getPrefBoolean(PreferKey.openBookInfoByClickTitle, true)
+        set(value) {
+            appCtx.putPrefBoolean(PreferKey.openBookInfoByClickTitle, value)
+        }
+
     var contentSelectSpeakMod: Int
         get() = appCtx.getPrefInt(PreferKey.contentSelectSpeakMod)
         set(value) {
             appCtx.putPrefInt(PreferKey.contentSelectSpeakMod, value)
         }
 
+    var batchChangeSourceDelay: Int
+        get() = appCtx.getPrefInt(PreferKey.batchChangeSourceDelay)
+        set(value) {
+            appCtx.putPrefInt(PreferKey.batchChangeSourceDelay, value)
+        }
+
     val importKeepName get() = appCtx.getPrefBoolean(PreferKey.importKeepName)
     val importKeepGroup get() = appCtx.getPrefBoolean(PreferKey.importKeepGroup)
 

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

@@ -18,6 +18,7 @@ import io.legado.app.utils.postEvent
 
 import io.legado.app.utils.startService
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers.IO
 import kotlinx.coroutines.delay
 
 import java.util.concurrent.ConcurrentHashMap
@@ -243,7 +244,7 @@ object CacheBook {
             waitDownloadSet.remove(chapterIndex)
             onDownloadSet.add(chapterIndex)
             if (BookHelp.hasContent(book, chapter)) {
-                Coroutine.async {
+                Coroutine.async(executeContext = context) {
                     BookHelp.getContent(book, chapter)?.let {
                         BookHelp.saveImages(bookSource, book, chapter, it)
                     }
@@ -266,7 +267,8 @@ object CacheBook {
                 bookSource,
                 book,
                 chapter,
-                context = context
+                context = context,
+                executeContext = context
             ).onSuccess { content ->
                 onSuccess(chapter)
                 downloadFinish(chapter, content)
@@ -295,7 +297,7 @@ object CacheBook {
             postEvent(EventBus.UP_DOWNLOAD, book.bookUrl)
             onDownloadSet.add(chapter.index)
             waitDownloadSet.remove(chapter.index)
-            WebBook.getContent(scope, bookSource, book, chapter)
+            WebBook.getContent(scope, bookSource, book, chapter, executeContext = IO)
                 .onSuccess { content ->
                     onSuccess(chapter)
                     downloadFinish(chapter, content, resetPageOffset)

+ 28 - 26
app/src/main/java/io/legado/app/model/ReadBook.kt

@@ -441,38 +441,40 @@ object ReadBook : CoroutineScope by MainScope() {
         pageChanged: Boolean,
         success: (() -> Unit)? = null
     ) {
+        if (chapter.index !in durChapterIndex - 1..durChapterIndex + 1) {
+            return
+        }
         Coroutine.async {
             removeLoading(chapter.index)
-            if (chapter.index in durChapterIndex - 1..durChapterIndex + 1) {
-                val contentProcessor = ContentProcessor.get(book.name, book.origin)
-                val displayTitle = chapter.getDisplayTitle(
-                    contentProcessor.getTitleReplaceRules(),
-                    book.getUseReplaceRule()
-                )
-                val contents = contentProcessor
-                    .getContent(book, chapter, content, includeTitle = false)
-                val textChapter = ChapterProvider
-                    .getTextChapter(book, chapter, displayTitle, contents, chapterSize)
-                when (val offset = chapter.index - durChapterIndex) {
-                    0 -> {
-                        curTextChapter = textChapter
-                        if (upContent) callBack?.upContent(offset, resetPageOffset)
-                        callBack?.upMenuView()
-                        if (pageChanged) curPageChanged()
-                        callBack?.contentLoadFinish()
-                    }
+            val contentProcessor = ContentProcessor.get(book.name, book.origin)
+            val displayTitle = chapter.getDisplayTitle(
+                contentProcessor.getTitleReplaceRules(),
+                book.getUseReplaceRule()
+            )
+            val contents = contentProcessor
+                .getContent(book, chapter, content, includeTitle = false)
+            val textChapter = ChapterProvider
+                .getTextChapter(book, chapter, displayTitle, contents, chapterSize)
+            when (val offset = chapter.index - durChapterIndex) {
+                0 -> {
+                    curTextChapter = textChapter
+                    if (upContent) callBack?.upContent(offset, resetPageOffset)
+                    callBack?.upMenuView()
+                    if (pageChanged) curPageChanged()
+                    callBack?.contentLoadFinish()
+                }
 
-                    -1 -> {
-                        prevTextChapter = textChapter
-                        if (upContent) callBack?.upContent(offset, resetPageOffset)
-                    }
+                -1 -> {
+                    prevTextChapter = textChapter
+                    if (upContent) callBack?.upContent(offset, resetPageOffset)
+                }
 
-                    1 -> {
-                        nextTextChapter = textChapter
-                        if (upContent) callBack?.upContent(offset, resetPageOffset)
-                    }
+                1 -> {
+                    nextTextChapter = textChapter
+                    if (upContent) callBack?.upContent(offset, resetPageOffset)
                 }
             }
+            Unit
         }.onError {
             AppLog.put("ChapterProvider ERROR", it)
             appCtx.toastOnUi("ChapterProvider ERROR:\n${it.stackTraceStr}")

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

@@ -265,9 +265,10 @@ object WebBook {
         bookChapter: BookChapter,
         nextChapterUrl: String? = null,
         needSave: Boolean = true,
-        context: CoroutineContext = Dispatchers.IO
+        context: CoroutineContext = Dispatchers.IO,
+        executeContext: CoroutineContext = Dispatchers.Main,
     ): Coroutine<String> {
-        return Coroutine.async(scope, context) {
+        return Coroutine.async(scope, context, executeContext = executeContext) {
             getContentAwait(bookSource, book, bookChapter, nextChapterUrl, needSave)
         }
     }

+ 4 - 8
app/src/main/java/io/legado/app/service/HttpReadAloudService.kt

@@ -152,8 +152,7 @@ class HttpReadAloudService : BaseReadAloudService(),
                 }
             }
         }.onError {
-            toastOnUi("朗读出错:${it.localizedMessage}")
-            AppLog.put("朗读下载出错\n${it.localizedMessage}", it)
+            AppLog.put("朗读下载出错\n${it.localizedMessage}", it, true)
         }
     }
 
@@ -196,8 +195,7 @@ class HttpReadAloudService : BaseReadAloudService(),
                     is CancellationException -> throw e
                     is ConcurrentException -> delay(e.waitTime.toLong())
                     is ScriptException, is WrappedException -> {
-                        AppLog.put("js错误\n${e.localizedMessage}", e)
-                        toastOnUi("js错误\n${e.localizedMessage}")
+                        AppLog.put("js错误\n${e.localizedMessage}", e, true)
                         e.printOnDebug()
                         throw e
                     }
@@ -206,8 +204,7 @@ class HttpReadAloudService : BaseReadAloudService(),
                         downloadErrorNo++
                         if (downloadErrorNo > 5) {
                             val msg = "tts超时或连接错误超过5次\n${e.localizedMessage}"
-                            AppLog.put(msg, e)
-                            toastOnUi(msg)
+                            AppLog.put(msg, e, true)
                             throw e
                         }
                     }
@@ -219,8 +216,7 @@ class HttpReadAloudService : BaseReadAloudService(),
                         e.printOnDebug()
                         if (downloadErrorNo > 5) {
                             val msg1 = "TTS服务器连续5次错误,已暂停阅读。"
-                            AppLog.put(msg1)
-                            toastOnUi(msg1)
+                            AppLog.put(msg1, e, true)
                             throw e
                         } else {
                             AppLog.put("TTS下载音频出错,使用无声音频代替。\n朗读文本:$speakText")

+ 1 - 2
app/src/main/java/io/legado/app/service/TTSReadAloudService.kt

@@ -117,8 +117,7 @@ class TTSReadAloudService : BaseReadAloudService(), TextToSpeech.OnInitListener
                 }
             }
         }.onError {
-            AppLog.put("tts朗读出错", it)
-            toastOnUi(it.localizedMessage)
+            AppLog.put("tts朗读出错\n${it.localizedMessage}", it, true)
         }
     }
 

+ 6 - 3
app/src/main/java/io/legado/app/ui/book/manage/BookAdapter.kt

@@ -13,6 +13,7 @@ import io.legado.app.data.entities.Book
 import io.legado.app.data.entities.BookGroup
 import io.legado.app.databinding.ItemArrangeBookBinding
 import io.legado.app.help.book.isLocal
+import io.legado.app.help.config.AppConfig
 import io.legado.app.lib.theme.backgroundColor
 import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
 import io.legado.app.ui.widget.recycler.ItemTouchCallback
@@ -89,9 +90,11 @@ class BookAdapter(context: Context, val callBack: CallBack) :
                     callBack.upSelectCount()
                 }
             }
-            tvName.setOnClickListener {
-                getItem(holder.layoutPosition)?.let {
-                    callBack.openBook(it)
+            if (AppConfig.openBookInfoByClickTitle) {
+                tvName.setOnClickListener {
+                    getItem(holder.layoutPosition)?.let {
+                        callBack.openBook(it)
+                    }
                 }
             }
             tvDelete.setOnClickListener {

+ 7 - 0
app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageActivity.kt

@@ -120,6 +120,8 @@ class BookshelfManageActivity :
 
     override fun onPrepareOptionsMenu(menu: Menu): Boolean {
         this.menu = menu
+        menu.findItem(R.id.menu_open_book_info_by_click_title)?.isChecked =
+            AppConfig.openBookInfoByClickTitle
         upMenu()
         return super.onPrepareOptionsMenu(menu)
     }
@@ -248,6 +250,11 @@ class BookshelfManageActivity :
     override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
         when (item.itemId) {
             R.id.menu_group_manage -> showDialogFragment<GroupManageDialog>()
+            R.id.menu_open_book_info_by_click_title -> {
+                AppConfig.openBookInfoByClickTitle = !item.isChecked
+                adapter.notifyItemRangeChanged(0, adapter.itemCount)
+            }
+
             else -> if (item.groupId == R.id.menu_group) {
                 viewModel.groupName = item.title.toString()
                 upTitle()

+ 4 - 1
app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageViewModel.kt

@@ -10,10 +10,11 @@ import io.legado.app.data.entities.Book
 import io.legado.app.data.entities.BookSource
 import io.legado.app.help.book.isLocal
 import io.legado.app.help.book.removeType
+import io.legado.app.help.config.AppConfig
 import io.legado.app.help.coroutine.Coroutine
 import io.legado.app.model.localBook.LocalBook
 import io.legado.app.model.webBook.WebBook
-import io.legado.app.utils.toastOnUi
+import kotlinx.coroutines.delay
 
 
 class BookshelfManageViewModel(application: Application) : BaseViewModel(application) {
@@ -52,6 +53,7 @@ class BookshelfManageViewModel(application: Application) : BaseViewModel(applica
     fun changeSource(books: List<Book>, source: BookSource) {
         batchChangeSourceCoroutine?.cancel()
         batchChangeSourceCoroutine = execute {
+            val changeSourceDelay = AppConfig.batchChangeSourceDelay * 1000L
             books.forEachIndexed { index, book ->
                 batchChangeSourceProcessLiveData.postValue("${index + 1} / ${books.size}")
                 if (book.isLocal) return@forEachIndexed
@@ -69,6 +71,7 @@ class BookshelfManageViewModel(application: Application) : BaseViewModel(applica
                         appDb.bookDao.insert(newBook)
                         appDb.bookChapterDao.insert(*toc.toTypedArray())
                     }
+                delay(changeSourceDelay)
             }
         }.onStart {
             batchChangeSourceState.postValue(true)

+ 30 - 1
app/src/main/java/io/legado/app/ui/book/manage/SourcePickerDialog.kt

@@ -2,9 +2,11 @@ package io.legado.app.ui.book.manage
 
 import android.content.Context
 import android.os.Bundle
+import android.view.MenuItem
 import android.view.View
 import android.view.ViewGroup
 import androidx.appcompat.widget.SearchView
+import androidx.appcompat.widget.Toolbar
 import androidx.core.view.setPadding
 import androidx.lifecycle.lifecycleScope
 import androidx.recyclerview.widget.LinearLayoutManager
@@ -17,8 +19,10 @@ import io.legado.app.data.entities.BookSource
 import io.legado.app.data.entities.BookSourcePart
 import io.legado.app.databinding.DialogSourcePickerBinding
 import io.legado.app.databinding.Item1lineTextBinding
+import io.legado.app.help.config.AppConfig
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.lib.theme.primaryTextColor
+import io.legado.app.ui.widget.number.NumberPickerDialog
 import io.legado.app.utils.applyTint
 import io.legado.app.utils.dpToPx
 import io.legado.app.utils.setLayout
@@ -27,12 +31,16 @@ import kotlinx.coroutines.Job
 import kotlinx.coroutines.launch
 import splitties.views.onClick
 
-class SourcePickerDialog : BaseDialogFragment(R.layout.dialog_source_picker) {
+class SourcePickerDialog : BaseDialogFragment(R.layout.dialog_source_picker),
+    Toolbar.OnMenuItemClickListener {
 
     private val binding by viewBinding(DialogSourcePickerBinding::bind)
     private val searchView: SearchView by lazy {
         binding.toolBar.findViewById(R.id.search_view)
     }
+    private val toolBar: Toolbar by lazy {
+        binding.toolBar.toolbar
+    }
     private val adapter by lazy {
         SourceAdapter(requireContext())
     }
@@ -46,6 +54,7 @@ class SourcePickerDialog : BaseDialogFragment(R.layout.dialog_source_picker) {
     override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
         initView()
         initData()
+        initMenu()
     }
 
     private fun initView() {
@@ -82,6 +91,26 @@ class SourcePickerDialog : BaseDialogFragment(R.layout.dialog_source_picker) {
         }
     }
 
+    private fun initMenu() {
+        toolBar.setOnMenuItemClickListener(this)
+        toolBar.inflateMenu(R.menu.source_picker)
+        toolBar.menu.applyTint(requireContext())
+    }
+
+    override fun onMenuItemClick(item: MenuItem?): Boolean {
+        when (item?.itemId) {
+            R.id.menu_change_source_delay -> NumberPickerDialog(requireContext())
+                .setTitle(getString(R.string.change_source_delay))
+                .setMaxValue(9999)
+                .setMinValue(0)
+                .setValue(AppConfig.batchChangeSourceDelay)
+                .show {
+                    AppConfig.batchChangeSourceDelay = it
+                }
+        }
+        return true
+    }
+
     inner class SourceAdapter(context: Context) :
         RecyclerAdapter<BookSourcePart, Item1lineTextBinding>(context) {
 

+ 2 - 0
app/src/main/java/io/legado/app/ui/widget/keyboard/KeyboardAssistsConfig.kt

@@ -21,6 +21,7 @@ import io.legado.app.databinding.DialogMultipleEditTextBinding
 import io.legado.app.databinding.DialogRecyclerViewBinding
 import io.legado.app.databinding.Item1lineTextAndDelBinding
 import io.legado.app.lib.dialogs.alert
+import io.legado.app.lib.theme.backgroundColor
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.ui.widget.recycler.ItemTouchCallback
 import io.legado.app.ui.widget.recycler.VerticalDivider
@@ -132,6 +133,7 @@ class KeyboardAssistsConfig : BaseDialogFragment(R.layout.dialog_recycler_view),
             item: KeyboardAssist,
             payloads: MutableList<Any>
         ) {
+            binding.root.setBackgroundColor(context.backgroundColor)
             binding.textView.text = item.key
         }
 

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

@@ -11,7 +11,6 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:theme="?attr/actionBarStyle"
-        android:paddingRight="16dp"
         app:attachToActivity="false"
         app:contentLayout="@layout/view_search"
         app:fitStatusBar="false"

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

@@ -14,7 +14,6 @@
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_weight="1"
-        android:background="?attr/selectableItemBackground"
         android:singleLine="true"
         android:textColor="@color/primaryText" />
 

+ 6 - 1
app/src/main/res/menu/bookshelf_manage.xml

@@ -20,4 +20,9 @@
 
     </item>
 
-</menu>
+    <item
+        android:id="@+id/menu_open_book_info_by_click_title"
+        android:checkable="true"
+        android:title="@string/open_book_info_by_click_title" />
+
+</menu>

+ 8 - 0
app/src/main/res/menu/source_picker.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:id="@+id/menu_change_source_delay"
+        android:title="@string/change_source_delay" />
+
+</menu>

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

@@ -1125,4 +1125,6 @@
     <string name="export_book">导出书籍</string>
     <string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string>
     <string name="export_md">导出(MD)</string>
+    <string name="change_source_delay">换源间隔</string>
+    <string name="open_book_info_by_click_title">点击书名打开详情</string>
 </resources>

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

@@ -1128,4 +1128,6 @@
     <string name="export_book">导出书籍</string>
     <string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string>
     <string name="export_md">导出(MD)</string>
+    <string name="change_source_delay">换源间隔</string>
+    <string name="open_book_info_by_click_title">点击书名打开详情</string>
 </resources>

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

@@ -1128,4 +1128,6 @@
     <string name="export_book">导出书籍</string>
     <string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string>
     <string name="export_md">导出(MD)</string>
+    <string name="change_source_delay">换源间隔</string>
+    <string name="open_book_info_by_click_title">点击书名打开详情</string>
 </resources>

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

@@ -1124,4 +1124,6 @@ Còn </string>
     <string name="export_book">导出书籍</string>
     <string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string>
     <string name="export_md">导出(MD)</string>
+    <string name="change_source_delay">换源间隔</string>
+    <string name="open_book_info_by_click_title">点击书名打开详情</string>
 </resources>

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

@@ -1125,4 +1125,6 @@
     <string name="export_book">导出书籍</string>
     <string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string>
     <string name="export_md">导出(MD)</string>
+    <string name="change_source_delay">换源间隔</string>
+    <string name="open_book_info_by_click_title">点击书名打开详情</string>
 </resources>

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

@@ -1127,4 +1127,6 @@
     <string name="export_book">导出书籍</string>
     <string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string>
     <string name="export_md">导出(MD)</string>
+    <string name="change_source_delay">换源间隔</string>
+    <string name="open_book_info_by_click_title">点击书名打开详情</string>
 </resources>

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

@@ -1127,4 +1127,6 @@
     <string name="export_book">导出书籍</string>
     <string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string>
     <string name="export_md">导出(MD)</string>
+    <string name="change_source_delay">换源间隔</string>
+    <string name="open_book_info_by_click_title">点击书名打开详情</string>
 </resources>

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

@@ -1128,4 +1128,6 @@
     <string name="export_book">导出书籍</string>
     <string name="export_book_notification_content">正在导出(%1$s),还有%2$d本待导出</string>
     <string name="export_md">导出(MD)</string>
+    <string name="change_source_delay">换源间隔</string>
+    <string name="open_book_info_by_click_title">点击书名打开详情</string>
 </resources>