This commit is contained in:
Horis
2025-02-27 17:15:35 +08:00
parent c7e0e16b44
commit 356cd25200
6 changed files with 117 additions and 11 deletions
@@ -88,6 +88,10 @@ class ContentProcessor private constructor(
return contentReplaceRules return contentReplaceRules
} }
fun getAllReplaceRules(): List<ReplaceRule> {
return titleReplaceRules + contentReplaceRules
}
fun getContent( fun getContent(
book: Book, book: Book,
chapter: BookChapter, chapter: BookChapter,
@@ -1165,7 +1165,11 @@ class ReadBookActivity : BaseReadBookActivity(),
* 替换 * 替换
*/ */
override fun openReplaceRule() { override fun openReplaceRule() {
replaceActivity.launch(Intent(this, ReplaceRuleActivity::class.java)) val intent = Intent(this, ReplaceRuleActivity::class.java).apply {
val showApplied = ReadBook.book?.getUseReplaceRule() == true
putExtra("showApplied", showApplied)
}
replaceActivity.launch(intent)
} }
/** /**
@@ -1,7 +1,6 @@
package io.legado.app.ui.replace package io.legado.app.ui.replace
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
@@ -122,8 +121,10 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
initRecyclerView() initRecyclerView()
initSearchView() initSearchView()
initSelectActionView() initSelectActionView()
observeReplaceRuleData()
observeGroupData() observeGroupData()
viewModel.initData(intent) {
observeReplaceRuleData()
}
} }
override fun dispatchTouchEvent(ev: MotionEvent): Boolean { override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
@@ -215,6 +216,7 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
val key = searchKey.substringAfter("group:") val key = searchKey.substringAfter("group:")
appDb.replaceRuleDao.flowGroupSearch("%$key%") appDb.replaceRuleDao.flowGroupSearch("%$key%")
} }
else -> { else -> {
appDb.replaceRuleDao.flowSearch("%$searchKey%") appDb.replaceRuleDao.flowSearch("%$searchKey%")
} }
@@ -222,7 +224,7 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
AppLog.put("替换规则管理界面更新数据出错", it) AppLog.put("替换规则管理界面更新数据出错", it)
}.flowOn(IO).conflate().collect { }.flowOn(IO).conflate().collect {
if (dataInit) { if (dataInit) {
setResult(Activity.RESULT_OK) setResult(RESULT_OK)
} }
adapter.setItems(it, adapter.diffItemCallBack) adapter.setItems(it, adapter.diffItemCallBack)
dataInit = true dataInit = true
@@ -245,6 +247,7 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
when (item.itemId) { when (item.itemId) {
R.id.menu_add_replace_rule -> R.id.menu_add_replace_rule ->
editActivity.launch(ReplaceEditActivity.startIntent(this)) editActivity.launch(ReplaceEditActivity.startIntent(this))
R.id.menu_group_manage -> showDialogFragment<GroupManageDialog>() R.id.menu_group_manage -> showDialogFragment<GroupManageDialog>()
R.id.menu_del_selection -> viewModel.delSelection(adapter.selection) R.id.menu_del_selection -> viewModel.delSelection(adapter.selection)
R.id.menu_import_onLine -> showImportDialog() R.id.menu_import_onLine -> showImportDialog()
@@ -252,11 +255,13 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
mode = HandleFileContract.FILE mode = HandleFileContract.FILE
allowExtensions = arrayOf("txt", "json") allowExtensions = arrayOf("txt", "json")
} }
R.id.menu_import_qr -> qrCodeResult.launch() R.id.menu_import_qr -> qrCodeResult.launch()
R.id.menu_help -> showHelp("replaceRuleHelp") R.id.menu_help -> showHelp("replaceRuleHelp")
R.id.menu_group_null -> { R.id.menu_group_null -> {
searchView.setQuery(getString(R.string.no_group), true) searchView.setQuery(getString(R.string.no_group), true)
} }
else -> if (item.groupId == R.id.replace_group) { else -> if (item.groupId == R.id.replace_group) {
searchView.setQuery("group:${item.title}", true) searchView.setQuery("group:${item.title}", true)
} }
@@ -343,6 +348,14 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
) )
} }
override fun isEnabledForBook(rule: ReplaceRule): Boolean {
return viewModel.isEnabledForBook(rule)
}
override fun isAppliedForBook(rule: ReplaceRule): Boolean {
return viewModel.isAppliedForBook(rule)
}
override fun update(vararg rule: ReplaceRule) { override fun update(vararg rule: ReplaceRule) {
setResult(RESULT_OK) setResult(RESULT_OK)
viewModel.update(*rule) viewModel.update(*rule)
@@ -1,9 +1,11 @@
package io.legado.app.ui.replace package io.legado.app.ui.replace
import android.content.Context import android.content.Context
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView
import android.widget.PopupMenu import android.widget.PopupMenu
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
@@ -17,6 +19,8 @@ import io.legado.app.lib.theme.backgroundColor
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
import io.legado.app.ui.widget.recycler.ItemTouchCallback import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.utils.ColorUtils import io.legado.app.utils.ColorUtils
import io.legado.app.utils.invisible
import io.legado.app.utils.visible
class ReplaceRuleAdapter(context: Context, var callBack: CallBack) : class ReplaceRuleAdapter(context: Context, var callBack: CallBack) :
@@ -120,6 +124,7 @@ class ReplaceRuleAdapter(context: Context, var callBack: CallBack) :
} }
} }
} }
upShowApplied(ivApplied, item)
} }
} }
@@ -172,6 +177,23 @@ class ReplaceRuleAdapter(context: Context, var callBack: CallBack) :
popupMenu.show() popupMenu.show()
} }
private fun upShowApplied(iv: ImageView, rule: ReplaceRule) {
val isEnabledForBook = callBack.isEnabledForBook(rule)
val isAppliedForBook = callBack.isAppliedForBook(rule)
if (!isEnabledForBook && !isAppliedForBook) {
iv.invisible()
} else {
iv.visible()
}
if (isEnabledForBook) {
iv.setColorFilter(Color.RED)
}
if (isAppliedForBook) {
iv.setColorFilter(Color.GREEN)
}
}
override fun swap(srcPosition: Int, targetPosition: Int): Boolean { override fun swap(srcPosition: Int, targetPosition: Int): Boolean {
val srcItem = getItem(srcPosition) val srcItem = getItem(srcPosition)
val targetItem = getItem(targetPosition) val targetItem = getItem(targetPosition)
@@ -232,5 +254,7 @@ class ReplaceRuleAdapter(context: Context, var callBack: CallBack) :
fun toBottom(rule: ReplaceRule) fun toBottom(rule: ReplaceRule)
fun upOrder() fun upOrder()
fun upCountView() fun upCountView()
fun isEnabledForBook(rule: ReplaceRule): Boolean
fun isAppliedForBook(rule: ReplaceRule): Boolean
} }
} }
@@ -1,10 +1,13 @@
package io.legado.app.ui.replace package io.legado.app.ui.replace
import android.app.Application import android.app.Application
import android.content.Intent
import android.text.TextUtils import android.text.TextUtils
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.ReplaceRule import io.legado.app.data.entities.ReplaceRule
import io.legado.app.help.book.ContentProcessor
import io.legado.app.model.ReadBook
import io.legado.app.utils.splitNotBlank import io.legado.app.utils.splitNotBlank
/** /**
@@ -13,6 +16,34 @@ import io.legado.app.utils.splitNotBlank
*/ */
class ReplaceRuleViewModel(application: Application) : BaseViewModel(application) { class ReplaceRuleViewModel(application: Application) : BaseViewModel(application) {
var showApplied = false
var enabledForBookRules = emptySet<ReplaceRule>()
var appliedForBookRules = emptySet<ReplaceRule>()
fun initData(intent: Intent, block: () -> Unit) {
execute {
showApplied = intent.getBooleanExtra("showApplied", false)
if (showApplied) {
val book = ReadBook.book ?: return@execute
val textChapter = ReadBook.curTextChapter ?: return@execute
enabledForBookRules = ContentProcessor.get(book).getAllReplaceRules().toSet()
textChapter.effectiveReplaceRules?.let {
appliedForBookRules = it.toSet()
}
}
}.onFinally {
block.invoke()
}
}
fun isEnabledForBook(rule: ReplaceRule): Boolean {
return showApplied && enabledForBookRules.contains(rule)
}
fun isAppliedForBook(rule: ReplaceRule): Boolean {
return showApplied && appliedForBookRules.contains(rule)
}
fun update(vararg rule: ReplaceRule) { fun update(vararg rule: ReplaceRule) {
execute { execute {
appDb.replaceRuleDao.update(*rule) appDb.replaceRuleDao.update(*rule)
+37 -7
View File
@@ -1,17 +1,25 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:orientation="horizontal" android:orientation="horizontal"
android:padding="8dp"> android:padding="8dp"
android:paddingStart="16dp"
android:paddingEnd="16dp">
<io.legado.app.lib.theme.view.ThemeCheckBox <io.legado.app.lib.theme.view.ThemeCheckBox
android:id="@+id/cb_name" android:id="@+id/cb_name"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:scrollbars="none"
android:singleLine="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/swt_enabled"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="RtlSymmetry" /> tools:ignore="RtlSymmetry" />
<io.legado.app.lib.theme.view.ThemeSwitch <io.legado.app.lib.theme.view.ThemeSwitch
@@ -21,6 +29,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="6dp" android:layout_marginLeft="6dp"
android:layout_marginRight="6dp" android:layout_marginRight="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@id/iv_edit"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="RtlSymmetry" /> tools:ignore="RtlSymmetry" />
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
@@ -32,16 +43,35 @@
android:contentDescription="@string/edit" android:contentDescription="@string/edit"
android:padding="6dp" android:padding="6dp"
android:src="@drawable/ic_edit" android:src="@drawable/ic_edit"
android:tint="@color/primaryText" /> android:tint="@color/primaryText"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@id/iv_menu_more"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_menu_more" android:id="@+id/iv_menu_more"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
android:padding="6dp"
android:background="?attr/selectableItemBackgroundBorderless" android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/more_menu"
android:padding="6dp"
android:src="@drawable/ic_more_vert" android:src="@drawable/ic_more_vert"
android:tint="@color/primaryText" android:tint="@color/primaryText"
android:contentDescription="@string/more_menu" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="RtlHardcoded" /> tools:ignore="RtlHardcoded" />
</LinearLayout>
<io.legado.app.ui.widget.image.CircleImageView
android:id="@+id/iv_applied"
android:layout_width="8dp"
android:layout_height="8dp"
android:scaleType="centerCrop"
android:scrollbars="none"
android:src="@color/md_green_600"
android:visibility="invisible"
app:layout_constraintRight_toRightOf="@id/iv_menu_more"
app:layout_constraintTop_toTopOf="@id/iv_menu_more"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>