Просмотр исходного кода

feat: 统一简介文本处理

5151561 3 месяцев назад
Родитель
Сommit
d5a83f83a9

+ 14 - 4
app/src/main/java/io/legado/app/ui/main/bookshelf/BookItem.kt

@@ -757,8 +757,19 @@ fun BookItem(
         columnContent = if (layoutMode == 0 && !isCompact && settings.showBookIntro) {
             {
                 val kindList = bookUi.displayTags
-                val intro = remember(book.intro) {
-                    HtmlFormatter.formatDisplayText(book.intro).takeIf { it.isNotBlank() }
+                //不限行数时保留分段, 限行数时压成摘要, 否则第一段之后会被直接截掉
+                val introMaxLines = if (settings.bookshelfIntroMaxLines == 0) {
+                    Int.MAX_VALUE
+                } else {
+                    settings.bookshelfIntroMaxLines
+                }
+                val intro = remember(book.intro, introMaxLines) {
+                    val text = if (introMaxLines == Int.MAX_VALUE) {
+                        HtmlFormatter.formatDisplayText(book.intro)
+                    } else {
+                        HtmlFormatter.formatSummaryText(book.intro)
+                    }
+                    text.takeIf { it.isNotBlank() }
                 }
                 if (settings.bookshelfShowTag && kindList.isNotEmpty()) {
                     Row(
@@ -788,12 +799,11 @@ fun BookItem(
                     }
                 }
                 if (settings.bookshelfShowIntro && intro != null) {
-                    val maxLines = if (settings.bookshelfIntroMaxLines == 0) Int.MAX_VALUE else settings.bookshelfIntroMaxLines
                     AppText(
                         text = intro,
                         style = LegadoTheme.typography.bodySmall,
                         color = LegadoTheme.colorScheme.onSurfaceVariant,
-                        maxLines = maxLines,
+                        maxLines = introMaxLines,
                         overflow = TextOverflow.Ellipsis,
                         modifier = Modifier
                             .fillMaxWidth()

+ 4 - 3
app/src/main/java/io/legado/app/ui/main/homepage/modules/CardModule.kt

@@ -21,6 +21,7 @@ import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Check
 import androidx.compose.material.icons.filled.Shuffle
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
@@ -35,6 +36,7 @@ import io.legado.app.ui.theme.fadingEdge
 import io.legado.app.ui.widget.components.card.TextCard
 import io.legado.app.ui.widget.components.image.cover.CoilBookCover
 import io.legado.app.ui.widget.components.text.AppText
+import io.legado.app.utils.HtmlFormatter
 import kotlinx.collections.immutable.ImmutableList
 
 /**
@@ -133,9 +135,8 @@ fun CardModule(
                     ),
                 )
 
-                val intro = book.intro?.takeIf { it.isNotBlank() }
-                    ?.replace("\\s+".toRegex(), " ")
-                if (intro != null) {
+                val intro = remember(book.intro) { HtmlFormatter.formatSummaryText(book.intro) }
+                if (intro.isNotEmpty()) {
                     AppText(
                         text = intro,
                         style = LegadoTheme.typography.labelSmallEmphasized,

+ 4 - 2
app/src/main/java/io/legado/app/ui/main/homepage/modules/WaterfallModule.kt

@@ -17,6 +17,7 @@ import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Check
 import androidx.compose.material.icons.filled.Shuffle
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.text.font.FontWeight
@@ -31,6 +32,7 @@ import io.legado.app.ui.widget.components.card.GlassCard
 import io.legado.app.ui.widget.components.card.TextCard
 import io.legado.app.ui.widget.components.image.cover.CoilBookCover
 import io.legado.app.ui.widget.components.text.AppText
+import io.legado.app.utils.HtmlFormatter
 
 /**
  * 瀑布流单项组件
@@ -134,8 +136,8 @@ fun WaterfallItem(
                     )
                 }
 
-                val intro = book.intro?.replace("\\s+".toRegex(), " ")
-                if (!intro.isNullOrBlank()) {
+                val intro = remember(book.intro) { HtmlFormatter.formatSummaryText(book.intro) }
+                if (intro.isNotEmpty()) {
                     AppText(
                         text = intro,
                         style = LegadoTheme.typography.labelSmallEmphasized,

+ 3 - 1
app/src/main/java/io/legado/app/ui/widget/components/book/SearchBookItem.kt

@@ -24,6 +24,7 @@ import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Check
 import androidx.compose.material.icons.filled.Shuffle
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
@@ -42,6 +43,7 @@ import io.legado.app.ui.widget.components.card.GlassCard
 import io.legado.app.ui.widget.components.card.TextCard
 import io.legado.app.ui.widget.components.image.cover.CoilBookCover
 import io.legado.app.ui.widget.components.text.AppText
+import io.legado.app.utils.HtmlFormatter
 
 @OptIn(ExperimentalSharedTransitionApi::class, ExperimentalFoundationApi::class)
 @Composable
@@ -157,7 +159,7 @@ fun SearchBookListItem(
 
             Spacer(modifier = Modifier.height(4.dp))
 
-            val intro = book.intro?.replace("\\s+".toRegex(), "") ?: ""
+            val intro = remember(book.intro) { HtmlFormatter.formatSummaryText(book.intro) }
             if (intro.isNotEmpty()) {
                 AppText(
                     text = intro,

+ 3 - 2
app/src/main/java/io/legado/app/ui/widget/components/book/SearchBookPreviewSheet.kt

@@ -33,6 +33,7 @@ import io.legado.app.ui.widget.components.button.ConfirmDismissButtonsRow
 import io.legado.app.ui.widget.components.image.cover.CoilBookCover
 import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet
 import io.legado.app.ui.widget.components.text.AppText
+import io.legado.app.utils.HtmlFormatter
 import java.text.SimpleDateFormat
 import java.util.Date
 import java.util.Locale
@@ -154,8 +155,8 @@ fun SearchBookPreviewSheet(
                 }
             }
 
-            val intro = book.intro?.replace("\\s+".toRegex(), " ")?.trim()
-            if (!intro.isNullOrBlank()) {
+            val intro = remember(book.intro) { HtmlFormatter.formatDisplayText(book.intro) }
+            if (intro.isNotEmpty()) {
                 Spacer(modifier = Modifier.height(12.dp))
                 Box(
                     modifier = Modifier

+ 12 - 0
app/src/main/java/io/legado/app/utils/HtmlFormatter.kt

@@ -77,6 +77,18 @@ object HtmlFormatter {
             .joinToString("\n") { PARAGRAPH_INDENT + it }
     }
 
+    /**
+     * 与 [formatDisplayText] 同样清洗, 但压成单行摘要。
+     * 列表/卡片只显示一两行并 ellipsis, 保留换行会让首段之后的内容被直接截断。
+     */
+    fun formatSummaryText(html: String?): String {
+        return formatDisplayText(html)
+            .lineSequence()
+            .map { it.trim(*blankChars) }
+            .filterNot { it.isEmpty() }
+            .joinToString(" ")
+    }
+
     fun formatKeepImg(html: String?, redirectUrl: URL? = null): String {
         html ?: return ""
         val keepImgHtml = format(html, notImgHtmlRegex)