This commit is contained in:
Horis
2025-04-27 18:20:42 +08:00
parent 9081abf58f
commit 4b57f89a87
5 changed files with 47 additions and 31 deletions
+3
View File
@@ -100,6 +100,9 @@ cn.hutool.core.util.**{*;}
*** mNavButtonView; *** mNavButtonView;
} }
# FileDocExtensions.kt TreeDocumentFileConstructor
-keep class androidx.documentfile.provider.TreeDocumentFile
# JsoupXpath # JsoupXpath
-keep,allowobfuscation class * implements org.seimicrawler.xpath.core.AxisSelector{*;} -keep,allowobfuscation class * implements org.seimicrawler.xpath.core.AxisSelector{*;}
-keep,allowobfuscation class * implements org.seimicrawler.xpath.core.NodeTest{*;} -keep,allowobfuscation class * implements org.seimicrawler.xpath.core.NodeTest{*;}
@@ -17,15 +17,12 @@ import io.legado.app.help.book.ContentProcessor
import io.legado.app.help.book.getFolderNameNoCache import io.legado.app.help.book.getFolderNameNoCache
import io.legado.app.help.book.isEpub import io.legado.app.help.book.isEpub
import io.legado.app.help.book.isImage import io.legado.app.help.book.isImage
import io.legado.app.help.book.isLocal
import io.legado.app.help.book.simulatedTotalChapterNum import io.legado.app.help.book.simulatedTotalChapterNum
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.config.ReadBookConfig import io.legado.app.help.config.ReadBookConfig
import io.legado.app.model.ReadBook import io.legado.app.model.ReadBook
import io.legado.app.utils.ConvertUtils
import io.legado.app.utils.fromJsonObject
import io.legado.app.utils.FileUtils
import io.legado.app.utils.GSON import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonObject
import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import java.nio.charset.Charset import java.nio.charset.Charset
@@ -169,17 +166,6 @@ data class Book(
fun getDisplayIntro() = if (customIntro.isNullOrEmpty()) intro else customIntro fun getDisplayIntro() = if (customIntro.isNullOrEmpty()) intro else customIntro
override fun getKindList(): List<String> {
val kindList = super.getKindList().toMutableList()
if (isLocal) {
// local book add filesize tag
val size = FileUtils.getLength(bookUrl)
if (size > 0) {
kindList.add(ConvertUtils.formatFileSize(size))
}
}
return kindList
}
//自定义简介有自动更新的需求时,可通过更新intro再调用upCustomIntro()完成 //自定义简介有自动更新的需求时,可通过更新intro再调用upCustomIntro()完成
@Suppress("unused") @Suppress("unused")
fun upCustomIntro() { fun upCustomIntro() {
@@ -862,6 +862,7 @@ interface JsExtensions : JsEncodeUtils {
): String { ): String {
if (errorQueryTTF == null || correctQueryTTF == null) return text if (errorQueryTTF == null || correctQueryTTF == null) return text
val contentArray = text.toStringArray() //这里不能用toCharArray,因为有些文字占多个字节 val contentArray = text.toStringArray() //这里不能用toCharArray,因为有些文字占多个字节
val intArray = IntArray(1)
contentArray.forEachIndexed { index, s -> contentArray.forEachIndexed { index, s ->
val oldCode = s.codePointAt(0) val oldCode = s.codePointAt(0)
// 忽略正常的空白字符 // 忽略正常的空白字符
@@ -878,7 +879,8 @@ interface JsExtensions : JsEncodeUtils {
// 使用轮廓数据反查Unicode // 使用轮廓数据反查Unicode
val code = correctQueryTTF.getUnicodeByGlyf(glyf) val code = correctQueryTTF.getUnicodeByGlyf(glyf)
if (code != 0) { if (code != 0) {
contentArray[index] = code.toChar().toString() intArray[0] = code
contentArray[index] = String(intArray, 0, 1)
} }
} }
return contentArray.joinToString("") return contentArray.joinToString("")
@@ -60,6 +60,8 @@ import io.legado.app.ui.widget.dialog.PhotoDialog
import io.legado.app.ui.widget.dialog.VariableDialog import io.legado.app.ui.widget.dialog.VariableDialog
import io.legado.app.ui.widget.dialog.WaitDialog import io.legado.app.ui.widget.dialog.WaitDialog
import io.legado.app.utils.ColorUtils import io.legado.app.utils.ColorUtils
import io.legado.app.utils.ConvertUtils
import io.legado.app.utils.FileDoc
import io.legado.app.utils.GSON import io.legado.app.utils.GSON
import io.legado.app.utils.StartActivityContract import io.legado.app.utils.StartActivityContract
import io.legado.app.utils.applyNavigationBarPadding import io.legado.app.utils.applyNavigationBarPadding
@@ -339,16 +341,31 @@ class BookInfoActivity :
tvIntro.text = book.getDisplayIntro() tvIntro.text = book.getDisplayIntro()
llToc?.visible(!book.isWebFile) llToc?.visible(!book.isWebFile)
upTvBookshelf() upTvBookshelf()
val kinds = book.getKindList() upKinds(book)
if (kinds.isEmpty()) {
lbKind.gone()
} else {
lbKind.visible()
lbKind.setLabels(kinds)
}
upGroup(book.group) upGroup(book.group)
} }
private fun upKinds(book: Book) = binding.run {
lifecycleScope.launch {
var kinds = book.getKindList()
if (book.isLocal) {
withContext(IO) {
val size = FileDoc.fromFile(book.bookUrl).size
if (size > 0) {
kinds = kinds.toMutableList()
kinds.add(ConvertUtils.formatFileSize(size))
}
}
}
if (kinds.isEmpty()) {
lbKind.gone()
} else {
lbKind.visible()
lbKind.setLabels(kinds)
}
}
}
private fun showCover(book: Book) { private fun showCover(book: Book) {
binding.ivCover.load(book.getDisplayCover(), book.name, book.author, false, book.origin) { binding.ivCover.load(book.getDisplayCover(), book.name, book.author, false, book.origin) {
if (!AppConfig.isEInkMode) { if (!AppConfig.isEInkMode) {
@@ -45,14 +45,7 @@ data class FileDoc(
fun asDocumentFile(): DocumentFile? { fun asDocumentFile(): DocumentFile? {
if (isContentScheme) { if (isContentScheme) {
return if (isDir) { return if (isDir) {
Class.forName("androidx.documentfile.provider.TreeDocumentFile") TreeDocumentFileConstructor.newInstance(null, appCtx, uri) as DocumentFile
.getDeclaredConstructor(
DocumentFile::class.java,
Context::class.java,
Uri::class.java
).apply {
isAccessible = true
}.newInstance(null, appCtx, uri) as DocumentFile
} else { } else {
DocumentFile.fromSingleUri(appCtx, uri) DocumentFile.fromSingleUri(appCtx, uri)
} }
@@ -69,10 +62,25 @@ data class FileDoc(
companion object { companion object {
private val TreeDocumentFileConstructor by lazy {
Class.forName("androidx.documentfile.provider.TreeDocumentFile")
.getDeclaredConstructor(
DocumentFile::class.java,
Context::class.java,
Uri::class.java
).apply {
isAccessible = true
}
}
fun fromDir(path: String): FileDoc { fun fromDir(path: String): FileDoc {
return fromUri(path.toUri(), true) return fromUri(path.toUri(), true)
} }
fun fromFile(path: String): FileDoc {
return fromUri(path.toUri(), false)
}
fun fromUri(uri: Uri, isDir: Boolean): FileDoc { fun fromUri(uri: Uri, isDir: Boolean): FileDoc {
if (uri.isContentScheme()) { if (uri.isContentScheme()) {
val doc = if (isDir) { val doc = if (isDir) {