fix(CustomExport): 修复自定义导出进度条错误的问题

This commit is contained in:
Discut
2023-05-23 10:06:49 +08:00
parent 82f0d0af17
commit 4bda1c400e
5 changed files with 84 additions and 101 deletions
@@ -35,7 +35,6 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import androidx.core.widget.doOnTextChanged
/** /**
* cache/download 缓存界面 * cache/download 缓存界面
@@ -136,6 +135,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
CacheBook.stop(this@CacheActivity) CacheBook.stop(this@CacheActivity)
} }
} }
R.id.menu_export_all -> exportAll() R.id.menu_export_all -> exportAll()
R.id.menu_enable_replace -> AppConfig.exportUseReplace = !item.isChecked R.id.menu_enable_replace -> AppConfig.exportUseReplace = !item.isChecked
// 更改菜单状态[enableCustomExport] // 更改菜单状态[enableCustomExport]
@@ -147,6 +147,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
R.id.menu_export_folder -> { R.id.menu_export_folder -> {
selectExportFolder(-1) selectExportFolder(-1)
} }
R.id.menu_export_file_name -> alertExportFileName() R.id.menu_export_file_name -> alertExportFileName()
R.id.menu_export_type -> showExportTypeConfig() R.id.menu_export_type -> showExportTypeConfig()
R.id.menu_export_charset -> showCharsetConfig() R.id.menu_export_charset -> showCharsetConfig()
@@ -184,6 +185,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
2 -> booksDownload.sortedWith { o1, o2 -> 2 -> booksDownload.sortedWith { o1, o2 ->
o1.name.cnCompare(o2.name) o1.name.cnCompare(o2.name)
} }
3 -> booksDownload.sortedBy { it.order } 3 -> booksDownload.sortedBy { it.order }
else -> booksDownload.sortedByDescending { it.durChapterTime } else -> booksDownload.sortedByDescending { it.durChapterTime }
} }
@@ -247,8 +249,8 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
val path = ACache.get().getAsString(exportBookPathKey) val path = ACache.get().getAsString(exportBookPathKey)
if (path.isNullOrEmpty()) { if (path.isNullOrEmpty()) {
selectExportFolder(position) selectExportFolder(position)
} else if (AppConfig.enableCustomExport) {// 启用自定义导出 } else if (AppConfig.enableCustomExport && AppConfig.exportType == 1) {// 启用自定义导出 and 导出类型为Epub
configExportSection(path, position); configExportSection(path, position)
} else { } else {
startExport(path, position) startExport(path, position)
} }
@@ -272,76 +274,63 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
* @since 1.0.0 * @since 1.0.0
*/ */
private fun configExportSection(path: String, position: Int) { private fun configExportSection(path: String, position: Int) {
if (AppConfig.enableCustomExport) { val alertBinding = DialogSelectSectionExportBinding.inflate(layoutInflater)
val alertBinding = DialogSelectSectionExportBinding.inflate(layoutInflater) .apply {
.apply { cbAllExport.isChecked = true
cbSelectExport.isChecked = false
etEpubSize.isEnabled = false
etInputScope.isEnabled = false
tvAllExport.setOnClickListener {
cbAllExport.isChecked = true 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) { tvSelectExport.setOnClickListener {
customView { alertBinding.root } cbSelectExport.isChecked = true
positiveButton("确认") }
//okButton { cbSelectExport.onCheckedChangeListener = { _, isChecked ->
// alertBinding.apply { if (isChecked) {
// it.dismiss() etEpubSize.isEnabled = true
// if (cbAllExport.isChecked) { etInputScope.isEnabled = true
// // export all sections of the book. cbAllExport.isChecked = false
// startExport(path, position) }
// } else if (cbSelectExport.isChecked) { }
// cbAllExport.onCheckedChangeListener = { _, isChecked ->
// } if (isChecked) {
// } etEpubSize.isEnabled = false
//} etInputScope.isEnabled = false
cancelButton() cbSelectExport.isChecked = false
}
}
etInputScope.onFocusChangeListener =
View.OnFocusChangeListener { _, hasFocus ->
if (hasFocus) {
etInputScope.hint = "例如:1-5,8,10-18"
} else {
etInputScope.hint = ""
}
}
} }
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { val alertDialog = alert(titleResource = R.string.select_section_export) {
alertBinding.apply { customView { alertBinding.root }
val text = etInputScope.text positiveButton("确认")
if (!verificationField(text.toString())) { cancelButton()
etInputScope.error = "请输入正确的范围" }
} else { alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
etInputScope.error = null alertBinding.apply {
val toInt = etEpubSize.text.toString().toInt() if (cbAllExport.isChecked) {
startExport(path, position, toInt, text.toString()) startExport(path, position)
alertDialog.hide(); alertDialog.hide()
} return@apply
} }
val text = etInputScope.text
if (!verificationField(text.toString())) {
etInputScope.error = "请输入正确的范围"
return@apply
}
etInputScope.error = null
val toInt = etEpubSize.text.toString().toInt()
startExport(path, position, toInt, text.toString())
alertDialog.hide()
} }
@@ -376,7 +365,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
if (exportPosition >= 0) { if (exportPosition >= 0) {
adapter.getItem(exportPosition)?.let { book -> adapter.getItem(exportPosition)?.let { book ->
when (AppConfig.exportType) { when (AppConfig.exportType) {
1 -> viewModel.exportEPUB(path, book, size, scope) 1 -> viewModel.exportEPUBs(path, book, size, scope)
// 目前仅支持 epub // 目前仅支持 epub
//else -> viewModel.export(path, book) //else -> viewModel.export(path, book)
} }
@@ -268,8 +268,8 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
result.add(s.toInt() - 1) result.add(s.toInt() - 1)
continue continue
} }
val left = v[0].toInt(); val left = v[0].toInt()
val right = v[1].toInt(); val right = v[1].toInt()
if (left > right) if (left > right)
return IntArray(0) return IntArray(0)
for (i in left..right) for (i in left..right)
@@ -290,7 +290,7 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
* @author Discut * @author Discut
* @since 2023/5/22 * @since 2023/5/22
*/ */
fun exportEPUB(path: String, book: Book, size: Int = 1, scope: String) { fun exportEPUBs(path: String, book: Book, size: Int = 1, scope: String) {
if (exportProgress.contains(book.bookUrl)) return if (exportProgress.contains(book.bookUrl)) return
CustomExporter(this).let { CustomExporter(this).let {
it.scope = paresScope(scope) it.scope = paresScope(scope)
@@ -627,13 +627,23 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
//////end of EPUB //////end of EPUB
//////start of custom exporter
/** /**
* 自定义Exporter * 自定义Exporter
*
* @since 2023/5/23
*/ */
class CustomExporter(private val context: CacheViewModel) { class CustomExporter(private val context: CacheViewModel) {
var scope: IntArray = IntArray(0); var scope: IntArray = IntArray(0)
var size: Int = 1; var size: Int = 1
/**
* 导出Epub
*
* from [io.legado.app.ui.book.cache.CacheViewModel.exportEPUB]
* @param path 导出的路径
* @param book 书籍
*/
fun exportEPUB( fun exportEPUB(
path: String, path: String,
book: Book book: Book
@@ -653,7 +663,6 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
val doc = DocumentFile.fromTreeUri(context.context, uri) val doc = DocumentFile.fromTreeUri(context.context, uri)
?: throw NoStackTraceException("获取导出文档失败") ?: throw NoStackTraceException("获取导出文档失败")
book.totalChapterNum book.totalChapterNum
// TODO
exportEpub(doc, book) exportEpub(doc, book)
} else { } else {
context.exportEpub(File(path).createFolderIfNotExist(), book) context.exportEpub(File(path).createFolderIfNotExist(), book)
@@ -683,7 +692,7 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
epubList.forEachIndexed { index, epubBook -> epubList.forEachIndexed { index, epubBook ->
//设置正文 //设置正文
this.setEpubContent(contentModel, book, epubBook, index) this.setEpubContent(contentModel, book, epubBook, index)
save2Drive(book.name+index+".epub", epubBook, doc) save2Drive(book.name + index + ".epub", epubBook, doc)
} }
} }
@@ -703,17 +712,18 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
//正文 //正文
val useReplace = AppConfig.exportUseReplace && book.getUseReplaceRule() val useReplace = AppConfig.exportUseReplace && book.getUseReplaceRule()
val contentProcessor = ContentProcessor.get(book.name, book.origin) val contentProcessor = ContentProcessor.get(book.name, book.origin)
var chapterList: MutableList<BookChapter> = ArrayList(); var chapterList: MutableList<BookChapter> = ArrayList()
appDb.bookChapterDao.getChapterList(book.bookUrl).forEachIndexed { index, chapter -> appDb.bookChapterDao.getChapterList(book.bookUrl).forEachIndexed { index, chapter ->
if (scope.indexOf(index) >= 0) { if (scope.indexOf(index) >= 0) {
chapterList.add(chapter) chapterList.add(chapter)
} }
} }
val totalChapterNum = book.totalChapterNum / scope.size
chapterList = chapterList.subList(epubBookIndex * size, (epubBookIndex + 1) * size) chapterList = chapterList.subList(epubBookIndex * size, (epubBookIndex + 1) * size)
chapterList.forEachIndexed { index, chapter -> chapterList.forEachIndexed { index, chapter ->
coroutineContext.ensureActive() coroutineContext.ensureActive()
context.upAdapterLiveData.postValue(book.bookUrl) context.upAdapterLiveData.postValue(book.bookUrl)
context.exportProgress[book.bookUrl] = index context.exportProgress[book.bookUrl] = totalChapterNum * (epubBookIndex * size + index)
BookHelp.getContent(book, chapter).let { content -> BookHelp.getContent(book, chapter).let { content ->
var content1 = context.fixPic( var content1 = context.fixPic(
epubBook, epubBook,
@@ -758,7 +768,7 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
private fun createEpubs(doc: DocumentFile, book: Book): Pair<String, List<EpubBook>> { private fun createEpubs(doc: DocumentFile, book: Book): Pair<String, List<EpubBook>> {
val paresNumOfEpub = paresNumOfEpub(scope.size, size) val paresNumOfEpub = paresNumOfEpub(scope.size, size)
val result: MutableList<EpubBook> = ArrayList(paresNumOfEpub) val result: MutableList<EpubBook> = ArrayList(paresNumOfEpub)
var contentModel = ""; var contentModel = ""
for (i in 1..paresNumOfEpub) { for (i in 1..paresNumOfEpub) {
val filename = book.getExportFileName("epub") val filename = book.getExportFileName("epub")
DocumentUtils.delete(doc, filename) DocumentUtils.delete(doc, filename)
@@ -798,11 +808,11 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
*/ */
private fun paresNumOfEpub(total: Int, size: Int): Int { private fun paresNumOfEpub(total: Int, size: Int): Int {
val i = total % size val i = total % size
var result = total / size; var result = total / size
if (i > 0) { if (i > 0) {
result++; result++
} }
return result; return result
} }
} }
} }
@@ -1,16 +0,0 @@
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")
}
}
+1 -1
View File
@@ -31,7 +31,7 @@
<string name="delete_all">删除所有</string> <string name="delete_all">删除所有</string>
<string name="replace">替换</string> <string name="replace">替换</string>
<string name="replace_purify">替换净化</string> <string name="replace_purify">替换净化</string>
<string name="custom_export_section">自定义导出章节</string> <string name="custom_export_section">自定义Epub导出章节</string>
<string name="replace_purify_desc">配置替换净化规则</string> <string name="replace_purify_desc">配置替换净化规则</string>
<string name="not_available">暂无</string> <string name="not_available">暂无</string>
<string name="enable">启用</string> <string name="enable">启用</string>
+1 -1
View File
@@ -30,7 +30,7 @@
<string name="edit">Edit</string> <string name="edit">Edit</string>
<string name="delete">Delete</string> <string name="delete">Delete</string>
<string name="delete_all">Delete all</string> <string name="delete_all">Delete all</string>
<string name="custom_export_section">Custom export chapter</string> <string name="custom_export_section">Custom export chapter of epub</string>
<string name="replace">Replace</string> <string name="replace">Replace</string>
<string name="replace_purify">Replacement</string> <string name="replace_purify">Replacement</string>
<string name="replace_purify_desc">Configure replacement rules</string> <string name="replace_purify_desc">Configure replacement rules</string>