pull/1630/head
kunfei 3 years ago
parent 55e8af89af
commit 400db881ad
  1. 34
      app/src/main/java/io/legado/app/help/BookHelp.kt
  2. 14
      app/src/main/java/io/legado/app/model/CacheBook.kt
  3. 2
      app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt
  4. 4
      app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt
  5. 2
      app/src/main/java/io/legado/app/ui/book/read/BaseReadBookActivity.kt
  6. 103
      app/src/main/java/io/legado/app/ui/book/read/ContentEditDialog.kt
  7. 45
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  8. 25
      app/src/main/res/layout/dialog_content_edit.xml
  9. 4
      app/src/main/res/menu/book_read.xml
  10. 18
      app/src/main/res/menu/content_edit.xml
  11. 1
      app/src/main/res/values-es-rES/strings.xml
  12. 1
      app/src/main/res/values-ja-rJP/strings.xml
  13. 1
      app/src/main/res/values-pt-rBR/strings.xml
  14. 1
      app/src/main/res/values-zh-rHK/strings.xml
  15. 1
      app/src/main/res/values-zh-rTW/strings.xml
  16. 1
      app/src/main/res/values-zh/strings.xml
  17. 1
      app/src/main/res/values/strings.xml

@ -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()

@ -54,12 +54,14 @@ object CacheBook {
return cacheBook
}
fun start(context: Context, bookUrl: String, start: Int, end: Int) {
context.startService<CacheBookService> {
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<CacheBookService> {
action = IntentAction.start
putExtra("bookUrl", book.bookUrl)
putExtra("start", start)
putExtra("end", end)
}
}
}

@ -113,7 +113,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
adapter.getItems().forEach { book ->
CacheBook.start(
this@CacheActivity,
book.bookUrl,
book,
book.durChapterIndex,
book.totalChapterNum
)

@ -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)
}
}
}

@ -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()

@ -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<ContentEditViewModel>()
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 ?: "")
}
}
}
}

@ -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>("searchResult$key")
val searchResultList = IntentData.get<List<SearchResult>>("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>("searchResult$key")
val searchResultList = IntentData.get<List<SearchResult>>("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

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/background"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="?attr/actionBarStyle"
app:title="code edit"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:titleTextAppearance="@style/ToolbarTitle" />
<io.legado.app.lib.theme.view.ThemeEditText
android:id="@+id/content_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="12dp"
android:textIsSelectable="true" />
</LinearLayout>

@ -71,8 +71,8 @@
app:showAsAction="never" />
<item
android:id="@+id/menu_copy_text"
android:title="@string/copy_text"
android:id="@+id/menu_edit_content"
android:title="@string/edit_content"
app:showAsAction="never" />
<item

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<menu 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"
tools:ignore="AlwaysShowAction">
<item
android:id="@+id/menu_save"
android:icon="@drawable/ic_save"
android:title="@string/action_save"
app:showAsAction="always" />
<item
android:id="@+id/menu_reset"
android:title="@string/reset"
app:showAsAction="never" />
</menu>

@ -938,5 +938,6 @@
<string name="menu_refresh_dur">刷新当前章节</string>
<string name="menu_refresh_after">刷新之后章节</string>
<string name="menu_refresh_all">刷新全部章节</string>
<string name="edit_content">编辑内容</string>
<!-- string end -->
</resources>

@ -941,5 +941,6 @@
<string name="menu_refresh_dur">刷新当前章节</string>
<string name="menu_refresh_after">刷新之后章节</string>
<string name="menu_refresh_all">刷新全部章节</string>
<string name="edit_content">编辑内容</string>
<!-- string end -->
</resources>

@ -941,5 +941,6 @@
<string name="menu_refresh_dur">刷新当前章节</string>
<string name="menu_refresh_after">刷新之后章节</string>
<string name="menu_refresh_all">刷新全部章节</string>
<string name="edit_content">编辑内容</string>
<!-- string end -->
</resources>

@ -938,5 +938,6 @@
<string name="menu_refresh_dur">刷新当前章节</string>
<string name="menu_refresh_after">刷新之后章节</string>
<string name="menu_refresh_all">刷新全部章节</string>
<string name="edit_content">编辑内容</string>
<!-- string end -->
</resources>

@ -940,5 +940,6 @@
<string name="menu_refresh_dur">刷新当前章节</string>
<string name="menu_refresh_after">刷新之后章节</string>
<string name="menu_refresh_all">刷新全部章节</string>
<string name="edit_content">编辑内容</string>
<!-- string end -->
</resources>

@ -940,5 +940,6 @@
<string name="menu_refresh_dur">刷新当前章节</string>
<string name="menu_refresh_after">刷新之后章节</string>
<string name="menu_refresh_all">刷新全部章节</string>
<string name="edit_content">编辑内容</string>
<!-- string end -->
</resources>

@ -941,5 +941,6 @@
<string name="menu_refresh_dur">刷新当前章节</string>
<string name="menu_refresh_after">刷新之后章节</string>
<string name="menu_refresh_all">刷新全部章节</string>
<string name="edit_content">编辑内容</string>
<!-- string end -->
</resources>

Loading…
Cancel
Save