kunfei 4 лет назад
Родитель
Сommit
95ec47c3fe

+ 16 - 4
app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverDialog.kt

@@ -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 {

+ 38 - 45
app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverViewModel.kt

@@ -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)