pull/1649/head
kunfei 3 years ago
parent 0373af42c8
commit 17aaae27a5
  1. 22
      app/src/main/java/io/legado/app/model/webBook/SearchModel.kt
  2. 2
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt
  3. 19
      app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt
  4. 83
      app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt

@ -17,7 +17,7 @@ import splitties.init.appCtx
import java.util.concurrent.Executors
import kotlin.math.min
class SearchModel(private val scope: CoroutineScope, private val callBack: CallBack) {
class SearchModel(private val scope: CoroutineScope) {
val threadCount = AppConfig.threadCount
private var searchPool: ExecutorCoroutineDispatcher? = null
private var mSearchId = 0L
@ -26,10 +26,19 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
private var tasks = CompositeCoroutine()
private var bookSourceList = arrayListOf<BookSource>()
private var searchBooks = arrayListOf<SearchBook>()
private var callBack: CallBack? = null
@Volatile
private var searchIndex = -1
fun registerCallback(callBack: CallBack) {
this.callBack = callBack
}
fun unRegisterCallback() {
this.callBack = null
}
private fun initSearchPool() {
searchPool?.close()
searchPool = Executors
@ -37,10 +46,10 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
}
fun search(searchId: Long, key: String) {
callBack.onSearchStart()
callBack?.onSearchStart()
if (searchId != mSearchId) {
if (key.isEmpty()) {
callBack.onSearchCancel()
callBack?.onSearchCancel()
return
} else {
this.searchKey = key
@ -53,6 +62,7 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
searchPage = 1
val searchGroup = appCtx.getPrefString("searchGroup") ?: ""
bookSourceList.clear()
callBack?.onSearchSuccess(searchBooks)
if (searchGroup.isBlank()) {
bookSourceList.addAll(appDb.bookSourceDao.allEnabled)
} else {
@ -103,7 +113,7 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
appDb.searchBookDao.insert(*items.toTypedArray())
val precision = appCtx.getPrefBoolean(PreferKey.precisionSearch)
mergeItems(scope, items, precision)
callBack.onSearchSuccess(searchBooks)
callBack?.onSearchSuccess(searchBooks)
}
}
@ -117,7 +127,7 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
if (searchIndex >= bookSourceList.lastIndex
+ min(bookSourceList.size, threadCount)
) {
callBack.onSearchFinish()
callBack?.onSearchFinish()
}
}
@ -189,7 +199,7 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
fun cancelSearch() {
close()
callBack.onSearchCancel()
callBack?.onSearchCancel()
}
fun close() {

@ -148,6 +148,8 @@ class ChangeSourceDialog() : BaseDialogFragment(R.layout.dialog_change_source),
adapter.setItems(it)
delay(1000)
}
}
launch {
appDb.bookSourceDao.flowGroupEnabled().collect {
groups.clear()
it.map { group ->

@ -19,7 +19,6 @@ import io.legado.app.constant.AppPattern
import io.legado.app.constant.PreferKey
import io.legado.app.data.appDb
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.SearchBook
import io.legado.app.data.entities.SearchKeyword
import io.legado.app.databinding.ActivityBookSearchBinding
import io.legado.app.lib.theme.*
@ -30,6 +29,7 @@ import io.legado.app.utils.*
import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -195,6 +195,13 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
}
private fun initData() {
launch {
viewModel.searchDataFlow
.collect {
adapter.setItems(it)
delay(1000)
}
}
launch {
appDb.bookSourceDao.flowGroupEnabled().collect {
groups.clear()
@ -204,9 +211,6 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
upGroupMenu()
}
}
viewModel.searchBookLiveData.observe(this) {
upSearchItems(it)
}
viewModel.isSearchLiveData.observe(this) {
if (it) {
startSearch()
@ -310,13 +314,6 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
}
}
/**
* 更新搜索结果
*/
private fun upSearchItems(items: List<SearchBook>) {
adapter.setItems(items)
}
/**
* 开始搜索
*/

@ -8,20 +8,47 @@ import io.legado.app.data.appDb
import io.legado.app.data.entities.SearchBook
import io.legado.app.data.entities.SearchKeyword
import io.legado.app.model.webBook.SearchModel
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.conflate
class SearchViewModel(application: Application) : BaseViewModel(application), SearchModel.CallBack {
private val searchModel = SearchModel(viewModelScope, this)
private var upAdapterJob: Job? = null
class SearchViewModel(application: Application) : BaseViewModel(application) {
private val searchModel = SearchModel(viewModelScope)
var isSearchLiveData = MutableLiveData<Boolean>()
var searchBookLiveData = MutableLiveData<List<SearchBook>>()
var searchKey: String = ""
var isLoading = false
private var searchBooks = arrayListOf<SearchBook>()
private var searchID = 0L
private var postTime = 0L
val searchDataFlow = callbackFlow {
val callback = object : SearchModel.CallBack {
override fun onSearchStart() {
isSearchLiveData.postValue(true)
isLoading = true
}
@Synchronized
override fun onSearchSuccess(searchBooks: ArrayList<SearchBook>) {
trySend(ArrayList(searchBooks))
}
override fun onSearchFinish() {
isSearchLiveData.postValue(false)
isLoading = false
}
override fun onSearchCancel() {
isSearchLiveData.postValue(false)
isLoading = false
}
}
searchModel.registerCallback(callback)
awaitClose {
searchModel.unRegisterCallback()
}
}.conflate()
/**
* 开始搜索
@ -29,8 +56,6 @@ class SearchViewModel(application: Application) : BaseViewModel(application), Se
fun search(key: String) {
if ((searchKey == key) || key.isNotEmpty()) {
searchModel.cancelSearch()
searchBooks.clear()
searchBookLiveData.postValue(searchBooks)
searchID = System.currentTimeMillis()
searchKey = key
}
@ -40,42 +65,6 @@ class SearchViewModel(application: Application) : BaseViewModel(application), Se
searchModel.search(searchID, searchKey)
}
@Synchronized
private fun upAdapter() {
upAdapterJob?.cancel()
if (System.currentTimeMillis() >= postTime + 1000) {
postTime = System.currentTimeMillis()
searchBookLiveData.postValue(searchBooks)
} else {
upAdapterJob = viewModelScope.launch {
delay(1000)
upAdapter()
}
}
}
override fun onSearchStart() {
isSearchLiveData.postValue(true)
isLoading = true
}
@Synchronized
override fun onSearchSuccess(searchBooks: ArrayList<SearchBook>) {
this.searchBooks = searchBooks
upAdapter()
}
override fun onSearchFinish() {
isSearchLiveData.postValue(false)
isLoading = false
}
override fun onSearchCancel() {
isSearchLiveData.postValue(false)
isLoading = false
}
/**
* 停止搜索
*/

Loading…
Cancel
Save