From 400db881ad1831b8b4b5a23ed715bce85bb86f57 Mon Sep 17 00:00:00 2001 From: kunfei Date: Thu, 17 Feb 2022 21:23:07 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/help/BookHelp.kt | 34 +++--- .../java/io/legado/app/model/CacheBook.kt | 14 ++- .../legado/app/ui/book/cache/CacheActivity.kt | 2 +- .../legado/app/ui/book/cache/CacheAdapter.kt | 4 +- .../app/ui/book/read/BaseReadBookActivity.kt | 2 +- .../app/ui/book/read/ContentEditDialog.kt | 103 ++++++++++++++++++ .../app/ui/book/read/ReadBookActivity.kt | 45 ++++---- .../main/res/layout/dialog_content_edit.xml | 25 +++++ app/src/main/res/menu/book_read.xml | 4 +- app/src/main/res/menu/content_edit.xml | 18 +++ app/src/main/res/values-es-rES/strings.xml | 1 + app/src/main/res/values-ja-rJP/strings.xml | 1 + app/src/main/res/values-pt-rBR/strings.xml | 1 + app/src/main/res/values-zh-rHK/strings.xml | 1 + app/src/main/res/values-zh-rTW/strings.xml | 1 + app/src/main/res/values-zh/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 17 files changed, 206 insertions(+), 52 deletions(-) create mode 100644 app/src/main/java/io/legado/app/ui/book/read/ContentEditDialog.kt create mode 100644 app/src/main/res/layout/dialog_content_edit.xml create mode 100644 app/src/main/res/menu/content_edit.xml diff --git a/app/src/main/java/io/legado/app/help/BookHelp.kt b/app/src/main/java/io/legado/app/help/BookHelp.kt index fb9357f1f..a033cd06b 100644 --- a/app/src/main/java/io/legado/app/help/BookHelp.kt +++ b/app/src/main/java/io/legado/app/help/BookHelp.kt @@ -72,7 +72,7 @@ object BookHelp { postEvent(EventBus.SAVE_CONTENT, bookChapter) } - private fun saveText( + fun saveText( book: Book, bookChapter: BookChapter, content: String @@ -208,23 +208,20 @@ object BookHelp { * 读取章节内容 */ fun getContent(book: Book, bookChapter: BookChapter): String? { - if (book.isLocalTxt() || book.isUmd()) { - return LocalBook.getContent(book, bookChapter) - } else if (book.isEpub() && !hasContent(book, bookChapter)) { + val file = downloadDir.getFile( + cacheFolderName, + book.getFolderName(), + bookChapter.getFileName() + ) + if (file.exists()) { + return file.readText() + } + if (book.isLocalBook()) { val string = LocalBook.getContent(book, bookChapter) - string?.let { - saveText(book, bookChapter, it) + if (string != null && book.isEpub()) { + saveText(book, bookChapter, string) } return string - } else { - val file = downloadDir.getFile( - cacheFolderName, - book.getFolderName(), - bookChapter.getFileName() - ) - if (file.exists()) { - return file.readText() - } } return null } @@ -366,9 +363,9 @@ object BookHelp { val chapterName1 = StringUtils.fullToHalf(chapterName).replace(regexA, "") return StringUtils.stringToInt( ( - chapterNamePattern1.matcher(chapterName1).takeIf { it.find() } - ?: chapterNamePattern2.matcher(chapterName1).takeIf { it.find() } - )?.group(1) + chapterNamePattern1.matcher(chapterName1).takeIf { it.find() } + ?: chapterNamePattern2.matcher(chapterName1).takeIf { it.find() } + )?.group(1) ?: "-1" ) } @@ -380,6 +377,7 @@ object BookHelp { return@lazy "[^\\w\\u4E00-\\u9FEF〇\\u3400-\\u4DBF\\u20000-\\u2A6DF\\u2A700-\\u2EBEF]".toRegex() } + @Suppress("RegExpUnnecessaryNonCapturingGroup") private val regexB by lazy { //章节序号,排除处于结尾的状况,避免将章节名替换为空字串 return@lazy "^.*?第(?:[\\d零〇一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]+)[章节篇回集话](?!$)|^(?:[\\d零〇一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]+[,:、])*(?:[\\d零〇一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]+)(?:[,:、](?!$)|\\.(?=[^\\d]))".toRegex() diff --git a/app/src/main/java/io/legado/app/model/CacheBook.kt b/app/src/main/java/io/legado/app/model/CacheBook.kt index 2174dbfd3..fbbc58a81 100644 --- a/app/src/main/java/io/legado/app/model/CacheBook.kt +++ b/app/src/main/java/io/legado/app/model/CacheBook.kt @@ -54,12 +54,14 @@ object CacheBook { return cacheBook } - fun start(context: Context, bookUrl: String, start: Int, end: Int) { - context.startService { - action = IntentAction.start - putExtra("bookUrl", bookUrl) - putExtra("start", start) - putExtra("end", end) + fun start(context: Context, book: Book, start: Int, end: Int) { + if (!book.isLocalBook()) { + context.startService { + action = IntentAction.start + putExtra("bookUrl", book.bookUrl) + putExtra("start", start) + putExtra("end", end) + } } } 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 fea90d039..c6d3ae03d 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 @@ -113,7 +113,7 @@ class CacheActivity : VMBaseActivity() adapter.getItems().forEach { book -> CacheBook.start( this@CacheActivity, - book.bookUrl, + book, book.durChapterIndex, book.totalChapterNum ) diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt b/app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt index bf8ae7001..4a4e601c4 100644 --- a/app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt @@ -70,10 +70,10 @@ class CacheAdapter(context: Context, private val callBack: CallBack) : if (it.isRun()) { CacheBook.remove(context, book.bookUrl) } else { - CacheBook.start(context, book.bookUrl, 0, book.totalChapterNum) + CacheBook.start(context, book, 0, book.totalChapterNum) } } ?: let { - CacheBook.start(context, book.bookUrl, 0, book.totalChapterNum) + CacheBook.start(context, book, 0, book.totalChapterNum) } } } diff --git a/app/src/main/java/io/legado/app/ui/book/read/BaseReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/BaseReadBookActivity.kt index b6037d383..b49483a59 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/BaseReadBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/BaseReadBookActivity.kt @@ -231,7 +231,7 @@ abstract class BaseReadBookActivity : alertBinding.run { val start = editStart.text?.toString()?.toInt() ?: 0 val end = editEnd.text?.toString()?.toInt() ?: book.totalChapterNum - CacheBook.start(this@BaseReadBookActivity, book.bookUrl, start - 1, end - 1) + CacheBook.start(this@BaseReadBookActivity, book, start - 1, end - 1) } } noButton() diff --git a/app/src/main/java/io/legado/app/ui/book/read/ContentEditDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/ContentEditDialog.kt new file mode 100644 index 000000000..13077fa02 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/book/read/ContentEditDialog.kt @@ -0,0 +1,103 @@ +package io.legado.app.ui.book.read + +import android.app.Application +import android.os.Bundle +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.viewModels +import io.legado.app.R +import io.legado.app.base.BaseDialogFragment +import io.legado.app.base.BaseViewModel +import io.legado.app.data.appDb +import io.legado.app.databinding.DialogContentEditBinding +import io.legado.app.help.BookHelp +import io.legado.app.help.ContentProcessor +import io.legado.app.lib.theme.primaryColor +import io.legado.app.model.ReadBook +import io.legado.app.model.webBook.WebBook +import io.legado.app.utils.applyTint +import io.legado.app.utils.setLayout +import io.legado.app.utils.viewbindingdelegate.viewBinding +import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * 内容编辑 + */ +class ContentEditDialog : BaseDialogFragment(R.layout.dialog_content_edit) { + + val binding by viewBinding(DialogContentEditBinding::bind) + val viewModel by viewModels() + + override fun onStart() { + super.onStart() + setLayout(ViewGroup.LayoutParams.MATCH_PARENT, 0.9f) + } + + override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { + binding.toolBar.setBackgroundColor(primaryColor) + binding.toolBar.title = ReadBook.curTextChapter?.title + initMenu() + viewModel.initContent { + binding.contentView.setText(it) + } + } + + private fun initMenu() { + binding.toolBar.inflateMenu(R.menu.content_edit) + binding.toolBar.menu.applyTint(requireContext()) + binding.toolBar.setOnMenuItemClickListener { + when (it.itemId) { + R.id.menu_save -> launch { + binding.contentView.text?.toString()?.let { content -> + withContext(IO) { + val book = ReadBook.book ?: return@withContext + val chapter = appDb.bookChapterDao + .getChapter(book.bookUrl, ReadBook.durChapterIndex) + ?: return@withContext + BookHelp.saveText(book, chapter, content) + } + } + ReadBook.loadContent(ReadBook.durChapterIndex, resetPageOffset = false) + dismiss() + } + R.id.menu_reset -> viewModel.initContent(true) { content -> + binding.contentView.setText(content) + } + } + return@setOnMenuItemClickListener true + } + } + + class ContentEditViewModel(application: Application) : BaseViewModel(application) { + + var content: String? = null + + fun initContent(reset: Boolean = false, success: (String) -> Unit) { + execute { + val book = ReadBook.book ?: return@execute null + val chapter = appDb.bookChapterDao + .getChapter(book.bookUrl, ReadBook.durChapterIndex) + ?: return@execute null + if (reset) { + content = null + BookHelp.delContent(book, chapter) + if (!book.isLocalBook()) ReadBook.bookSource?.let { bookSource -> + WebBook.getContentAwait(this, bookSource, book, chapter) + } + } + return@execute content ?: let { + val contentProcessor = ContentProcessor.get(book.name, book.origin) + val content = BookHelp.getContent(book, chapter) ?: return@let null + contentProcessor.getContent(book, chapter, content, includeTitle = false) + .joinToString("\n") + } + }.onSuccess { + success.invoke(it ?: "") + } + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt index 14ef665dc..893987264 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt @@ -96,24 +96,25 @@ class ReadBookActivity : BaseReadBookActivity(), viewModel.replaceRuleChanged() } } - private val searchContentActivity = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { - it ?: return@registerForActivityResult - it.data?.let { data -> - val key = data.getLongExtra("key", System.currentTimeMillis()) - val searchResult = IntentData.get("searchResult$key") - val searchResultList = IntentData.get>("searchResultList$key") - if (searchResult != null && searchResultList != null) { - viewModel.searchContentQuery = searchResult.query - binding.searchMenu.upSearchResultList(searchResultList) - isShowingSearchResult = true - binding.searchMenu.updateSearchResultIndex(searchResultList.indexOf(searchResult)) - binding.searchMenu.selectedSearchResult?.let { currentResult -> - skipToSearch(currentResult) - showActionMenu() + private val searchContentActivity = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + it ?: return@registerForActivityResult + it.data?.let { data -> + val key = data.getLongExtra("key", System.currentTimeMillis()) + val searchResult = IntentData.get("searchResult$key") + val searchResultList = IntentData.get>("searchResultList$key") + if (searchResult != null && searchResultList != null) { + viewModel.searchContentQuery = searchResult.query + binding.searchMenu.upSearchResultList(searchResultList) + isShowingSearchResult = true + binding.searchMenu.updateSearchResultIndex(searchResultList.indexOf(searchResult)) + binding.searchMenu.selectedSearchResult?.let { currentResult -> + skipToSearch(currentResult) + showActionMenu() + } } } } - } private var menu: Menu? = null val textActionMenu: TextActionMenu by lazy { TextActionMenu(this, this) @@ -288,9 +289,7 @@ class ReadBookActivity : BaseReadBookActivity(), showDialogFragment(BookmarkDialog(bookmark)) } } - R.id.menu_copy_text -> showDialogFragment( - TextDialog(ReadBook.curTextChapter?.getContent()) - ) + R.id.menu_edit_content -> showDialogFragment(ContentEditDialog()) R.id.menu_update_toc -> ReadBook.book?.let { if (it.isEpub()) { BookHelp.clearCache(it) @@ -945,7 +944,7 @@ class ReadBookActivity : BaseReadBookActivity(), private fun skipToSearch(searchResult: SearchResult) { val previousResult = binding.searchMenu.previousSearchResult - fun jumpToPosition(){ + fun jumpToPosition() { ReadBook.curTextChapter?.let { binding.searchMenu.updateSearchInfo() val positions = viewModel.searchResultPositions(it, searchResult) @@ -954,10 +953,12 @@ class ReadBookActivity : BaseReadBookActivity(), isSelectingSearchResult = true binding.readView.curPage.selectStartMoveIndex(0, positions[1], positions[2]) when (positions[3]) { - 0 -> binding.readView.curPage.selectEndMoveIndex( - 0, positions[1], positions[2] + viewModel.searchContentQuery.length - 1 + 0 -> binding.readView.curPage.selectEndMoveIndex( + 0, + positions[1], + positions[2] + viewModel.searchContentQuery.length - 1 ) - 1 -> binding.readView.curPage.selectEndMoveIndex( + 1 -> binding.readView.curPage.selectEndMoveIndex( 0, positions[1] + 1, positions[4] ) //consider change page, jump to scroll position diff --git a/app/src/main/res/layout/dialog_content_edit.xml b/app/src/main/res/layout/dialog_content_edit.xml new file mode 100644 index 000000000..2f1d21bd5 --- /dev/null +++ b/app/src/main/res/layout/dialog_content_edit.xml @@ -0,0 +1,25 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/book_read.xml b/app/src/main/res/menu/book_read.xml index b8372597f..c6b87b55e 100644 --- a/app/src/main/res/menu/book_read.xml +++ b/app/src/main/res/menu/book_read.xml @@ -71,8 +71,8 @@ app:showAsAction="never" /> + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index 43765a33a..eea5355d9 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -938,5 +938,6 @@ 刷新当前章节 刷新之后章节 刷新全部章节 + 编辑内容 diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index 9554f5dcc..dc7c74989 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -941,5 +941,6 @@ 刷新当前章节 刷新之后章节 刷新全部章节 + 编辑内容 diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 234a5b8e9..bbab00ab5 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -941,5 +941,6 @@ 刷新当前章节 刷新之后章节 刷新全部章节 + 编辑内容 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index c59cfa3a2..38bb2f7e4 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -938,5 +938,6 @@ 刷新当前章节 刷新之后章节 刷新全部章节 + 编辑内容 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 85e794583..575685f14 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -940,5 +940,6 @@ 刷新当前章节 刷新之后章节 刷新全部章节 + 编辑内容 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 56b019775..e9c3b2ce6 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -940,5 +940,6 @@ 刷新当前章节 刷新之后章节 刷新全部章节 + 编辑内容 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 692bd282e..eeaa3236e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -941,5 +941,6 @@ 刷新当前章节 刷新之后章节 刷新全部章节 + 编辑内容