From d95376448d2d53041f830ac7f21b8f0ae13b7c38 Mon Sep 17 00:00:00 2001 From: Discut Date: Mon, 22 May 2023 21:00:37 +0800 Subject: [PATCH] =?UTF-8?q?feat(Cache/Export):=20=E2=9C=A8=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=20=E5=BC=80=E5=90=AF=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=20=E8=8F=9C=E5=8D=95=E4=B8=8E=E5=AF=B9?= =?UTF-8?q?=E8=AF=9D=E6=A1=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/constant/PreferKey.kt | 1 + .../io/legado/app/help/config/AppConfig.kt | 6 + .../legado/app/ui/book/cache/CacheActivity.kt | 124 ++++++++++++++++++ .../book/cache/CustomExportSectionDialog.kt | 16 +++ .../layout/dialog_select_section_export.xml | 110 ++++++++++++++++ app/src/main/res/menu/book_cache.xml | 7 + app/src/main/res/values-zh/strings.xml | 2 + app/src/main/res/values/strings.xml | 2 + 8 files changed, 268 insertions(+) create mode 100644 app/src/main/java/io/legado/app/ui/book/cache/CustomExportSectionDialog.kt create mode 100644 app/src/main/res/layout/dialog_select_section_export.xml diff --git a/app/src/main/java/io/legado/app/constant/PreferKey.kt b/app/src/main/java/io/legado/app/constant/PreferKey.kt index 47a5c7c64..5cf81230b 100644 --- a/app/src/main/java/io/legado/app/constant/PreferKey.kt +++ b/app/src/main/java/io/legado/app/constant/PreferKey.kt @@ -54,6 +54,7 @@ object PreferKey { const val webDavAccount = "web_dav_account" const val webDavPassword = "web_dav_password" const val webDavDir = "webDavDir" + const val enableCustomExport = "enableCustomExport" const val exportToWebDav = "webDavCacheBackup" const val exportNoChapterName = "exportNoChapterName" const val exportType = "exportType" diff --git a/app/src/main/java/io/legado/app/help/config/AppConfig.kt b/app/src/main/java/io/legado/app/help/config/AppConfig.kt index dec18efa9..369a06236 100644 --- a/app/src/main/java/io/legado/app/help/config/AppConfig.kt +++ b/app/src/main/java/io/legado/app/help/config/AppConfig.kt @@ -268,6 +268,12 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener { set(value) { appCtx.putPrefBoolean(PreferKey.exportNoChapterName, value) } + var enableCustomExport: Boolean + get() = appCtx.getPrefBoolean(PreferKey.enableCustomExport) + set(value) { + appCtx.putPrefBoolean(PreferKey.enableCustomExport, value) + } + var exportType: Int get() = appCtx.getPrefInt(PreferKey.exportType) set(value) { diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt b/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt index f98802f25..3d48b3136 100644 --- a/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt @@ -4,7 +4,9 @@ import android.annotation.SuppressLint import android.os.Bundle import android.view.Menu import android.view.MenuItem +import android.view.View import androidx.activity.viewModels +import androidx.appcompat.app.AlertDialog import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.R import io.legado.app.base.VMBaseActivity @@ -17,6 +19,7 @@ import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookGroup import io.legado.app.databinding.ActivityCacheBookBinding import io.legado.app.databinding.DialogEditTextBinding +import io.legado.app.databinding.DialogSelectSectionExportBinding import io.legado.app.help.book.isAudio import io.legado.app.help.config.AppConfig import io.legado.app.lib.dialogs.SelectItem @@ -32,7 +35,11 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import androidx.core.widget.doOnTextChanged +/** + * cache/download 缓存界面 + */ class CacheActivity : VMBaseActivity(), CacheAdapter.CallBack { @@ -88,6 +95,8 @@ class CacheActivity : VMBaseActivity() override fun onMenuOpened(featureId: Int, menu: Menu): Boolean { menu.findItem(R.id.menu_enable_replace)?.isChecked = AppConfig.exportUseReplace + // 菜单打开时读取状态[enableCustomExport] + menu.findItem(R.id.menu_enable_custom_export)?.isChecked = AppConfig.enableCustomExport menu.findItem(R.id.menu_export_no_chapter_name)?.isChecked = AppConfig.exportNoChapterName menu.findItem(R.id.menu_export_web_dav)?.isChecked = AppConfig.exportToWebDav menu.findItem(R.id.menu_export_pics_file)?.isChecked = AppConfig.exportPictureFile @@ -108,6 +117,9 @@ class CacheActivity : VMBaseActivity() } } + /** + * 菜单按下回调 + */ override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.menu_download -> { @@ -126,6 +138,8 @@ class CacheActivity : VMBaseActivity() } R.id.menu_export_all -> exportAll() R.id.menu_enable_replace -> AppConfig.exportUseReplace = !item.isChecked + // 更改菜单状态[enableCustomExport] + R.id.menu_enable_custom_export -> AppConfig.enableCustomExport = !item.isChecked R.id.menu_export_no_chapter_name -> AppConfig.exportNoChapterName = !item.isChecked R.id.menu_export_web_dav -> AppConfig.exportToWebDav = !item.isChecked R.id.menu_export_pics_file -> AppConfig.exportPictureFile = !item.isChecked @@ -233,6 +247,8 @@ class CacheActivity : VMBaseActivity() val path = ACache.get().getAsString(exportBookPathKey) if (path.isNullOrEmpty()) { selectExportFolder(position) + } else if (AppConfig.enableCustomExport) {// 启用自定义导出 + configExportSection(path, position); } else { startExport(path, position) } @@ -247,6 +263,102 @@ class CacheActivity : VMBaseActivity() } } + /** + * 配置自定义导出对话框 + * + * @param path 导出路径 + * @param position book位置 + * @author Discut + * @since 1.0.0 + */ + private fun configExportSection(path: String, position: Int) { + if (AppConfig.enableCustomExport) { + val alertBinding = DialogSelectSectionExportBinding.inflate(layoutInflater) + .apply { + cbAllExport.isChecked = true + cbSelectExport.isChecked = false + etEpubSize.isEnabled = false + etInputScope.isEnabled = false + tvAllExport.setOnClickListener { + cbAllExport.isChecked = true + } + tvSelectExport.setOnClickListener { + cbSelectExport.isChecked = true + } + cbSelectExport.onCheckedChangeListener = { _, isChecked -> + if (isChecked) { + etEpubSize.isEnabled = true + etInputScope.isEnabled = true + cbAllExport.isChecked = false + } + } + cbAllExport.onCheckedChangeListener = { _, isChecked -> + if (isChecked) { + etEpubSize.isEnabled = false + etInputScope.isEnabled = false + cbSelectExport.isChecked = false + } + } + + etInputScope.onFocusChangeListener = + View.OnFocusChangeListener { v, hasFocus -> + if (hasFocus) { + etInputScope.hint = "例如:1-5,8,10-18" + } else { + etInputScope.hint = "" + } + } + etInputScope.doOnTextChanged { text, start, before, count -> + var a: Int = 1 + a = 2 + } + + } + val alertDialog = alert(titleResource = R.string.select_section_export) { + customView { alertBinding.root } + positiveButton("确认") + //okButton { +// alertBinding.apply { +// it.dismiss() +// if (cbAllExport.isChecked) { +// // export all sections of the book. +// startExport(path, position) +// } else if (cbSelectExport.isChecked) { +// +// } +// } + //} + cancelButton() + } + alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { + alertBinding.apply { + val text = etInputScope.text + if (!verificationField(text.toString())) { + etInputScope.error = "请输入正确的范围" + } else { + etInputScope.error = null + val toInt = etEpubSize.text.toString().toInt() + startExport(path, position, toInt, text.toString()) + } + } + + } + + } + } + + /** + * 验证 输入的范围 是否正确 + * + * @since 1.0.0 + * @author Discut + * @param text 输入的范围 字符串 + * @return 是否正确 + */ + private fun verificationField(text: String): Boolean { + return text.matches(Regex("\\d+(-\\d+)?(,\\d+(-\\d+)?)*")) + } + private fun selectExportFolder(exportPosition: Int) { val default = arrayListOf>() val path = ACache.get().getAsString(exportBookPathKey) @@ -259,6 +371,18 @@ class CacheActivity : VMBaseActivity() } } + private fun startExport(path: String, exportPosition: Int, size: Int, scope: String) { + if (exportPosition >= 0) { + adapter.getItem(exportPosition)?.let { book -> + when (AppConfig.exportType) { + 1 -> viewModel.exportEPUB(path, book, size, scope) + // 目前仅支持 epub + //else -> viewModel.export(path, book) + } + } + } + } + private fun startExport(path: String, exportPosition: Int) { if (exportPosition == -10) { if (adapter.getItems().isNotEmpty()) { diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CustomExportSectionDialog.kt b/app/src/main/java/io/legado/app/ui/book/cache/CustomExportSectionDialog.kt new file mode 100644 index 000000000..b26f54b43 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/book/cache/CustomExportSectionDialog.kt @@ -0,0 +1,16 @@ +package io.legado.app.ui.book.cache + +import android.os.Bundle +import android.view.View +import io.legado.app.R +import io.legado.app.base.BaseDialogFragment +import io.legado.app.databinding.DialogSelectSectionExportBinding +import io.legado.app.utils.viewbindingdelegate.viewBinding + +class CustomExportSectionDialog() : BaseDialogFragment(R.layout.dialog_select_section_export) { + + private val binding by viewBinding(DialogSelectSectionExportBinding::bind) + override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_select_section_export.xml b/app/src/main/res/layout/dialog_select_section_export.xml new file mode 100644 index 000000000..b22c69f9f --- /dev/null +++ b/app/src/main/res/layout/dialog_select_section_export.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/book_cache.xml b/app/src/main/res/menu/book_cache.xml index 8e06e17b4..a943d2669 100644 --- a/app/src/main/res/menu/book_cache.xml +++ b/app/src/main/res/menu/book_cache.xml @@ -31,6 +31,13 @@ android:checkable="true" app:showAsAction="never" /> + + + 删除所有 替换 替换净化 + 自定义导出章节 配置替换净化规则 暂无 启用 @@ -346,6 +347,7 @@ 关闭则只显示勾选源的发现 更新目录 TXT 目录规则 + 选择待导出章节 设置编码 倒序-顺序 排序 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cb06feb3e..18df6b071 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -30,6 +30,7 @@ Edit Delete Delete all + Custom export chapter Replace Replacement Configure replacement rules @@ -347,6 +348,7 @@ Display the selected origin\'s Discovery if closed Update chapters Txt Chapters Rule + Choose some chapters to be exported Text encoding Ascending/Descending order Sort