From 7c151e1b86891d26beaa841dff6459a28134916d Mon Sep 17 00:00:00 2001 From: HapeLee <1321903405@qq.com> Date: Sat, 1 Nov 2025 16:12:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E8=A7=84=E5=88=99=E7=95=8C?= =?UTF-8?q?=E9=9D=A2=E6=8E=92=E5=BA=8F=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/data/dao/ReplaceRuleDao.kt | 49 ++++++++++++++ .../app/ui/replace/ReplaceRuleActivity.kt | 48 +++++--------- .../app/ui/replace/ReplaceRuleViewModel.kt | 64 +++++++++++++++++++ app/src/main/res/menu/replace_rule.xml | 18 ++++++ app/src/main/res/values-zh/strings.xml | 4 ++ app/src/main/res/values/strings.xml | 4 ++ 6 files changed, 155 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/io/legado/app/data/dao/ReplaceRuleDao.kt b/app/src/main/java/io/legado/app/data/dao/ReplaceRuleDao.kt index 09867c9b9..d0550e9db 100644 --- a/app/src/main/java/io/legado/app/data/dao/ReplaceRuleDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/ReplaceRuleDao.kt @@ -22,6 +22,55 @@ interface ReplaceRuleDao { @Query("SELECT * FROM replace_rules ORDER BY sortOrder ASC") fun flowAll(): Flow> + @Query("SELECT * FROM replace_rules ORDER BY sortOrder ASC") + fun flowAllAsc(): Flow> + + @Query("SELECT * FROM replace_rules ORDER BY sortOrder DESC") + fun flowAllDesc(): Flow> + + @Query("SELECT * FROM replace_rules ORDER BY name COLLATE NOCASE ASC") + fun flowAllNameAsc(): Flow> + + @Query("SELECT * FROM replace_rules ORDER BY name COLLATE NOCASE DESC") + fun flowAllNameDesc(): Flow> + + @Query("SELECT * FROM replace_rules WHERE `group` LIKE :key OR name LIKE :key ORDER BY sortOrder ASC") + fun flowSearchAsc(key: String): Flow> + + @Query("SELECT * FROM replace_rules WHERE `group` LIKE :key OR name LIKE :key ORDER BY sortOrder DESC") + fun flowSearchDesc(key: String): Flow> + + @Query("SELECT * FROM replace_rules WHERE `group` LIKE :key OR name LIKE :key ORDER BY name COLLATE NOCASE ASC") + fun flowSearchNameAsc(key: String): Flow> + + @Query("SELECT * FROM replace_rules WHERE `group` LIKE :key OR name LIKE :key ORDER BY name COLLATE NOCASE DESC") + fun flowSearchNameDesc(key: String): Flow> + + @Query("SELECT * FROM replace_rules WHERE `group` LIKE :key ORDER BY sortOrder ASC") + fun flowGroupSearchAsc(key: String): Flow> + + @Query("SELECT * FROM replace_rules WHERE `group` LIKE :key ORDER BY sortOrder DESC") + fun flowGroupSearchDesc(key: String): Flow> + + @Query("SELECT * FROM replace_rules WHERE `group` LIKE :key ORDER BY name COLLATE NOCASE ASC") + fun flowGroupSearchNameAsc(key: String): Flow> + + @Query("SELECT * FROM replace_rules WHERE `group` LIKE :key ORDER BY name COLLATE NOCASE DESC") + fun flowGroupSearchNameDesc(key: String): Flow> + + // === 未分组 === + @Query("SELECT * FROM replace_rules WHERE `group` IS NULL OR trim(`group`) = '' OR trim(`group`) LIKE '%未分组%' ORDER BY sortOrder ASC") + fun flowNoGroupAsc(): Flow> + + @Query("SELECT * FROM replace_rules WHERE `group` IS NULL OR trim(`group`) = '' OR trim(`group`) LIKE '%未分组%' ORDER BY sortOrder DESC") + fun flowNoGroupDesc(): Flow> + + @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> + + @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> + @Query("SELECT * FROM replace_rules where `group` like :key or name like :key ORDER BY sortOrder ASC") fun flowSearch(key: String): Flow> diff --git a/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt b/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt index 8c47f1eae..0f1175041 100644 --- a/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt +++ b/app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt @@ -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() 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 { - 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 { 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(null) + + val sortMode: StateFlow = _sortMode + val searchKey: StateFlow = _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) diff --git a/app/src/main/res/menu/replace_rule.xml b/app/src/main/res/menu/replace_rule.xml index 3ab56934e..82388ed29 100644 --- a/app/src/main/res/menu/replace_rule.xml +++ b/app/src/main/res/menu/replace_rule.xml @@ -28,6 +28,24 @@ + + + + + + + + + + + + + + 阻止所有重定向 域内询问且域外阻止 显示状态栏 + 从旧到新 + 从新到旧 + 名称升序 + 名称降序 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c9a4c8675..0006e1b56 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1322,4 +1322,8 @@ 阻止所有重定向 域内询问且域外阻止 显示状态栏 + 从旧到新 + 从新到旧 + 名称升序 + 名称降序