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