优化
This commit is contained in:
@@ -36,6 +36,8 @@ class ChangeBookSourceAdapter(
|
|||||||
override fun areContentsTheSame(oldItem: SearchBook, newItem: SearchBook): Boolean {
|
override fun areContentsTheSame(oldItem: SearchBook, newItem: SearchBook): Boolean {
|
||||||
return oldItem.originName == newItem.originName
|
return oldItem.originName == newItem.originName
|
||||||
&& oldItem.getDisplayLastChapterTitle() == newItem.getDisplayLastChapterTitle()
|
&& 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 adapter by lazy { ChangeBookSourceAdapter(requireContext(), viewModel, this) }
|
||||||
private val editSourceResult =
|
private val editSourceResult =
|
||||||
registerForActivityResult(StartActivityContract(BookSourceEditActivity::class.java)) {
|
registerForActivityResult(StartActivityContract(BookSourceEditActivity::class.java)) {
|
||||||
viewModel.startSearch()
|
val origin = it.data?.getStringExtra("origin") ?: return@registerForActivityResult
|
||||||
|
viewModel.startSearch(origin)
|
||||||
}
|
}
|
||||||
private val searchFinishCallback: (isEmpty: Boolean) -> Unit = {
|
private val searchFinishCallback: (isEmpty: Boolean) -> Unit = {
|
||||||
if (it) {
|
if (it) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import io.legado.app.data.entities.BookSource
|
|||||||
import io.legado.app.data.entities.SearchBook
|
import io.legado.app.data.entities.SearchBook
|
||||||
import io.legado.app.exception.NoStackTraceException
|
import io.legado.app.exception.NoStackTraceException
|
||||||
import io.legado.app.help.book.BookHelp
|
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.AppConfig
|
||||||
import io.legado.app.help.config.SourceConfig
|
import io.legado.app.help.config.SourceConfig
|
||||||
import io.legado.app.help.coroutine.CompositeCoroutine
|
import io.legado.app.help.coroutine.CompositeCoroutine
|
||||||
@@ -50,8 +51,25 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
|
|||||||
private var searchBookList = arrayListOf<SearchBook>()
|
private var searchBookList = arrayListOf<SearchBook>()
|
||||||
private val searchBooks = Collections.synchronizedList(arrayListOf<SearchBook>())
|
private val searchBooks = Collections.synchronizedList(arrayListOf<SearchBook>())
|
||||||
private val tocMap = ConcurrentHashMap<String, List<BookChapter>>()
|
private val tocMap = ConcurrentHashMap<String, List<BookChapter>>()
|
||||||
|
private val contentProcessor by lazy {
|
||||||
|
ContentProcessor.get(oldBook!!)
|
||||||
|
}
|
||||||
private var searchCallback: SourceCallback? = null
|
private var searchCallback: SourceCallback? = null
|
||||||
private val emptyBookSource = BookSource()
|
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 bookMap = ConcurrentHashMap<String, Book>()
|
||||||
val searchDataFlow = callbackFlow {
|
val searchDataFlow = callbackFlow {
|
||||||
|
|
||||||
@@ -88,26 +106,12 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
|
|||||||
}
|
}
|
||||||
}.map {
|
}.map {
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
searchBooks.sortedWith { o1, o2 ->
|
val comparator = if (AppConfig.changeSourceLoadWordCount) {
|
||||||
val o1bs = SourceConfig.getBookScore(o1.origin, o1.name, o1.author)
|
wordCountComparator
|
||||||
val o2bs = SourceConfig.getBookScore(o2.origin, o2.name, o2.author)
|
} else {
|
||||||
when {
|
defaultComparator
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
searchBooks.sortedWith(comparator)
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
AppLog.put("换源排序出错\n${it.localizedMessage}", it)
|
AppLog.put("换源排序出错\n${it.localizedMessage}", it)
|
||||||
}.getOrDefault(searchBooks)
|
}.getOrDefault(searchBooks)
|
||||||
@@ -153,9 +157,18 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
|
|||||||
/**
|
/**
|
||||||
* 搜索书籍
|
* 搜索书籍
|
||||||
*/
|
*/
|
||||||
fun startSearch() {
|
fun startSearch(origin: String? = null) {
|
||||||
execute {
|
execute {
|
||||||
stopSearch()
|
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)
|
appDb.searchBookDao.clear(name, author)
|
||||||
searchBooks.clear()
|
searchBooks.clear()
|
||||||
searchCallback?.upAdapter()
|
searchCallback?.upAdapter()
|
||||||
@@ -182,7 +195,7 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
|
|||||||
|
|
||||||
private fun search() {
|
private fun search() {
|
||||||
val searchIndex = synchronized(this) {
|
val searchIndex = synchronized(this) {
|
||||||
if (searchIndex >= bookSourceList.lastIndex) {
|
if (searchIndex > bookSourceList.lastIndex) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
searchIndex++
|
searchIndex++
|
||||||
@@ -256,17 +269,18 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
|
|||||||
)
|
)
|
||||||
} ?: chapters.lastIndex
|
} ?: chapters.lastIndex
|
||||||
} else chapters.lastIndex
|
} else chapters.lastIndex
|
||||||
val bookChapter = chapters.getOrNull(chapterIndex)
|
val bookChapter = chapters[chapterIndex]
|
||||||
|
val title = bookChapter.title.trim()
|
||||||
val startTime = System.currentTimeMillis()
|
val startTime = System.currentTimeMillis()
|
||||||
val pair = try {
|
val pair = try {
|
||||||
if (bookChapter == null) throw NoStackTraceException("章节缺失,总章节数${chapters.size}")
|
|
||||||
val nextChapterUrl = chapters.getOrNull(chapterIndex + 1)?.url
|
val nextChapterUrl = chapters.getOrNull(chapterIndex + 1)?.url
|
||||||
WebBook.getContentAwait(source, book, bookChapter, nextChapterUrl, false).length.let {
|
var content = WebBook.getContentAwait(source, book, bookChapter, nextChapterUrl, false)
|
||||||
it to "第${chapterIndex + 1}章 字数:${it}"
|
content = contentProcessor.getContent(oldBook!!, bookChapter, content, false).toString()
|
||||||
}
|
val len = content.length
|
||||||
|
len to "[${chapterIndex + 1}] ${title}\n字数:${len}"
|
||||||
} catch (t: Throwable) {
|
} catch (t: Throwable) {
|
||||||
if (t is CancellationException) throw t
|
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 endTime = System.currentTimeMillis()
|
||||||
val searchBook = book.toSearchBook().apply {
|
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)
|
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 {
|
interface SourceCallback {
|
||||||
|
|
||||||
fun searchSuccess(searchBook: SearchBook)
|
fun searchSuccess(searchBook: SearchBook)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.legado.app.ui.book.source.edit
|
package io.legado.app.ui.book.source.edit
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
@@ -119,7 +120,7 @@ class BookSourceEditActivity :
|
|||||||
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.menu_save -> viewModel.save(getSource()) {
|
R.id.menu_save -> viewModel.save(getSource()) {
|
||||||
setResult(Activity.RESULT_OK)
|
setResult(Activity.RESULT_OK, Intent().putExtra("origin", it.bookSourceUrl))
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,7 @@
|
|||||||
tools:text="word count"
|
tools:text="word count"
|
||||||
android:textColor="@color/secondaryText"
|
android:textColor="@color/secondaryText"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toLeftOf="@+id/iv_checked"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/tv_last" />
|
app:layout_constraintTop_toBottomOf="@+id/tv_last" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
android:textColor="@color/secondaryText"
|
android:textColor="@color/secondaryText"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintLeft_toLeftOf="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" />
|
app:layout_constraintTop_toBottomOf="@+id/tv_current_chapter_word_count" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
|||||||
Reference in New Issue
Block a user