Merge remote-tracking branch 'origin/master'

This commit is contained in:
kunfei
2023-11-23 11:28:44 +08:00
8 changed files with 70 additions and 39 deletions

View File

@@ -19,6 +19,7 @@ import kotlin.coroutines.CoroutineContext
/**
* 链式协程
* 注意:如果协程太快完成,回调会不执行
*/
@Suppress("unused", "MemberVisibilityCanBePrivate")
class Coroutine<T>(

View File

@@ -18,6 +18,7 @@ import io.legado.app.utils.postEvent
import io.legado.app.utils.startService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.delay
@@ -268,6 +269,7 @@ object CacheBook {
book,
chapter,
context = context,
start = CoroutineStart.LAZY,
executeContext = context
).onSuccess { content ->
onSuccess(chapter)
@@ -282,7 +284,7 @@ object CacheBook {
onCancel(chapterIndex)
}.onFinally {
onFinally()
}
}.start()
}
@Synchronized
@@ -297,22 +299,28 @@ object CacheBook {
postEvent(EventBus.UP_DOWNLOAD, book.bookUrl)
onDownloadSet.add(chapter.index)
waitDownloadSet.remove(chapter.index)
WebBook.getContent(scope, bookSource, book, chapter, executeContext = IO)
.onSuccess { content ->
onSuccess(chapter)
ReadBook.downloadedChapters.add(chapter.index)
ReadBook.downloadFailChapters.remove(chapter.index)
downloadFinish(chapter, content, resetPageOffset)
}.onError {
onError(chapter, it)
ReadBook.downloadFailChapters[chapter.index] =
(ReadBook.downloadFailChapters[chapter.index] ?: 0) + 1
downloadFinish(chapter, "获取正文失败\n${it.localizedMessage}", resetPageOffset)
}.onCancel {
onCancel(chapter.index)
}.onFinally {
postEvent(EventBus.UP_DOWNLOAD, book.bookUrl)
}
WebBook.getContent(
scope,
bookSource,
book,
chapter,
start = CoroutineStart.LAZY,
executeContext = IO
).onSuccess { content ->
onSuccess(chapter)
ReadBook.downloadedChapters.add(chapter.index)
ReadBook.downloadFailChapters.remove(chapter.index)
downloadFinish(chapter, content, resetPageOffset)
}.onError {
onError(chapter, it)
ReadBook.downloadFailChapters[chapter.index] =
(ReadBook.downloadFailChapters[chapter.index] ?: 0) + 1
downloadFinish(chapter, "获取正文失败\n${it.localizedMessage}", resetPageOffset)
}.onCancel {
onCancel(chapter.index)
}.onFinally {
postEvent(EventBus.UP_DOWNLOAD, book.bookUrl)
}.start()
}
private fun downloadFinish(

View File

@@ -11,6 +11,7 @@ import io.legado.app.help.coroutine.CompositeCoroutine
import io.legado.app.ui.book.search.SearchScope
import io.legado.app.utils.getPrefBoolean
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.ExecutorCoroutineDispatcher
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.ensureActive
@@ -76,7 +77,7 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
return
}
searchIndex++
val source = bookSourceList[searchIndex]
val source = bookSourceList.getOrNull(searchIndex) ?: return
val searchPool = searchPool ?: return
val task = WebBook.searchBook(
scope,
@@ -84,6 +85,7 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
searchKey,
searchPage,
context = searchPool,
start = CoroutineStart.LAZY,
executeContext = searchPool
).timeout(30000L)
.onSuccess {
@@ -93,6 +95,7 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
.onFinally {
onFinally(searchId)
}
task.start()
tasks.add(task)
}

View File

@@ -14,6 +14,7 @@ import io.legado.app.model.analyzeRule.AnalyzeRule
import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.model.analyzeRule.RuleData
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.isActive
import kotlin.coroutines.CoroutineContext
@@ -30,9 +31,10 @@ object WebBook {
key: String,
page: Int? = 1,
context: CoroutineContext = Dispatchers.IO,
start: CoroutineStart = CoroutineStart.DEFAULT,
executeContext: CoroutineContext = Dispatchers.Main,
): Coroutine<ArrayList<SearchBook>> {
return Coroutine.async(scope, context, executeContext = executeContext) {
return Coroutine.async(scope, context, start = start, executeContext = executeContext) {
searchBookAwait(bookSource, key, page)
}
}
@@ -266,9 +268,10 @@ object WebBook {
nextChapterUrl: String? = null,
needSave: Boolean = true,
context: CoroutineContext = Dispatchers.IO,
start: CoroutineStart = CoroutineStart.DEFAULT,
executeContext: CoroutineContext = Dispatchers.Main,
): Coroutine<String> {
return Coroutine.async(scope, context, executeContext = executeContext) {
return Coroutine.async(scope, context, start = start, executeContext = executeContext) {
getContentAwait(bookSource, book, bookChapter, nextChapterUrl, needSave)
}
}

View File

@@ -452,7 +452,7 @@ class AudioPlayService : BaseService(),
.setBufferedPosition(exoPlayer.bufferedPosition)
.addCustomAction(
APP_ACTION_STOP,
getString(R.string.set_timer),
getString(R.string.stop),
R.drawable.ic_stop_black_24dp
)
.addCustomAction(

View File

@@ -200,9 +200,13 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
}
++searchIndex
}
val source = bookSourceList[searchIndex]
val source = bookSourceList.getOrNull(searchIndex) ?: return
bookSourceList[searchIndex] = emptyBookSource
val task = execute(context = searchPool!!, executeContext = searchPool!!) {
val task = execute(
context = searchPool!!,
start = CoroutineStart.LAZY,
executeContext = searchPool!!
) {
val resultBooks = WebBook.searchBookAwait(source, name)
resultBooks.forEach { searchBook ->
if (searchBook.name != name) {
@@ -223,11 +227,14 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
}
}.timeout(60000L)
.onError {
ensureActive()
nextSearch()
}
.onSuccess {
ensureActive()
nextSearch()
}
task.start()
tasks.add(task)
}
@@ -293,8 +300,9 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
searchCallback?.searchSuccess(searchBook)
}
@Synchronized
private fun nextSearch() {
synchronized(this) {
kotlin.runCatching {
if (searchIndex < bookSourceList.lastIndex) {
search()
} else {

View File

@@ -36,6 +36,7 @@ import org.apache.commons.text.StringEscapeUtils
import org.jsoup.Jsoup
import java.io.ByteArrayInputStream
import java.net.URLDecoder
import java.util.regex.PatternSyntaxException
/**
* rss阅读界面
@@ -346,24 +347,32 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
request: WebResourceRequest
): WebResourceResponse? {
val url = request.url.toString()
viewModel.rssSource?.let { source ->
val blacklist = source.contentBlacklist?.splitNotBlank(",")
if (!blacklist.isNullOrEmpty()) {
blacklist.forEach {
val source = viewModel.rssSource ?: return super.shouldInterceptRequest(view, request)
val blacklist = source.contentBlacklist?.splitNotBlank(",")
if (!blacklist.isNullOrEmpty()) {
blacklist.forEach {
try {
if (url.startsWith(it) || url.matches(it.toRegex())) {
return createEmptyResource()
}
} catch (e: PatternSyntaxException) {
AppLog.put("黑名单规则正则语法错误 源名称:${source.sourceName} 正则:$it", e)
}
} else {
val whitelist = source.contentWhitelist?.splitNotBlank(",")
if (!whitelist.isNullOrEmpty()) {
whitelist.forEach {
}
} else {
val whitelist = source.contentWhitelist?.splitNotBlank(",")
if (!whitelist.isNullOrEmpty()) {
whitelist.forEach {
try {
if (url.startsWith(it) || url.matches(it.toRegex())) {
return super.shouldInterceptRequest(view, request)
}
} catch (e: PatternSyntaxException) {
val msg = "白名单规则正则语法错误 源名称:${source.sourceName} 正则:$it"
AppLog.put(msg, e)
}
return createEmptyResource()
}
return createEmptyResource()
}
}
return super.shouldInterceptRequest(view, request)

View File

@@ -4,6 +4,7 @@ package io.legado.app.utils
import android.annotation.SuppressLint
import android.content.Context
import android.view.View
import android.widget.TextView
import android.widget.Toast
import androidx.cardview.widget.CardView
@@ -28,12 +29,10 @@ fun Context.toastOnUi(message: Int, duration: Int = Toast.LENGTH_SHORT) {
fun Context.toastOnUi(message: CharSequence?, duration: Int = Toast.LENGTH_SHORT) {
runOnUI {
kotlin.runCatching {
if (toast == null || BuildConfig.DEBUG || AppConfig.recordLog) {
toast?.cancel()
toast = Toast(this)
toast?.view = inflate(R.layout.view_toast)
}
val toastView = toast?.view!!
toast?.cancel()
toast = Toast(this)
val toastView: View = inflate(R.layout.view_toast)
toast?.view = toastView
val cardView = toastView.findViewById<CardView>(R.id.cv_content)
cardView.setCardBackgroundColor(bottomBackground)
val isLight = ColorUtils.isColorLight(bottomBackground)