优化源导入

pull/1222/head
gedoor 3 years ago
parent 34a88993b8
commit f31cca5da7
  1. 8
      app/src/main/java/io/legado/app/ui/association/ImportBookSourceDialog.kt
  2. 28
      app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt
  3. 78
      app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleDialog.kt
  4. 87
      app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleViewModel.kt
  5. 8
      app/src/main/java/io/legado/app/ui/association/ImportRssSourceDialog.kt
  6. 28
      app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt
  7. 18
      app/src/main/res/menu/import_replace.xml

@ -107,7 +107,7 @@ class ImportBookSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickList
} }
binding.tvFooterLeft.visible() binding.tvFooterLeft.visible()
binding.tvFooterLeft.setOnClickListener { binding.tvFooterLeft.setOnClickListener {
val selectAll = viewModel.isSelectAll() val selectAll = viewModel.isSelectAll
viewModel.selectStatus.forEachIndexed { index, b -> viewModel.selectStatus.forEachIndexed { index, b ->
if (b != !selectAll) { if (b != !selectAll) {
viewModel.selectStatus[index] = !selectAll viewModel.selectStatus[index] = !selectAll
@ -144,16 +144,16 @@ class ImportBookSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickList
} }
private fun upSelectText() { private fun upSelectText() {
if (viewModel.isSelectAll()) { if (viewModel.isSelectAll) {
binding.tvFooterLeft.text = getString( binding.tvFooterLeft.text = getString(
R.string.select_cancel_count, R.string.select_cancel_count,
viewModel.selectCount(), viewModel.selectCount,
viewModel.allSources.size viewModel.allSources.size
) )
} else { } else {
binding.tvFooterLeft.text = getString( binding.tvFooterLeft.text = getString(
R.string.select_all_count, R.string.select_all_count,
viewModel.selectCount(), viewModel.selectCount,
viewModel.allSources.size viewModel.allSources.size
) )
} }

@ -31,24 +31,26 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
val checkSources = arrayListOf<BookSource?>() val checkSources = arrayListOf<BookSource?>()
val selectStatus = arrayListOf<Boolean>() val selectStatus = arrayListOf<Boolean>()
fun isSelectAll(): Boolean { val isSelectAll: Boolean
selectStatus.forEach { get() {
if (!it) { selectStatus.forEach {
return false if (!it) {
return false
}
} }
return true
} }
return true
}
fun selectCount(): Int { val selectCount: Int
var count = 0 get() {
selectStatus.forEach { var count = 0
if (it) { selectStatus.forEach {
count++ if (it) {
count++
}
} }
return count
} }
return count
}
fun importSelect(finally: () -> Unit) { fun importSelect(finally: () -> Unit) {
execute { execute {

@ -5,8 +5,10 @@ import android.content.Context
import android.content.DialogInterface import android.content.DialogInterface
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
@ -14,15 +16,23 @@ import io.legado.app.R
import io.legado.app.base.BaseDialogFragment import io.legado.app.base.BaseDialogFragment
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.RecyclerAdapter import io.legado.app.base.adapter.RecyclerAdapter
import io.legado.app.constant.AppPattern
import io.legado.app.constant.PreferKey
import io.legado.app.data.appDb
import io.legado.app.data.entities.ReplaceRule import io.legado.app.data.entities.ReplaceRule
import io.legado.app.databinding.DialogCustomGroupBinding
import io.legado.app.databinding.DialogRecyclerViewBinding import io.legado.app.databinding.DialogRecyclerViewBinding
import io.legado.app.databinding.ItemSourceImportBinding import io.legado.app.databinding.ItemSourceImportBinding
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.dialog.WaitDialog import io.legado.app.ui.widget.dialog.WaitDialog
import io.legado.app.utils.dp
import io.legado.app.utils.putPrefBoolean
import io.legado.app.utils.splitNotBlank
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.visible import io.legado.app.utils.visible
class ImportReplaceRuleDialog : BaseDialogFragment() { class ImportReplaceRuleDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
companion object { companion object {
fun start( fun start(
@ -71,6 +81,7 @@ class ImportReplaceRuleDialog : BaseDialogFragment() {
binding.toolBar.setBackgroundColor(primaryColor) binding.toolBar.setBackgroundColor(primaryColor)
binding.toolBar.setTitle(R.string.import_replace_rule) binding.toolBar.setTitle(R.string.import_replace_rule)
binding.rotateLoading.show() binding.rotateLoading.show()
initMenu()
adapter = SourcesAdapter(requireContext()) adapter = SourcesAdapter(requireContext())
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext()) binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
binding.recyclerView.adapter = adapter binding.recyclerView.adapter = adapter
@ -89,7 +100,7 @@ class ImportReplaceRuleDialog : BaseDialogFragment() {
} }
binding.tvFooterLeft.visible() binding.tvFooterLeft.visible()
binding.tvFooterLeft.setOnClickListener { binding.tvFooterLeft.setOnClickListener {
val selectAll = viewModel.isSelectAll() val selectAll = viewModel.isSelectAll
viewModel.selectStatus.forEachIndexed { index, b -> viewModel.selectStatus.forEachIndexed { index, b ->
if (b != !selectAll) { if (b != !selectAll) {
viewModel.selectStatus[index] = !selectAll viewModel.selectStatus[index] = !selectAll
@ -125,17 +136,65 @@ class ImportReplaceRuleDialog : BaseDialogFragment() {
viewModel.import(source) viewModel.import(source)
} }
private fun initMenu() {
binding.toolBar.setOnMenuItemClickListener(this)
binding.toolBar.inflateMenu(R.menu.import_replace)
}
override fun onMenuItemClick(item: MenuItem?): Boolean {
when (item?.itemId) {
R.id.menu_new_group -> alertCustomGroup(item)
R.id.menu_Keep_original_name -> {
item.isChecked = !item.isChecked
putPrefBoolean(PreferKey.importKeepName, item.isChecked)
}
}
return true
}
private fun alertCustomGroup(item: MenuItem) {
alert(R.string.diy_edit_source_group) {
val alertBinding = DialogCustomGroupBinding.inflate(layoutInflater).apply {
val groups = linkedSetOf<String>()
appDb.bookSourceDao.allGroup.forEach { group ->
groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex))
}
textInputLayout.setHint(R.string.group_name)
editView.setFilterValues(groups.toList())
editView.dropDownHeight = 180.dp
}
customView {
alertBinding.root
}
okButton {
viewModel.isAddGroup = alertBinding.swAddGroup.isChecked
viewModel.groupName = alertBinding.editView.text?.toString()
if (viewModel.groupName.isNullOrBlank()) {
item.title = getString(R.string.diy_source_group)
} else {
val group = getString(R.string.diy_edit_source_group_title, viewModel.groupName)
if (viewModel.isAddGroup) {
item.title = "+$group"
} else {
item.title = group
}
}
}
noButton()
}.show()
}
private fun upSelectText() { private fun upSelectText() {
if (viewModel.isSelectAll()) { if (viewModel.isSelectAll) {
binding.tvFooterLeft.text = getString( binding.tvFooterLeft.text = getString(
R.string.select_cancel_count, R.string.select_cancel_count,
viewModel.selectCount(), viewModel.selectCount,
viewModel.allRules.size viewModel.allRules.size
) )
} else { } else {
binding.tvFooterLeft.text = getString( binding.tvFooterLeft.text = getString(
R.string.select_all_count, R.string.select_all_count,
viewModel.selectCount(), viewModel.selectCount,
viewModel.allRules.size viewModel.allRules.size
) )
} }
@ -157,6 +216,15 @@ class ImportReplaceRuleDialog : BaseDialogFragment() {
binding.run { binding.run {
cbSourceName.isChecked = viewModel.selectStatus[holder.layoutPosition] cbSourceName.isChecked = viewModel.selectStatus[holder.layoutPosition]
cbSourceName.text = item.name cbSourceName.text = item.name
val localRule = viewModel.checkRules[holder.layoutPosition]
tvSourceState.text = when {
localRule == null -> "新规则"
item.pattern != localRule.pattern
|| item.replacement != localRule.replacement
|| item.isRegex != localRule.isRegex
|| item.scope != localRule.scope -> "更新"
else -> "已存在"
}
} }
} }

@ -3,6 +3,7 @@ package io.legado.app.ui.association
import android.app.Application import android.app.Application
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.constant.AppPattern
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.AppConfig import io.legado.app.help.AppConfig
@ -11,8 +12,11 @@ import io.legado.app.help.http.okHttpClient
import io.legado.app.help.http.text import io.legado.app.help.http.text
import io.legado.app.help.storage.OldReplace import io.legado.app.help.storage.OldReplace
import io.legado.app.utils.isAbsUrl import io.legado.app.utils.isAbsUrl
import io.legado.app.utils.splitNotBlank
class ImportReplaceRuleViewModel(app: Application) : BaseViewModel(app) { class ImportReplaceRuleViewModel(app: Application) : BaseViewModel(app) {
var isAddGroup = false
var groupName: String? = null
val errorLiveData = MutableLiveData<String>() val errorLiveData = MutableLiveData<String>()
val successLiveData = MutableLiveData<Int>() val successLiveData = MutableLiveData<Int>()
@ -20,23 +24,61 @@ class ImportReplaceRuleViewModel(app: Application) : BaseViewModel(app) {
val checkRules = arrayListOf<ReplaceRule?>() val checkRules = arrayListOf<ReplaceRule?>()
val selectStatus = arrayListOf<Boolean>() val selectStatus = arrayListOf<Boolean>()
fun isSelectAll(): Boolean { val isSelectAll: Boolean
selectStatus.forEach { get() {
if (!it) { selectStatus.forEach {
return false if (!it) {
return false
}
} }
return true
} }
return true
}
fun selectCount(): Int { val selectCount: Int
var count = 0 get() {
selectStatus.forEach { var count = 0
if (it) { selectStatus.forEach {
count++ if (it) {
count++
}
} }
return count
}
fun importSelect(finally: () -> Unit) {
execute {
val group = groupName?.trim()
val keepName = AppConfig.importKeepName
val selectRules = arrayListOf<ReplaceRule>()
selectStatus.forEachIndexed { index, b ->
if (b) {
val rule = allRules[index]
if (keepName) {
checkRules[index]?.let {
rule.name = it.name
rule.group = it.group
rule.order = it.order
}
}
if (!group.isNullOrEmpty()) {
if (isAddGroup) {
val groups = linkedSetOf<String>()
rule.group?.splitNotBlank(AppPattern.splitGroupRegex)?.let {
groups.addAll(it)
}
groups.add(group)
rule.group = groups.joinToString(",")
} else {
rule.group = group
}
}
selectRules.add(rule)
}
}
appDb.replaceRuleDao.insert(*selectRules.toTypedArray())
}.onFinally {
finally.invoke()
} }
return count
} }
fun import(text: String) { fun import(text: String) {
@ -59,27 +101,12 @@ class ImportReplaceRuleViewModel(app: Application) : BaseViewModel(app) {
} }
} }
fun importSelect(finally: () -> Unit) {
execute {
val keepName = AppConfig.importKeepName
val selectRules = arrayListOf<ReplaceRule>()
selectStatus.forEachIndexed { index, b ->
if (b) {
val rule = allRules[index]
selectRules.add(rule)
}
}
appDb.replaceRuleDao.insert(*selectRules.toTypedArray())
}.onFinally {
finally.invoke()
}
}
private fun comparisonSource() { private fun comparisonSource() {
execute { execute {
allRules.forEach { allRules.forEach {
checkRules.add(null) val rule = appDb.replaceRuleDao.findById(it.id)
selectStatus.add(false) checkRules.add(rule)
selectStatus.add(rule == null)
} }
}.onSuccess { }.onSuccess {
successLiveData.postValue(allRules.size) successLiveData.postValue(allRules.size)

@ -104,7 +104,7 @@ class ImportRssSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListe
} }
binding.tvFooterLeft.visible() binding.tvFooterLeft.visible()
binding.tvFooterLeft.setOnClickListener { binding.tvFooterLeft.setOnClickListener {
val selectAll = viewModel.isSelectAll() val selectAll = viewModel.isSelectAll
viewModel.selectStatus.forEachIndexed { index, b -> viewModel.selectStatus.forEachIndexed { index, b ->
if (b != !selectAll) { if (b != !selectAll) {
viewModel.selectStatus[index] = !selectAll viewModel.selectStatus[index] = !selectAll
@ -141,16 +141,16 @@ class ImportRssSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListe
} }
private fun upSelectText() { private fun upSelectText() {
if (viewModel.isSelectAll()) { if (viewModel.isSelectAll) {
binding.tvFooterLeft.text = getString( binding.tvFooterLeft.text = getString(
R.string.select_cancel_count, R.string.select_cancel_count,
viewModel.selectCount(), viewModel.selectCount,
viewModel.allSources.size viewModel.allSources.size
) )
} else { } else {
binding.tvFooterLeft.text = getString( binding.tvFooterLeft.text = getString(
R.string.select_all_count, R.string.select_all_count,
viewModel.selectCount(), viewModel.selectCount,
viewModel.allSources.size viewModel.allSources.size
) )
} }

@ -26,24 +26,26 @@ class ImportRssSourceViewModel(app: Application) : BaseViewModel(app) {
val checkSources = arrayListOf<RssSource?>() val checkSources = arrayListOf<RssSource?>()
val selectStatus = arrayListOf<Boolean>() val selectStatus = arrayListOf<Boolean>()
fun isSelectAll(): Boolean { val isSelectAll: Boolean
selectStatus.forEach { get() {
if (!it) { selectStatus.forEach {
return false if (!it) {
return false
}
} }
return true
} }
return true
}
fun selectCount(): Int { val selectCount: Int
var count = 0 get() {
selectStatus.forEach { var count = 0
if (it) { selectStatus.forEach {
count++ if (it) {
count++
}
} }
return count
} }
return count
}
fun importSelect(finally: () -> Unit) { fun importSelect(finally: () -> Unit) {
execute { execute {

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_new_group"
android:title="@string/diy_source_group"
app:showAsAction="always"
tools:ignore="AlwaysShowAction" />
<item
android:id="@+id/menu_Keep_original_name"
android:title="@string/keep_original_name"
android:checkable="true"
app:showAsAction="never" />
</menu>
Loading…
Cancel
Save