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

[优化] 支持更多Sigma版本特性(@Luoyacheng)

HapeLee 9 месяцев назад
Родитель
Сommit
2d14d82251

+ 1 - 0
app/src/main/java/io/legado/app/constant/EventBus.kt

@@ -35,5 +35,6 @@ object EventBus {
     const val UP_MANGA_CONFIG = "upMangaConfig"
     const val PLAY_MODE_CHANGED = "playModeChanged"
     const val REFRESH_BOOK_INFO = "refreshBookInfo"
+    const val REFRESH_BOOK_CONTENT = "refreshBookContent"
     const val UP_TOC = "upToc"
 }

+ 1 - 1
app/src/main/java/io/legado/app/constant/PreferKey.kt

@@ -118,7 +118,7 @@ object PreferKey {
     const val enableMangaEInk = "enableMangaEInk"
     const val mangaEInkThreshold = "mangaEInkThreshold"
     const val enableMangaGray = "enableMangaGray"
-
+    const val mediaButtonOnExit = "mediaButtonOnExit"
     const val autoRefresh = "auto_refresh"
     const val defaultToRead = "defaultToRead"
     const val exportCharset = "exportCharset"

+ 61 - 25
app/src/main/java/io/legado/app/data/entities/BaseSource.kt

@@ -9,17 +9,21 @@ import io.legado.app.constant.AppConst
 import io.legado.app.constant.AppLog
 import io.legado.app.data.entities.rule.RowUi
 import io.legado.app.help.CacheManager
+import io.legado.app.help.ConcurrentRateLimiter.Companion.updateConcurrentRate
 import io.legado.app.help.JsExtensions
 import io.legado.app.help.config.AppConfig
 import io.legado.app.help.crypto.SymmetricCryptoAndroid
 import io.legado.app.help.http.CookieStore
+import io.legado.app.help.source.clearExploreKindsCache
 import io.legado.app.help.source.getShareScope
+import io.legado.app.model.SharedJsScope.remove
 import io.legado.app.utils.GSON
 import io.legado.app.utils.GSONStrict
 import io.legado.app.utils.fromJsonArray
 import io.legado.app.utils.fromJsonObject
 import io.legado.app.utils.has
-import io.legado.app.utils.printOnDebug
+import io.legado.app.utils.isMainThread
+import kotlinx.coroutines.runBlocking
 import org.intellij.lang.annotations.Language
 
 /**
@@ -75,6 +79,9 @@ interface BaseSource : JsExtensions {
         }
     }
 
+    /**
+     * 调用login函数 实现登录请求
+     */
     @JavascriptInterface
     fun login() {
         val loginJs = getLoginJs()
@@ -91,30 +98,6 @@ interface BaseSource : JsExtensions {
         }
     }
 
-    fun loginUi(): List<RowUi>? {
-        val json = loginUi?.let {
-            val loginJS = getLoginJs() ?: ""
-            try {
-                when {
-                    it.startsWith("@js:") -> evalJS(loginJS + it.substring(4)){
-                        put("result", getLoginInfoMap())
-                    }.toString()
-                    it.startsWith("<js>") -> evalJS(loginJS + it.substring(4,it.lastIndexOf("<"))){
-                        put("result", getLoginInfoMap())
-                    }.toString()
-                    else -> it
-                }
-            } catch (e: Throwable) {
-                log(e)
-                e.printOnDebug()
-                null
-            }
-        }
-        return GSON.fromJsonArray<RowUi>(json).onFailure {
-            it.printOnDebug()
-        }.getOrNull()
-    }
-
     /**
      * 解析header规则
      */
@@ -152,6 +135,7 @@ interface BaseSource : JsExtensions {
     /**
      * 获取用于登录的头部信息
      */
+    @JavascriptInterface
     fun getLoginHeader(): String? {
         return CacheManager.get("loginHeader_${getKey()}")
     }
@@ -182,6 +166,7 @@ interface BaseSource : JsExtensions {
      * 获取用户信息,可以用来登录
      * 用户信息采用aes加密存储
      */
+    @JavascriptInterface
     fun getLoginInfo(): String? {
         try {
             val key = AppConst.androidId.encodeToByteArray(0, 16)
@@ -232,6 +217,7 @@ interface BaseSource : JsExtensions {
     /**
      * 保存用户信息,aes加密
      */
+    @JavascriptInterface
     fun putLoginInfo(info: String): Boolean {
         return try {
             val key = (AppConst.androidId).encodeToByteArray(0, 16)
@@ -244,6 +230,7 @@ interface BaseSource : JsExtensions {
         }
     }
 
+    @JavascriptInterface
     fun removeLoginInfo() {
         CacheManager.delete("userInfo_${getKey()}")
     }
@@ -260,9 +247,23 @@ interface BaseSource : JsExtensions {
         }
     }
 
+    /**
+     * 设置自定义变量
+     * 新,统一为put名称存变量
+     */
+    @JavascriptInterface
+    fun putVariable(variable: String?) {
+        if (variable != null) {
+            CacheManager.put("sourceVariable_${getKey()}", variable)
+        } else {
+            CacheManager.delete("sourceVariable_${getKey()}")
+        }
+    }
+
     /**
      * 获取自定义变量
      */
+    @JavascriptInterface
     fun getVariable(): String {
         return CacheManager.get("sourceVariable_${getKey()}") ?: ""
     }
@@ -270,6 +271,7 @@ interface BaseSource : JsExtensions {
     /**
      * 保存数据
      */
+    @JavascriptInterface
     fun put(key: String, value: String): String {
         CacheManager.put("v_${getKey()}_${key}", value)
         return value
@@ -278,10 +280,44 @@ interface BaseSource : JsExtensions {
     /**
      * 获取保存的数据
      */
+    @JavascriptInterface
     fun get(key: String): String {
         return CacheManager.get("v_${getKey()}_${key}") ?: ""
     }
 
+    /**
+     * 刷新发现
+     */
+    fun refreshExplore() {
+        if (isMainThread) {
+            error("refreshExplore must be called on a background thread")
+        }
+        runBlocking {
+            if (this@BaseSource is BookSource) {
+                this@BaseSource.clearExploreKindsCache()
+            }
+        }
+    }
+
+    /**
+     * 刷新JSLib
+     */
+    fun refreshJSLib() {
+        if (isMainThread) {
+            error("refreshJSLib must be called on a background thread")
+        }
+        runBlocking {
+            remove(jsLib)
+        }
+    }
+
+    /**
+     * 设置并发率
+     */
+    fun putConcurrent(value: String) {
+        updateConcurrentRate(getKey(), value)
+    }
+
     /**
      * 执行JS
      */

+ 13 - 23
app/src/main/java/io/legado/app/help/JsExtensions.kt

@@ -16,6 +16,7 @@ import io.legado.app.data.entities.BaseSource
 import io.legado.app.exception.NoStackTraceException
 import io.legado.app.help.config.AppConfig
 import io.legado.app.help.config.ReadBookConfig
+import io.legado.app.help.config.ThemeConfig
 import io.legado.app.help.http.BackstageWebView
 import io.legado.app.help.http.CookieManager.cookieJarHeader
 import io.legado.app.help.http.CookieStore
@@ -321,17 +322,6 @@ interface JsExtensions : JsEncodeUtils {
         }
     }
 
-    /**
-     * 打开内置视频播放器
-     * @param url 视频播放链接
-     * @param title 视频的标题
-     * @param float 是否悬浮窗打开
-     */
-    @JavascriptInterface
-    fun openVideoPlayer(url: String, title: String, float: Boolean) {
-        //SourceHelp.openVideoPlayer(getSource(), url, title, float)
-    }
-
     /**
      * 使用内置浏览器打开链接,手动验证网站防爬
      * @param url 要打开的链接
@@ -1196,9 +1186,9 @@ interface JsExtensions : JsEncodeUtils {
         return GSON.toJson(ReadBookConfig.durConfig)
     }
 
-    //fun getReadBookConfigMap(): Map<String, Any> {
-    //    return ReadBookConfig.durConfig.toMap()
-    //}
+    fun getReadBookConfigMap(): Map<String, Any> {
+        return ReadBookConfig.durConfig.toMap()
+    }
 
     /**
      * 获取主题模式
@@ -1211,14 +1201,14 @@ interface JsExtensions : JsEncodeUtils {
     /**
      * 获取主题配置
      */
-    // @JavascriptInterface
-    //fun getThemeConfig(): String {
-    //    val themeConfig = ThemeConfig.getDurConfig(appCtx)
-    //    return GSON.toJson(themeConfig)
-    //}
-
-    //fun getThemeConfigMap(): Map<String, Any?> {
-    //    return ThemeConfig.getDurConfig(appCtx).toMap()
-    //}
+    @JavascriptInterface
+    fun getThemeConfig(): String {
+        val themeConfig = ThemeConfig.getDurConfig(appCtx)
+        return GSON.toJson(themeConfig)
+    }
+
+    fun getThemeConfigMap(): Map<String, Any?> {
+        return ThemeConfig.getDurConfig(appCtx).toMap()
+    }
 
 }

+ 3 - 3
app/src/main/java/io/legado/app/help/book/BookHelp.kt

@@ -31,6 +31,7 @@ import io.legado.app.utils.onEachParallel
 import io.legado.app.utils.postEvent
 import kotlinx.coroutines.Dispatchers.IO
 import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.currentCoroutineContext
 import kotlinx.coroutines.ensureActive
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.collect
@@ -47,7 +48,6 @@ import java.io.IOException
 import java.util.concurrent.ConcurrentHashMap
 import java.util.regex.Pattern
 import java.util.zip.ZipFile
-import kotlin.coroutines.coroutineContext
 import kotlin.math.abs
 import kotlin.math.max
 import kotlin.math.min
@@ -234,7 +234,7 @@ object BookHelp {
                 return
             }
             val analyzeUrl = AnalyzeUrl(
-                src, source = bookSource, coroutineContext = coroutineContext
+                src, source = bookSource, coroutineContext = currentCoroutineContext()
             )
             val bytes = analyzeUrl.getByteArrayAwait()
             //某些图片被加密,需要进一步解密
@@ -252,7 +252,7 @@ object BookHelp {
                 writeImage(book, src, it)
             }
         } catch (e: Exception) {
-            coroutineContext.ensureActive()
+            currentCoroutineContext().ensureActive()
             val msg = "${book.name} ${chapter?.title} 图片 $src 下载失败\n${e.localizedMessage}"
             AppLog.put(msg, e)
         } finally {

+ 1 - 1
app/src/main/java/io/legado/app/help/config/AppConfig.kt

@@ -578,7 +578,7 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
 
     val syncBookProgressPlus get() = appCtx.getPrefBoolean(PreferKey.syncBookProgressPlus, false)
 
-    val mediaButtonOnExit get() = appCtx.getPrefBoolean("mediaButtonOnExit", true)
+    val mediaButtonOnExit get() = appCtx.getPrefBoolean(PreferKey.mediaButtonOnExit, true)
 
     val readAloudByMediaButton
         get() = appCtx.getPrefBoolean(PreferKey.readAloudByMediaButton, false)

+ 63 - 0
app/src/main/java/io/legado/app/help/config/ReadBookConfig.kt

@@ -788,6 +788,69 @@ object ReadBookConfig {
         @Transient
         private var initColorInt = false
 
+        fun toMap() = mapOf(
+            "name" to name,
+            "bgStr" to bgStr,
+            "bgStrNight" to bgStrNight,
+            "bgStrEInk" to bgStrEInk,
+            "bgAlpha" to bgAlpha,
+            "bgType" to bgType,
+            "bgTypeNight" to bgTypeNight,
+            "bgTypeEInk" to bgTypeEInk,
+            "darkStatusIcon" to darkStatusIcon,
+            "darkStatusIconNight" to darkStatusIconNight,
+            "darkStatusIconEInk" to darkStatusIconEInk,
+            "textColor" to textColor,
+            "textColorNight" to textColorNight,
+            "textColorEInk" to textColorEInk,
+            "textColorInt" to textColorInt,
+            "textColorIntNight" to textColorIntNight,
+            "textColorIntEInk" to textColorIntEInk,
+            "textAccentColor" to textAccentColor,
+            "textAccentColorNight" to textAccentColorNight,
+            "textAccentColorEInk" to textAccentColorEInk,
+            "textAccentColorInt" to textAccentColorInt,
+            "textAccentColorIntNight" to textAccentColorIntNight,
+            "textAccentColorIntEInk" to textAccentColorIntEInk,
+            "pageAnim" to pageAnim,
+            "pageAnimEInk" to pageAnimEInk,
+            "textFont" to textFont,
+            "textBold" to textBold,
+            "textSize" to textSize,
+            "letterSpacing" to letterSpacing,
+            "lineSpacingExtra" to lineSpacingExtra,
+            "paragraphSpacing" to paragraphSpacing,
+            "titleMode" to titleMode,
+            "titleSize" to titleSize,
+            "titleTopSpacing" to titleTopSpacing,
+            "titleBottomSpacing" to titleBottomSpacing,
+            "paragraphIndent" to paragraphIndent,
+            "paddingBottom" to paddingBottom,
+            "paddingLeft" to paddingLeft,
+            "paddingRight" to paddingRight,
+            "paddingTop" to paddingTop,
+            "headerPaddingBottom" to headerPaddingBottom,
+            "headerPaddingLeft" to headerPaddingLeft,
+            "headerPaddingRight" to headerPaddingRight,
+            "headerPaddingTop" to headerPaddingTop,
+            "footerPaddingBottom" to footerPaddingBottom,
+            "footerPaddingLeft" to footerPaddingLeft,
+            "footerPaddingRight" to footerPaddingRight,
+            "footerPaddingTop" to footerPaddingTop,
+            "showHeaderLine" to showHeaderLine,
+            "showFooterLine" to showFooterLine,
+            "tipHeaderLeft" to tipHeaderLeft,
+            "tipHeaderMiddle" to tipHeaderMiddle,
+            "tipHeaderRight" to tipHeaderRight,
+            "tipFooterLeft" to tipFooterLeft,
+            "tipFooterMiddle" to tipFooterMiddle,
+            "tipFooterRight" to tipFooterRight,
+            "tipColor" to tipColor,
+            "tipDividerColor" to tipDividerColor,
+            "headerMode" to headerMode,
+            "footerMode" to footerMode
+        )
+
         fun getBgPath(bgIndex: Int): String? {
             val bgType = when (bgIndex) {
                 0 -> bgType

+ 0 - 1
app/src/main/java/io/legado/app/help/webView/WebJsExtensions.kt

@@ -218,7 +218,6 @@ class WebJsExtensions(
             val letters = "abcdefghijklmnopqrstuvwxyz"
             return letters.random()
         }
-
         val uuid by lazy {
             UUID.randomUUID().toString().replace('-', getRandomLetter()).chunked(6)
         }

+ 1 - 1
app/src/main/java/io/legado/app/model/ImageProvider.kt

@@ -41,7 +41,7 @@ object ImageProvider {
     private const val M = 1024 * 1024
     val cacheSize: Int
         get() {
-            if (AppConfig.bitmapCacheSize <= 0 || AppConfig.bitmapCacheSize >= 2048) {
+            if (AppConfig.bitmapCacheSize !in 1..<2048) {
                 AppConfig.bitmapCacheSize = 50
             }
             return AppConfig.bitmapCacheSize * M

+ 21 - 14
app/src/main/java/io/legado/app/model/ReadBook.kt

@@ -183,6 +183,12 @@ object ReadBook : CoroutineScope by MainScope(), KoinComponent {
         } else {
             appDb.bookSourceDao.getBookSource(book.origin)?.let {
                 bookSource = it
+                SourceCallBack.callBackBook(
+                    SourceCallBack.START_READ,
+                    it,
+                    book,
+                    curTextChapter?.chapter
+                )
                 if (book.getImageStyle().isNullOrBlank()) {
                     var imageStyle = it.getContentRule().imageStyle
                     if (imageStyle.isNullOrBlank() && (book.isImage || book.isPdf)) {
@@ -978,9 +984,9 @@ object ReadBook : CoroutineScope by MainScope(), KoinComponent {
     }
 
     fun saveRead(pageChanged: Boolean = false) {
+        val book = book ?: return
         executor.execute {
             kotlin.runCatching {
-                val book = book ?: return@execute
                 book.lastCheckCount = 0
                 book.durChapterTime = System.currentTimeMillis()
                 val chapterChanged = book.durChapterIndex != durChapterIndex
@@ -992,9 +998,10 @@ object ReadBook : CoroutineScope by MainScope(), KoinComponent {
                             ContentProcessor.get(book.name, book.origin).getTitleReplaceRules(),
                             book.getUseReplaceRule()
                         )
+                        SourceCallBack.callBackBook(SourceCallBack.SAVE_READ, bookSource, book, it)
                     }
                 }
-                appDb.bookDao.update(book)
+                book.update()
             }.onFailure {
                 AppLog.put("保存书籍阅读进度信息出错\n$it", it)
             }
@@ -1034,17 +1041,6 @@ object ReadBook : CoroutineScope by MainScope(), KoinComponent {
         }
     }
 
-    private fun clearExpiredChapterLoadingJob(clearAll: Boolean = false) {
-        val iterator = chapterLoadingJobs.iterator()
-        while (iterator.hasNext()) {
-            val (index, job) = iterator.next()
-            if (clearAll || index !in durChapterIndex - 1..durChapterIndex + 1) {
-                job.cancel()
-                iterator.remove()
-            }
-        }
-    }
-
     fun cancelPreDownloadTask() {
         if (contentLoadFinish) {
             preDownloadTask?.cancel()
@@ -1068,6 +1064,17 @@ object ReadBook : CoroutineScope by MainScope(), KoinComponent {
         }
     }
 
+    private fun clearExpiredChapterLoadingJob(clearAll: Boolean = false) {
+        val iterator = chapterLoadingJobs.iterator()
+        while (iterator.hasNext()) {
+            val (index, job) = iterator.next()
+            if (clearAll || index !in durChapterIndex - 1..durChapterIndex + 1) {
+                job.cancel()
+                iterator.remove()
+            }
+        }
+    }
+
     /**
      * 注册回调
      */
@@ -1124,4 +1131,4 @@ object ReadBook : CoroutineScope by MainScope(), KoinComponent {
         fun cancelSelect()
     }
 
-}
+}

+ 0 - 1
app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt

@@ -969,4 +969,3 @@ class AnalyzeUrl(
     )
 
 }
-

+ 7 - 0
app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt

@@ -1918,6 +1918,13 @@ class ReadBookActivity : BaseReadBookActivity(),
         observeEvent<Boolean>(EventBus.UP_SEEK_BAR) {
             readMenu.upSeekBar()
         }
+        observeEvent<Boolean>(EventBus.REFRESH_BOOK_CONTENT) {
+            ReadBook.book?.let {
+                ReadBook.curTextChapter = null
+                binding.readView.upContent()
+                viewModel.refreshContentDur(it)
+            }
+        }
     }
 
     private fun upScreenTimeOut() {

+ 1 - 2
app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt

@@ -97,7 +97,6 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
         if (!isMainView) return
         ChapterProvider.upViewSize(w, h)
         textPage.format()
-        //TODO: 有关测量相关问题
     }
 
     override fun onDraw(canvas: Canvas) {
@@ -267,7 +266,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
 
                 is ImageColumn -> when (AppConfig.clickImgWay) {
                     "1" -> { //预览图片
-                        activity?.showDialogFragment(PhotoDialog(column.src))
+                        activity?.showDialogFragment(PhotoDialog(column.src, isBook = true))
                         handled = true
                     }
                     "2" -> { //兼容处理

+ 4 - 12
app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt

@@ -7,12 +7,10 @@ import android.graphics.Paint.FontMetrics
 import android.graphics.RectF
 import android.graphics.Typeface
 import android.os.Build
-import android.text.Layout
 import android.text.StaticLayout
 import android.text.TextPaint
 import androidx.core.net.toUri
 import androidx.core.os.postDelayed
-import io.legado.app.constant.AppPattern
 import io.legado.app.constant.EventBus
 import io.legado.app.data.entities.Book
 import io.legado.app.data.entities.BookChapter
@@ -21,28 +19,18 @@ import io.legado.app.help.config.AppConfig
 import io.legado.app.help.config.ReadBookConfig
 import io.legado.app.help.config.ReadBookConfig.dottedBase
 import io.legado.app.help.config.ReadBookConfig.dottedRatio
-import io.legado.app.model.ImageProvider
 import io.legado.app.model.ReadBook
 import io.legado.app.ui.book.read.page.entities.TextChapter
-import io.legado.app.ui.book.read.page.entities.TextLine
-import io.legado.app.ui.book.read.page.entities.TextPage
-import io.legado.app.ui.book.read.page.entities.column.ImageColumn
-import io.legado.app.ui.book.read.page.entities.column.ReviewColumn
-import io.legado.app.ui.book.read.page.entities.column.TextColumn
 import io.legado.app.utils.buildMainHandler
 import io.legado.app.utils.dpToPx
-import io.legado.app.utils.fastSum
 import io.legado.app.utils.isContentScheme
 import io.legado.app.utils.isPad
 import io.legado.app.utils.postEvent
 import io.legado.app.utils.spToPx
-import io.legado.app.utils.splitNotBlank
 import io.legado.app.utils.textHeight
 import kotlinx.coroutines.CoroutineScope
 import splitties.init.appCtx
 import java.io.File
-import java.util.LinkedList
-import java.util.Locale
 
 /**
  * 解析内容生成章节和页面
@@ -180,6 +168,7 @@ object ChapterProvider {
         upStyle()
     }
 
+    /*
     /**
      * 获取拆分完的章节数据
      */
@@ -337,6 +326,7 @@ object ChapterProvider {
             bookContent.effectiveReplaceRules
         )
     }
+    */
 
     fun getTextChapterAsync(
         scope: CoroutineScope,
@@ -362,6 +352,7 @@ object ChapterProvider {
         return textChapter
     }
 
+    /*
     /**
      * 排版图片
      */
@@ -869,6 +860,7 @@ object ChapterProvider {
         }
         return stringList to widths
     }
+    */
 
     /**
      * 更新样式

+ 4 - 0
app/src/main/java/io/legado/app/ui/login/SourceLoginJsExtensions.kt

@@ -47,6 +47,10 @@ class SourceLoginJsExtensions(
         postEvent(EventBus.REFRESH_BOOK_INFO, true)
     }
 
+    fun refreshContent() {
+        postEvent(EventBus.REFRESH_BOOK_CONTENT, true)
+    }
+
     fun copyText(text: String) {
         activityRef.get()?.sendToClip(text)
     }

+ 2 - 1
app/src/main/java/io/legado/app/ui/widget/dialog/PhotoDialog.kt

@@ -28,10 +28,11 @@ import java.io.ByteArrayOutputStream
  */
 class PhotoDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_photo_view) {
 
-    constructor(src: String, sourceOrigin: String? = null) : this() {
+    constructor(src: String, sourceOrigin: String? = null, isBook: Boolean = false) : this() {
         arguments = Bundle().apply {
             putString("src", src)
             putString("sourceOrigin", sourceOrigin)
+            putBoolean("isBook", isBook)
         }
     }
 

+ 12 - 1
app/src/main/res/menu/web_view.xml

@@ -6,7 +6,13 @@
         android:id="@+id/menu_ok"
         android:icon="@drawable/ic_check"
         android:title="@string/ok"
-        app:showAsAction="always" />
+        app:showAsAction="ifRoom" />
+
+    <item
+        android:id="@+id/menu_web_refresh"
+        android:icon="@drawable/ic_refresh"
+        android:title="@string/refresh"
+        app:showAsAction="ifRoom" />
 
     <item
         android:id="@+id/menu_open_in_browser"
@@ -23,6 +29,11 @@
         android:title="@string/full_screen"
         app:showAsAction="never" />
 
+    <item
+        android:id="@+id/menu_show_web_log"
+        android:checkable="true"
+        android:title="@string/show_web_log" />
+
     <item
         android:id="@+id/menu_disable_source"
         android:title="@string/disable_source"

+ 1 - 0
app/src/main/res/values/array_values.xml

@@ -57,6 +57,7 @@
         <item>1</item>
         <item>2</item>
         <item>3</item>
+        <item>4</item>
     </string-array>
 
     <string-array name="double_page_value">

+ 4 - 3
app/src/main/res/values/arrays.xml

@@ -117,10 +117,11 @@
 	</string-array>
 
     <string-array name="click_image_way_title">
-        <item>新包名阅读行为</item>
+        <item>新包名行为</item>
         <item>预览图片</item>
-        <item>经典阅读行为</item>
-        <item>不响应</item>
+        <item>经典行为</item>
+        <item>关闭点击</item>
+        <item>双击生效</item>
     </string-array>
 
     <string-array name="double_page_title">

+ 1 - 0
app/src/main/res/values/strings.xml

@@ -1387,4 +1387,5 @@
     <string name="audio_cache_clean_time_summary">当前%d, 输入 0 代表退出即刻清理。</string>
     <string name="show_swipe_animation">启用滑动时动画</string>
     <string name="click_image_way">点击图片行为</string>
+    <string name="show_web_log">输出日志</string>
 </resources>