格式化代码

pull/1771/head
kunfei 3 years ago
parent 34bde6bc21
commit fc2b1cb1ff
  1. 1
      app/src/main/java/io/legado/app/constant/AppPattern.kt
  2. 1
      app/src/main/java/io/legado/app/data/README.md
  3. 32
      app/src/main/java/io/legado/app/data/entities/BookSource.kt
  4. 24
      app/src/main/java/io/legado/app/data/entities/RssSource.kt
  5. 6
      app/src/main/java/io/legado/app/help/BookHelp.kt
  6. 32
      app/src/main/java/io/legado/app/help/RuleComplete.kt
  7. 2
      app/src/main/java/io/legado/app/help/exoplayer/OkhttpCacheDataSource.java
  8. 2
      app/src/main/java/io/legado/app/help/http/CookieStore.kt
  9. 2
      app/src/main/java/io/legado/app/help/http/HttpHelper.kt
  10. 5
      app/src/main/java/io/legado/app/help/http/cronet/CronetLoader.kt
  11. 2
      app/src/main/java/io/legado/app/help/storage/AppWebDav.kt
  12. 1
      app/src/main/java/io/legado/app/lib/README.md
  13. 7
      app/src/main/java/io/legado/app/model/CheckSource.kt
  14. 5
      app/src/main/java/io/legado/app/model/Debug.kt
  15. 1
      app/src/main/java/io/legado/app/model/README.md
  16. 2
      app/src/main/java/io/legado/app/model/ReadBook.kt
  17. 6
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt
  18. 2
      app/src/main/java/io/legado/app/service/CheckSourceService.kt
  19. 2
      app/src/main/java/io/legado/app/service/HttpReadAloudService.kt
  20. 1
      app/src/main/java/io/legado/app/service/README.md
  21. 3
      app/src/main/java/io/legado/app/ui/book/audio/ComposeView.kt
  22. 2
      app/src/main/java/io/legado/app/ui/book/bookmark/BookmarkAdapter.kt
  23. 2
      app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt
  24. 2
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceAdapter.kt
  25. 2
      app/src/main/java/io/legado/app/ui/book/read/BaseReadBookActivity.kt
  26. 2
      app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt
  27. 2
      app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt
  28. 4
      app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt
  29. 15
      app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentViewModel.kt
  30. 9
      app/src/main/java/io/legado/app/ui/book/searchContent/SearchResult.kt
  31. 8
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceAdapter.kt
  32. 12
      app/src/main/java/io/legado/app/ui/book/toc/ChapterListAdapter.kt
  33. 1
      app/src/main/java/io/legado/app/ui/config/CheckSourceConfig.kt
  34. 4
      app/src/main/java/io/legado/app/ui/dict/DictViewModel.kt
  35. 70
      app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BaseBooksAdapter.kt
  36. 4
      app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceAdapter.kt
  37. 2
      app/src/main/java/io/legado/app/ui/widget/BatteryView.kt
  38. 8
      app/src/main/java/io/legado/app/utils/ACache.kt
  39. 5
      app/src/main/java/io/legado/app/utils/ContextExtensions.kt
  40. 2
      app/src/main/java/io/legado/app/utils/FileUtils.kt
  41. 2
      app/src/main/java/io/legado/app/utils/NetworkUtils.kt
  42. 18
      app/src/main/java/io/legado/app/utils/Utf8BomUtils.kt

@ -10,6 +10,7 @@ object AppPattern {
//匹配格式化后的图片格式 //匹配格式化后的图片格式
val imgPattern: Pattern = Pattern.compile("<img[^>]*src=\"([^\"]*(?:\"[^>]+\\})?)\"[^>]*>") val imgPattern: Pattern = Pattern.compile("<img[^>]*src=\"([^\"]*(?:\"[^>]+\\})?)\"[^>]*>")
//dataURL图片类型 //dataURL图片类型
val dataUriRegex = Regex("data:.*?;base64,(.*)") val dataUriRegex = Regex("data:.*?;base64,(.*)")

@ -1,4 +1,5 @@
# 存储数据用 # 存储数据用
* dao 数据操作 * dao 数据操作
* entities 数据模型 * entities 数据模型
* \Book 书籍信息 * \Book 书籍信息

@ -183,22 +183,22 @@ data class BookSource(
fun equal(source: BookSource) = fun equal(source: BookSource) =
equal(bookSourceName, source.bookSourceName) equal(bookSourceName, source.bookSourceName)
&& equal(bookSourceUrl, source.bookSourceUrl) && equal(bookSourceUrl, source.bookSourceUrl)
&& equal(bookSourceGroup, source.bookSourceGroup) && equal(bookSourceGroup, source.bookSourceGroup)
&& bookSourceType == source.bookSourceType && bookSourceType == source.bookSourceType
&& equal(bookUrlPattern, source.bookUrlPattern) && equal(bookUrlPattern, source.bookUrlPattern)
&& equal(bookSourceComment, source.bookSourceComment) && equal(bookSourceComment, source.bookSourceComment)
&& enabled == source.enabled && enabled == source.enabled
&& enabledExplore == source.enabledExplore && enabledExplore == source.enabledExplore
&& equal(header, source.header) && equal(header, source.header)
&& loginUrl == source.loginUrl && loginUrl == source.loginUrl
&& equal(exploreUrl, source.exploreUrl) && equal(exploreUrl, source.exploreUrl)
&& equal(searchUrl, source.searchUrl) && equal(searchUrl, source.searchUrl)
&& getSearchRule() == source.getSearchRule() && getSearchRule() == source.getSearchRule()
&& getExploreRule() == source.getExploreRule() && getExploreRule() == source.getExploreRule()
&& getBookInfoRule() == source.getBookInfoRule() && getBookInfoRule() == source.getBookInfoRule()
&& getTocRule() == source.getTocRule() && getTocRule() == source.getTocRule()
&& getContentRule() == source.getContentRule() && getContentRule() == source.getContentRule()
private fun equal(a: String?, b: String?) = a == b || (a.isNullOrEmpty() && b.isNullOrEmpty()) private fun equal(a: String?, b: String?) = a == b || (a.isNullOrEmpty() && b.isNullOrEmpty())

@ -63,18 +63,18 @@ data class RssSource(
fun equal(source: RssSource): Boolean { fun equal(source: RssSource): Boolean {
return equal(sourceUrl, source.sourceUrl) return equal(sourceUrl, source.sourceUrl)
&& equal(sourceIcon, source.sourceIcon) && equal(sourceIcon, source.sourceIcon)
&& enabled == source.enabled && enabled == source.enabled
&& equal(sourceGroup, source.sourceGroup) && equal(sourceGroup, source.sourceGroup)
&& equal(ruleArticles, source.ruleArticles) && equal(ruleArticles, source.ruleArticles)
&& equal(ruleNextPage, source.ruleNextPage) && equal(ruleNextPage, source.ruleNextPage)
&& equal(ruleTitle, source.ruleTitle) && equal(ruleTitle, source.ruleTitle)
&& equal(rulePubDate, source.rulePubDate) && equal(rulePubDate, source.rulePubDate)
&& equal(ruleDescription, source.ruleDescription) && equal(ruleDescription, source.ruleDescription)
&& equal(ruleLink, source.ruleLink) && equal(ruleLink, source.ruleLink)
&& equal(ruleContent, source.ruleContent) && equal(ruleContent, source.ruleContent)
&& enableJs == source.enableJs && enableJs == source.enableJs
&& loadWithBaseUrl == source.loadWithBaseUrl && loadWithBaseUrl == source.loadWithBaseUrl
} }
private fun equal(a: String?, b: String?): Boolean { private fun equal(a: String?, b: String?): Boolean {

@ -324,9 +324,9 @@ object BookHelp {
val chapterName1 = StringUtils.fullToHalf(chapterName).replace(regexA, "") val chapterName1 = StringUtils.fullToHalf(chapterName).replace(regexA, "")
return StringUtils.stringToInt( return StringUtils.stringToInt(
( (
chapterNamePattern1.matcher(chapterName1).takeIf { it.find() } chapterNamePattern1.matcher(chapterName1).takeIf { it.find() }
?: chapterNamePattern2.matcher(chapterName1).takeIf { it.find() } ?: chapterNamePattern2.matcher(chapterName1).takeIf { it.find() }
)?.group(1) )?.group(1)
?: "-1" ?: "-1"
) )
} }

@ -1,18 +1,21 @@
package io.legado.app.help package io.legado.app.help
@Suppress("RegExpRedundantEscape")
object RuleComplete { object RuleComplete {
// 需要补全 // 需要补全
private val needComplete =Regex( private val needComplete = Regex(
"""(?<!(@|/|^|[|%&]{2})(attr|text|ownText|textNodes|href|content|html|alt|all|value|src)(\(\))?)(?<seq>\&{2}|%%|\|{2}|$)""") """(?<!(@|/|^|[|%&]{2})(attr|text|ownText|textNodes|href|content|html|alt|all|value|src)(\(\))?)(?<seq>\&{2}|%%|\|{2}|$)"""
)
// 不能补全 存在js/json/{{xx}}的复杂情况 // 不能补全 存在js/json/{{xx}}的复杂情况
private val notComplete = Regex("""^:|^##|\{\{|@js:|<js>|@Json:|\$\.""") private val notComplete = Regex("""^:|^##|\{\{|@js:|<js>|@Json:|\$\.""")
// 修正从图片获取信息 // 修正从图片获取信息
private val fixImgInfo = Regex("""(?<=(^|tag\.|[\+/@>~| &]))img(?<at>(\[@?.+\]|\.[-\w]+)?)[@/]+text(\(\))?(?<seq>\&{2}|%%|\|{2}|$)""") private val fixImgInfo =
Regex("""(?<=(^|tag\.|[\+/@>~| &]))img(?<at>(\[@?.+\]|\.[-\w]+)?)[@/]+text(\(\))?(?<seq>\&{2}|%%|\|{2}|$)""")
private val isXpath= Regex("^//|^@Xpath:") private val isXpath = Regex("^//|^@Xpath:")
/** /**
* 对简单规则进行补全简化部分书源规则的编写 * 对简单规则进行补全简化部分书源规则的编写
@ -31,33 +34,38 @@ object RuleComplete {
preRule: String? = null, preRule: String? = null,
type: Int = 1 type: Int = 1
): String? { ): String? {
if (rules.isNullOrEmpty()||rules.contains(notComplete) || preRule?.contains(notComplete) ?: false){ if (rules.isNullOrEmpty() || rules.contains(notComplete) || preRule?.contains(notComplete) == true) {
return rules return rules
} }
/** 尾部##分割的正则或由,分割的参数 */ /** 尾部##分割的正则或由,分割的参数 */
val tailStr: String val tailStr: String
/** 分割字符 */ /** 分割字符 */
val splitStr:String val splitStr: String
/** 用于获取文字时添加的规则 */ /** 用于获取文字时添加的规则 */
val textRule: String val textRule: String
/** 用于获取链接时添加的规则 */ /** 用于获取链接时添加的规则 */
val linkRule: String val linkRule: String
/** 用于获取图片时添加的规则 */ /** 用于获取图片时添加的规则 */
val imgRule: String val imgRule: String
/** 用于获取图片alt属性时添加的规则 */ /** 用于获取图片alt属性时添加的规则 */
val imgText: String val imgText: String
// 分离尾部规则 // 分离尾部规则
val regexSplit=rules.split("""##|,\{""".toRegex(),2) val regexSplit = rules.split("""##|,\{""".toRegex(), 2)
val cleanedRule=regexSplit[0] val cleanedRule = regexSplit[0]
if (regexSplit.size>1){ if (regexSplit.size > 1) {
splitStr="""##|,\{""".toRegex().find(rules)?.value ?: "" splitStr = """##|,\{""".toRegex().find(rules)?.value ?: ""
tailStr = splitStr + regexSplit[1] tailStr = splitStr + regexSplit[1]
}else{ } else {
tailStr = "" tailStr = ""
} }
if (cleanedRule.contains(isXpath)){ if (cleanedRule.contains(isXpath)) {
textRule = "//text()\${seq}" textRule = "//text()\${seq}"
linkRule = "//@href\${seq}" linkRule = "//@href\${seq}"
imgRule = "//@src\${seq}" imgRule = "//@src\${seq}"

@ -173,7 +173,7 @@ public final class OkhttpCacheDataSource implements DataSource {
return this; return this;
} }
public Factory setDefaultRequestProperties(Map<String, String> defaultRequestProperties){ public Factory setDefaultRequestProperties(Map<String, String> defaultRequestProperties) {
if (this.upstreamDataSourceFactory != null) { if (this.upstreamDataSourceFactory != null) {
this.upstreamDataSourceFactory.setDefaultRequestProperties(defaultRequestProperties); this.upstreamDataSourceFactory.setDefaultRequestProperties(defaultRequestProperties);
} }

@ -34,7 +34,7 @@ object CookieStore : CookieManager {
val cookieBean = appDb.cookieDao.get(NetworkUtils.getSubDomain(url)) val cookieBean = appDb.cookieDao.get(NetworkUtils.getSubDomain(url))
return cookieBean?.cookie ?: "" return cookieBean?.cookie ?: ""
} }
fun getKey(url: String, key: String): String { fun getKey(url: String, key: String): String {
val cookie = getCookie(url) val cookie = getCookie(url)
val cookieMap = cookieToMap(cookie) val cookieMap = cookieToMap(cookie)

@ -27,7 +27,7 @@ val okHttpClient: OkHttpClient by lazy {
.connectTimeout(15, TimeUnit.SECONDS) .connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS) .writeTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS) .readTimeout(15, TimeUnit.SECONDS)
.callTimeout(60,TimeUnit.SECONDS) .callTimeout(60, TimeUnit.SECONDS)
.sslSocketFactory(SSLHelper.unsafeSSLSocketFactory, SSLHelper.unsafeTrustManager) .sslSocketFactory(SSLHelper.unsafeSSLSocketFactory, SSLHelper.unsafeTrustManager)
.retryOnConnectionFailure(true) .retryOnConnectionFailure(true)
.hostnameVerifier(SSLHelper.unsafeHostnameVerifier) .hostnameVerifier(SSLHelper.unsafeHostnameVerifier)

@ -34,13 +34,14 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
private var cpuAbi: String? = null private var cpuAbi: String? = null
private var md5: String private var md5: String
var download = false var download = false
@Volatile @Volatile
private var cacheInstall = false private var cacheInstall = false
init { init {
soUrl = ("https://storage.googleapis.com/chromium-cronet/android/" soUrl = ("https://storage.googleapis.com/chromium-cronet/android/"
+ soVersion + "/Release/cronet/libs/" + soVersion + "/Release/cronet/libs/"
+ getCpuAbi(appCtx) + "/" + soName) + getCpuAbi(appCtx) + "/" + soName)
md5 = getMd5(appCtx) md5 = getMd5(appCtx)
val dir = appCtx.getDir("cronet", Context.MODE_PRIVATE) val dir = appCtx.getDir("cronet", Context.MODE_PRIVATE)
soFile = File(dir.toString() + "/" + getCpuAbi(appCtx), soName) soFile = File(dir.toString() + "/" + getCpuAbi(appCtx), soName)

@ -205,7 +205,7 @@ object AppWebDav {
getBookProgress(book)?.let { bookProgress -> getBookProgress(book)?.let { bookProgress ->
if (bookProgress.durChapterIndex > book.durChapterIndex || if (bookProgress.durChapterIndex > book.durChapterIndex ||
(bookProgress.durChapterIndex == book.durChapterIndex && (bookProgress.durChapterIndex == book.durChapterIndex &&
bookProgress.durChapterPos > book.durChapterPos) bookProgress.durChapterPos > book.durChapterPos)
) { ) {
book.durChapterIndex = bookProgress.durChapterIndex book.durChapterIndex = bookProgress.durChapterIndex
book.durChapterPos = bookProgress.durChapterPos book.durChapterPos = bookProgress.durChapterPos

@ -1,4 +1,5 @@
# 放置一些copy过来的库 # 放置一些copy过来的库
* dialogs 弹出框 * dialogs 弹出框
* icu4j 编码识别库 * icu4j 编码识别库
* permission 权限申请库 * permission 权限申请库

@ -11,6 +11,7 @@ import splitties.init.appCtx
object CheckSource { object CheckSource {
var keyword = "我的" var keyword = "我的"
//校验设置 //校验设置
var timeout = CacheManager.getLong("checkSourceTimeout") ?: 180000L var timeout = CacheManager.getLong("checkSourceTimeout") ?: 180000L
var checkSearch = CacheManager.get("checkSearch")?.toBoolean() ?: true var checkSearch = CacheManager.get("checkSearch")?.toBoolean() ?: true
@ -53,6 +54,10 @@ object CheckSource {
if (checkInfo) checkItem = "$checkItem ${appCtx.getString(R.string.source_tab_info)}" if (checkInfo) checkItem = "$checkItem ${appCtx.getString(R.string.source_tab_info)}"
if (checkCategory) checkItem = "$checkItem ${appCtx.getString(R.string.chapter_list)}" if (checkCategory) checkItem = "$checkItem ${appCtx.getString(R.string.chapter_list)}"
if (checkContent) checkItem = "$checkItem ${appCtx.getString(R.string.main_body)}" if (checkContent) checkItem = "$checkItem ${appCtx.getString(R.string.main_body)}"
return appCtx.getString(R.string.check_source_config_summary, (timeout / 1000).toString(), checkItem) return appCtx.getString(
R.string.check_source_config_summary,
(timeout / 1000).toString(),
checkItem
)
} }
} }

@ -55,7 +55,7 @@ object Debug {
if (showTime && debugTimeMap[sourceUrl] != null) { if (showTime && debugTimeMap[sourceUrl] != null) {
val time = val time =
debugTimeFormat.format(Date(System.currentTimeMillis() - debugTimeMap[sourceUrl]!!)) debugTimeFormat.format(Date(System.currentTimeMillis() - debugTimeMap[sourceUrl]!!))
printMsg = printMsg.replace(AppPattern.debugMessageSymbolRegex,"") printMsg = printMsg.replace(AppPattern.debugMessageSymbolRegex, "")
debugMessageMap[sourceUrl] = "$time $printMsg" debugMessageMap[sourceUrl] = "$time $printMsg"
} }
@ -93,7 +93,8 @@ object Debug {
fun updateFinalMessage(sourceUrl: String, state: String) { fun updateFinalMessage(sourceUrl: String, state: String) {
if (debugTimeMap[sourceUrl] != null && debugMessageMap[sourceUrl] != null) { if (debugTimeMap[sourceUrl] != null && debugMessageMap[sourceUrl] != null) {
val spendingTime = System.currentTimeMillis() - debugTimeMap[sourceUrl]!! val spendingTime = System.currentTimeMillis() - debugTimeMap[sourceUrl]!!
debugTimeMap[sourceUrl] = if (state == "校验成功") spendingTime else CheckSource.timeout + spendingTime debugTimeMap[sourceUrl] =
if (state == "校验成功") spendingTime else CheckSource.timeout + spendingTime
val printTime = debugTimeFormat.format(Date(spendingTime)) val printTime = debugTimeFormat.format(Date(spendingTime))
debugMessageMap[sourceUrl] = "$printTime $state" debugMessageMap[sourceUrl] = "$printTime $state"
} }

@ -1,4 +1,5 @@
# 放置一些模块类 # 放置一些模块类
* analyzeRule 书源规则解析 * analyzeRule 书源规则解析
* localBook 本地书籍解析 * localBook 本地书籍解析
* rss 订阅规则解析 * rss 订阅规则解析

@ -91,7 +91,7 @@ object ReadBook : CoroutineScope by MainScope() {
fun setProgress(progress: BookProgress) { fun setProgress(progress: BookProgress) {
if (progress.durChapterIndex < chapterSize && if (progress.durChapterIndex < chapterSize &&
(durChapterIndex != progress.durChapterIndex (durChapterIndex != progress.durChapterIndex
|| durChapterPos != progress.durChapterPos) || durChapterPos != progress.durChapterPos)
) { ) {
durChapterIndex = progress.durChapterIndex durChapterIndex = progress.durChapterIndex
durChapterPos = progress.durChapterPos durChapterPos = progress.durChapterPos

@ -600,9 +600,9 @@ class AnalyzeRule(
private fun isRule(ruleStr: String): Boolean { private fun isRule(ruleStr: String): Boolean {
return ruleStr.startsWith('@') //js首个字符不可能是@,除非是装饰器,所以@开头规定为规则 return ruleStr.startsWith('@') //js首个字符不可能是@,除非是装饰器,所以@开头规定为规则
|| ruleStr.startsWith("$.") || ruleStr.startsWith("$.")
|| ruleStr.startsWith("$[") || ruleStr.startsWith("$[")
|| ruleStr.startsWith("//") || ruleStr.startsWith("//")
} }
} }

@ -181,7 +181,7 @@ class CheckSourceService : BaseService() {
if (finalCheckMessage.isNotBlank()) throw NoStackTraceException(finalCheckMessage) if (finalCheckMessage.isNotBlank()) throw NoStackTraceException(finalCheckMessage)
}.timeout(CheckSource.timeout) }.timeout(CheckSource.timeout)
.onError(searchCoroutine) { .onError(searchCoroutine) {
when(it) { when (it) {
is TimeoutCancellationException -> source.addGroup("校验超时") is TimeoutCancellationException -> source.addGroup("校验超时")
is ScriptException, is WrappedException -> source.addGroup("js失效") is ScriptException, is WrappedException -> source.addGroup("js失效")
!is NoStackTraceException -> source.addGroup("网站失效") !is NoStackTraceException -> source.addGroup("网站失效")

@ -229,7 +229,7 @@ class HttpReadAloudService : BaseReadAloudService(),
private fun md5SpeakFileName(url: String, ttsConfig: String, content: String): String { private fun md5SpeakFileName(url: String, ttsConfig: String, content: String): String {
return MD5Utils.md5Encode16(textChapter?.title ?: "") + "_" + return MD5Utils.md5Encode16(textChapter?.title ?: "") + "_" +
MD5Utils.md5Encode16("$url-|-$ttsConfig-|-$content") MD5Utils.md5Encode16("$url-|-$ttsConfig-|-$content")
} }
private fun createSilentSound(fileName: String) { private fun createSilentSound(fileName: String) {

@ -1,4 +1,5 @@
# android服务 # android服务
* AudioPlayService 音频播放服务 * AudioPlayService 音频播放服务
* CheckSourceService 书源检测服务 * CheckSourceService 书源检测服务
* DownloadService 缓存服务 * DownloadService 缓存服务

@ -28,7 +28,8 @@ fun TimerDialog(state: MutableState<Boolean>, parent: View) {
Card(Modifier.fillMaxWidth()) { Card(Modifier.fillMaxWidth()) {
Slider( Slider(
modifier = Modifier.padding(horizontal = 16.dp), modifier = Modifier.padding(horizontal = 16.dp),
value = timeMinute.value.toFloat(), onValueChange = { value = timeMinute.value.toFloat(),
onValueChange = {
timeMinute.value = it.toInt() timeMinute.value = it.toInt()
AudioPlay.setTimer(it.toInt()) AudioPlay.setTimer(it.toInt())
}, },

@ -48,7 +48,7 @@ class BookmarkAdapter(context: Context, val callback: Callback) :
val lastItem = getItem(position - 1) val lastItem = getItem(position - 1)
val curItem = getItem(position) val curItem = getItem(position)
return !(lastItem?.bookName == curItem?.bookName return !(lastItem?.bookName == curItem?.bookName
&& lastItem?.bookAuthor == curItem?.bookAuthor) && lastItem?.bookAuthor == curItem?.bookAuthor)
} }
interface Callback { interface Callback {

@ -278,7 +278,7 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
when { when {
//正文模板 //正文模板
file.name.equals("chapter.html", true) file.name.equals("chapter.html", true)
|| file.name.equals("chapter.xhtml", true) -> { || file.name.equals("chapter.xhtml", true) -> {
contentModel = file.readText(context) contentModel = file.readText(context)
} }
//封面等其他模板 //封面等其他模板

@ -29,7 +29,7 @@ class ChangeChapterSourceAdapter(
override fun areContentsTheSame(oldItem: SearchBook, newItem: SearchBook): Boolean { override fun areContentsTheSame(oldItem: SearchBook, newItem: SearchBook): Boolean {
return oldItem.originName == newItem.originName return oldItem.originName == newItem.originName
&& oldItem.getDisplayLastChapterTitle() == newItem.getDisplayLastChapterTitle() && oldItem.getDisplayLastChapterTitle() == newItem.getDisplayLastChapterTitle()
} }
} }

@ -45,7 +45,7 @@ abstract class BaseReadBookActivity :
override val binding by viewBinding(ActivityBookReadBinding::inflate) override val binding by viewBinding(ActivityBookReadBinding::inflate)
override val viewModel by viewModels<ReadBookViewModel>() override val viewModel by viewModels<ReadBookViewModel>()
var bottomDialog = 0 var bottomDialog = 0
private val selectBookFolderResult = registerForActivityResult(HandleFileContract()){ private val selectBookFolderResult = registerForActivityResult(HandleFileContract()) {
it.uri?.let { it.uri?.let {
ReadBook.book?.let { book -> ReadBook.book?.let { book ->
viewModel.loadChapterList(book) viewModel.loadChapterList(book)

@ -178,7 +178,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
}.onSuccess { progress -> }.onSuccess { progress ->
if (progress.durChapterIndex < book.durChapterIndex || if (progress.durChapterIndex < book.durChapterIndex ||
(progress.durChapterIndex == book.durChapterIndex (progress.durChapterIndex == book.durChapterIndex
&& progress.durChapterPos < book.durChapterPos) && progress.durChapterPos < book.durChapterPos)
) { ) {
alertSync?.invoke(progress) alertSync?.invoke(progress)
} else { } else {

@ -145,7 +145,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
drawImage(canvas, it, lineTop, lineBottom, isImageLine) drawImage(canvas, it, lineTop, lineBottom, isImageLine)
} else { } else {
textPaint.color = textColor textPaint.color = textColor
if(it.isSearchResult) { if (it.isSearchResult) {
textPaint.color = context.accentColor textPaint.color = context.accentColor
} }
canvas.drawText(it.charData, it.start, lineBase, textPaint) canvas.drawText(it.charData, it.start, lineBase, textPaint)

@ -622,8 +622,8 @@ object ChapterProvider {
*/ */
fun upLayout() { fun upLayout() {
doublePage = (viewWidth > viewHeight || appCtx.isPad) doublePage = (viewWidth > viewHeight || appCtx.isPad)
&& ReadBook.pageAnim() != 3 && ReadBook.pageAnim() != 3
&& AppConfig.doublePageHorizontal && AppConfig.doublePageHorizontal
if (viewWidth > 0 && viewHeight > 0) { if (viewWidth > 0 && viewHeight > 0) {
paddingLeft = ReadBookConfig.paddingLeft.dpToPx() paddingLeft = ReadBookConfig.paddingLeft.dpToPx()
paddingTop = ReadBookConfig.paddingTop.dpToPx() paddingTop = ReadBookConfig.paddingTop.dpToPx()

@ -44,12 +44,15 @@ class SearchContentViewModel(application: Application) : BaseViewModel(applicati
//先搜索没有启用净化的正文 //先搜索没有启用净化的正文
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
chapter.title = when (AppConfig.chineseConverterType) { chapter.title = when (AppConfig.chineseConverterType) {
1 -> ChineseUtils.t2s(chapter.title) 1 -> ChineseUtils.t2s(chapter.title)
2 -> ChineseUtils.s2t(chapter.title) 2 -> ChineseUtils.s2t(chapter.title)
else -> chapter.title else -> chapter.title
} }
mContent = contentProcessor!!.getContent( mContent = contentProcessor!!.getContent(
book, chapter, chapterContent, chineseConvert = false, reSegment = false, useReplace = false book, chapter, chapterContent,
chineseConvert = false,
reSegment = false,
useReplace = false
).joinToString("") ).joinToString("")
} }
val positions = searchPosition(query) val positions = searchPosition(query)
@ -90,7 +93,11 @@ class SearchContentViewModel(application: Application) : BaseViewModel(applicati
return position return position
} }
private fun getResultAndQueryIndex(content: String, queryIndexInContent: Int, query: String): Pair<Int, String> { private fun getResultAndQueryIndex(
content: String,
queryIndexInContent: Int,
query: String
): Pair<Int, String> {
// 左右移动20个字符,构建关键词周边文字,在搜索结果里显示 // 左右移动20个字符,构建关键词周边文字,在搜索结果里显示
// todo: 判断段落,只在关键词所在段落内分割 // todo: 判断段落,只在关键词所在段落内分割
// todo: 利用标点符号分割完整的句 // todo: 利用标点符号分割完整的句

@ -23,9 +23,9 @@ data class SearchResult(
val rightString = val rightString =
resultText.substring(queryIndexInSurrounding + query.length, resultText.length) resultText.substring(queryIndexInSurrounding + query.length, resultText.length)
val html = leftString.colorTextForHtml(textColor) + val html = leftString.colorTextForHtml(textColor) +
query.colorTextForHtml(accentColor) + query.colorTextForHtml(accentColor) +
rightString.colorTextForHtml(textColor) + rightString.colorTextForHtml(textColor) +
chapterTitle.colorTextForHtml(accentColor) chapterTitle.colorTextForHtml(accentColor)
HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY) HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY)
} else { } else {
HtmlCompat.fromHtml( HtmlCompat.fromHtml(
@ -35,6 +35,7 @@ data class SearchResult(
} }
} }
private fun String.colorTextForHtml(textColor: String) = "<font color=#${textColor}>$this</font>" private fun String.colorTextForHtml(textColor: String) =
"<font color=#${textColor}>$this</font>"
} }

@ -52,10 +52,10 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) :
override fun areContentsTheSame(oldItem: BookSource, newItem: BookSource): Boolean { override fun areContentsTheSame(oldItem: BookSource, newItem: BookSource): Boolean {
return oldItem.bookSourceName == newItem.bookSourceName return oldItem.bookSourceName == newItem.bookSourceName
&& oldItem.bookSourceGroup == newItem.bookSourceGroup && oldItem.bookSourceGroup == newItem.bookSourceGroup
&& oldItem.enabled == newItem.enabled && oldItem.enabled == newItem.enabled
&& oldItem.enabledExplore == newItem.enabledExplore && oldItem.enabledExplore == newItem.enabledExplore
&& oldItem.exploreUrl == newItem.exploreUrl && oldItem.exploreUrl == newItem.exploreUrl
} }
override fun getChangePayload(oldItem: BookSource, newItem: BookSource): Any? { override fun getChangePayload(oldItem: BookSource, newItem: BookSource): Any? {

@ -43,12 +43,12 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
newItem: BookChapter newItem: BookChapter
): Boolean { ): Boolean {
return oldItem.bookUrl == newItem.bookUrl return oldItem.bookUrl == newItem.bookUrl
&& oldItem.url == newItem.url && oldItem.url == newItem.url
&& oldItem.isVip == newItem.isVip && oldItem.isVip == newItem.isVip
&& oldItem.isPay == newItem.isPay && oldItem.isPay == newItem.isPay
&& oldItem.title == newItem.title && oldItem.title == newItem.title
&& oldItem.tag == newItem.tag && oldItem.tag == newItem.tag
&& oldItem.isVolume == newItem.isVolume && oldItem.isVolume == newItem.isVolume
} }
} }

@ -18,6 +18,7 @@ import splitties.views.onClick
class CheckSourceConfig : BaseDialogFragment(R.layout.dialog_check_source_config) { class CheckSourceConfig : BaseDialogFragment(R.layout.dialog_check_source_config) {
private val binding by viewBinding(DialogCheckSourceConfigBinding::bind) private val binding by viewBinding(DialogCheckSourceConfigBinding::bind)
//允许的最小超时时间,秒 //允许的最小超时时间,秒
private val minTimeout = 0L private val minTimeout = 0L

@ -15,9 +15,9 @@ class DictViewModel(application: Application) : BaseViewModel(application) {
var dictHtmlData: MutableLiveData<String> = MutableLiveData() var dictHtmlData: MutableLiveData<String> = MutableLiveData()
fun dict(word: String) { fun dict(word: String) {
if(isChinese(word)){ if (isChinese(word)) {
baiduDict(word) baiduDict(word)
}else{ } else {
haiciDict(word) haiciDict(word)
} }

@ -22,46 +22,46 @@ abstract class BaseBooksAdapter<VH : RecyclerView.ViewHolder>(
return when { return when {
oldItem.durChapterTime != newItem.durChapterTime -> false oldItem.durChapterTime != newItem.durChapterTime -> false
oldItem.name != newItem.name -> false oldItem.name != newItem.name -> false
oldItem.author != newItem.author -> false oldItem.author != newItem.author -> false
oldItem.durChapterTitle != newItem.durChapterTitle -> false oldItem.durChapterTitle != newItem.durChapterTitle -> false
oldItem.latestChapterTitle != newItem.latestChapterTitle -> false oldItem.latestChapterTitle != newItem.latestChapterTitle -> false
oldItem.lastCheckCount != newItem.lastCheckCount -> false oldItem.lastCheckCount != newItem.lastCheckCount -> false
oldItem.getDisplayCover() != newItem.getDisplayCover() -> false oldItem.getDisplayCover() != newItem.getDisplayCover() -> false
oldItem.getUnreadChapterNum() != newItem.getUnreadChapterNum() -> false oldItem.getUnreadChapterNum() != newItem.getUnreadChapterNum() -> false
else -> true else -> true
}
} }
}
override fun getChangePayload(oldItem: Book, newItem: Book): Any? { override fun getChangePayload(oldItem: Book, newItem: Book): Any? {
val bundle = bundleOf() val bundle = bundleOf()
if (oldItem.name != newItem.name) { if (oldItem.name != newItem.name) {
bundle.putString("name", newItem.name) bundle.putString("name", newItem.name)
}
if (oldItem.author != newItem.author) {
bundle.putString("author", newItem.author)
}
if (oldItem.durChapterTitle != newItem.durChapterTitle) {
bundle.putString("dur", newItem.durChapterTitle)
}
if (oldItem.latestChapterTitle != newItem.latestChapterTitle) {
bundle.putString("last", newItem.latestChapterTitle)
}
if (oldItem.getDisplayCover() != newItem.getDisplayCover()) {
bundle.putString("cover", newItem.getDisplayCover())
}
if (oldItem.lastCheckCount != newItem.lastCheckCount
|| oldItem.durChapterTime != newItem.durChapterTime
|| oldItem.getUnreadChapterNum() != newItem.getUnreadChapterNum()
|| oldItem.lastCheckCount != newItem.lastCheckCount
) {
bundle.putBoolean("refresh", true)
}
if (bundle.isEmpty) return null
return bundle
} }
if (oldItem.author != newItem.author) {
bundle.putString("author", newItem.author)
}
if (oldItem.durChapterTitle != newItem.durChapterTitle) {
bundle.putString("dur", newItem.durChapterTitle)
}
if (oldItem.latestChapterTitle != newItem.latestChapterTitle) {
bundle.putString("last", newItem.latestChapterTitle)
}
if (oldItem.getDisplayCover() != newItem.getDisplayCover()) {
bundle.putString("cover", newItem.getDisplayCover())
}
if (oldItem.lastCheckCount != newItem.lastCheckCount
|| oldItem.durChapterTime != newItem.durChapterTime
|| oldItem.getUnreadChapterNum() != newItem.getUnreadChapterNum()
|| oldItem.lastCheckCount != newItem.lastCheckCount
) {
bundle.putBoolean("refresh", true)
}
if (bundle.isEmpty) return null
return bundle
} }
}
fun notification(bookUrl: String) { fun notification(bookUrl: String) {
for (i in 0 until itemCount) { for (i in 0 until itemCount) {
callBack.getItem(i).let { callBack.getItem(i).let {

@ -44,8 +44,8 @@ class RssSourceAdapter(context: Context, val callBack: CallBack) :
override fun areContentsTheSame(oldItem: RssSource, newItem: RssSource): Boolean { override fun areContentsTheSame(oldItem: RssSource, newItem: RssSource): Boolean {
return oldItem.sourceName == newItem.sourceName return oldItem.sourceName == newItem.sourceName
&& oldItem.sourceGroup == newItem.sourceGroup && oldItem.sourceGroup == newItem.sourceGroup
&& oldItem.enabled == newItem.enabled && oldItem.enabled == newItem.enabled
} }
override fun getChangePayload(oldItem: RssSource, newItem: RssSource): Any? { override fun getChangePayload(oldItem: RssSource, newItem: RssSource): Any? {

@ -69,7 +69,7 @@ class BatteryView @JvmOverloads constructor(
.getPrimaryHorizontal(text.length - battery.toString().length) .getPrimaryHorizontal(text.length - battery.toString().length)
.toInt() + 2.dpToPx() .toInt() + 2.dpToPx()
val batteryEnd = batteryStart + val batteryEnd = batteryStart +
StaticLayout.getDesiredWidth(battery.toString(), paint).toInt() + 4.dpToPx() StaticLayout.getDesiredWidth(battery.toString(), paint).toInt() + 4.dpToPx()
outFrame.set( outFrame.set(
batteryStart, batteryStart,
2.dpToPx(), 2.dpToPx(),

@ -109,7 +109,10 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
* @param saveTime 保存的时间单位 * @param saveTime 保存的时间单位
*/ */
fun put(key: String, value: String, saveTime: Int) { fun put(key: String, value: String, saveTime: Int) {
if (saveTime == 0) put(key, value) else put(key, Utils.newStringWithDateInfo(saveTime, value)) if (saveTime == 0) put(key, value) else put(
key,
Utils.newStringWithDateInfo(saveTime, value)
)
} }
/** /**
@ -245,7 +248,8 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
* @param saveTime 保存的时间单位 * @param saveTime 保存的时间单位
*/ */
fun put(key: String, value: ByteArray, saveTime: Int) { fun put(key: String, value: ByteArray, saveTime: Int) {
if (saveTime == 0) put(key, value) else put(key, Utils.newByteArrayWithDateInfo(saveTime, value)) if (saveTime == 0) put(key, value)
else put(key, Utils.newByteArrayWithDateInfo(saveTime, value))
} }
/** /**

@ -162,8 +162,8 @@ fun Context.restart() {
intent?.let { intent?.let {
intent.addFlags( intent.addFlags(
Intent.FLAG_ACTIVITY_NEW_TASK Intent.FLAG_ACTIVITY_NEW_TASK
or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
) )
startActivity(intent) startActivity(intent)
//杀掉以前进程 //杀掉以前进程
@ -327,6 +327,7 @@ fun Context.openFileUri(uri: Uri, type: String? = null) {
} }
} }
@Suppress("DEPRECATION")
val Context.isWifiConnect: Boolean val Context.isWifiConnect: Boolean
get() { get() {
val info = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI) val info = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)

@ -278,7 +278,7 @@ object FileUtils {
//返回当前目录所有以某些扩展名结尾的文件 //返回当前目录所有以某些扩展名结尾的文件
val extension = getExtension(name) val extension = getExtension(name)
allowExtensions?.contentDeepToString()?.contains(extension) == true allowExtensions?.contentDeepToString()?.contains(extension) == true
|| allowExtensions == null || allowExtensions == null
} }
} }

@ -231,7 +231,7 @@ object NetworkUtils {
*/ */
private val IPV4_PATTERN = Pattern.compile( private val IPV4_PATTERN = Pattern.compile(
"^(" + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" + "^(" + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" +
"([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$" "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
) )
/** /**

@ -7,9 +7,9 @@ object Utf8BomUtils {
fun removeUTF8BOM(xmlText: String): String { fun removeUTF8BOM(xmlText: String): String {
val bytes = xmlText.toByteArray() val bytes = xmlText.toByteArray()
val containsBOM = (bytes.size > 3 val containsBOM = (bytes.size > 3
&& bytes[0] == UTF8_BOM_BYTES[0] && bytes[0] == UTF8_BOM_BYTES[0]
&& bytes[1] == UTF8_BOM_BYTES[1] && bytes[1] == UTF8_BOM_BYTES[1]
&& bytes[2] == UTF8_BOM_BYTES[2]) && bytes[2] == UTF8_BOM_BYTES[2])
if (containsBOM) { if (containsBOM) {
return String(bytes, 3, bytes.size - 3) return String(bytes, 3, bytes.size - 3)
} }
@ -18,9 +18,9 @@ object Utf8BomUtils {
fun removeUTF8BOM(bytes: ByteArray): ByteArray { fun removeUTF8BOM(bytes: ByteArray): ByteArray {
val containsBOM = (bytes.size > 3 val containsBOM = (bytes.size > 3
&& bytes[0] == UTF8_BOM_BYTES[0] && bytes[0] == UTF8_BOM_BYTES[0]
&& bytes[1] == UTF8_BOM_BYTES[1] && bytes[1] == UTF8_BOM_BYTES[1]
&& bytes[2] == UTF8_BOM_BYTES[2]) && bytes[2] == UTF8_BOM_BYTES[2])
if (containsBOM) { if (containsBOM) {
val copy = ByteArray(bytes.size - 3) val copy = ByteArray(bytes.size - 3)
System.arraycopy(bytes, 3, copy, 0, bytes.size - 3) System.arraycopy(bytes, 3, copy, 0, bytes.size - 3)
@ -31,8 +31,8 @@ object Utf8BomUtils {
fun hasBom(bytes: ByteArray): Boolean { fun hasBom(bytes: ByteArray): Boolean {
return (bytes.size > 3 return (bytes.size > 3
&& bytes[0] == UTF8_BOM_BYTES[0] && bytes[0] == UTF8_BOM_BYTES[0]
&& bytes[1] == UTF8_BOM_BYTES[1] && bytes[1] == UTF8_BOM_BYTES[1]
&& bytes[2] == UTF8_BOM_BYTES[2]) && bytes[2] == UTF8_BOM_BYTES[2])
} }
} }
Loading…
Cancel
Save