@ -1,4 +1,4 @@ | 
				
			|||||||
<resources> | 
					<resources> | 
				
			||||||
    <string name="app_name">阅读·D</string> | 
					    <string name="app_name" translatable="false">阅读·D</string> | 
				
			||||||
    <string name="receiving_shared_label">阅读·D·搜索</string> | 
					    <string name="receiving_shared_label" translatable="false">阅读·D·搜索</string> | 
				
			||||||
</resources> | 
					</resources> | 
				
			||||||
@ -0,0 +1,3 @@ | 
				
			|||||||
 | 
					OGN5dS5jb20= | 
				
			||||||
 | 
					c2cwMC54eXo= | 
				
			||||||
 | 
					aXRyYWZmaWNuZXQuY29t | 
				
			||||||
@ -0,0 +1,46 @@ | 
				
			|||||||
 | 
					<!DOCTYPE html> | 
				
			||||||
 | 
					<html lang=en style="padding: 0;height:100%"> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<head> | 
				
			||||||
 | 
					  <meta charset=utf-8> | 
				
			||||||
 | 
					  <meta http-equiv=X-UA-Compatible content="IE=edge"> | 
				
			||||||
 | 
					  <meta name=viewport content="width=device-width,initial-scale=1"> | 
				
			||||||
 | 
					  <!--[if IE]><link rel="icon" href="favicon.ico" /><![endif]--> | 
				
			||||||
 | 
					  <title>yd-web-tool</title> | 
				
			||||||
 | 
					  <link href=css/about.f23c15cb.css rel=prefetch> | 
				
			||||||
 | 
					  <link href=css/detail.42c41bd6.css rel=prefetch> | 
				
			||||||
 | 
					  <link href=js/about.2589b5fe.js rel=prefetch> | 
				
			||||||
 | 
					  <link href=js/about~detail.08c372e6.js rel=prefetch> | 
				
			||||||
 | 
					  <link href=js/detail.043d6e39.js rel=prefetch> | 
				
			||||||
 | 
					  <link href=css/app.e1c0d2e4.css rel=preload as=style> | 
				
			||||||
 | 
					  <link href=css/chunk-vendors.ad4ff18f.css rel=preload as=style> | 
				
			||||||
 | 
					  <link href=js/app.b25f3cec.js rel=preload as=script> | 
				
			||||||
 | 
					  <link href=js/chunk-vendors.b3838a2d.js rel=preload as=script> | 
				
			||||||
 | 
					  <link href=css/chunk-vendors.ad4ff18f.css rel=stylesheet> | 
				
			||||||
 | 
					  <link href=css/app.e1c0d2e4.css rel=stylesheet> | 
				
			||||||
 | 
					  <link rel=icon type=image/png sizes=32x32 href=img/icons/favicon-32x32.png> | 
				
			||||||
 | 
					  <link rel=icon type=image/png sizes=16x16 href=img/icons/favicon-16x16.png> | 
				
			||||||
 | 
					  <link rel=manifest href=manifest.json> | 
				
			||||||
 | 
					  <meta name=theme-color content=#4DBA87> | 
				
			||||||
 | 
					  <meta name=apple-mobile-web-app-capable content=no> | 
				
			||||||
 | 
					  <meta name=apple-mobile-web-app-status-bar-style content=default> | 
				
			||||||
 | 
					  <meta name=apple-mobile-web-app-title content=yd-web-tool> | 
				
			||||||
 | 
					  <link rel=apple-touch-icon href=img/icons/apple-touch-icon-152x152.png> | 
				
			||||||
 | 
					  <link rel=mask-icon href=img/icons/safari-pinned-tab.svg color=#4DBA87> | 
				
			||||||
 | 
					  <meta name=msapplication-TileImage content=img/icons/msapplication-icon-144x144.png> | 
				
			||||||
 | 
					  <meta name=msapplication-TileColor content=#000000> | 
				
			||||||
 | 
					</head> | 
				
			||||||
 | 
					<style> | 
				
			||||||
 | 
					  body::-webkit-scrollbar { | 
				
			||||||
 | 
					    display: none; | 
				
			||||||
 | 
					  } | 
				
			||||||
 | 
					</style> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<body style="margin: 0;height:100%"><noscript><strong>We're sorry but yd-web-tool doesn't work properly without | 
				
			||||||
 | 
					      JavaScript enabled. Please enable it to continue.</strong></noscript> | 
				
			||||||
 | 
					  <div id=app></div> | 
				
			||||||
 | 
					  <script src=js/chunk-vendors.b3838a2d.js></script> | 
				
			||||||
 | 
					  <script src=js/app.b25f3cec.js></script> | 
				
			||||||
 | 
					</body> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</html> | 
				
			||||||
| 
		 Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB  | 
| 
		 Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB  | 
| 
		 Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB  | 
| 
		 Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB  | 
| 
		 Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB  | 
| 
		 Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB  | 
| 
		 Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB  | 
| 
		 Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB  | 
| 
		 Before Width: | Height: | Size: 799 B After Width: | Height: | Size: 799 B  | 
| 
		 Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB  | 
| 
		 Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB  | 
| 
		 Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB  | 
| 
		 Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB  | 
| 
		 Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB  | 
@ -1,8 +1,39 @@ | 
				
			|||||||
package io.legado.app.data.entities.rule | 
					package io.legado.app.data.entities.rule | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.os.Parcel | 
				
			||||||
 | 
					import android.os.Parcelable | 
				
			||||||
 | 
					
 | 
				
			||||||
data class ContentRule( | 
					data class ContentRule( | 
				
			||||||
    var content: String? = null, | 
					    var content: String? = null, | 
				
			||||||
    var nextContentUrl: String? = null, | 
					    var nextContentUrl: String? = null, | 
				
			||||||
    var webJs: String? = null, | 
					    var webJs: String? = null, | 
				
			||||||
    var sourceRegex: String? = null | 
					    var sourceRegex: String? = null | 
				
			||||||
) | 
					) : Parcelable { | 
				
			||||||
 | 
					    constructor(parcel: Parcel) : this( | 
				
			||||||
 | 
					        parcel.readString(), | 
				
			||||||
 | 
					        parcel.readString(), | 
				
			||||||
 | 
					        parcel.readString(), | 
				
			||||||
 | 
					        parcel.readString() | 
				
			||||||
 | 
					    ) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun writeToParcel(dest: Parcel, flags: Int) { | 
				
			||||||
 | 
					        dest.writeString(content) | 
				
			||||||
 | 
					        dest.writeString(nextContentUrl) | 
				
			||||||
 | 
					        dest.writeString(webJs) | 
				
			||||||
 | 
					        dest.writeString(sourceRegex) | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun describeContents(): Int { | 
				
			||||||
 | 
					        return 0 | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    companion object CREATOR : Parcelable.Creator<ContentRule> { | 
				
			||||||
 | 
					        override fun createFromParcel(parcel: Parcel): ContentRule { | 
				
			||||||
 | 
					            return ContentRule(parcel) | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        override fun newArray(size: Int): Array<ContentRule?> { | 
				
			||||||
 | 
					            return arrayOfNulls(size) | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,54 @@ | 
				
			|||||||
 | 
					package io.legado.app.help | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.os.Handler | 
				
			||||||
 | 
					import android.os.Looper | 
				
			||||||
 | 
					import io.legado.app.App | 
				
			||||||
 | 
					import io.legado.app.data.entities.RssSource | 
				
			||||||
 | 
					import io.legado.app.utils.EncoderUtils | 
				
			||||||
 | 
					import io.legado.app.utils.NetworkUtils | 
				
			||||||
 | 
					import io.legado.app.utils.splitNotBlank | 
				
			||||||
 | 
					import org.jetbrains.anko.toast | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object SourceHelp { | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private val handler = Handler(Looper.getMainLooper()) | 
				
			||||||
 | 
					    private val list18Plus by lazy { | 
				
			||||||
 | 
					        try { | 
				
			||||||
 | 
					            return@lazy String(App.INSTANCE.assets.open("18PlusList.txt").readBytes()) | 
				
			||||||
 | 
					                .splitNotBlank("\n") | 
				
			||||||
 | 
					        } catch (e: Exception) { | 
				
			||||||
 | 
					            return@lazy arrayOf<String>() | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun insertRssSource(vararg rssSources: RssSource) { | 
				
			||||||
 | 
					        rssSources.forEach { rssSource -> | 
				
			||||||
 | 
					            if (is18Plus(rssSource.sourceUrl)) { | 
				
			||||||
 | 
					                handler.post { | 
				
			||||||
 | 
					                    App.INSTANCE.toast("${rssSource.sourceName}是18+网址,禁止导入.") | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					            } else { | 
				
			||||||
 | 
					                App.db.rssSourceDao().insert(rssSource) | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun is18Plus(url: String?): Boolean { | 
				
			||||||
 | 
					        url ?: return false | 
				
			||||||
 | 
					        if (AppConfig.isGooglePlay) return false | 
				
			||||||
 | 
					        val baseUrl = NetworkUtils.getBaseUrl(url) | 
				
			||||||
 | 
					        baseUrl ?: return false | 
				
			||||||
 | 
					        try { | 
				
			||||||
 | 
					            val host = baseUrl.split("//", ".") | 
				
			||||||
 | 
					            val base64Url = EncoderUtils.base64Encode("${host[host.lastIndex - 1]}.${host.last()}") | 
				
			||||||
 | 
					            list18Plus.forEach { | 
				
			||||||
 | 
					                if (base64Url == it) { | 
				
			||||||
 | 
					                    return true | 
				
			||||||
 | 
					                } | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } catch (e: Exception) { | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return false | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,32 @@ | 
				
			|||||||
 | 
					package io.legado.app.help.storage | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import io.legado.app.data.entities.ReplaceRule | 
				
			||||||
 | 
					import io.legado.app.utils.* | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object OldReplace { | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun jsonToReplaceRule(json: String): ReplaceRule? { | 
				
			||||||
 | 
					        var replaceRule: ReplaceRule? = null | 
				
			||||||
 | 
					        runCatching { | 
				
			||||||
 | 
					            replaceRule = GSON.fromJsonObject<ReplaceRule>(json.trim()) | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        runCatching { | 
				
			||||||
 | 
					            if (replaceRule == null || replaceRule?.pattern.isNullOrBlank()) { | 
				
			||||||
 | 
					                val jsonItem = Restore.jsonPath.parse(json.trim()) | 
				
			||||||
 | 
					                val rule = ReplaceRule() | 
				
			||||||
 | 
					                rule.id = jsonItem.readLong("$.id") ?: System.currentTimeMillis() | 
				
			||||||
 | 
					                rule.pattern = jsonItem.readString("$.regex") ?: "" | 
				
			||||||
 | 
					                if (rule.pattern.isEmpty()) return null | 
				
			||||||
 | 
					                rule.name = jsonItem.readString("$.replaceSummary") ?: "" | 
				
			||||||
 | 
					                rule.replacement = jsonItem.readString("$.replacement") ?: "" | 
				
			||||||
 | 
					                rule.isRegex = jsonItem.readBool("$.isRegex") == true | 
				
			||||||
 | 
					                rule.scope = jsonItem.readString("$.useTo") | 
				
			||||||
 | 
					                rule.isEnabled = jsonItem.readBool("$.enable") == true | 
				
			||||||
 | 
					                rule.order = jsonItem.readInt("$.serialNumber") ?: 0 | 
				
			||||||
 | 
					                return rule | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        return replaceRule | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,100 @@ | 
				
			|||||||
 | 
					package io.legado.app.ui.book.read.config | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.os.Bundle | 
				
			||||||
 | 
					import android.util.DisplayMetrics | 
				
			||||||
 | 
					import android.view.Gravity | 
				
			||||||
 | 
					import android.view.LayoutInflater | 
				
			||||||
 | 
					import android.view.View | 
				
			||||||
 | 
					import android.view.ViewGroup | 
				
			||||||
 | 
					import android.widget.SeekBar | 
				
			||||||
 | 
					import io.legado.app.R | 
				
			||||||
 | 
					import io.legado.app.base.BaseDialogFragment | 
				
			||||||
 | 
					import io.legado.app.help.ReadBookConfig | 
				
			||||||
 | 
					import io.legado.app.lib.theme.bottomBackground | 
				
			||||||
 | 
					import io.legado.app.service.BaseReadAloudService | 
				
			||||||
 | 
					import io.legado.app.service.help.ReadAloud | 
				
			||||||
 | 
					import io.legado.app.ui.book.read.Help | 
				
			||||||
 | 
					import kotlinx.android.synthetic.main.dialog_auto_read.* | 
				
			||||||
 | 
					import org.jetbrains.anko.sdk27.listeners.onClick | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AutoReadDialog : BaseDialogFragment() { | 
				
			||||||
 | 
					    var callBack: CallBack? = null | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun onStart() { | 
				
			||||||
 | 
					        super.onStart() | 
				
			||||||
 | 
					        val dm = DisplayMetrics() | 
				
			||||||
 | 
					        activity?.let { | 
				
			||||||
 | 
					            Help.upSystemUiVisibility(it) | 
				
			||||||
 | 
					            it.windowManager?.defaultDisplay?.getMetrics(dm) | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        dialog?.window?.let { | 
				
			||||||
 | 
					            it.setBackgroundDrawableResource(R.color.background) | 
				
			||||||
 | 
					            it.decorView.setPadding(0, 0, 0, 0) | 
				
			||||||
 | 
					            val attr = it.attributes | 
				
			||||||
 | 
					            attr.dimAmount = 0.0f | 
				
			||||||
 | 
					            attr.gravity = Gravity.BOTTOM | 
				
			||||||
 | 
					            it.attributes = attr | 
				
			||||||
 | 
					            it.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun onCreateView( | 
				
			||||||
 | 
					        inflater: LayoutInflater, | 
				
			||||||
 | 
					        container: ViewGroup?, | 
				
			||||||
 | 
					        savedInstanceState: Bundle? | 
				
			||||||
 | 
					    ): View? { | 
				
			||||||
 | 
					        callBack = activity as? CallBack | 
				
			||||||
 | 
					        return inflater.inflate(R.layout.dialog_auto_read, container) | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { | 
				
			||||||
 | 
					        root_view.setBackgroundColor(requireContext().bottomBackground) | 
				
			||||||
 | 
					        initOnChange() | 
				
			||||||
 | 
					        initData() | 
				
			||||||
 | 
					        initEvent() | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun initData() { | 
				
			||||||
 | 
					        seek_auto_read.progress = ReadBookConfig.autoReadSpeed | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun initOnChange() { | 
				
			||||||
 | 
					        seek_auto_read.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { | 
				
			||||||
 | 
					            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            override fun onStartTrackingTouch(seekBar: SeekBar?) = Unit | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            override fun onStopTrackingTouch(seekBar: SeekBar?) { | 
				
			||||||
 | 
					                ReadBookConfig.autoReadSpeed = seek_auto_read.progress | 
				
			||||||
 | 
					                upTtsSpeechRate() | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					        }) | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun initEvent() { | 
				
			||||||
 | 
					        ll_main_menu.onClick { callBack?.showMenuBar(); dismiss() } | 
				
			||||||
 | 
					        ll_setting.onClick { | 
				
			||||||
 | 
					            ReadAloudConfigDialog().show(childFragmentManager, "readAloudConfigDialog") | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        ll_catalog.onClick { callBack?.openChapterList() } | 
				
			||||||
 | 
					        ll_auto_page_stop.onClick { | 
				
			||||||
 | 
					            callBack?.autoPageStop() | 
				
			||||||
 | 
					            dismiss() | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun upTtsSpeechRate() { | 
				
			||||||
 | 
					        ReadAloud.upTtsSpeechRate(requireContext()) | 
				
			||||||
 | 
					        if (!BaseReadAloudService.pause) { | 
				
			||||||
 | 
					            ReadAloud.pause(requireContext()) | 
				
			||||||
 | 
					            ReadAloud.resume(requireContext()) | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    interface CallBack { | 
				
			||||||
 | 
					        fun showMenuBar() | 
				
			||||||
 | 
					        fun openChapterList() | 
				
			||||||
 | 
					        fun autoPageStop() | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					} | 
				
			||||||