优化
This commit is contained in:
@@ -13,6 +13,9 @@ import io.legado.app.lib.theme.primaryColor
|
||||
import io.legado.app.utils.applyTint
|
||||
import io.legado.app.utils.setLayout
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.conflate
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
class ChangeCoverDialog() : BaseDialogFragment(R.layout.dialog_change_cover),
|
||||
@@ -45,6 +48,7 @@ class ChangeCoverDialog() : BaseDialogFragment(R.layout.dialog_change_cover),
|
||||
viewModel.initData(arguments)
|
||||
initMenu()
|
||||
initView()
|
||||
initData()
|
||||
}
|
||||
|
||||
private fun initMenu() {
|
||||
@@ -56,7 +60,17 @@ class ChangeCoverDialog() : BaseDialogFragment(R.layout.dialog_change_cover),
|
||||
private fun initView() {
|
||||
binding.recyclerView.layoutManager = GridLayoutManager(requireContext(), 3)
|
||||
binding.recyclerView.adapter = adapter
|
||||
viewModel.loadDbSearchBook()
|
||||
}
|
||||
|
||||
private fun initData() {
|
||||
launch {
|
||||
viewModel.dataFlow
|
||||
.conflate()
|
||||
.collect {
|
||||
adapter.setItems(it)
|
||||
delay(1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun observeLiveBus() {
|
||||
@@ -76,9 +90,7 @@ class ChangeCoverDialog() : BaseDialogFragment(R.layout.dialog_change_cover),
|
||||
}
|
||||
binding.toolBar.menu.applyTint(requireContext())
|
||||
}
|
||||
viewModel.searchBooksLiveData.observe(viewLifecycleOwner) {
|
||||
adapter.setItems(it)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onMenuItemClick(item: MenuItem?): Boolean {
|
||||
|
||||
@@ -13,23 +13,48 @@ import io.legado.app.data.entities.SearchBook
|
||||
import io.legado.app.help.AppConfig
|
||||
import io.legado.app.help.coroutine.CompositeCoroutine
|
||||
import io.legado.app.model.webBook.WebBook
|
||||
import kotlinx.coroutines.*
|
||||
import java.util.concurrent.CopyOnWriteArraySet
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.ExecutorCoroutineDispatcher
|
||||
import kotlinx.coroutines.asCoroutineDispatcher
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.channels.trySendBlocking
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.math.min
|
||||
|
||||
class ChangeCoverViewModel(application: Application) : BaseViewModel(application) {
|
||||
private val threadCount = AppConfig.threadCount
|
||||
private var searchPool: ExecutorCoroutineDispatcher? = null
|
||||
private var upAdapterJob: Job? = null
|
||||
var name: String = ""
|
||||
var author: String = ""
|
||||
private var tasks = CompositeCoroutine()
|
||||
private val tasks = CompositeCoroutine()
|
||||
private var searchSuccess: ((SearchBook) -> Unit)? = null
|
||||
private var bookSourceList = arrayListOf<BookSource>()
|
||||
val searchStateData = MutableLiveData<Boolean>()
|
||||
val searchBooksLiveData = MutableLiveData<List<SearchBook>>()
|
||||
private val searchBooks = CopyOnWriteArraySet<SearchBook>()
|
||||
private var postTime = 0L
|
||||
var name: String = ""
|
||||
var author: String = ""
|
||||
val dataFlow = callbackFlow<List<SearchBook>> {
|
||||
val searchBooks = arrayListOf<SearchBook>()
|
||||
|
||||
searchSuccess = {
|
||||
if (!searchBooks.contains(it)) {
|
||||
searchBooks.add(it)
|
||||
trySendBlocking(searchBooks)
|
||||
}
|
||||
}
|
||||
|
||||
appDb.searchBookDao.getEnableHasCover(name, author).let {
|
||||
searchBooks.addAll(it)
|
||||
trySendBlocking(searchBooks)
|
||||
}
|
||||
|
||||
if (searchBooks.size <= 1) {
|
||||
startSearch()
|
||||
}
|
||||
|
||||
awaitClose {
|
||||
searchBooks.clear()
|
||||
searchSuccess = null
|
||||
}
|
||||
}
|
||||
|
||||
@Volatile
|
||||
private var searchIndex = -1
|
||||
@@ -51,34 +76,6 @@ class ChangeCoverViewModel(application: Application) : BaseViewModel(application
|
||||
searchIndex = -1
|
||||
}
|
||||
|
||||
fun loadDbSearchBook() {
|
||||
execute {
|
||||
appDb.searchBookDao.getEnableHasCover(name, author).let {
|
||||
searchBooks.addAll(it)
|
||||
searchBooksLiveData.postValue(searchBooks.toList())
|
||||
if (it.size <= 1) {
|
||||
startSearch()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun upAdapter() {
|
||||
if (System.currentTimeMillis() >= postTime + 500) {
|
||||
upAdapterJob?.cancel()
|
||||
postTime = System.currentTimeMillis()
|
||||
val books = searchBooks.toList()
|
||||
searchBooksLiveData.postValue(books.sortedBy { it.originOrder })
|
||||
} else {
|
||||
upAdapterJob?.cancel()
|
||||
upAdapterJob = viewModelScope.launch {
|
||||
delay(500)
|
||||
upAdapter()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun startSearch() {
|
||||
execute {
|
||||
stopSearch()
|
||||
@@ -106,17 +103,13 @@ class ChangeCoverViewModel(application: Application) : BaseViewModel(application
|
||||
val task = WebBook
|
||||
.searchBook(viewModelScope, source, name, context = searchPool!!)
|
||||
.timeout(60000L)
|
||||
.onSuccess(searchPool) {
|
||||
if (it.isNotEmpty()) {
|
||||
val searchBook = it[0]
|
||||
.onSuccess(IO) {
|
||||
it.firstOrNull()?.let { searchBook ->
|
||||
if (searchBook.name == name && searchBook.author == author
|
||||
&& !searchBook.coverUrl.isNullOrEmpty()
|
||||
) {
|
||||
appDb.searchBookDao.insert(searchBook)
|
||||
if (!searchBooks.contains(searchBook)) {
|
||||
searchBooks.add(searchBook)
|
||||
upAdapter()
|
||||
}
|
||||
searchSuccess?.invoke(searchBook)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,7 +144,7 @@ class ChangeCoverViewModel(application: Application) : BaseViewModel(application
|
||||
}
|
||||
}
|
||||
|
||||
fun stopSearch() {
|
||||
private fun stopSearch() {
|
||||
tasks.clear()
|
||||
searchPool?.close()
|
||||
searchStateData.postValue(false)
|
||||
|
||||
Reference in New Issue
Block a user