替换规则界面排序功能
This commit is contained in:
@@ -22,6 +22,55 @@ interface ReplaceRuleDao {
|
||||
@Query("SELECT * FROM replace_rules ORDER BY sortOrder ASC")
|
||||
fun flowAll(): Flow<List<ReplaceRule>>
|
||||
|
||||
@Query("SELECT * FROM replace_rules ORDER BY sortOrder ASC")
|
||||
fun flowAllAsc(): Flow<List<ReplaceRule>>
|
||||
|
||||
@Query("SELECT * FROM replace_rules ORDER BY sortOrder DESC")
|
||||
fun flowAllDesc(): Flow<List<ReplaceRule>>
|
||||
|
||||
@Query("SELECT * FROM replace_rules ORDER BY name COLLATE NOCASE ASC")
|
||||
fun flowAllNameAsc(): Flow<List<ReplaceRule>>
|
||||
|
||||
@Query("SELECT * FROM replace_rules ORDER BY name COLLATE NOCASE DESC")
|
||||
fun flowAllNameDesc(): Flow<List<ReplaceRule>>
|
||||
|
||||
@Query("SELECT * FROM replace_rules WHERE `group` LIKE :key OR name LIKE :key ORDER BY sortOrder ASC")
|
||||
fun flowSearchAsc(key: String): Flow<List<ReplaceRule>>
|
||||
|
||||
@Query("SELECT * FROM replace_rules WHERE `group` LIKE :key OR name LIKE :key ORDER BY sortOrder DESC")
|
||||
fun flowSearchDesc(key: String): Flow<List<ReplaceRule>>
|
||||
|
||||
@Query("SELECT * FROM replace_rules WHERE `group` LIKE :key OR name LIKE :key ORDER BY name COLLATE NOCASE ASC")
|
||||
fun flowSearchNameAsc(key: String): Flow<List<ReplaceRule>>
|
||||
|
||||
@Query("SELECT * FROM replace_rules WHERE `group` LIKE :key OR name LIKE :key ORDER BY name COLLATE NOCASE DESC")
|
||||
fun flowSearchNameDesc(key: String): Flow<List<ReplaceRule>>
|
||||
|
||||
@Query("SELECT * FROM replace_rules WHERE `group` LIKE :key ORDER BY sortOrder ASC")
|
||||
fun flowGroupSearchAsc(key: String): Flow<List<ReplaceRule>>
|
||||
|
||||
@Query("SELECT * FROM replace_rules WHERE `group` LIKE :key ORDER BY sortOrder DESC")
|
||||
fun flowGroupSearchDesc(key: String): Flow<List<ReplaceRule>>
|
||||
|
||||
@Query("SELECT * FROM replace_rules WHERE `group` LIKE :key ORDER BY name COLLATE NOCASE ASC")
|
||||
fun flowGroupSearchNameAsc(key: String): Flow<List<ReplaceRule>>
|
||||
|
||||
@Query("SELECT * FROM replace_rules WHERE `group` LIKE :key ORDER BY name COLLATE NOCASE DESC")
|
||||
fun flowGroupSearchNameDesc(key: String): Flow<List<ReplaceRule>>
|
||||
|
||||
// === 未分组 ===
|
||||
@Query("SELECT * FROM replace_rules WHERE `group` IS NULL OR trim(`group`) = '' OR trim(`group`) LIKE '%未分组%' ORDER BY sortOrder ASC")
|
||||
fun flowNoGroupAsc(): Flow<List<ReplaceRule>>
|
||||
|
||||
@Query("SELECT * FROM replace_rules WHERE `group` IS NULL OR trim(`group`) = '' OR trim(`group`) LIKE '%未分组%' ORDER BY sortOrder DESC")
|
||||
fun flowNoGroupDesc(): Flow<List<ReplaceRule>>
|
||||
|
||||
@Query("SELECT * FROM replace_rules WHERE `group` IS NULL OR trim(`group`) = '' OR trim(`group`) LIKE '%未分组%' ORDER BY name COLLATE NOCASE ASC")
|
||||
fun flowNoGroupNameAsc(): Flow<List<ReplaceRule>>
|
||||
|
||||
@Query("SELECT * FROM replace_rules WHERE `group` IS NULL OR trim(`group`) = '' OR trim(`group`) LIKE '%未分组%' ORDER BY name COLLATE NOCASE DESC")
|
||||
fun flowNoGroupNameDesc(): Flow<List<ReplaceRule>>
|
||||
|
||||
@Query("SELECT * FROM replace_rules where `group` like :key or name like :key ORDER BY sortOrder ASC")
|
||||
fun flowSearch(key: String): Flow<List<ReplaceRule>>
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.conflate
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -71,8 +72,9 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
|
||||
}
|
||||
private var groups = arrayListOf<String>()
|
||||
private var groupMenu: SubMenu? = null
|
||||
private var replaceRuleFlowJob: Job? = null
|
||||
private var dataInit = false
|
||||
|
||||
private var sortMode = "desc"
|
||||
private var searchKey: String? = null
|
||||
private val qrCodeResult = registerForActivityResult(QrCodeResult()) {
|
||||
it ?: return@registerForActivityResult
|
||||
showDialogFragment(
|
||||
@@ -197,35 +199,10 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
|
||||
binding.selectActionBar.setCallBack(this)
|
||||
}
|
||||
|
||||
private fun observeReplaceRuleData(searchKey: String? = null) {
|
||||
dataInit = false
|
||||
replaceRuleFlowJob?.cancel()
|
||||
replaceRuleFlowJob = lifecycleScope.launch {
|
||||
when {
|
||||
searchKey.isNullOrEmpty() -> {
|
||||
appDb.replaceRuleDao.flowAll()
|
||||
}
|
||||
|
||||
searchKey == getString(R.string.no_group) -> {
|
||||
appDb.replaceRuleDao.flowNoGroup()
|
||||
}
|
||||
|
||||
searchKey.startsWith("group:") -> {
|
||||
val key = searchKey.substringAfter("group:")
|
||||
appDb.replaceRuleDao.flowGroupSearch("%$key%")
|
||||
}
|
||||
else -> {
|
||||
appDb.replaceRuleDao.flowSearch("%$searchKey%")
|
||||
}
|
||||
}.catch {
|
||||
AppLog.put("替换规则管理界面更新数据出错", it)
|
||||
}.flowOn(IO).conflate().collect {
|
||||
if (dataInit) {
|
||||
setResult(RESULT_OK)
|
||||
}
|
||||
adapter.setItems(it, adapter.diffItemCallBack)
|
||||
dataInit = true
|
||||
delay(100)
|
||||
private fun observeReplaceRuleData() {
|
||||
lifecycleScope.launch {
|
||||
viewModel.rulesFlow.collectLatest { rules ->
|
||||
adapter.setItems(rules, adapter.diffItemCallBack)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -256,10 +233,16 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
|
||||
R.id.menu_group_null -> {
|
||||
searchView.setQuery(getString(R.string.no_group), true)
|
||||
}
|
||||
R.id.sort_order_asc -> viewModel.setSortMode("asc")
|
||||
R.id.sort_order_desc -> viewModel.setSortMode("desc")
|
||||
R.id.sort_name_asc -> viewModel.setSortMode("name_asc")
|
||||
R.id.sort_name_desc -> viewModel.setSortMode("name_desc")
|
||||
else -> if (item.groupId == R.id.replace_group) {
|
||||
searchView.setQuery("group:${item.title}", true)
|
||||
viewModel.setSearchKey("group:${item.title}")
|
||||
}
|
||||
}
|
||||
observeReplaceRuleData()
|
||||
return super.onCompatOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
@@ -322,7 +305,8 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
observeReplaceRuleData(newText)
|
||||
searchKey = newText
|
||||
viewModel.setSearchKey(newText)
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,22 @@ package io.legado.app.ui.replace
|
||||
|
||||
import android.app.Application
|
||||
import android.text.TextUtils
|
||||
import io.legado.app.R
|
||||
import io.legado.app.base.BaseViewModel
|
||||
import io.legado.app.constant.AppLog
|
||||
import io.legado.app.data.appDb
|
||||
import io.legado.app.data.entities.ReplaceRule
|
||||
import io.legado.app.utils.splitNotBlank
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import splitties.init.appCtx
|
||||
|
||||
/**
|
||||
* 替换规则数据修改
|
||||
@@ -13,6 +25,58 @@ import io.legado.app.utils.splitNotBlank
|
||||
*/
|
||||
class ReplaceRuleViewModel(application: Application) : BaseViewModel(application) {
|
||||
|
||||
private val _sortMode = MutableStateFlow("desc")
|
||||
private val _searchKey = MutableStateFlow<String?>(null)
|
||||
|
||||
val sortMode: StateFlow<String> = _sortMode
|
||||
val searchKey: StateFlow<String?> = _searchKey
|
||||
|
||||
fun setSortMode(mode: String) {
|
||||
_sortMode.value = mode
|
||||
}
|
||||
|
||||
fun setSearchKey(key: String?) {
|
||||
_searchKey.value = key
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
val rulesFlow = combine(_searchKey, _sortMode) { search, sort ->
|
||||
Pair(search, sort)
|
||||
}.flatMapLatest { (searchKey, sortMode) ->
|
||||
when {
|
||||
searchKey.isNullOrEmpty() -> when (sortMode) {
|
||||
"asc" -> appDb.replaceRuleDao.flowAllAsc()
|
||||
"name_asc" -> appDb.replaceRuleDao.flowAllNameAsc()
|
||||
"name_desc" -> appDb.replaceRuleDao.flowAllNameDesc()
|
||||
else -> appDb.replaceRuleDao.flowAllDesc()
|
||||
}
|
||||
|
||||
searchKey == appCtx.getString(R.string.no_group) -> when (sortMode) {
|
||||
"asc" -> appDb.replaceRuleDao.flowNoGroupAsc()
|
||||
"name_asc" -> appDb.replaceRuleDao.flowNoGroupNameAsc()
|
||||
"name_desc" -> appDb.replaceRuleDao.flowNoGroupNameDesc()
|
||||
else -> appDb.replaceRuleDao.flowNoGroupDesc()
|
||||
}
|
||||
|
||||
searchKey.startsWith("group:") -> {
|
||||
val key = searchKey.substringAfter("group:")
|
||||
when (sortMode) {
|
||||
"asc" -> appDb.replaceRuleDao.flowGroupSearchAsc("%$key%")
|
||||
"name_asc" -> appDb.replaceRuleDao.flowGroupSearchNameAsc("%$key%")
|
||||
"name_desc" -> appDb.replaceRuleDao.flowGroupSearchNameDesc("%$key%")
|
||||
else -> appDb.replaceRuleDao.flowGroupSearchDesc("%$key%")
|
||||
}
|
||||
}
|
||||
|
||||
else -> when (sortMode) {
|
||||
"asc" -> appDb.replaceRuleDao.flowSearchAsc("%$searchKey%")
|
||||
"name_asc" -> appDb.replaceRuleDao.flowSearchNameAsc("%$searchKey%")
|
||||
"name_desc" -> appDb.replaceRuleDao.flowSearchNameDesc("%$searchKey%")
|
||||
else -> appDb.replaceRuleDao.flowSearchDesc("%$searchKey%")
|
||||
}
|
||||
}
|
||||
}.flowOn(Dispatchers.IO)
|
||||
|
||||
fun update(vararg rule: ReplaceRule) {
|
||||
execute {
|
||||
appDb.replaceRuleDao.update(*rule)
|
||||
|
||||
Reference in New Issue
Block a user