Sfoglia il codice sorgente

Merge remote-tracking branch 'origin/master'

kunfei 3 anni fa
parent
commit
1bd043fea9

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

@@ -137,6 +137,7 @@ object PreferKey {
     const val openBookInfoByClickTitle = "openBookInfoByClickTitle"
     const val defaultHomePage = "defaultHomePage"
     const val showBookshelfFastScroller = "showBookshelfFastScroller"
+    const val importKeepEnable = "importKeepEnable"
 
     const val cPrimary = "colorPrimary"
     const val cAccent = "colorAccent"

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

@@ -420,6 +420,11 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
 
     val importKeepName get() = appCtx.getPrefBoolean(PreferKey.importKeepName)
     val importKeepGroup get() = appCtx.getPrefBoolean(PreferKey.importKeepGroup)
+    var importKeepEnable: Boolean
+        get() = appCtx.getPrefBoolean(PreferKey.importKeepEnable, false)
+        set(value) {
+            appCtx.putPrefBoolean(PreferKey.importKeepEnable, value)
+        }
 
     var preDownloadNum
         get() = appCtx.getPrefInt(PreferKey.preDownloadNum, 10)

+ 7 - 0
app/src/main/java/io/legado/app/ui/association/ImportBookSourceDialog.kt

@@ -142,6 +142,8 @@ class ImportBookSourceDialog() : BaseDialogFragment(R.layout.dialog_recycler_vie
             ?.isChecked = AppConfig.importKeepName
         binding.toolBar.menu.findItem(R.id.menu_keep_group)
             ?.isChecked = AppConfig.importKeepGroup
+        binding.toolBar.menu.findItem(R.id.menu_keep_enable)
+            ?.isChecked = AppConfig.importKeepEnable
     }
 
     @SuppressLint("InflateParams", "NotifyDataSetChanged")
@@ -179,6 +181,11 @@ class ImportBookSourceDialog() : BaseDialogFragment(R.layout.dialog_recycler_vie
                 item.isChecked = !item.isChecked
                 putPrefBoolean(PreferKey.importKeepGroup, item.isChecked)
             }
+
+            R.id.menu_keep_enable -> {
+                item.isChecked = !item.isChecked
+                AppConfig.importKeepEnable = item.isChecked
+            }
         }
         return false
     }

+ 5 - 0
app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt

@@ -87,6 +87,7 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
             val group = groupName?.trim()
             val keepName = AppConfig.importKeepName
             val keepGroup = AppConfig.importKeepGroup
+            val keepEnable = AppConfig.importKeepEnable
             val selectSource = arrayListOf<BookSource>()
             selectStatus.forEachIndexed { index, b ->
                 if (b) {
@@ -98,6 +99,10 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
                         if (keepGroup) {
                             source.bookSourceGroup = it.bookSourceGroup
                         }
+                        if (keepEnable) {
+                            source.enabled = it.enabled
+                            source.enabledExplore = it.enabledExplore
+                        }
                         source.customOrder = it.customOrder
                     }
                     if (!group.isNullOrEmpty()) {

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

@@ -36,6 +36,8 @@ class ChangeBookSourceAdapter(
         override fun areContentsTheSame(oldItem: SearchBook, newItem: SearchBook): Boolean {
             return oldItem.originName == newItem.originName
                     && oldItem.getDisplayLastChapterTitle() == newItem.getDisplayLastChapterTitle()
+                    && oldItem.chapterWordCountText == newItem.chapterWordCountText
+                    && oldItem.respondTime == newItem.respondTime
         }
 
     }

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

@@ -72,7 +72,8 @@ class ChangeBookSourceDialog() : BaseDialogFragment(R.layout.dialog_book_change_
     private val adapter by lazy { ChangeBookSourceAdapter(requireContext(), viewModel, this) }
     private val editSourceResult =
         registerForActivityResult(StartActivityContract(BookSourceEditActivity::class.java)) {
-            viewModel.startSearch()
+            val origin = it.data?.getStringExtra("origin") ?: return@registerForActivityResult
+            viewModel.startSearch(origin)
         }
     private val searchFinishCallback: (isEmpty: Boolean) -> Unit = {
         if (it) {

+ 46 - 27
app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceViewModel.kt

@@ -16,6 +16,7 @@ import io.legado.app.data.entities.BookSource
 import io.legado.app.data.entities.SearchBook
 import io.legado.app.exception.NoStackTraceException
 import io.legado.app.help.book.BookHelp
+import io.legado.app.help.book.ContentProcessor
 import io.legado.app.help.config.AppConfig
 import io.legado.app.help.config.SourceConfig
 import io.legado.app.help.coroutine.CompositeCoroutine
@@ -50,8 +51,25 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
     private var searchBookList = arrayListOf<SearchBook>()
     private val searchBooks = Collections.synchronizedList(arrayListOf<SearchBook>())
     private val tocMap = ConcurrentHashMap<String, List<BookChapter>>()
+    private val contentProcessor by lazy {
+        ContentProcessor.get(oldBook!!)
+    }
     private var searchCallback: SourceCallback? = null
     private val emptyBookSource = BookSource()
+    private val chapterNumRegex = "^\\[(\\d+)]".toRegex()
+    private val comparatorBase by lazy {
+        compareByDescending<SearchBook> { getBookScore(it) }
+            .thenByDescending { SourceConfig.getSourceScore(it.origin) }
+    }
+    private val defaultComparator by lazy {
+        comparatorBase.thenBy { it.originOrder }
+    }
+    private val wordCountComparator by lazy {
+        comparatorBase.thenByDescending { it.chapterWordCount > 1000 }
+            .thenByDescending { getChapterNum(it.chapterWordCountText) }
+            .thenByDescending { it.chapterWordCount }
+            .thenBy { it.originOrder }
+    }
     val bookMap = ConcurrentHashMap<String, Book>()
     val searchDataFlow = callbackFlow {
 
@@ -88,26 +106,12 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
         }
     }.map {
         kotlin.runCatching {
-            searchBooks.sortedWith { o1, o2 ->
-                val o1bs = SourceConfig.getBookScore(o1.origin, o1.name, o1.author)
-                val o2bs = SourceConfig.getBookScore(o2.origin, o2.name, o2.author)
-                when {
-                    o1bs - o2bs > 0 -> -1
-                    o1bs - o2bs < 0 -> 1
-                    else -> {
-                        val o1ss = SourceConfig.getSourceScore(o1.origin)
-                        val o2ss = SourceConfig.getSourceScore(o2.origin)
-                        when {
-                            o1ss - o2ss > 0 -> -1
-                            o1ss - o2ss < 0 -> 1
-                            else -> {
-                                val n = o1.originOrder - o2.originOrder
-                                if (n == 0) -1 else n
-                            }
-                        }
-                    }
-                }
+            val comparator = if (AppConfig.changeSourceLoadWordCount) {
+                wordCountComparator
+            } else {
+                defaultComparator
             }
+            searchBooks.sortedWith(comparator)
         }.onFailure {
             AppLog.put("换源排序出错\n${it.localizedMessage}", it)
         }.getOrDefault(searchBooks)
@@ -153,9 +157,18 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
     /**
      * 搜索书籍
      */
-    fun startSearch() {
+    fun startSearch(origin: String? = null) {
         execute {
             stopSearch()
+            origin?.let {
+                bookSourceList.clear()
+                bookSourceList.add(appDb.bookSourceDao.getBookSource(origin)!!)
+                searchStateData.postValue(true)
+                searchBooks.removeIf { it.origin == origin }
+                initSearchPool()
+                search()
+                return@execute
+            }
             appDb.searchBookDao.clear(name, author)
             searchBooks.clear()
             searchCallback?.upAdapter()
@@ -182,7 +195,7 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
 
     private fun search() {
         val searchIndex = synchronized(this) {
-            if (searchIndex >= bookSourceList.lastIndex) {
+            if (searchIndex > bookSourceList.lastIndex) {
                 return
             }
             searchIndex++
@@ -256,17 +269,18 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
                 )
             } ?: chapters.lastIndex
         } else chapters.lastIndex
-        val bookChapter = chapters.getOrNull(chapterIndex)
+        val bookChapter = chapters[chapterIndex]
+        val title = bookChapter.title.trim()
         val startTime = System.currentTimeMillis()
         val pair = try {
-            if (bookChapter == null) throw NoStackTraceException("章节缺失,总章节数${chapters.size}")
             val nextChapterUrl = chapters.getOrNull(chapterIndex + 1)?.url
-            WebBook.getContentAwait(source, book, bookChapter, nextChapterUrl, false).length.let {
-                it to "第${chapterIndex + 1}章 字数:${it}"
-            }
+            var content = WebBook.getContentAwait(source, book, bookChapter, nextChapterUrl, false)
+            content = contentProcessor.getContent(oldBook!!, bookChapter, content, false).toString()
+            val len = content.length
+            len to "[${chapterIndex + 1}] ${title}\n字数:${len}"
         } catch (t: Throwable) {
             if (t is CancellationException) throw t
-            -1 to "第${chapterIndex + 1}章 获取字数失败:${t.localizedMessage}"
+            -1 to "[${chapterIndex + 1}] ${title}\n获取字数失败:${t.localizedMessage}"
         }
         val endTime = System.currentTimeMillis()
         val searchBook = book.toSearchBook().apply {
@@ -526,6 +540,11 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
         return SourceConfig.getBookScore(searchBook.origin, searchBook.name, searchBook.author)
     }
 
+    private fun getChapterNum(wordCountText: String?): Int {
+        wordCountText ?: return -1
+        return chapterNumRegex.find(wordCountText)?.groupValues?.get(1)?.toIntOrNull() ?: -1
+    }
+
     interface SourceCallback {
 
         fun searchSuccess(searchBook: SearchBook)

+ 8 - 7
app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt

@@ -1,6 +1,7 @@
 package io.legado.app.ui.book.source.edit
 
 import android.app.Activity
+import android.content.Intent
 import android.os.Bundle
 import android.view.Menu
 import android.view.MenuItem
@@ -119,7 +120,7 @@ class BookSourceEditActivity :
     override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
         when (item.itemId) {
             R.id.menu_save -> viewModel.save(getSource()) {
-                setResult(Activity.RESULT_OK)
+                setResult(Activity.RESULT_OK, Intent().putExtra("origin", it.bookSourceUrl))
                 finish()
             }
 
@@ -410,8 +411,8 @@ class BookSourceEditActivity :
                 "intro" -> searchRule.intro =
                     viewModel.ruleComplete(it.value, searchRule.bookList)
 
-                "updateTime" -> searchRule.updateTime =
-                    viewModel.ruleComplete(it.value, searchRule.bookList)
+//                "updateTime" -> searchRule.updateTime =
+//                    viewModel.ruleComplete(it.value, searchRule.bookList)
 
                 "wordCount" -> searchRule.wordCount =
                     viewModel.ruleComplete(it.value, searchRule.bookList)
@@ -442,8 +443,8 @@ class BookSourceEditActivity :
                 "intro" -> exploreRule.intro =
                     viewModel.ruleComplete(it.value, exploreRule.bookList)
 
-                "updateTime" -> exploreRule.updateTime =
-                    viewModel.ruleComplete(it.value, exploreRule.bookList)
+//                "updateTime" -> exploreRule.updateTime =
+//                    viewModel.ruleComplete(it.value, exploreRule.bookList)
 
                 "wordCount" -> exploreRule.wordCount =
                     viewModel.ruleComplete(it.value, exploreRule.bookList)
@@ -471,8 +472,8 @@ class BookSourceEditActivity :
                 "intro" -> bookInfoRule.intro =
                     viewModel.ruleComplete(it.value, bookInfoRule.init)
 
-                "updateTime" -> bookInfoRule.updateTime =
-                    viewModel.ruleComplete(it.value, bookInfoRule.init)
+//                "updateTime" -> bookInfoRule.updateTime =
+//                    viewModel.ruleComplete(it.value, bookInfoRule.init)
 
                 "wordCount" -> bookInfoRule.wordCount =
                     viewModel.ruleComplete(it.value, bookInfoRule.init)

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

@@ -41,8 +41,8 @@ class BookSourceEditViewModel(application: Application) : BaseViewModel(applicat
             if (source.bookSourceUrl.isBlank() || source.bookSourceName.isBlank()) {
                 throw NoStackTraceException(context.getString(R.string.non_null_name_url))
             }
-            if (!source.equal(bookSource ?: BookSource())) {
-                source.lastUpdateTime = System.currentTimeMillis()
+            if (source.equal(bookSource ?: BookSource())) {
+                return@execute source
             }
             bookSource?.let {
                 appDb.bookSourceDao.delete(it)
@@ -91,6 +91,7 @@ class BookSourceEditViewModel(application: Application) : BaseViewModel(applicat
                 val text1 = okHttpClient.newCallStrResponse { url(text) }.body
                 importSource(text1!!)
             }
+
             text.isJsonArray() -> {
                 if (text.contains("ruleSearchUrl") || text.contains("ruleFindUrl")) {
                     val items: List<Map<String, Any>> = jsonPath.parse(text).read("$")
@@ -100,6 +101,7 @@ class BookSourceEditViewModel(application: Application) : BaseViewModel(applicat
                     GSON.fromJsonArray<BookSource>(text).getOrThrow()[0]
                 }
             }
+
             text.isJsonObject() -> {
                 if (text.contains("ruleSearchUrl") || text.contains("ruleFindUrl")) {
                     val jsonItem = jsonPath.parse(text)
@@ -108,6 +110,7 @@ class BookSourceEditViewModel(application: Application) : BaseViewModel(applicat
                     GSON.fromJsonObject<BookSource>(text).getOrThrow()
                 }
             }
+
             else -> throw NoStackTraceException("格式不对")
         }
     }

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

@@ -82,7 +82,7 @@
         tools:text="word count"
         android:textColor="@color/secondaryText"
         app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintRight_toLeftOf="@+id/iv_checked"
         app:layout_constraintTop_toBottomOf="@+id/tv_last" />
 
     <TextView
@@ -96,7 +96,7 @@
         android:textColor="@color/secondaryText"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintRight_toLeftOf="@+id/iv_checked"
         app:layout_constraintTop_toBottomOf="@+id/tv_current_chapter_word_count" />
 
     <androidx.appcompat.widget.AppCompatImageView

+ 7 - 1
app/src/main/res/menu/import_source.xml

@@ -31,4 +31,10 @@
         android:checkable="true"
         app:showAsAction="never" />
 
-</menu>
+    <item
+        android:id="@+id/menu_keep_enable"
+        android:title="@string/keep_enable"
+        android:checkable="true"
+        app:showAsAction="never" />
+
+</menu>

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

@@ -1131,4 +1131,5 @@
     <string name="default_home_page">默认主页</string>
     <string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
     <string name="export_all_use_book_source">导出所有书的书源</string>
+    <string name="keep_enable">保留启用状态</string>
 </resources>

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

@@ -1134,4 +1134,5 @@
     <string name="default_home_page">默认主页</string>
     <string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
     <string name="export_all_use_book_source">导出所有书的书源</string>
+    <string name="keep_enable">保留启用状态</string>
 </resources>

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

@@ -1134,4 +1134,5 @@
     <string name="default_home_page">默认主页</string>
     <string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
     <string name="export_all_use_book_source">导出所有书的书源</string>
+    <string name="keep_enable">保留启用状态</string>
 </resources>

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

@@ -1129,4 +1129,5 @@ Còn </string>
     <string name="export_wait">等待导出</string>
     <string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
     <string name="export_all_use_book_source">导出所有书的书源</string>
+    <string name="keep_enable">保留启用状态</string>
 </resources>

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

@@ -1130,4 +1130,5 @@
     <string name="export_wait">等待导出</string>
     <string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
     <string name="export_all_use_book_source">导出所有书的书源</string>
+    <string name="keep_enable">保留启用状态</string>
 </resources>

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

@@ -1132,4 +1132,5 @@
     <string name="export_wait">等待导出</string>
     <string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
     <string name="export_all_use_book_source">导出所有书的书源</string>
+    <string name="keep_enable">保留启用状态</string>
 </resources>

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

@@ -1132,4 +1132,5 @@
     <string name="export_wait">等待导出</string>
     <string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
     <string name="export_all_use_book_source">导出所有书的书源</string>
+    <string name="keep_enable">保留启用状态</string>
 </resources>

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

@@ -1134,4 +1134,5 @@
     <string name="default_home_page">默认主页</string>
     <string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
     <string name="export_all_use_book_source">导出所有书的书源</string>
+    <string name="keep_enable">保留启用状态</string>
 </resources>