diff --git a/app/src/main/assets/web/assets/css/main.css b/app/src/main/assets/web/assets/css/main.css index 3f700d6d4..0d9b00e17 100644 --- a/app/src/main/assets/web/assets/css/main.css +++ b/app/src/main/assets/web/assets/css/main.css @@ -29,7 +29,10 @@ footer, header, hgroup, menu, nav, section { body { line-height: 1; background: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)),url("../../images/bg.jpg") no-repeat center center fixed; - background-size: 100%; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; } ol, ul { diff --git a/app/src/main/java/io/legado/app/data/entities/Book.kt b/app/src/main/java/io/legado/app/data/entities/Book.kt index c19e44c1f..0b37807d6 100644 --- a/app/src/main/java/io/legado/app/data/entities/Book.kt +++ b/app/src/main/java/io/legado/app/data/entities/Book.kt @@ -245,6 +245,14 @@ data class Book( return config.delTag and tag == tag } + fun addDelTag(tag: Long) { + config.delTag = config.delTag and tag + } + + fun removeDelTag(tag: Long) { + config.delTag = config.delTag and tag.inv() + } + fun getFolderName(): String { folderName?.let { return it diff --git a/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt b/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt index 449893ac9..874056c02 100644 --- a/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt +++ b/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt @@ -67,6 +67,10 @@ class EpubFile(var book: Book) { override fun upBookInfo(book: Book) { return getEFile(book).upBookInfo() } + + fun clear() { + eFile = null + } } private var mCharset: Charset = Charset.defaultCharset() @@ -182,11 +186,11 @@ class EpubFile(var book: Book) { } it.attr("src", absSrc) } - var html = elements.outerHtml() val tag = Book.rubyTag if (book.getDelTag(tag)) { - html = html.replace("\\s?([\\u4e00-\\u9fa5])\\s?.*?".toRegex(), "$1") + elements.select("rp, rt").remove() } + val html = elements.outerHtml() return HtmlFormatter.formatKeepImg(html) } @@ -242,12 +246,7 @@ class EpubFile(var book: Book) { val tag = Book.hTag if (book.getDelTag(tag)) { bodyElement.run { - getElementsByTag("h1").remove() - getElementsByTag("h2").remove() - getElementsByTag("h3").remove() - getElementsByTag("h4").remove() - getElementsByTag("h5").remove() - getElementsByTag("h6").remove() + select("h1, h2, h3, h4, h5, h6").remove() //getElementsMatchingOwnText(chapter.title)?.remove() } } diff --git a/app/src/main/java/io/legado/app/model/localBook/TextFile.kt b/app/src/main/java/io/legado/app/model/localBook/TextFile.kt index 8e4c2d748..f45a4daf9 100644 --- a/app/src/main/java/io/legado/app/model/localBook/TextFile.kt +++ b/app/src/main/java/io/legado/app/model/localBook/TextFile.kt @@ -21,9 +21,9 @@ class TextFile(private val book: Book) { companion object { private val padRegex = "^[\\n\\s]+".toRegex() private const val bufferSize = 8 * 1024 * 1024 + private var bufferStart = -1 + private var bufferEnd = -1 var txtBuffer: ByteArray? = null - var bufferStart = -1 - var bufferEnd = -1 var bookUrl = "" @Throws(FileNotFoundException::class) 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 f27424ea0..cb067333f 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 @@ -40,6 +40,7 @@ import io.legado.app.lib.theme.accentColor import io.legado.app.model.ReadAloud import io.legado.app.model.ReadBook import io.legado.app.model.analyzeRule.AnalyzeRule +import io.legado.app.model.localBook.EpubFile import io.legado.app.receiver.TimeBatteryReceiver import io.legado.app.service.BaseReadAloudService import io.legado.app.ui.about.AppLogDialog @@ -332,6 +333,7 @@ class ReadBookActivity : BaseReadBookActivity(), R.id.menu_group_on_line -> item.isVisible = onLine R.id.menu_group_local -> item.isVisible = !onLine R.id.menu_group_text -> item.isVisible = book.isLocalTxt + R.id.menu_group_epub -> item.isVisible = book.isEpub else -> when (item.itemId) { R.id.menu_enable_replace -> item.isChecked = book.getUseReplaceRule() R.id.menu_re_segment -> item.isChecked = book.getReSegment() @@ -341,6 +343,8 @@ class ReadBookActivity : BaseReadBookActivity(), } R.id.menu_reverse_content -> item.isVisible = onLine + R.id.menu_del_ruby_tag -> item.isChecked = book.getDelTag(Book.rubyTag) + R.id.menu_del_h_tag -> item.isChecked = book.getDelTag(Book.hTag) } } } @@ -405,9 +409,7 @@ class ReadBookActivity : BaseReadBookActivity(), upContent() } else { ReadBook.book?.let { - ReadBook.clearTextChapter() - binding.readView.upContent() - viewModel.refreshContentAll(it) + refreshContentDur(it) } } } @@ -418,6 +420,7 @@ class ReadBookActivity : BaseReadBookActivity(), R.id.menu_update_toc -> ReadBook.book?.let { if (it.isEpub) { BookHelp.clearCache(it) + EpubFile.clear() } loadChapterList(it) } @@ -425,16 +428,36 @@ class ReadBookActivity : BaseReadBookActivity(), R.id.menu_enable_replace -> changeReplaceRuleState() R.id.menu_re_segment -> ReadBook.book?.let { it.setReSegment(!it.getReSegment()) - menu?.findItem(R.id.menu_re_segment)?.isChecked = it.getReSegment() + item.isChecked = it.getReSegment() ReadBook.loadContent(false) } R.id.menu_enable_review -> { AppConfig.enableReview = !AppConfig.enableReview - menu?.findItem(R.id.menu_enable_review)?.isChecked = AppConfig.enableReview + item.isChecked = AppConfig.enableReview ReadBook.loadContent(false) } + R.id.menu_del_ruby_tag -> ReadBook.book?.let { + item.isChecked = !item.isChecked + if (item.isChecked) { + it.addDelTag(Book.rubyTag) + } else { + it.removeDelTag(Book.rubyTag) + } + refreshContentDur(it) + } + + R.id.menu_del_h_tag -> ReadBook.book?.let { + item.isChecked = !item.isChecked + if (item.isChecked) { + it.addDelTag(Book.hTag) + } else { + it.removeDelTag(Book.hTag) + } + refreshContentDur(it) + } + R.id.menu_page_anim -> showPageAnimConfig { binding.readView.upPageAnim() ReadBook.loadContent(false) @@ -491,6 +514,12 @@ class ReadBookActivity : BaseReadBookActivity(), return super.onCompatOptionsItemSelected(item) } + private fun refreshContentDur(book: Book) { + ReadBook.curTextChapter = null + binding.readView.upContent() + viewModel.refreshContentDur(book) + } + override fun onMenuItemClick(item: MenuItem): Boolean { return onCompatOptionsItemSelected(item) } diff --git a/app/src/main/res/menu/book_read.xml b/app/src/main/res/menu/book_read.xml index 79356f2d0..8384f4443 100644 --- a/app/src/main/res/menu/book_read.xml +++ b/app/src/main/res/menu/book_read.xml @@ -79,8 +79,8 @@ + + + + + + + + 保留启用状态 点击预览图片 反向竖屏 + 删除ruby标签 + 删除h标签 diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index 30091bb2e..913c490fe 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -1137,4 +1137,6 @@ 保留启用状态 点击预览图片 反向竖屏 + 删除ruby标签 + 删除h标签 diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 5f5f9a1b2..46f3db7ac 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -1137,4 +1137,6 @@ 保留启用状态 点击预览图片 反向竖屏 + 删除ruby标签 + 删除h标签 diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 35c8c1e20..ea6f5b573 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -1133,4 +1133,6 @@ Còn 保留启用状态 点击预览图片 反向竖屏 + 删除ruby标签 + 删除h标签 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index e30e85298..9c81c94c6 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -1134,4 +1134,6 @@ 保留启用状态 点击预览图片 反向竖屏 + 删除ruby标签 + 删除h标签 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 95a5953f9..8a586ae32 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -1136,4 +1136,6 @@ 保留启用状态 点击预览图片 反向竖屏 + 删除ruby标签 + 删除h标签 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index f804c6e60..4ea9e3034 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -1136,4 +1136,6 @@ 保留启用状态 点击预览图片 反向竖屏 + 删除ruby标签 + 删除h标签 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 97b7a4175..efbd6c021 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1137,4 +1137,6 @@ Click to preview image Default HomePage Portrait Reversed + Delete ruby tag + Delete h tag diff --git a/modules/web/src/components/PopCatalog.vue b/modules/web/src/components/PopCatalog.vue index 078bcaa97..2523041e4 100644 --- a/modules/web/src/components/PopCatalog.vue +++ b/modules/web/src/components/PopCatalog.vue @@ -69,6 +69,7 @@ const gotoChapter = (note) => { currentChapterIndex.value = chapterIndex; store.setPopCataVisible(false); store.setContentLoading(true); + store.saveBookProgress(); emit("getContent", chapterIndex); }; diff --git a/modules/web/src/views/BookChapter.vue b/modules/web/src/views/BookChapter.vue index 23cf7b632..5cdd48f9c 100644 --- a/modules/web/src/views/BookChapter.vue +++ b/modules/web/src/views/BookChapter.vue @@ -111,6 +111,7 @@ import jump from "@/plugins/jump"; import settings from "@/config/themeConfig"; import API from "@api"; import { useLoading } from "@/hooks/loading"; +import { useThrottleFn } from "@vueuse/shared"; const content = ref(); // loading spinner @@ -299,8 +300,13 @@ const toChapterPos = (pos) => { chapterRef.value[0].scrollToReadedLength(pos); }); }; + +// 60秒保存一次进度 +const saveBookProgressThrottle = useThrottleFn(() => store.saveBookProgress(), 60000) + const onReadedLengthChange = (index, pos) => { saveReadingBookProgressToBrowser(index, pos); + saveBookProgressThrottle(); }; // 文档标题 @@ -354,6 +360,7 @@ const toNextChapter = () => { type: "info", }); getContent(index); + store.saveBookProgress(); } else { ElMessage({ message: "本章是最后一章", @@ -370,6 +377,7 @@ const toPreChapter = () => { type: "info", }); getContent(index); + store.saveBookProgress(); } else { ElMessage({ message: "本章是第一章", @@ -392,6 +400,7 @@ const loadMore = () => { let index = chapterData.value.slice(-1)[0].index; if (catalog.value.length - 1 > index) { getContent(index + 1, false); + store.saveBookProgress(); // 保存的是上一章的进度,不是预载的本章进度 } }; // IntersectionObserver回调 底部加载