mirror of
https://github.com/gedoor/legado.git
synced 2025-08-10 00:52:30 +00:00
格式化代码
This commit is contained in:
@@ -10,6 +10,7 @@ object AppPattern {
|
||||
|
||||
//匹配格式化后的图片格式
|
||||
val imgPattern: Pattern = Pattern.compile("<img[^>]*src=\"([^\"]*(?:\"[^>]+\\})?)\"[^>]*>")
|
||||
|
||||
//dataURL图片类型
|
||||
val dataUriRegex = Regex("data:.*?;base64,(.*)")
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# 存储数据用
|
||||
|
||||
* dao 数据操作
|
||||
* entities 数据模型
|
||||
* \Book 书籍信息
|
||||
|
||||
@@ -183,22 +183,22 @@ data class BookSource(
|
||||
|
||||
fun equal(source: BookSource) =
|
||||
equal(bookSourceName, source.bookSourceName)
|
||||
&& equal(bookSourceUrl, source.bookSourceUrl)
|
||||
&& equal(bookSourceGroup, source.bookSourceGroup)
|
||||
&& bookSourceType == source.bookSourceType
|
||||
&& equal(bookUrlPattern, source.bookUrlPattern)
|
||||
&& equal(bookSourceComment, source.bookSourceComment)
|
||||
&& enabled == source.enabled
|
||||
&& enabledExplore == source.enabledExplore
|
||||
&& equal(header, source.header)
|
||||
&& loginUrl == source.loginUrl
|
||||
&& equal(exploreUrl, source.exploreUrl)
|
||||
&& equal(searchUrl, source.searchUrl)
|
||||
&& getSearchRule() == source.getSearchRule()
|
||||
&& getExploreRule() == source.getExploreRule()
|
||||
&& getBookInfoRule() == source.getBookInfoRule()
|
||||
&& getTocRule() == source.getTocRule()
|
||||
&& getContentRule() == source.getContentRule()
|
||||
&& equal(bookSourceUrl, source.bookSourceUrl)
|
||||
&& equal(bookSourceGroup, source.bookSourceGroup)
|
||||
&& bookSourceType == source.bookSourceType
|
||||
&& equal(bookUrlPattern, source.bookUrlPattern)
|
||||
&& equal(bookSourceComment, source.bookSourceComment)
|
||||
&& enabled == source.enabled
|
||||
&& enabledExplore == source.enabledExplore
|
||||
&& equal(header, source.header)
|
||||
&& loginUrl == source.loginUrl
|
||||
&& equal(exploreUrl, source.exploreUrl)
|
||||
&& equal(searchUrl, source.searchUrl)
|
||||
&& getSearchRule() == source.getSearchRule()
|
||||
&& getExploreRule() == source.getExploreRule()
|
||||
&& getBookInfoRule() == source.getBookInfoRule()
|
||||
&& getTocRule() == source.getTocRule()
|
||||
&& getContentRule() == source.getContentRule()
|
||||
|
||||
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 {
|
||||
return equal(sourceUrl, source.sourceUrl)
|
||||
&& equal(sourceIcon, source.sourceIcon)
|
||||
&& enabled == source.enabled
|
||||
&& equal(sourceGroup, source.sourceGroup)
|
||||
&& equal(ruleArticles, source.ruleArticles)
|
||||
&& equal(ruleNextPage, source.ruleNextPage)
|
||||
&& equal(ruleTitle, source.ruleTitle)
|
||||
&& equal(rulePubDate, source.rulePubDate)
|
||||
&& equal(ruleDescription, source.ruleDescription)
|
||||
&& equal(ruleLink, source.ruleLink)
|
||||
&& equal(ruleContent, source.ruleContent)
|
||||
&& enableJs == source.enableJs
|
||||
&& loadWithBaseUrl == source.loadWithBaseUrl
|
||||
&& equal(sourceIcon, source.sourceIcon)
|
||||
&& enabled == source.enabled
|
||||
&& equal(sourceGroup, source.sourceGroup)
|
||||
&& equal(ruleArticles, source.ruleArticles)
|
||||
&& equal(ruleNextPage, source.ruleNextPage)
|
||||
&& equal(ruleTitle, source.ruleTitle)
|
||||
&& equal(rulePubDate, source.rulePubDate)
|
||||
&& equal(ruleDescription, source.ruleDescription)
|
||||
&& equal(ruleLink, source.ruleLink)
|
||||
&& equal(ruleContent, source.ruleContent)
|
||||
&& enableJs == source.enableJs
|
||||
&& loadWithBaseUrl == source.loadWithBaseUrl
|
||||
}
|
||||
|
||||
private fun equal(a: String?, b: String?): Boolean {
|
||||
|
||||
@@ -324,9 +324,9 @@ object BookHelp {
|
||||
val chapterName1 = StringUtils.fullToHalf(chapterName).replace(regexA, "")
|
||||
return StringUtils.stringToInt(
|
||||
(
|
||||
chapterNamePattern1.matcher(chapterName1).takeIf { it.find() }
|
||||
?: chapterNamePattern2.matcher(chapterName1).takeIf { it.find() }
|
||||
)?.group(1)
|
||||
chapterNamePattern1.matcher(chapterName1).takeIf { it.find() }
|
||||
?: chapterNamePattern2.matcher(chapterName1).takeIf { it.find() }
|
||||
)?.group(1)
|
||||
?: "-1"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
package io.legado.app.help
|
||||
|
||||
|
||||
@Suppress("RegExpRedundantEscape")
|
||||
object RuleComplete {
|
||||
// 需要补全
|
||||
private val needComplete =Regex(
|
||||
"""(?<!(@|/|^|[|%&]{2})(attr|text|ownText|textNodes|href|content|html|alt|all|value|src)(\(\))?)(?<seq>\&{2}|%%|\|{2}|$)""")
|
||||
private val needComplete = Regex(
|
||||
"""(?<!(@|/|^|[|%&]{2})(attr|text|ownText|textNodes|href|content|html|alt|all|value|src)(\(\))?)(?<seq>\&{2}|%%|\|{2}|$)"""
|
||||
)
|
||||
|
||||
// 不能补全 存在js/json/{{xx}}的复杂情况
|
||||
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,
|
||||
type: Int = 1
|
||||
): String? {
|
||||
if (rules.isNullOrEmpty()||rules.contains(notComplete) || preRule?.contains(notComplete) ?: false){
|
||||
if (rules.isNullOrEmpty() || rules.contains(notComplete) || preRule?.contains(notComplete) == true) {
|
||||
return rules
|
||||
}
|
||||
|
||||
/** 尾部##分割的正则或由,分割的参数 */
|
||||
val tailStr: String
|
||||
|
||||
/** 分割字符 */
|
||||
val splitStr:String
|
||||
val splitStr: String
|
||||
|
||||
/** 用于获取文字时添加的规则 */
|
||||
val textRule: String
|
||||
|
||||
/** 用于获取链接时添加的规则 */
|
||||
val linkRule: String
|
||||
|
||||
/** 用于获取图片时添加的规则 */
|
||||
val imgRule: String
|
||||
|
||||
/** 用于获取图片alt属性时添加的规则 */
|
||||
val imgText: String
|
||||
|
||||
// 分离尾部规则
|
||||
val regexSplit=rules.split("""##|,\{""".toRegex(),2)
|
||||
val cleanedRule=regexSplit[0]
|
||||
if (regexSplit.size>1){
|
||||
splitStr="""##|,\{""".toRegex().find(rules)?.value ?: ""
|
||||
val regexSplit = rules.split("""##|,\{""".toRegex(), 2)
|
||||
val cleanedRule = regexSplit[0]
|
||||
if (regexSplit.size > 1) {
|
||||
splitStr = """##|,\{""".toRegex().find(rules)?.value ?: ""
|
||||
tailStr = splitStr + regexSplit[1]
|
||||
}else{
|
||||
} else {
|
||||
tailStr = ""
|
||||
}
|
||||
if (cleanedRule.contains(isXpath)){
|
||||
if (cleanedRule.contains(isXpath)) {
|
||||
textRule = "//text()\${seq}"
|
||||
linkRule = "//@href\${seq}"
|
||||
imgRule = "//@src\${seq}"
|
||||
|
||||
@@ -173,7 +173,7 @@ public final class OkhttpCacheDataSource implements DataSource {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Factory setDefaultRequestProperties(Map<String, String> defaultRequestProperties){
|
||||
public Factory setDefaultRequestProperties(Map<String, String> defaultRequestProperties) {
|
||||
if (this.upstreamDataSourceFactory != null) {
|
||||
this.upstreamDataSourceFactory.setDefaultRequestProperties(defaultRequestProperties);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ object CookieStore : CookieManager {
|
||||
val cookieBean = appDb.cookieDao.get(NetworkUtils.getSubDomain(url))
|
||||
return cookieBean?.cookie ?: ""
|
||||
}
|
||||
|
||||
|
||||
fun getKey(url: String, key: String): String {
|
||||
val cookie = getCookie(url)
|
||||
val cookieMap = cookieToMap(cookie)
|
||||
|
||||
@@ -27,7 +27,7 @@ val okHttpClient: OkHttpClient by lazy {
|
||||
.connectTimeout(15, TimeUnit.SECONDS)
|
||||
.writeTimeout(15, TimeUnit.SECONDS)
|
||||
.readTimeout(15, TimeUnit.SECONDS)
|
||||
.callTimeout(60,TimeUnit.SECONDS)
|
||||
.callTimeout(60, TimeUnit.SECONDS)
|
||||
.sslSocketFactory(SSLHelper.unsafeSSLSocketFactory, SSLHelper.unsafeTrustManager)
|
||||
.retryOnConnectionFailure(true)
|
||||
.hostnameVerifier(SSLHelper.unsafeHostnameVerifier)
|
||||
|
||||
@@ -34,13 +34,14 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
|
||||
private var cpuAbi: String? = null
|
||||
private var md5: String
|
||||
var download = false
|
||||
|
||||
@Volatile
|
||||
private var cacheInstall = false
|
||||
|
||||
init {
|
||||
soUrl = ("https://storage.googleapis.com/chromium-cronet/android/"
|
||||
+ soVersion + "/Release/cronet/libs/"
|
||||
+ getCpuAbi(appCtx) + "/" + soName)
|
||||
+ soVersion + "/Release/cronet/libs/"
|
||||
+ getCpuAbi(appCtx) + "/" + soName)
|
||||
md5 = getMd5(appCtx)
|
||||
val dir = appCtx.getDir("cronet", Context.MODE_PRIVATE)
|
||||
soFile = File(dir.toString() + "/" + getCpuAbi(appCtx), soName)
|
||||
|
||||
@@ -205,7 +205,7 @@ object AppWebDav {
|
||||
getBookProgress(book)?.let { bookProgress ->
|
||||
if (bookProgress.durChapterIndex > book.durChapterIndex ||
|
||||
(bookProgress.durChapterIndex == book.durChapterIndex &&
|
||||
bookProgress.durChapterPos > book.durChapterPos)
|
||||
bookProgress.durChapterPos > book.durChapterPos)
|
||||
) {
|
||||
book.durChapterIndex = bookProgress.durChapterIndex
|
||||
book.durChapterPos = bookProgress.durChapterPos
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# 放置一些copy过来的库
|
||||
|
||||
* dialogs 弹出框
|
||||
* icu4j 编码识别库
|
||||
* permission 权限申请库
|
||||
|
||||
@@ -11,6 +11,7 @@ import splitties.init.appCtx
|
||||
|
||||
object CheckSource {
|
||||
var keyword = "我的"
|
||||
|
||||
//校验设置
|
||||
var timeout = CacheManager.getLong("checkSourceTimeout") ?: 180000L
|
||||
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 (checkCategory) checkItem = "$checkItem ${appCtx.getString(R.string.chapter_list)}"
|
||||
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) {
|
||||
val time =
|
||||
debugTimeFormat.format(Date(System.currentTimeMillis() - debugTimeMap[sourceUrl]!!))
|
||||
printMsg = printMsg.replace(AppPattern.debugMessageSymbolRegex,"")
|
||||
printMsg = printMsg.replace(AppPattern.debugMessageSymbolRegex, "")
|
||||
|
||||
debugMessageMap[sourceUrl] = "$time $printMsg"
|
||||
}
|
||||
@@ -93,7 +93,8 @@ object Debug {
|
||||
fun updateFinalMessage(sourceUrl: String, state: String) {
|
||||
if (debugTimeMap[sourceUrl] != null && debugMessageMap[sourceUrl] != null) {
|
||||
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))
|
||||
debugMessageMap[sourceUrl] = "$printTime $state"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# 放置一些模块类
|
||||
|
||||
* analyzeRule 书源规则解析
|
||||
* localBook 本地书籍解析
|
||||
* rss 订阅规则解析
|
||||
|
||||
@@ -91,7 +91,7 @@ object ReadBook : CoroutineScope by MainScope() {
|
||||
fun setProgress(progress: BookProgress) {
|
||||
if (progress.durChapterIndex < chapterSize &&
|
||||
(durChapterIndex != progress.durChapterIndex
|
||||
|| durChapterPos != progress.durChapterPos)
|
||||
|| durChapterPos != progress.durChapterPos)
|
||||
) {
|
||||
durChapterIndex = progress.durChapterIndex
|
||||
durChapterPos = progress.durChapterPos
|
||||
|
||||
@@ -600,9 +600,9 @@ class AnalyzeRule(
|
||||
|
||||
private fun isRule(ruleStr: String): Boolean {
|
||||
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)
|
||||
}.timeout(CheckSource.timeout)
|
||||
.onError(searchCoroutine) {
|
||||
when(it) {
|
||||
when (it) {
|
||||
is TimeoutCancellationException -> source.addGroup("校验超时")
|
||||
is ScriptException, is WrappedException -> source.addGroup("js失效")
|
||||
!is NoStackTraceException -> source.addGroup("网站失效")
|
||||
|
||||
@@ -229,7 +229,7 @@ class HttpReadAloudService : BaseReadAloudService(),
|
||||
|
||||
private fun md5SpeakFileName(url: String, ttsConfig: String, content: String): String {
|
||||
return MD5Utils.md5Encode16(textChapter?.title ?: "") + "_" +
|
||||
MD5Utils.md5Encode16("$url-|-$ttsConfig-|-$content")
|
||||
MD5Utils.md5Encode16("$url-|-$ttsConfig-|-$content")
|
||||
}
|
||||
|
||||
private fun createSilentSound(fileName: String) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# android服务
|
||||
|
||||
* AudioPlayService 音频播放服务
|
||||
* CheckSourceService 书源检测服务
|
||||
* DownloadService 缓存服务
|
||||
|
||||
@@ -28,7 +28,8 @@ fun TimerDialog(state: MutableState<Boolean>, parent: View) {
|
||||
Card(Modifier.fillMaxWidth()) {
|
||||
Slider(
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
value = timeMinute.value.toFloat(), onValueChange = {
|
||||
value = timeMinute.value.toFloat(),
|
||||
onValueChange = {
|
||||
timeMinute.value = it.toInt()
|
||||
AudioPlay.setTimer(it.toInt())
|
||||
},
|
||||
|
||||
@@ -48,7 +48,7 @@ class BookmarkAdapter(context: Context, val callback: Callback) :
|
||||
val lastItem = getItem(position - 1)
|
||||
val curItem = getItem(position)
|
||||
return !(lastItem?.bookName == curItem?.bookName
|
||||
&& lastItem?.bookAuthor == curItem?.bookAuthor)
|
||||
&& lastItem?.bookAuthor == curItem?.bookAuthor)
|
||||
}
|
||||
|
||||
interface Callback {
|
||||
|
||||
@@ -278,7 +278,7 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
|
||||
when {
|
||||
//正文模板
|
||||
file.name.equals("chapter.html", true)
|
||||
|| file.name.equals("chapter.xhtml", true) -> {
|
||||
|| file.name.equals("chapter.xhtml", true) -> {
|
||||
contentModel = file.readText(context)
|
||||
}
|
||||
//封面等其他模板
|
||||
|
||||
@@ -29,7 +29,7 @@ class ChangeChapterSourceAdapter(
|
||||
|
||||
override fun areContentsTheSame(oldItem: SearchBook, newItem: SearchBook): Boolean {
|
||||
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 viewModel by viewModels<ReadBookViewModel>()
|
||||
var bottomDialog = 0
|
||||
private val selectBookFolderResult = registerForActivityResult(HandleFileContract()){
|
||||
private val selectBookFolderResult = registerForActivityResult(HandleFileContract()) {
|
||||
it.uri?.let {
|
||||
ReadBook.book?.let { book ->
|
||||
viewModel.loadChapterList(book)
|
||||
|
||||
@@ -178,7 +178,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
|
||||
}.onSuccess { progress ->
|
||||
if (progress.durChapterIndex < book.durChapterIndex ||
|
||||
(progress.durChapterIndex == book.durChapterIndex
|
||||
&& progress.durChapterPos < book.durChapterPos)
|
||||
&& progress.durChapterPos < book.durChapterPos)
|
||||
) {
|
||||
alertSync?.invoke(progress)
|
||||
} else {
|
||||
|
||||
@@ -145,7 +145,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
drawImage(canvas, it, lineTop, lineBottom, isImageLine)
|
||||
} else {
|
||||
textPaint.color = textColor
|
||||
if(it.isSearchResult) {
|
||||
if (it.isSearchResult) {
|
||||
textPaint.color = context.accentColor
|
||||
}
|
||||
canvas.drawText(it.charData, it.start, lineBase, textPaint)
|
||||
|
||||
@@ -622,8 +622,8 @@ object ChapterProvider {
|
||||
*/
|
||||
fun upLayout() {
|
||||
doublePage = (viewWidth > viewHeight || appCtx.isPad)
|
||||
&& ReadBook.pageAnim() != 3
|
||||
&& AppConfig.doublePageHorizontal
|
||||
&& ReadBook.pageAnim() != 3
|
||||
&& AppConfig.doublePageHorizontal
|
||||
if (viewWidth > 0 && viewHeight > 0) {
|
||||
paddingLeft = ReadBookConfig.paddingLeft.dpToPx()
|
||||
paddingTop = ReadBookConfig.paddingTop.dpToPx()
|
||||
|
||||
@@ -44,12 +44,15 @@ class SearchContentViewModel(application: Application) : BaseViewModel(applicati
|
||||
//先搜索没有启用净化的正文
|
||||
withContext(Dispatchers.IO) {
|
||||
chapter.title = when (AppConfig.chineseConverterType) {
|
||||
1 -> ChineseUtils.t2s(chapter.title)
|
||||
2 -> ChineseUtils.s2t(chapter.title)
|
||||
1 -> ChineseUtils.t2s(chapter.title)
|
||||
2 -> ChineseUtils.s2t(chapter.title)
|
||||
else -> chapter.title
|
||||
}
|
||||
mContent = contentProcessor!!.getContent(
|
||||
book, chapter, chapterContent, chineseConvert = false, reSegment = false, useReplace = false
|
||||
book, chapter, chapterContent,
|
||||
chineseConvert = false,
|
||||
reSegment = false,
|
||||
useReplace = false
|
||||
).joinToString("")
|
||||
}
|
||||
val positions = searchPosition(query)
|
||||
@@ -90,7 +93,11 @@ class SearchContentViewModel(application: Application) : BaseViewModel(applicati
|
||||
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个字符,构建关键词周边文字,在搜索结果里显示
|
||||
// todo: 判断段落,只在关键词所在段落内分割
|
||||
// todo: 利用标点符号分割完整的句
|
||||
|
||||
@@ -23,9 +23,9 @@ data class SearchResult(
|
||||
val rightString =
|
||||
resultText.substring(queryIndexInSurrounding + query.length, resultText.length)
|
||||
val html = leftString.colorTextForHtml(textColor) +
|
||||
query.colorTextForHtml(accentColor) +
|
||||
rightString.colorTextForHtml(textColor) +
|
||||
chapterTitle.colorTextForHtml(accentColor)
|
||||
query.colorTextForHtml(accentColor) +
|
||||
rightString.colorTextForHtml(textColor) +
|
||||
chapterTitle.colorTextForHtml(accentColor)
|
||||
HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY)
|
||||
} else {
|
||||
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 {
|
||||
return oldItem.bookSourceName == newItem.bookSourceName
|
||||
&& oldItem.bookSourceGroup == newItem.bookSourceGroup
|
||||
&& oldItem.enabled == newItem.enabled
|
||||
&& oldItem.enabledExplore == newItem.enabledExplore
|
||||
&& oldItem.exploreUrl == newItem.exploreUrl
|
||||
&& oldItem.bookSourceGroup == newItem.bookSourceGroup
|
||||
&& oldItem.enabled == newItem.enabled
|
||||
&& oldItem.enabledExplore == newItem.enabledExplore
|
||||
&& oldItem.exploreUrl == newItem.exploreUrl
|
||||
}
|
||||
|
||||
override fun getChangePayload(oldItem: BookSource, newItem: BookSource): Any? {
|
||||
|
||||
@@ -43,12 +43,12 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
|
||||
newItem: BookChapter
|
||||
): Boolean {
|
||||
return oldItem.bookUrl == newItem.bookUrl
|
||||
&& oldItem.url == newItem.url
|
||||
&& oldItem.isVip == newItem.isVip
|
||||
&& oldItem.isPay == newItem.isPay
|
||||
&& oldItem.title == newItem.title
|
||||
&& oldItem.tag == newItem.tag
|
||||
&& oldItem.isVolume == newItem.isVolume
|
||||
&& oldItem.url == newItem.url
|
||||
&& oldItem.isVip == newItem.isVip
|
||||
&& oldItem.isPay == newItem.isPay
|
||||
&& oldItem.title == newItem.title
|
||||
&& oldItem.tag == newItem.tag
|
||||
&& oldItem.isVolume == newItem.isVolume
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import splitties.views.onClick
|
||||
class CheckSourceConfig : BaseDialogFragment(R.layout.dialog_check_source_config) {
|
||||
|
||||
private val binding by viewBinding(DialogCheckSourceConfigBinding::bind)
|
||||
|
||||
//允许的最小超时时间,秒
|
||||
private val minTimeout = 0L
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@ class DictViewModel(application: Application) : BaseViewModel(application) {
|
||||
var dictHtmlData: MutableLiveData<String> = MutableLiveData()
|
||||
|
||||
fun dict(word: String) {
|
||||
if(isChinese(word)){
|
||||
if (isChinese(word)) {
|
||||
baiduDict(word)
|
||||
}else{
|
||||
} else {
|
||||
haiciDict(word)
|
||||
}
|
||||
|
||||
|
||||
@@ -22,46 +22,46 @@ abstract class BaseBooksAdapter<VH : RecyclerView.ViewHolder>(
|
||||
return when {
|
||||
oldItem.durChapterTime != newItem.durChapterTime -> false
|
||||
oldItem.name != newItem.name -> false
|
||||
oldItem.author != newItem.author -> false
|
||||
oldItem.durChapterTitle != newItem.durChapterTitle -> false
|
||||
oldItem.latestChapterTitle != newItem.latestChapterTitle -> false
|
||||
oldItem.lastCheckCount != newItem.lastCheckCount -> false
|
||||
oldItem.getDisplayCover() != newItem.getDisplayCover() -> false
|
||||
oldItem.getUnreadChapterNum() != newItem.getUnreadChapterNum() -> false
|
||||
else -> true
|
||||
}
|
||||
oldItem.author != newItem.author -> false
|
||||
oldItem.durChapterTitle != newItem.durChapterTitle -> false
|
||||
oldItem.latestChapterTitle != newItem.latestChapterTitle -> false
|
||||
oldItem.lastCheckCount != newItem.lastCheckCount -> false
|
||||
oldItem.getDisplayCover() != newItem.getDisplayCover() -> false
|
||||
oldItem.getUnreadChapterNum() != newItem.getUnreadChapterNum() -> false
|
||||
else -> true
|
||||
}
|
||||
|
||||
override fun getChangePayload(oldItem: Book, newItem: Book): Any? {
|
||||
val bundle = bundleOf()
|
||||
if (oldItem.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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun getChangePayload(oldItem: Book, newItem: Book): Any? {
|
||||
val bundle = bundleOf()
|
||||
if (oldItem.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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun notification(bookUrl: String) {
|
||||
for (i in 0 until itemCount) {
|
||||
callBack.getItem(i).let {
|
||||
|
||||
@@ -44,8 +44,8 @@ class RssSourceAdapter(context: Context, val callBack: CallBack) :
|
||||
|
||||
override fun areContentsTheSame(oldItem: RssSource, newItem: RssSource): Boolean {
|
||||
return oldItem.sourceName == newItem.sourceName
|
||||
&& oldItem.sourceGroup == newItem.sourceGroup
|
||||
&& oldItem.enabled == newItem.enabled
|
||||
&& oldItem.sourceGroup == newItem.sourceGroup
|
||||
&& oldItem.enabled == newItem.enabled
|
||||
}
|
||||
|
||||
override fun getChangePayload(oldItem: RssSource, newItem: RssSource): Any? {
|
||||
|
||||
@@ -69,7 +69,7 @@ class BatteryView @JvmOverloads constructor(
|
||||
.getPrimaryHorizontal(text.length - battery.toString().length)
|
||||
.toInt() + 2.dpToPx()
|
||||
val batteryEnd = batteryStart +
|
||||
StaticLayout.getDesiredWidth(battery.toString(), paint).toInt() + 4.dpToPx()
|
||||
StaticLayout.getDesiredWidth(battery.toString(), paint).toInt() + 4.dpToPx()
|
||||
outFrame.set(
|
||||
batteryStart,
|
||||
2.dpToPx(),
|
||||
|
||||
@@ -109,7 +109,10 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
|
||||
* @param saveTime 保存的时间,单位:秒
|
||||
*/
|
||||
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 保存的时间,单位:秒
|
||||
*/
|
||||
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.addFlags(
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
or Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
or Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
)
|
||||
startActivity(intent)
|
||||
//杀掉以前进程
|
||||
@@ -327,6 +327,7 @@ fun Context.openFileUri(uri: Uri, type: String? = null) {
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
val Context.isWifiConnect: Boolean
|
||||
get() {
|
||||
val info = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
|
||||
|
||||
@@ -278,7 +278,7 @@ object FileUtils {
|
||||
//返回当前目录所有以某些扩展名结尾的文件
|
||||
val extension = getExtension(name)
|
||||
allowExtensions?.contentDeepToString()?.contains(extension) == true
|
||||
|| allowExtensions == null
|
||||
|| allowExtensions == null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -231,7 +231,7 @@ object NetworkUtils {
|
||||
*/
|
||||
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])$"
|
||||
"([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 {
|
||||
val bytes = xmlText.toByteArray()
|
||||
val containsBOM = (bytes.size > 3
|
||||
&& bytes[0] == UTF8_BOM_BYTES[0]
|
||||
&& bytes[1] == UTF8_BOM_BYTES[1]
|
||||
&& bytes[2] == UTF8_BOM_BYTES[2])
|
||||
&& bytes[0] == UTF8_BOM_BYTES[0]
|
||||
&& bytes[1] == UTF8_BOM_BYTES[1]
|
||||
&& bytes[2] == UTF8_BOM_BYTES[2])
|
||||
if (containsBOM) {
|
||||
return String(bytes, 3, bytes.size - 3)
|
||||
}
|
||||
@@ -18,9 +18,9 @@ object Utf8BomUtils {
|
||||
|
||||
fun removeUTF8BOM(bytes: ByteArray): ByteArray {
|
||||
val containsBOM = (bytes.size > 3
|
||||
&& bytes[0] == UTF8_BOM_BYTES[0]
|
||||
&& bytes[1] == UTF8_BOM_BYTES[1]
|
||||
&& bytes[2] == UTF8_BOM_BYTES[2])
|
||||
&& bytes[0] == UTF8_BOM_BYTES[0]
|
||||
&& bytes[1] == UTF8_BOM_BYTES[1]
|
||||
&& bytes[2] == UTF8_BOM_BYTES[2])
|
||||
if (containsBOM) {
|
||||
val copy = ByteArray(bytes.size - 3)
|
||||
System.arraycopy(bytes, 3, copy, 0, bytes.size - 3)
|
||||
@@ -31,8 +31,8 @@ object Utf8BomUtils {
|
||||
|
||||
fun hasBom(bytes: ByteArray): Boolean {
|
||||
return (bytes.size > 3
|
||||
&& bytes[0] == UTF8_BOM_BYTES[0]
|
||||
&& bytes[1] == UTF8_BOM_BYTES[1]
|
||||
&& bytes[2] == UTF8_BOM_BYTES[2])
|
||||
&& bytes[0] == UTF8_BOM_BYTES[0]
|
||||
&& bytes[1] == UTF8_BOM_BYTES[1]
|
||||
&& bytes[2] == UTF8_BOM_BYTES[2])
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user