替换规则

This commit is contained in:
HapeLee committed 2025-11-16 13:54:19 +08:00
1 parent 5362d4f47f
commit 4f719d4030
2 files changed
+48 -103

No files matched your search

@@ -120,6 +120,9 @@ interface ReplaceRuleDao {
) )
fun findEnabledByTitleScope(name: String, origin: String): List<ReplaceRule> fun findEnabledByTitleScope(name: String, origin: String): List<ReplaceRule>
@Query("UPDATE replace_rules SET `group` = NULL WHERE `group` IN (:groups)")
suspend fun clearGroups(groups: List<String>)
@Query("select * from replace_rules where `group` like '%' || :group || '%'") @Query("select * from replace_rules where `group` like '%' || :group || '%'")
fun getByGroup(group: String): List<ReplaceRule> fun getByGroup(group: String): List<ReplaceRule>
@@ -22,8 +22,11 @@ import io.legado.app.utils.setOnApplyWindowInsetsListenerCompat
import io.legado.app.utils.showHelp import io.legado.app.utils.showHelp
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import androidx.core.content.edit import androidx.core.content.edit
import io.legado.app.data.appDb
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
/** /**
* 编辑替换规则 * 编辑替换规则
@@ -32,53 +35,6 @@ class ReplaceEditActivity :
VMBaseActivity<ActivityReplaceEditBinding, ReplaceEditViewModel>(), VMBaseActivity<ActivityReplaceEditBinding, ReplaceEditViewModel>(),
KeyboardToolPop.CallBack { KeyboardToolPop.CallBack {
object GroupManager {
private const val PREF_NAME = "replace_groups"
private const val KEY_CUSTOM_GROUPS = "custom_groups"
private const val KEY_LAST_SELECTED = "last_selected_group"
private val presetGroups = listOf(
"默认", "地名", "国家", "企业", "人名", "敏感词", "生僻字", "乱码或广告"
)
private fun prefs(context: Context) =
context.getSharedPreferences(PREF_NAME, MODE_PRIVATE)
fun getAllGroups(context: Context): List<String> =
(getCustomGroups(context) + presetGroups).distinct()
fun getCustomGroups(context: Context): List<String> {
val json = prefs(context).getString(KEY_CUSTOM_GROUPS, "[]") ?: "[]"
return GSON.fromJson(json, Array<String>::class.java).toList()
}
fun saveCustomGroups(context: Context, groups: List<String>) {
prefs(context).edit { putString(KEY_CUSTOM_GROUPS, GSON.toJson(groups)) }
}
fun addCustomGroup(context: Context, group: String) {
if (group.isBlank() || presetGroups.contains(group)) return
val custom = getCustomGroups(context).toMutableList()
if (group !in custom) {
custom += group
saveCustomGroups(context, custom)
}
}
fun removeCustomGroups(context: Context, groupsToRemove: List<String>) {
if (groupsToRemove.isEmpty()) return
val updated = getCustomGroups(context).filterNot { it in groupsToRemove }
saveCustomGroups(context, updated)
}
fun getLastSelectedGroup(context: Context): String =
prefs(context).getString(KEY_LAST_SELECTED, "默认") ?: "默认"
fun setLastSelectedGroup(context: Context, group: String) {
prefs(context).edit { putString(KEY_LAST_SELECTED, group) }
}
}
companion object { companion object {
fun startIntent( fun startIntent(
context: Context, context: Context,
@@ -147,63 +103,50 @@ class ReplaceEditActivity :
} }
private fun setupGroupAutoComplete() = binding.run { private fun setupGroupAutoComplete() = binding.run {
val allGroups = GroupManager.getAllGroups(this@ReplaceEditActivity) lifecycleScope.launch {
val adapter = ArrayAdapter( appDb.replaceRuleDao.flowGroups().collectLatest { groups ->
this@ReplaceEditActivity, val allGroups = listOf("默认") + groups
android.R.layout.simple_dropdown_item_1line, val adapter = ArrayAdapter(
allGroups this@ReplaceEditActivity,
) android.R.layout.simple_dropdown_item_1line,
etGroup.setAdapter(adapter) allGroups
)
etGroup.setText(GroupManager.getLastSelectedGroup(this@ReplaceEditActivity), false) etGroup.setAdapter(adapter)
}
etGroup.setOnFocusChangeListener { _, hasFocus ->
if (!hasFocus) saveCurrentGroup()
} }
etGroup.setOnItemClickListener { parent, _, position, _ -> val defaultGroup = viewModel.replaceRule?.group ?: "默认"
val selected = parent.getItemAtPosition(position) as String etGroup.setText(defaultGroup, false)
GroupManager.setLastSelectedGroup(this@ReplaceEditActivity, selected)
}
} }
private fun refreshGroupList() {
val allGroups = GroupManager.getAllGroups(this)
val adapter = ArrayAdapter(
this,
android.R.layout.simple_dropdown_item_1line,
allGroups
)
binding.etGroup.setAdapter(adapter)
}
private fun saveCurrentGroup() {
val current = binding.etGroup.text.toString().trim()
if (current.isNotBlank()) {
GroupManager.addCustomGroup(this, current)
GroupManager.setLastSelectedGroup(this, current)
}
}
private fun showGroupManageDialog() { private fun showGroupManageDialog() {
val allGroups = GroupManager.getCustomGroups(this).toMutableList() lifecycleScope.launch {
if (allGroups.isEmpty()) { val allGroups = appDb.replaceRuleDao.allGroups()
toastOnUi("暂无自定义分组")
return
}
val checked = BooleanArray(allGroups.size) if (allGroups.isEmpty()) {
alert(title = getString(R.string.group_manage)) { toastOnUi("暂无分组")
multiChoiceItems(allGroups.toTypedArray(), checked) { _, _, _ -> } return@launch
negativeButton("关闭") }
neutralButton("删除所选") {
val toDelete = allGroups.filterIndexed { i, _ -> checked[i] } val checked = BooleanArray(allGroups.size)
if (toDelete.isNotEmpty()) {
GroupManager.removeCustomGroups(this@ReplaceEditActivity, toDelete) alert(title = getString(R.string.group_manage)) {
refreshGroupList() multiChoiceItems(allGroups.toTypedArray(), checked) { _, _, _ -> }
toastOnUi("已删除 ${toDelete.size} 个分组") negativeButton("关闭")
} else { neutralButton("删除所选") {
toastOnUi("未选择任何分组")
val toDelete = allGroups.filterIndexed { i, _ -> checked[i] }
if (toDelete.isEmpty()) {
toastOnUi("未选择任何分组")
return@neutralButton
}
lifecycleScope.launch {
appDb.replaceRuleDao.clearGroups(toDelete)
toastOnUi("已清空 ${toDelete.size} 个分组")
}
} }
} }
} }
@@ -224,15 +167,14 @@ class ReplaceEditActivity :
} }
private fun getReplaceRule(): ReplaceRule = binding.run { private fun getReplaceRule(): ReplaceRule = binding.run {
saveCurrentGroup()
val rule = viewModel.replaceRule ?: ReplaceRule() val rule = viewModel.replaceRule ?: ReplaceRule()
rule.name = etName.text.toString() rule.name = etName.text.toString()
val groupText = etGroup.text.toString().trim() val groupText = binding.etGroup.text.toString().trim()
rule.group = if (groupText == "默认") { rule.group = when {
null groupText.isBlank() -> null
} else { groupText == "默认" -> null
groupText.ifBlank { null } else -> groupText
} }
rule.pattern = etReplaceRule.text.toString() rule.pattern = etReplaceRule.text.toString()
rule.isRegex = cbUseRegex.isChecked rule.isRegex = cbUseRegex.isChecked