优化
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user