Explorar el Código

添加长章节段评调试夹具

5151561 hace 3 meses
padre
commit
41140eb018

+ 2 - 1
app/src/debug/assets/debug-fixtures/long-chapter-v1.json

@@ -15,7 +15,8 @@
       "title": "第一章 稳定翻页",
       "readyMarker": "LEGADO_DEBUG_LONG_CHAPTER_V1",
       "paragraph": "这是用于阅读页翻页调试的固定长章节。每一段都带有稳定编号,用于确认页面内容确实发生变化。天地玄黄,宇宙洪荒;日月盈昃,辰宿列张。",
-      "repeat": 180
+      "repeat": 180,
+      "paragraphReviewFixture": "paragraph-review-v1"
     },
     {
       "title": "第二章 边界验证",

+ 35 - 0
app/src/debug/assets/debug-fixtures/paragraph-review-v1.html

@@ -0,0 +1,35 @@
+<!doctype html>
+<html lang="zh-CN">
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width,initial-scale=1">
+  <style>
+    :root { color-scheme: light dark; font-family: sans-serif; }
+    body { margin: 0; padding: 18px; background: Canvas; color: CanvasText; }
+    h2 { margin: 0 0 6px; font-size: 20px; }
+    .quote { margin: 0 0 16px; padding: 10px 12px; border-left: 4px solid #4f6bed; opacity: .78; }
+    .review { display: grid; grid-template-columns: 38px 1fr; gap: 10px; padding: 14px 0; border-top: 1px solid color-mix(in srgb, CanvasText 18%, transparent); }
+    .avatar { width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center; color: white; font-weight: 700; background: #4f6bed; }
+    .name { font-weight: 700; }
+    .time { margin-left: 8px; opacity: .55; font-size: 12px; }
+    .content { margin: 6px 0 0; line-height: 1.55; }
+    .reply { margin-top: 8px; padding: 8px 10px; border-radius: 8px; background: color-mix(in srgb, CanvasText 8%, transparent); font-size: 14px; }
+  </style>
+</head>
+<body>
+  <h2>段评 · 3 条</h2>
+  <p id="LEGADO_DEBUG_PARAGRAPH_REVIEW_V1" class="quote">第一段:这是用于阅读页翻页调试的固定长章节……</p>
+  <section class="review">
+    <div class="avatar">长</div>
+    <div><span class="name">长章节读者</span><span class="time">刚刚</span><p class="content">这是一条由 Debug Tool 注入的假段评,用来观察日夜模式切换。</p></div>
+  </section>
+  <section class="review">
+    <div class="avatar" style="background:#b35c1e">测</div>
+    <div><span class="name">测试账号</span><span class="time">2 分钟前</span><p class="content">段评属于正文第一段,不属于章节标题。</p><div class="reply">回复:点击入口后应打开真实的半屏 WebView。</div></div>
+  </section>
+  <section class="review">
+    <div class="avatar" style="background:#23856d">阅</div>
+    <div><span class="name">阅读观察员</span><span class="time">5 分钟前</span><p class="content">切换日夜模式时,这个列表应当立即跟随主题变化。</p></div>
+  </section>
+</body>
+</html>

+ 26 - 0
app/src/debug/java/io/legado/app/debug/DebugParagraphReviewFixture.kt

@@ -0,0 +1,26 @@
+package io.legado.app.debug
+
+import android.content.res.AssetManager
+import android.util.Base64
+import org.json.JSONObject
+
+internal object DebugParagraphReviewFixture {
+
+    fun createTag(assets: AssetManager, fixtureId: String): String {
+        require(fixtureId == FIXTURE_ID) { "unsupported paragraph review fixture" }
+        val html = assets.open("debug-fixtures/$fixtureId.html").use { it.readBytes() }
+        val htmlBase64 = Base64.encodeToString(html, Base64.NO_WRAP)
+        val iconUrl = "data:image/svg+xml;base64," + Base64.encodeToString(
+            ICON.toByteArray(),
+            Base64.NO_WRAP,
+        )
+        val click = "$MARKER java.showBrowser('$URL', java.base64Decode('$htmlBase64'))"
+        val imageOptions = JSONObject(mapOf("style" to "text", "click" to click)).toString()
+        return "<img src=\"$iconUrl,$imageOptions\">"
+    }
+
+    private const val FIXTURE_ID = "paragraph-review-v1"
+    private const val URL = "https://legado-debug.local/paragraph-reviews"
+    const val MARKER = "/*LEGADO_DEBUG_PARAGRAPH_REVIEW_V1*/"
+    private const val ICON = """<svg xmlns="http://www.w3.org/2000/svg" width="48" height="32" viewBox="0 0 48 32"><path fill="#4f6bed" d="M4 2h40a4 4 0 0 1 4 4v17a4 4 0 0 1-4 4H20l-8 5v-5H4a4 4 0 0 1-4-4V6a4 4 0 0 1 4-4z"/><text x="24" y="21" text-anchor="middle" font-family="sans-serif" font-size="16" font-weight="700" fill="white">3</text></svg>"""
+}

+ 29 - 5
app/src/debug/java/io/legado/app/debug/DebugScenarioActivity.kt

@@ -131,12 +131,35 @@ class DebugScenarioActivity : AppCompatActivity() {
         }
         chapters.forEachIndexed { index, chapter ->
             val definition = fixture.chapters[index]
+            val paragraphReview = definition.paragraphReviewFixture?.let {
+                DebugParagraphReviewFixture.createTag(assets, it)
+            }
+            if (paragraphReview != null) {
+                AppConfigStore.putAll(
+                    mapOf(
+                        PreferKey.enableReview to false,
+                        PreferKey.clickImgWay to "0",
+                    )
+                )
+            }
             val content = buildString {
-                appendLine(definition.readyMarker)
-                repeat(definition.repeat) { paragraphIndex ->
-                    append(paragraphIndex + 1)
-                    append(". ")
-                    appendLine(definition.paragraph)
+                if (paragraphReview == null) {
+                    appendLine(definition.readyMarker)
+                    repeat(definition.repeat) { paragraphIndex ->
+                        append(paragraphIndex + 1)
+                        append(". ")
+                        appendLine(definition.paragraph)
+                    }
+                } else {
+                    append(definition.readyMarker)
+                    append(" 1. ")
+                    append(definition.paragraph)
+                    appendLine(paragraphReview)
+                    repeat(definition.repeat - 1) { paragraphIndex ->
+                        append(paragraphIndex + 2)
+                        append(". ")
+                        appendLine(definition.paragraph)
+                    }
                 }
             }
             BookHelp.saveText(book, chapter, content)
@@ -195,6 +218,7 @@ class DebugScenarioActivity : AppCompatActivity() {
         val readyMarker: String,
         val paragraph: String,
         val repeat: Int,
+        val paragraphReviewFixture: String? = null,
     )
 
     private companion object {

+ 7 - 0
tools/android/README.md

@@ -58,6 +58,13 @@ tools/android/debug.sh run source-edit/predictive-back
 | `theme/export-missing-content-uri` | 在确认导出前让受控 URI 失效,证明 `openInputStream` 调用链 |
 | `theme/export-current-after-deleting-applied-theme` | 保存并应用主题、删除主题包后,当前主题仍可完整导出 |
 
+## 长章节段评夹具
+
+`long-chapter-v1` 在正文第一段末尾注入 `paragraph-review-v1`:一个带书源 click 脚本的内联
+`ImageColumn`。点击后沿正式正文图片点击链调用 `java.showBrowser`,在 WebView 中展示三条固定假段评。
+章节 `reviewImg` 保持为空,因此入口不会挂到标题,也不会在每段尾部追加占位字符。夹具会固定关闭
+旧的字符段评开关,并把图片点击方式设为执行 click 脚本,避免受 debug 包历史设置影响。
+
 ## 主题资源故障注入
 
 主题场景支持顶层字段 `themeAsset`: