pull/2037/head
kunfei 2 years ago
parent 0f3996491e
commit ee51315b8e
  1. 23
      app/src/main/java/io/legado/app/model/webBook/SearchModel.kt
  2. 16
      app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt
  3. 26
      app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt

@ -16,7 +16,7 @@ import splitties.init.appCtx
import java.util.concurrent.Executors import java.util.concurrent.Executors
import kotlin.math.min import kotlin.math.min
class SearchModel(private val scope: CoroutineScope) { class SearchModel(private val scope: CoroutineScope, private val callBack: CallBack) {
val threadCount = AppConfig.threadCount val threadCount = AppConfig.threadCount
private var searchPool: ExecutorCoroutineDispatcher? = null private var searchPool: ExecutorCoroutineDispatcher? = null
private var mSearchId = 0L private var mSearchId = 0L
@ -25,19 +25,10 @@ class SearchModel(private val scope: CoroutineScope) {
private var tasks = CompositeCoroutine() private var tasks = CompositeCoroutine()
private var bookSourceList = arrayListOf<BookSource>() private var bookSourceList = arrayListOf<BookSource>()
private var searchBooks = arrayListOf<SearchBook>() private var searchBooks = arrayListOf<SearchBook>()
private var callBack: CallBack? = null
@Volatile @Volatile
private var searchIndex = -1 private var searchIndex = -1
fun registerCallback(callBack: CallBack) {
this.callBack = callBack
}
fun unRegisterCallback() {
this.callBack = null
}
private fun initSearchPool() { private fun initSearchPool() {
searchPool?.close() searchPool?.close()
searchPool = Executors searchPool = Executors
@ -45,10 +36,10 @@ class SearchModel(private val scope: CoroutineScope) {
} }
fun search(searchId: Long, key: String) { fun search(searchId: Long, key: String) {
callBack?.onSearchStart() callBack.onSearchStart()
if (searchId != mSearchId) { if (searchId != mSearchId) {
if (key.isEmpty()) { if (key.isEmpty()) {
callBack?.onSearchCancel() callBack.onSearchCancel()
return return
} else { } else {
this.searchKey = key this.searchKey = key
@ -62,7 +53,7 @@ class SearchModel(private val scope: CoroutineScope) {
val searchGroup = AppConfig.searchGroup val searchGroup = AppConfig.searchGroup
bookSourceList.clear() bookSourceList.clear()
searchBooks.clear() searchBooks.clear()
callBack?.onSearchSuccess(searchBooks) callBack.onSearchSuccess(searchBooks)
if (searchGroup.isBlank()) { if (searchGroup.isBlank()) {
bookSourceList.addAll(appDb.bookSourceDao.allEnabled) bookSourceList.addAll(appDb.bookSourceDao.allEnabled)
} else { } else {
@ -114,7 +105,7 @@ class SearchModel(private val scope: CoroutineScope) {
appDb.searchBookDao.insert(*items.toTypedArray()) appDb.searchBookDao.insert(*items.toTypedArray())
val precision = appCtx.getPrefBoolean(PreferKey.precisionSearch) val precision = appCtx.getPrefBoolean(PreferKey.precisionSearch)
mergeItems(scope, items, precision) mergeItems(scope, items, precision)
callBack?.onSearchSuccess(searchBooks) callBack.onSearchSuccess(searchBooks)
} }
} }
@ -128,7 +119,7 @@ class SearchModel(private val scope: CoroutineScope) {
if (searchIndex >= bookSourceList.lastIndex if (searchIndex >= bookSourceList.lastIndex
+ min(bookSourceList.size, threadCount) + min(bookSourceList.size, threadCount)
) { ) {
callBack?.onSearchFinish(searchBooks.isEmpty()) callBack.onSearchFinish(searchBooks.isEmpty())
} }
} }
@ -201,7 +192,7 @@ class SearchModel(private val scope: CoroutineScope) {
fun cancelSearch() { fun cancelSearch() {
close() close()
callBack?.onSearchCancel() callBack.onSearchCancel()
} }
fun close() { fun close() {

@ -86,12 +86,12 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
binding.llHistory.setBackgroundColor(backgroundColor) binding.llHistory.setBackgroundColor(backgroundColor)
viewModel.searchFinishCallback = searchFinishCallback
initRecyclerView() initRecyclerView()
initSearchView() initSearchView()
initOtherView() initOtherView()
initData() initData()
receiptIntent(intent) receiptIntent(intent)
viewModel.searchFinishCallback = searchFinishCallback
} }
override fun onNewIntent(data: Intent?) { override fun onNewIntent(data: Intent?) {
@ -219,6 +219,13 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
} }
private fun initData() { private fun initData() {
viewModel.isSearchLiveData.observe(this) {
if (it) {
startSearch()
} else {
searchFinally()
}
}
lifecycleScope.launchWhenStarted { lifecycleScope.launchWhenStarted {
viewModel.searchDataFlow.conflate().collect { viewModel.searchDataFlow.conflate().collect {
adapter.setItems(it) adapter.setItems(it)
@ -234,13 +241,6 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
upGroupMenu() upGroupMenu()
} }
} }
viewModel.isSearchLiveData.observe(this) {
if (it) {
startSearch()
} else {
searchFinally()
}
}
} }
private fun receiptIntent(intent: Intent? = null) { private fun receiptIntent(intent: Intent? = null) {

@ -14,21 +14,13 @@ import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
class SearchViewModel(application: Application) : BaseViewModel(application) { class SearchViewModel(application: Application) : BaseViewModel(application) {
private val searchModel = SearchModel(viewModelScope) private val searchModel = SearchModel(viewModelScope, object : SearchModel.CallBack {
var searchFinishCallback: ((isEmpty: Boolean) -> Unit)? = null
var isSearchLiveData = MutableLiveData<Boolean>()
var searchKey: String = ""
private var searchID = 0L
val searchDataFlow = callbackFlow {
val callback = object : SearchModel.CallBack {
override fun onSearchStart() { override fun onSearchStart() {
isSearchLiveData.postValue(true) isSearchLiveData.postValue(true)
} }
override fun onSearchSuccess(searchBooks: ArrayList<SearchBook>) { override fun onSearchSuccess(searchBooks: ArrayList<SearchBook>) {
trySend(ArrayList(searchBooks)) searchFlowCallBack?.invoke(searchBooks)
} }
override fun onSearchFinish(isEmpty: Boolean) { override fun onSearchFinish(isEmpty: Boolean) {
@ -39,12 +31,20 @@ class SearchViewModel(application: Application) : BaseViewModel(application) {
override fun onSearchCancel() { override fun onSearchCancel() {
isSearchLiveData.postValue(false) isSearchLiveData.postValue(false)
} }
} })
var searchFinishCallback: ((isEmpty: Boolean) -> Unit)? = null
var isSearchLiveData = MutableLiveData<Boolean>()
var searchKey: String = ""
private var searchID = 0L
private var searchFlowCallBack: ((searchBooks: ArrayList<SearchBook>) -> Unit)? = null
val searchDataFlow = callbackFlow {
searchModel.registerCallback(callback) searchFlowCallBack = {
trySend(ArrayList(it))
}
awaitClose { awaitClose {
searchModel.unRegisterCallback() searchFlowCallBack = null
} }
}.flowOn(IO) }.flowOn(IO)

Loading…
Cancel
Save