feat(Cache/Export): ✨ 新增 开启自定义导出 菜单与对话框
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<ActivityCacheBookBinding, CacheViewModel>(),
|
||||
CacheAdapter.CallBack {
|
||||
|
||||
@@ -88,6 +95,8 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
|
||||
|
||||
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<ActivityCacheBookBinding, CacheViewModel>()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜单按下回调
|
||||
*/
|
||||
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.menu_download -> {
|
||||
@@ -126,6 +138,8 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
|
||||
}
|
||||
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<ActivityCacheBookBinding, CacheViewModel>()
|
||||
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<ActivityCacheBookBinding, CacheViewModel>()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置自定义导出对话框
|
||||
*
|
||||
* @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<SelectItem<Int>>()
|
||||
val path = ACache.get().getAsString(exportBookPathKey)
|
||||
@@ -259,6 +371,18 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
|
||||
}
|
||||
}
|
||||
|
||||
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()) {
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- <androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:overScrollMode="ifContentScrolls"
|
||||
android:paddingTop="6dp">-->
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<io.legado.app.ui.widget.checkbox.SmoothCheckBox
|
||||
android:id="@+id/cb_all_export"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginEnd="16dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_all_export"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="全部导出"
|
||||
android:textSize="18sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- <com.google.android.material.divider.MaterialDivider-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content" />-->
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<io.legado.app.ui.widget.checkbox.SmoothCheckBox
|
||||
android:id="@+id/cb_select_export"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginEnd="16dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_select_export"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="选择导出"
|
||||
android:textSize="18sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<io.legado.app.ui.widget.text.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:hint="每个文件包含章节大小">
|
||||
|
||||
<io.legado.app.lib.theme.view.ThemeEditText
|
||||
android:id="@+id/et_epub_size"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="number"
|
||||
android:text="1"
|
||||
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
|
||||
|
||||
</io.legado.app.ui.widget.text.TextInputLayout>
|
||||
|
||||
<io.legado.app.ui.widget.text.TextInputLayout
|
||||
android:id="@+id/ly_et_input_scope"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="输出章节序号">
|
||||
|
||||
<io.legado.app.lib.theme.view.ThemeEditText
|
||||
android:id="@+id/et_input_scope"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
|
||||
|
||||
</io.legado.app.ui.widget.text.TextInputLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- </androidx.core.widget.NestedScrollView>-->
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -31,6 +31,13 @@
|
||||
android:checkable="true"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<!--自定义导出章节 选择菜单-->
|
||||
<item
|
||||
android:id="@+id/menu_enable_custom_export"
|
||||
android:title="@string/custom_export_section"
|
||||
android:checkable="true"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_export_web_dav"
|
||||
android:title="@string/export_to_web_dav"
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<string name="delete_all">删除所有</string>
|
||||
<string name="replace">替换</string>
|
||||
<string name="replace_purify">替换净化</string>
|
||||
<string name="custom_export_section">自定义导出章节</string>
|
||||
<string name="replace_purify_desc">配置替换净化规则</string>
|
||||
<string name="not_available">暂无</string>
|
||||
<string name="enable">启用</string>
|
||||
@@ -346,6 +347,7 @@
|
||||
<string name="ps_show_all_find">关闭则只显示勾选源的发现</string>
|
||||
<string name="update_toc">更新目录</string>
|
||||
<string name="txt_toc_rule">TXT 目录规则</string>
|
||||
<string name="select_section_export">选择待导出章节</string>
|
||||
<string name="set_charset">设置编码</string>
|
||||
<string name="swap_sort">倒序-顺序</string>
|
||||
<string name="sort">排序</string>
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
<string name="edit">Edit</string>
|
||||
<string name="delete">Delete</string>
|
||||
<string name="delete_all">Delete all</string>
|
||||
<string name="custom_export_section">Custom export chapter</string>
|
||||
<string name="replace">Replace</string>
|
||||
<string name="replace_purify">Replacement</string>
|
||||
<string name="replace_purify_desc">Configure replacement rules</string>
|
||||
@@ -347,6 +348,7 @@
|
||||
<string name="ps_show_all_find">Display the selected origin\'s Discovery if closed</string>
|
||||
<string name="update_toc">Update chapters</string>
|
||||
<string name="txt_toc_rule">Txt Chapters Rule</string>
|
||||
<string name="select_section_export">Choose some chapters to be exported</string>
|
||||
<string name="set_charset">Text encoding</string>
|
||||
<string name="swap_sort">Ascending/Descending order</string>
|
||||
<string name="sort">Sort</string>
|
||||
|
||||
Reference in New Issue
Block a user