优化
Some checks failed
Test Build / prepare (push) Waiting to run
Test Build / build (app, release) (push) Blocked by required conditions
Test Build / build (app, releaseA) (push) Blocked by required conditions
Test Build / prerelease (push) Blocked by required conditions
Test Build / lanzou (push) Blocked by required conditions
Test Build / test_Branch (push) Blocked by required conditions
Test Build / telegram (push) Blocked by required conditions
closeStaleIssue / stale (push) Has been cancelled

This commit is contained in:
Horis
2025-01-20 18:32:59 +08:00
parent 565187024a
commit 2842239757
5 changed files with 21 additions and 21 deletions

View File

@@ -73,6 +73,7 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
private fun startSearch() {
val precision = appCtx.getPrefBoolean(PreferKey.precisionSearch)
var hasMore = false
searchJob = scope.launch(searchPool!!) {
flow {
for (bs in bookSourceParts) {
@@ -90,12 +91,13 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
for (book in items) {
book.releaseHtmlData()
}
hasMore = hasMore || items.isNotEmpty()
appDb.searchBookDao.insert(*items.toTypedArray())
mergeItems(items, precision)
currentCoroutineContext().ensureActive()
callBack.onSearchSuccess(searchBooks)
}.onCompletion {
if (it == null) callBack.onSearchFinish(searchBooks.isEmpty())
if (it == null) callBack.onSearchFinish(searchBooks.isEmpty(), hasMore)
}.catch {
AppLog.put("书源搜索出错\n${it.localizedMessage}", it)
}.collect()
@@ -185,7 +187,7 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
fun getSearchScope(): SearchScope
fun onSearchStart()
fun onSearchSuccess(searchBooks: List<SearchBook>)
fun onSearchFinish(isEmpty: Boolean)
fun onSearchFinish(isEmpty: Boolean, hasMore: Boolean)
fun onSearchCancel(exception: Throwable? = null)
}

View File

@@ -54,7 +54,6 @@ import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import splitties.init.appCtx
import kotlin.math.abs
class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel>(),
BookAdapter.CallBack,
@@ -240,20 +239,7 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
if (!recyclerView.canScrollVertically(1)) {
val layoutManager = recyclerView.layoutManager as LinearLayoutManager
val lastPosition = layoutManager.findLastCompletelyVisibleItemPosition()
if (lastPosition == RecyclerView.NO_POSITION) {
return
}
val lastView = layoutManager.findViewByPosition(lastPosition)
if (lastView == null) {
scrollToBottom()
return
}
val bottom = abs(lastView.bottom - recyclerView.height)
if (bottom <= 1) {
scrollToBottom()
}
scrollToBottom()
}
}
})
@@ -324,6 +310,7 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
}
if (viewModel.isSearchLiveData.value == false
&& viewModel.searchKey.isNotEmpty()
&& viewModel.hasMore
) {
viewModel.search("")
}
@@ -407,8 +394,9 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
if (!isEmpty || viewModel.searchScope.isAll()) return@observe
alert("搜索结果为空") {
val precisionSearch = appCtx.getPrefBoolean(PreferKey.precisionSearch)
val displayScope = viewModel.searchScope.display
if (precisionSearch) {
setMessage("${viewModel.searchScope.display}分组搜索结果为空,是否关闭精准搜索?")
setMessage("${displayScope}分组搜索结果为空,是否关闭精准搜索?")
yesButton {
appCtx.putPrefBoolean(PreferKey.precisionSearch, false)
precisionSearchMenuItem?.isChecked = false
@@ -416,7 +404,7 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
viewModel.search(searchView.query.toString())
}
} else {
setMessage("${viewModel.searchScope.display}分组搜索结果为空,是否切换到全部分组?")
setMessage("${displayScope}分组搜索结果为空,是否切换到全部分组?")
yesButton {
viewModel.searchScope.update("")
}

View File

@@ -30,6 +30,7 @@ class SearchViewModel(application: Application) : BaseViewModel(application) {
var searchFinishLiveData = MutableLiveData<Boolean>()
var isSearchLiveData = MutableLiveData<Boolean>()
var searchKey: String = ""
var hasMore = true
private var searchID = 0L
private val searchModel = SearchModel(viewModelScope, object : SearchModel.CallBack {
@@ -45,9 +46,10 @@ class SearchViewModel(application: Application) : BaseViewModel(application) {
searchBookLiveData.postValue(searchBooks)
}
override fun onSearchFinish(isEmpty: Boolean) {
override fun onSearchFinish(isEmpty: Boolean, hasMore: Boolean) {
isSearchLiveData.postValue(false)
searchFinishLiveData.postValue(isEmpty)
this@SearchViewModel.hasMore = hasMore
}
override fun onSearchCancel(exception: Throwable?) {
@@ -99,6 +101,7 @@ class SearchViewModel(application: Application) : BaseViewModel(application) {
searchID = System.currentTimeMillis()
searchBookLiveData.postValue(emptyList())
searchKey = key
hasMore = true
}
if (searchKey.isEmpty()) {
return@execute

View File

@@ -1,12 +1,19 @@
package io.legado.app.ui.widget.text
import android.content.Context
import android.os.Build
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatTextView
class MultilineTextView(context: Context, attrs: AttributeSet?) :
AppCompatTextView(context, attrs) {
init {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
isFallbackLineSpacing = false
}
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val heightSize = MeasureSpec.getSize(heightMeasureSpec)
calculateLines(heightSize)

View File

@@ -90,7 +90,7 @@ class BookSearchWebSocket(handshakeRequest: NanoHTTPD.IHTTPSession) :
send(GSON.toJson(searchBooks))
}
override fun onSearchFinish(isEmpty: Boolean) = close(normalClosure, SEARCH_FINISH, false)
override fun onSearchFinish(isEmpty: Boolean, hasMore: Boolean) = close(normalClosure, SEARCH_FINISH, false)
override fun onSearchCancel(exception: Throwable?) = close(normalClosure, exception?.toString() ?: SEARCH_FINISH, false)